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