blob: 73d8fb178f1001287e156b0ac5ff09edc4cea959 [file] [log] [blame]
Antoine SOULIER4e34d052023-09-29 19:10:07 +00001/*
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
25namespace aidl::android::hardware::bluetooth::audio {
26
27/**
28 * Local Capabilities Configuration
29 */
30
31enum : bool {
32 kEnableAac = true,
33 kEnableSbc = true,
34};
35
36/**
37 * Class implementation
38 */
39
40const A2dpOffloadCodecFactory* A2dpOffloadCodecFactory::GetInstance() {
41 static A2dpOffloadCodecFactory instance;
42 return &instance;
43}
44
45A2dpOffloadCodecFactory::A2dpOffloadCodecFactory()
46 : name("Offload"), codecs(ranked_codecs_) {
47 ranked_codecs_.reserve(kEnableAac + kEnableSbc);
48
49 if (kEnableAac) ranked_codecs_.push_back(A2dpOffloadCodecAac::GetInstance());
50 if (kEnableSbc) ranked_codecs_.push_back(A2dpOffloadCodecSbc::GetInstance());
51}
52
53const A2dpOffloadCodec* A2dpOffloadCodecFactory::GetCodec(CodecId id) const {
54 auto codec = std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
55 [&](auto c) { return id == c->info.id; });
56
57 return codec != end(ranked_codecs_) ? *codec : nullptr;
58}
59
60bool A2dpOffloadCodecFactory::GetConfiguration(
61 const std::vector<A2dpRemoteCapabilities>& remote_capabilities,
62 const A2dpConfigurationHint& hint, A2dpConfiguration* configuration) const {
63 decltype(ranked_codecs_) codecs;
64
65 codecs.reserve(ranked_codecs_.size());
66
67 auto hinted_codec =
68 std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
69 [&](auto c) { return hint.codecId == c->info.id; });
70
71 if (hinted_codec != end(ranked_codecs_)) codecs.push_back(*hinted_codec);
72
73 std::copy_if(begin(ranked_codecs_), end(ranked_codecs_),
74 std::back_inserter(codecs),
75 [&](auto c) { return c != *hinted_codec; });
76
77 for (auto codec : codecs) {
78 auto rc =
79 std::find_if(begin(remote_capabilities), end(remote_capabilities),
80 [&](auto& rc__) { return codec->info.id == rc__.id; });
81
82 if ((rc == end(remote_capabilities)) ||
83 !codec->BuildConfiguration(rc->capabilities, hint.codecParameters,
84 &configuration->configuration))
85 continue;
86
87 configuration->id = codec->info.id;
88 A2dpStatus status = codec->ParseConfiguration(configuration->configuration,
89 &configuration->parameters);
90 assert(status == A2dpStatus::OK);
91
92 configuration->remoteSeid = rc->seid;
93
94 return true;
95 }
96
97 return false;
98}
99
100} // namespace aidl::android::hardware::bluetooth::audio