1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "A2dpOffloadCodecFactory.h"
18
19 #include <algorithm>
20 #include <cassert>
21
22 #include "A2dpOffloadCodecAac.h"
23 #include "A2dpOffloadCodecSbc.h"
24
25 namespace aidl::android::hardware::bluetooth::audio {
26
27 /**
28 * Local Capabilities Configuration
29 */
30
31 enum : bool {
32 kEnableAac = true,
33 kEnableSbc = true,
34 };
35
36 /**
37 * Class implementation
38 */
39
A2dpOffloadCodecFactory()40 A2dpOffloadCodecFactory::A2dpOffloadCodecFactory()
41 : name("Offload"), codecs(ranked_codecs_) {
42 ranked_codecs_.reserve(kEnableAac + kEnableSbc);
43
44 if (kEnableAac)
45 ranked_codecs_.push_back(std::make_shared<A2dpOffloadCodecAac>());
46 if (kEnableSbc)
47 ranked_codecs_.push_back(std::make_shared<A2dpOffloadCodecSbc>());
48 }
49
GetCodec(CodecId id) const50 std::shared_ptr<const A2dpOffloadCodec> A2dpOffloadCodecFactory::GetCodec(
51 CodecId id) const {
52 auto codec = std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
53 [&](auto c) { return id == c->info.id; });
54
55 return codec != end(ranked_codecs_) ? *codec : nullptr;
56 }
57
GetConfiguration(const std::vector<A2dpRemoteCapabilities> & remote_capabilities,const A2dpConfigurationHint & hint,A2dpConfiguration * configuration) const58 bool A2dpOffloadCodecFactory::GetConfiguration(
59 const std::vector<A2dpRemoteCapabilities>& remote_capabilities,
60 const A2dpConfigurationHint& hint, A2dpConfiguration* configuration) const {
61 decltype(ranked_codecs_) codecs;
62
63 codecs.reserve(ranked_codecs_.size());
64
65 auto hinted_codec =
66 std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
67 [&](auto c) { return hint.codecId == c->info.id; });
68
69 if (hinted_codec != end(ranked_codecs_)) codecs.push_back(*hinted_codec);
70
71 std::copy_if(begin(ranked_codecs_), end(ranked_codecs_),
72 std::back_inserter(codecs),
73 [&](auto c) { return c != *hinted_codec; });
74
75 for (auto codec : codecs) {
76 auto rc =
77 std::find_if(begin(remote_capabilities), end(remote_capabilities),
78 [&](auto& rc__) { return codec->info.id == rc__.id; });
79
80 if ((rc == end(remote_capabilities)) ||
81 !codec->BuildConfiguration(rc->capabilities, hint.codecParameters,
82 &configuration->configuration))
83 continue;
84
85 configuration->id = codec->info.id;
86 A2dpStatus status = codec->ParseConfiguration(configuration->configuration,
87 &configuration->parameters);
88 assert(status == A2dpStatus::OK);
89
90 configuration->remoteSeid = rc->seid;
91
92 return true;
93 }
94
95 return false;
96 }
97
98 } // namespace aidl::android::hardware::bluetooth::audio
99