1 /*
2  * Copyright 2020 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 "BTAudioProvidersFactory"
18 
19 #include "BluetoothAudioProvidersFactory.h"
20 
21 #include <android-base/logging.h>
22 
23 #include "BluetoothAudioSupportedCodecsDB_2_1.h"
24 
25 namespace android {
26 namespace hardware {
27 namespace bluetooth {
28 namespace audio {
29 namespace V2_1 {
30 namespace implementation {
31 
32 using ::android::hardware::hidl_vec;
33 using ::android::hardware::Void;
34 using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
35 
36 A2dpSoftwareAudioProvider
37     BluetoothAudioProvidersFactory::a2dp_software_provider_instance_;
38 A2dpOffloadAudioProvider
39     BluetoothAudioProvidersFactory::a2dp_offload_provider_instance_;
40 HearingAidAudioProvider
41     BluetoothAudioProvidersFactory::hearing_aid_provider_instance_;
42 LeAudioOutputAudioProvider
43     BluetoothAudioProvidersFactory::leaudio_output_provider_instance_;
44 LeAudioInputAudioProvider
45     BluetoothAudioProvidersFactory::leaudio_input_provider_instance_;
46 
openProvider(const V2_0::SessionType sessionType,openProvider_cb _hidl_cb)47 Return<void> BluetoothAudioProvidersFactory::openProvider(
48     const V2_0::SessionType sessionType, openProvider_cb _hidl_cb) {
49   LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
50   BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
51   BluetoothAudioProvider* provider = nullptr;
52   switch (sessionType) {
53     case V2_0::SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
54       provider = &a2dp_software_provider_instance_;
55       break;
56     case V2_0::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
57       provider = &a2dp_offload_provider_instance_;
58       break;
59     case V2_0::SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
60       provider = &hearing_aid_provider_instance_;
61       break;
62     default:
63       status = BluetoothAudioStatus::FAILURE;
64   }
65   if (provider == nullptr || !provider->isValid(sessionType)) {
66     provider = nullptr;
67     status = BluetoothAudioStatus::FAILURE;
68     LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
69                << ", status=" << toString(status);
70   }
71   _hidl_cb(status, provider);
72   return Void();
73 }
74 
openProvider_2_1(const SessionType sessionType,openProvider_2_1_cb _hidl_cb)75 Return<void> BluetoothAudioProvidersFactory::openProvider_2_1(
76     const SessionType sessionType, openProvider_2_1_cb _hidl_cb) {
77   LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
78   BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
79   BluetoothAudioProvider* provider = nullptr;
80   switch (sessionType) {
81     case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
82       provider = &a2dp_software_provider_instance_;
83       break;
84     case SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
85       provider = &a2dp_offload_provider_instance_;
86       break;
87     case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
88       provider = &hearing_aid_provider_instance_;
89       break;
90     case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
91       provider = &leaudio_output_provider_instance_;
92       break;
93     case SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
94       provider = &leaudio_input_provider_instance_;
95       break;
96     default:
97       status = BluetoothAudioStatus::FAILURE;
98   }
99   if (provider == nullptr || !provider->isValid(sessionType)) {
100     provider = nullptr;
101     status = BluetoothAudioStatus::FAILURE;
102     LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
103                << ", status=" << toString(status);
104   }
105   _hidl_cb(status, provider);
106   return Void();
107 }
108 
getProviderCapabilities(const V2_0::SessionType sessionType,getProviderCapabilities_cb _hidl_cb)109 Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities(
110     const V2_0::SessionType sessionType, getProviderCapabilities_cb _hidl_cb) {
111   hidl_vec<V2_0::AudioCapabilities> audio_capabilities =
112       hidl_vec<V2_0::AudioCapabilities>(0);
113   if (sessionType == V2_0::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
114     std::vector<CodecCapabilities> db_codec_capabilities =
115         android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
116     if (db_codec_capabilities.size()) {
117       audio_capabilities.resize(db_codec_capabilities.size());
118       for (int i = 0; i < db_codec_capabilities.size(); ++i) {
119         audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
120       }
121     }
122   } else if (sessionType != V2_0::SessionType::UNKNOWN) {
123     std::vector<::android::hardware::bluetooth::audio::V2_0::PcmParameters>
124         db_pcm_capabilities =
125             android::bluetooth::audio::GetSoftwarePcmCapabilities();
126     if (db_pcm_capabilities.size() == 1) {
127       audio_capabilities.resize(1);
128       audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
129     }
130   }
131   LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
132             << " supports " << audio_capabilities.size() << " codecs";
133   _hidl_cb(audio_capabilities);
134   return Void();
135 }
136 
getProviderCapabilities_2_1(const SessionType sessionType,getProviderCapabilities_2_1_cb _hidl_cb)137 Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities_2_1(
138     const SessionType sessionType, getProviderCapabilities_2_1_cb _hidl_cb) {
139   hidl_vec<AudioCapabilities> audio_capabilities =
140       hidl_vec<AudioCapabilities>(0);
141   if (sessionType == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
142     std::vector<CodecCapabilities> db_codec_capabilities =
143         android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
144     if (db_codec_capabilities.size()) {
145       audio_capabilities.resize(db_codec_capabilities.size());
146       for (int i = 0; i < db_codec_capabilities.size(); ++i) {
147         audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
148       }
149     }
150   } else if (sessionType != SessionType::UNKNOWN) {
151     std::vector<PcmParameters> db_pcm_capabilities =
152         android::bluetooth::audio::GetSoftwarePcmCapabilities_2_1();
153     if (db_pcm_capabilities.size() == 1) {
154       audio_capabilities.resize(1);
155       audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
156     }
157   }
158   LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
159             << " supports " << audio_capabilities.size() << " codecs";
160   _hidl_cb(audio_capabilities);
161   return Void();
162 }
163 
HIDL_FETCH_IBluetoothAudioProvidersFactory(const char *)164 IBluetoothAudioProvidersFactory* HIDL_FETCH_IBluetoothAudioProvidersFactory(
165     const char* /* name */) {
166   return new BluetoothAudioProvidersFactory();
167 }
168 
169 }  // namespace implementation
170 }  // namespace V2_1
171 }  // namespace audio
172 }  // namespace bluetooth
173 }  // namespace hardware
174 }  // namespace android
175