• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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