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