1 /*
2  * Copyright 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 #include "a2dp_encoding.h"
18 
19 #include <vector>
20 
21 #include "aidl/a2dp_encoding_aidl.h"
22 #include "hal_version_manager.h"
23 #include "hidl/a2dp_encoding_hidl.h"
24 
25 namespace bluetooth {
26 namespace audio {
27 namespace a2dp {
28 
update_codec_offloading_capabilities(const std::vector<btav_a2dp_codec_config_t> & framework_preference,bool supports_a2dp_hw_offload_v2)29 bool update_codec_offloading_capabilities(
30     const std::vector<btav_a2dp_codec_config_t>& framework_preference,
31     bool supports_a2dp_hw_offload_v2) {
32   if (HalVersionManager::GetHalTransport() ==
33       BluetoothAudioHalTransport::HIDL) {
34     return hidl::a2dp::update_codec_offloading_capabilities(
35         framework_preference);
36   }
37   return aidl::a2dp::update_codec_offloading_capabilities(
38       framework_preference, supports_a2dp_hw_offload_v2);
39 }
40 
41 // Check if new bluetooth_audio is enabled
is_hal_enabled()42 bool is_hal_enabled() {
43   if (HalVersionManager::GetHalTransport() ==
44       BluetoothAudioHalTransport::HIDL) {
45     return hidl::a2dp::is_hal_2_0_enabled();
46   }
47   return aidl::a2dp::is_hal_enabled();
48 }
49 
50 // Check if new bluetooth_audio is running with offloading encoders
is_hal_offloading()51 bool is_hal_offloading() {
52   if (HalVersionManager::GetHalTransport() ==
53       BluetoothAudioHalTransport::HIDL) {
54     return hidl::a2dp::is_hal_2_0_offloading();
55   }
56   return aidl::a2dp::is_hal_offloading();
57 }
58 
59 // Initialize BluetoothAudio HAL: openProvider
init(bluetooth::common::MessageLoopThread * message_loop)60 bool init(bluetooth::common::MessageLoopThread* message_loop) {
61   if (HalVersionManager::GetHalTransport() ==
62       BluetoothAudioHalTransport::HIDL) {
63     return hidl::a2dp::init(message_loop);
64   }
65   return aidl::a2dp::init(message_loop);
66 }
67 
68 // Clean up BluetoothAudio HAL
cleanup()69 void cleanup() {
70   if (HalVersionManager::GetHalTransport() ==
71       BluetoothAudioHalTransport::HIDL) {
72     hidl::a2dp::cleanup();
73     return;
74   }
75   aidl::a2dp::cleanup();
76 }
77 
78 // Set up the codec into BluetoothAudio HAL
setup_codec()79 bool setup_codec() {
80   if (HalVersionManager::GetHalTransport() ==
81       BluetoothAudioHalTransport::HIDL) {
82     return hidl::a2dp::setup_codec();
83   }
84   return aidl::a2dp::setup_codec();
85 }
86 
87 // Send command to the BluetoothAudio HAL: StartSession, EndSession,
88 // StreamStarted, StreamSuspended
start_session()89 void start_session() {
90   if (HalVersionManager::GetHalTransport() ==
91       BluetoothAudioHalTransport::HIDL) {
92     hidl::a2dp::start_session();
93     return;
94   }
95   aidl::a2dp::start_session();
96 }
end_session()97 void end_session() {
98   if (HalVersionManager::GetHalTransport() ==
99       BluetoothAudioHalTransport::AIDL) {
100     return aidl::a2dp::end_session();
101   }
102   if (HalVersionManager::GetHalTransport() ==
103       BluetoothAudioHalTransport::HIDL) {
104     hidl::a2dp::end_session();
105     return;
106   }
107 }
ack_stream_started(const tA2DP_CTRL_ACK & status)108 void ack_stream_started(const tA2DP_CTRL_ACK& status) {
109   if (HalVersionManager::GetHalTransport() ==
110       BluetoothAudioHalTransport::HIDL) {
111     hidl::a2dp::ack_stream_started(status);
112     return;
113   }
114   return aidl::a2dp::ack_stream_started(status);
115 }
ack_stream_suspended(const tA2DP_CTRL_ACK & status)116 void ack_stream_suspended(const tA2DP_CTRL_ACK& status) {
117   if (HalVersionManager::GetHalTransport() ==
118       BluetoothAudioHalTransport::HIDL) {
119     hidl::a2dp::ack_stream_suspended(status);
120     return;
121   }
122   aidl::a2dp::ack_stream_suspended(status);
123 }
124 
125 // Read from the FMQ of BluetoothAudio HAL
read(uint8_t * p_buf,uint32_t len)126 size_t read(uint8_t* p_buf, uint32_t len) {
127   if (HalVersionManager::GetHalTransport() ==
128       BluetoothAudioHalTransport::HIDL) {
129     return hidl::a2dp::read(p_buf, len);
130   }
131   return aidl::a2dp::read(p_buf, len);
132 }
133 
134 // Update A2DP delay report to BluetoothAudio HAL
set_remote_delay(uint16_t delay_report)135 void set_remote_delay(uint16_t delay_report) {
136   if (HalVersionManager::GetHalTransport() ==
137       BluetoothAudioHalTransport::HIDL) {
138     hidl::a2dp::set_remote_delay(delay_report);
139     return;
140   }
141   aidl::a2dp::set_remote_delay(delay_report);
142 }
143 
144 // Set low latency buffer mode allowed or disallowed
set_audio_low_latency_mode_allowed(bool allowed)145 void set_audio_low_latency_mode_allowed(bool allowed) {
146   if (HalVersionManager::GetHalTransport() ==
147       BluetoothAudioHalTransport::AIDL) {
148     aidl::a2dp::set_low_latency_mode_allowed(allowed);
149   }
150 }
151 
152 // Check if OPUS codec is supported
is_opus_supported()153 bool is_opus_supported() {
154   // OPUS codec was added after HIDL HAL was frozen
155   if (HalVersionManager::GetHalTransport() ==
156       BluetoothAudioHalTransport::AIDL) {
157     return true;
158   }
159   return false;
160 }
161 
162 namespace provider {
163 
164 // Lookup the codec info in the list of supported offloaded sink codecs.
sink_codec_index(const uint8_t * p_codec_info)165 std::optional<btav_a2dp_codec_index_t> sink_codec_index(
166     const uint8_t* p_codec_info) {
167   return (HalVersionManager::GetHalTransport() ==
168           BluetoothAudioHalTransport::AIDL)
169              ? aidl::a2dp::provider::sink_codec_index(p_codec_info)
170              : std::nullopt;
171 }
172 
173 // Lookup the codec info in the list of supported offloaded source codecs.
source_codec_index(const uint8_t * p_codec_info)174 std::optional<btav_a2dp_codec_index_t> source_codec_index(
175     const uint8_t* p_codec_info) {
176   return (HalVersionManager::GetHalTransport() ==
177           BluetoothAudioHalTransport::AIDL)
178              ? aidl::a2dp::provider::source_codec_index(p_codec_info)
179              : std::nullopt;
180 }
181 
182 // Return the name of the codec which is assigned to the input index.
183 // The codec index must be in the ranges
184 // BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX or
185 // BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN..BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX.
186 // Returns nullopt if the codec_index is not assigned or codec extensibility
187 // is not supported or enabled.
codec_index_str(btav_a2dp_codec_index_t codec_index)188 std::optional<const char*> codec_index_str(
189     btav_a2dp_codec_index_t codec_index) {
190   return (HalVersionManager::GetHalTransport() ==
191           BluetoothAudioHalTransport::AIDL)
192              ? aidl::a2dp::provider::codec_index_str(codec_index)
193              : std::nullopt;
194 }
195 
196 // Return true if the codec is supported for the session type
197 // A2DP_HARDWARE_ENCODING_DATAPATH or A2DP_HARDWARE_DECODING_DATAPATH.
supports_codec(btav_a2dp_codec_index_t codec_index)198 bool supports_codec(btav_a2dp_codec_index_t codec_index) {
199   return (HalVersionManager::GetHalTransport() ==
200           BluetoothAudioHalTransport::AIDL)
201              ? aidl::a2dp::provider::supports_codec(codec_index)
202              : false;
203 }
204 
205 // Return the A2DP capabilities for the selected codec.
codec_info(btav_a2dp_codec_index_t codec_index,uint64_t * codec_id,uint8_t * codec_info,btav_a2dp_codec_config_t * codec_config)206 bool codec_info(btav_a2dp_codec_index_t codec_index, uint64_t* codec_id,
207                 uint8_t* codec_info, btav_a2dp_codec_config_t* codec_config) {
208   return (HalVersionManager::GetHalTransport() ==
209           BluetoothAudioHalTransport::AIDL)
210              ? aidl::a2dp::provider::codec_info(codec_index, codec_id,
211                                                 codec_info, codec_config)
212              : false;
213 }
214 
215 // Query the codec selection fromt the audio HAL.
216 // The HAL is expected to pick the best audio configuration based on the
217 // discovered remote SEPs.
get_a2dp_configuration(RawAddress peer_address,std::vector<a2dp_remote_capabilities> const & remote_seps,btav_a2dp_codec_config_t const & user_preferences)218 std::optional<a2dp_configuration> get_a2dp_configuration(
219     RawAddress peer_address,
220     std::vector<a2dp_remote_capabilities> const& remote_seps,
221     btav_a2dp_codec_config_t const& user_preferences) {
222   return (HalVersionManager::GetHalTransport() ==
223           BluetoothAudioHalTransport::AIDL)
224              ? aidl::a2dp::provider::get_a2dp_configuration(
225                    peer_address, remote_seps, user_preferences)
226              : std::nullopt;
227 }
228 
229 // Query the codec parameters from the audio HAL.
230 // The HAL performs a two part validation:
231 //  - check if the configuration is valid
232 //  - check if the configuration is supported by the audio provider
233 // In case any of these checks fails, the corresponding A2DP
234 // status is returned. If the configuration is valid and supported,
235 // A2DP_OK is returned.
parse_a2dp_configuration(btav_a2dp_codec_index_t codec_index,const uint8_t * codec_info,btav_a2dp_codec_config_t * codec_parameters,std::vector<uint8_t> * vendor_specific_parameters)236 tA2DP_STATUS parse_a2dp_configuration(
237     btav_a2dp_codec_index_t codec_index, const uint8_t* codec_info,
238     btav_a2dp_codec_config_t* codec_parameters,
239     std::vector<uint8_t>* vendor_specific_parameters) {
240   return (HalVersionManager::GetHalTransport() ==
241           BluetoothAudioHalTransport::AIDL)
242              ? aidl::a2dp::provider::parse_a2dp_configuration(
243                    codec_index, codec_info, codec_parameters,
244                    vendor_specific_parameters)
245              : A2DP_FAIL;
246 }
247 
248 }  // namespace provider
249 }  // namespace a2dp
250 }  // namespace audio
251 }  // namespace bluetooth
252