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