1 /*
2 * Copyright (C) 2022 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 #define LOG_TAG "BTAudioProviderFactoryAIDL"
18
19 #include "BluetoothAudioProviderFactory.h"
20
21 #include <BluetoothAudioCodecs.h>
22 #include <android-base/logging.h>
23
24 #include "A2dpOffloadAudioProvider.h"
25 #include "A2dpSoftwareAudioProvider.h"
26 #include "BluetoothAudioProvider.h"
27 #include "HearingAidAudioProvider.h"
28 #include "HfpOffloadAudioProvider.h"
29 #include "HfpSoftwareAudioProvider.h"
30 #include "LeAudioOffloadAudioProvider.h"
31 #include "LeAudioSoftwareAudioProvider.h"
32
33 namespace aidl {
34 namespace android {
35 namespace hardware {
36 namespace bluetooth {
37 namespace audio {
38
39 static const std::string kLeAudioOffloadProviderName =
40 "LE_AUDIO_OFFLOAD_HARDWARE_OFFLOAD_PROVIDER";
41
42 static const std::string kHfpOffloadProviderName =
43 "HFP_OFFLOAD_HARDWARE_OFFLOAD_PROVIDER";
44
BluetoothAudioProviderFactory()45 BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {}
46
openProvider(const SessionType session_type,std::shared_ptr<IBluetoothAudioProvider> * _aidl_return)47 ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider(
48 const SessionType session_type,
49 std::shared_ptr<IBluetoothAudioProvider>* _aidl_return) {
50 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type);
51 std::shared_ptr<BluetoothAudioProvider> provider = nullptr;
52
53 switch (session_type) {
54 case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
55 provider = ndk::SharedRefBase::make<A2dpSoftwareEncodingAudioProvider>();
56 break;
57 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
58 provider = ndk::SharedRefBase::make<A2dpOffloadEncodingAudioProvider>(
59 a2dp_offload_codec_factory_);
60 break;
61 case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
62 provider = ndk::SharedRefBase::make<HearingAidAudioProvider>();
63 break;
64 case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
65 provider = ndk::SharedRefBase::make<LeAudioSoftwareOutputAudioProvider>();
66 break;
67 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
68 provider = ndk::SharedRefBase::make<LeAudioOffloadOutputAudioProvider>();
69 break;
70 case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
71 provider = ndk::SharedRefBase::make<LeAudioSoftwareInputAudioProvider>();
72 break;
73 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
74 provider = ndk::SharedRefBase::make<LeAudioOffloadInputAudioProvider>();
75 break;
76 case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
77 provider =
78 ndk::SharedRefBase::make<LeAudioSoftwareBroadcastAudioProvider>();
79 break;
80 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
81 provider =
82 ndk::SharedRefBase::make<LeAudioOffloadBroadcastAudioProvider>();
83 break;
84 case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
85 provider = ndk::SharedRefBase::make<A2dpSoftwareDecodingAudioProvider>();
86 break;
87 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
88 provider = ndk::SharedRefBase::make<A2dpOffloadDecodingAudioProvider>(
89 a2dp_offload_codec_factory_);
90 break;
91 case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH:
92 provider = ndk::SharedRefBase::make<HfpSoftwareOutputAudioProvider>();
93 break;
94 case SessionType::HFP_SOFTWARE_DECODING_DATAPATH:
95 provider = ndk::SharedRefBase::make<HfpSoftwareInputAudioProvider>();
96 break;
97 case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
98 provider = ndk::SharedRefBase::make<HfpOffloadAudioProvider>();
99 break;
100 default:
101 provider = nullptr;
102 break;
103 }
104
105 if (provider == nullptr || !provider->isValid(session_type)) {
106 provider = nullptr;
107 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type);
108 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
109 }
110 *_aidl_return = provider;
111
112 return ndk::ScopedAStatus::ok();
113 }
114
getProviderCapabilities(const SessionType session_type,std::vector<AudioCapabilities> * _aidl_return)115 ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderCapabilities(
116 const SessionType session_type,
117 std::vector<AudioCapabilities>* _aidl_return) {
118 if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
119 session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
120 auto codec_capabilities =
121 BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(session_type);
122 _aidl_return->resize(codec_capabilities.size());
123 for (int i = 0; i < codec_capabilities.size(); i++) {
124 _aidl_return->at(i).set<AudioCapabilities::a2dpCapabilities>(
125 codec_capabilities[i]);
126 }
127 } else if (session_type ==
128 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
129 session_type ==
130 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
131 session_type ==
132 SessionType::
133 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
134 std::vector<LeAudioCodecCapabilitiesSetting> db_codec_capabilities =
135 BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(session_type);
136 if (db_codec_capabilities.size()) {
137 _aidl_return->resize(db_codec_capabilities.size());
138 for (int i = 0; i < db_codec_capabilities.size(); ++i) {
139 _aidl_return->at(i).set<AudioCapabilities::leAudioCapabilities>(
140 db_codec_capabilities[i]);
141 }
142 }
143 } else if (session_type != SessionType::UNKNOWN) {
144 auto pcm_capabilities = BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
145 _aidl_return->resize(pcm_capabilities.size());
146 for (int i = 0; i < pcm_capabilities.size(); i++) {
147 _aidl_return->at(i).set<AudioCapabilities::pcmCapabilities>(
148 pcm_capabilities[i]);
149 }
150 }
151
152 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type)
153 << " supports " << _aidl_return->size() << " codecs";
154 return ndk::ScopedAStatus::ok();
155 }
156
getProviderInfo(SessionType session_type,std::optional<ProviderInfo> * _aidl_return)157 ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo(
158 SessionType session_type, std::optional<ProviderInfo>* _aidl_return) {
159 *_aidl_return = std::nullopt;
160
161 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type);
162
163 if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
164 session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
165 if (!kEnableA2dpCodecExtensibility) {
166 // Implementing getProviderInfo equates supporting
167 // A2dp codec extensibility.
168 return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION);
169 }
170
171 auto& provider_info = _aidl_return->emplace();
172
173 provider_info.name = a2dp_offload_codec_factory_.name;
174 for (auto codec : a2dp_offload_codec_factory_.codecs)
175 provider_info.codecInfos.push_back(codec->info);
176 return ndk::ScopedAStatus::ok();
177 }
178
179 if (session_type ==
180 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
181 session_type ==
182 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
183 session_type ==
184 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
185 std::vector<CodecInfo> db_codec_info =
186 BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(session_type);
187 // Return provider info supports without checking db_codec_info
188 // This help with various flow implementation for multidirectional support.
189 auto& provider_info = _aidl_return->emplace();
190 provider_info.supportsMultidirectionalCapabilities = true;
191 provider_info.name = kLeAudioOffloadProviderName;
192 provider_info.codecInfos = db_codec_info;
193 return ndk::ScopedAStatus::ok();
194 }
195
196 if (session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
197 std::vector<CodecInfo> db_codec_info =
198 BluetoothAudioCodecs::GetHfpOffloadCodecInfo();
199 if (!db_codec_info.empty()) {
200 auto& provider_info = _aidl_return->emplace();
201 provider_info.name = kHfpOffloadProviderName;
202 provider_info.codecInfos = db_codec_info;
203 return ndk::ScopedAStatus::ok();
204 }
205 }
206
207 // Unsupported for other sessions
208 return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
209 }
210
211 } // namespace audio
212 } // namespace bluetooth
213 } // namespace hardware
214 } // namespace android
215 } // namespace aidl
216