1 /*
2 * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
3 * www.ehima.com
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #define LOG_TAG "BTAudioClientLeAudioStub"
19
20 #include "le_audio_software.h"
21
22 #include <bluetooth/log.h>
23 #include <com_android_bluetooth_flags.h>
24
25 #include <vector>
26
27 #include "aidl/android/hardware/bluetooth/audio/AudioContext.h"
28 #include "aidl/le_audio_software_aidl.h"
29 #include "aidl/le_audio_utils.h"
30 #include "bta/le_audio/codec_manager.h"
31 #include "bta/le_audio/le_audio_types.h"
32 #include "hal_version_manager.h"
33 #include "hidl/le_audio_software_hidl.h"
34 #include "osi/include/properties.h"
35
36 namespace bluetooth {
37 namespace audio {
38
39 using aidl::GetAidlLeAudioBroadcastConfigurationRequirementFromStackFormat;
40 using aidl::GetAidlLeAudioDeviceCapabilitiesFromStackFormat;
41 using aidl::GetAidlLeAudioUnicastConfigurationRequirementsFromStackFormat;
42 using aidl::GetStackBroadcastConfigurationFromAidlFormat;
43 using aidl::GetStackUnicastConfigurationFromAidlFormat;
44
45 namespace le_audio {
46
47 namespace {
48
49 using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
50 using AudioConfiguration_2_1 = ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
51 using AudioConfigurationAIDL = ::aidl::android::hardware::bluetooth::audio::AudioConfiguration;
52 using ::aidl::android::hardware::bluetooth::audio::AudioContext;
53 using ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
54 using ::aidl::android::hardware::bluetooth::audio::LatencyMode;
55 using ::aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
56
57 using ::bluetooth::le_audio::CodecManager;
58 using ::bluetooth::le_audio::set_configurations::AudioSetConfiguration;
59 using ::bluetooth::le_audio::types::CodecLocation;
60 } // namespace
61
get_offload_capabilities()62 OffloadCapabilities get_offload_capabilities() {
63 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
64 return {std::vector<AudioSetConfiguration>(0), std::vector<AudioSetConfiguration>(0)};
65 }
66 return aidl::le_audio::get_offload_capabilities();
67 }
68
get_aidl_client_interface(bool is_broadcaster)69 static aidl::BluetoothAudioSinkClientInterface* get_aidl_client_interface(bool is_broadcaster) {
70 if (is_broadcaster) {
71 return aidl::le_audio::LeAudioSinkTransport::interface_broadcast_;
72 }
73
74 return aidl::le_audio::LeAudioSinkTransport::interface_unicast_;
75 }
76
get_aidl_transport_instance(bool is_broadcaster)77 static aidl::le_audio::LeAudioSinkTransport* get_aidl_transport_instance(bool is_broadcaster) {
78 if (is_broadcaster) {
79 return aidl::le_audio::LeAudioSinkTransport::instance_broadcast_;
80 }
81
82 return aidl::le_audio::LeAudioSinkTransport::instance_unicast_;
83 }
84
is_aidl_offload_encoding_session(bool is_broadcaster)85 static bool is_aidl_offload_encoding_session(bool is_broadcaster) {
86 return get_aidl_client_interface(is_broadcaster)->GetTransportInstance()->GetSessionType() ==
87 aidl::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
88 get_aidl_client_interface(is_broadcaster)->GetTransportInstance()->GetSessionType() ==
89 aidl::SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
90 }
91
92 LeAudioClientInterface* LeAudioClientInterface::interface = nullptr;
Get()93 LeAudioClientInterface* LeAudioClientInterface::Get() {
94 if (LeAudioClientInterface::interface == nullptr) {
95 LeAudioClientInterface::interface = new LeAudioClientInterface();
96 }
97
98 return LeAudioClientInterface::interface;
99 }
100
Cleanup()101 void LeAudioClientInterface::Sink::Cleanup() {
102 log::info("HAL transport: 0x{:02x}, is broadcast: {}",
103 static_cast<int>(HalVersionManager::GetHalTransport()), is_broadcaster_);
104
105 /* Cleanup transport interface and instance according to type and role */
106 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
107 if (hidl::le_audio::LeAudioSinkTransport::interface) {
108 delete hidl::le_audio::LeAudioSinkTransport::interface;
109 hidl::le_audio::LeAudioSinkTransport::interface = nullptr;
110 }
111 if (hidl::le_audio::LeAudioSinkTransport::instance) {
112 delete hidl::le_audio::LeAudioSinkTransport::instance;
113 hidl::le_audio::LeAudioSinkTransport::instance = nullptr;
114 }
115 } else if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::AIDL) {
116 if (IsBroadcaster()) {
117 if (aidl::le_audio::LeAudioSinkTransport::interface_broadcast_) {
118 delete aidl::le_audio::LeAudioSinkTransport::interface_broadcast_;
119 aidl::le_audio::LeAudioSinkTransport::interface_broadcast_ = nullptr;
120 }
121 if (aidl::le_audio::LeAudioSinkTransport::instance_broadcast_) {
122 delete aidl::le_audio::LeAudioSinkTransport::instance_broadcast_;
123 aidl::le_audio::LeAudioSinkTransport::instance_broadcast_ = nullptr;
124 }
125 } else {
126 if (aidl::le_audio::LeAudioSinkTransport::interface_unicast_) {
127 delete aidl::le_audio::LeAudioSinkTransport::interface_unicast_;
128 aidl::le_audio::LeAudioSinkTransport::interface_unicast_ = nullptr;
129 }
130 if (aidl::le_audio::LeAudioSinkTransport::instance_unicast_) {
131 delete aidl::le_audio::LeAudioSinkTransport::instance_unicast_;
132 aidl::le_audio::LeAudioSinkTransport::instance_unicast_ = nullptr;
133 }
134 }
135 } else {
136 log::error("Invalid HAL transport: 0x{:02x}",
137 static_cast<int>(HalVersionManager::GetHalTransport()));
138 }
139 }
140
SetPcmParameters(const PcmParameters & params)141 void LeAudioClientInterface::Sink::SetPcmParameters(const PcmParameters& params) {
142 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
143 return hidl::le_audio::LeAudioSinkTransport::instance->LeAudioSetSelectedHalPcmConfig(
144 params.sample_rate, params.bits_per_sample, params.channels_count,
145 params.data_interval_us);
146 }
147 return get_aidl_transport_instance(is_broadcaster_)
148 ->LeAudioSetSelectedHalPcmConfig(params.sample_rate, params.bits_per_sample,
149 params.channels_count, params.data_interval_us);
150 }
151
152 // Update Le Audio delay report to BluetoothAudio HAL
SetRemoteDelay(uint16_t delay_report_ms)153 void LeAudioClientInterface::Sink::SetRemoteDelay(uint16_t delay_report_ms) {
154 log::info("delay_report_ms={} ms", delay_report_ms);
155 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
156 hidl::le_audio::LeAudioSinkTransport::instance->SetRemoteDelay(delay_report_ms);
157 return;
158 }
159 get_aidl_transport_instance(is_broadcaster_)->SetRemoteDelay(delay_report_ms);
160 }
161
StartSession()162 void LeAudioClientInterface::Sink::StartSession() {
163 log::info("");
164 if (HalVersionManager::GetHalVersion() == BluetoothAudioHalVersion::VERSION_2_1) {
165 AudioConfiguration_2_1 audio_config;
166 audio_config.pcmConfig(
167 hidl::le_audio::LeAudioSinkTransport::instance->LeAudioGetSelectedHalPcmConfig());
168 if (!hidl::le_audio::LeAudioSinkTransport::interface->UpdateAudioConfig_2_1(audio_config)) {
169 log::error("cannot update audio config to HAL");
170 return;
171 }
172 hidl::le_audio::LeAudioSinkTransport::interface->StartSession_2_1();
173 return;
174 } else if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::AIDL) {
175 AudioConfigurationAIDL audio_config;
176 if (is_aidl_offload_encoding_session(is_broadcaster_)) {
177 if (is_broadcaster_) {
178 audio_config.set<AudioConfigurationAIDL::leAudioBroadcastConfig>(
179 get_aidl_transport_instance(is_broadcaster_)->LeAudioGetBroadcastConfig());
180 } else {
181 aidl::le_audio::LeAudioConfiguration le_audio_config = {};
182 audio_config.set<AudioConfigurationAIDL::leAudioConfig>(le_audio_config);
183 }
184 } else {
185 audio_config.set<AudioConfigurationAIDL::pcmConfig>(
186 get_aidl_transport_instance(is_broadcaster_)->LeAudioGetSelectedHalPcmConfig());
187 }
188 if (!get_aidl_client_interface(is_broadcaster_)->UpdateAudioConfig(audio_config)) {
189 log::error("cannot update audio config to HAL");
190 return;
191 }
192 get_aidl_client_interface(is_broadcaster_)->StartSession();
193 }
194 }
195
ConfirmStreamingRequest()196 void LeAudioClientInterface::Sink::ConfirmStreamingRequest() {
197 auto lambda =
198 [&](StartRequestState currect_start_request_state) -> std::pair<StartRequestState, bool> {
199 switch (currect_start_request_state) {
200 case StartRequestState::IDLE:
201 log::warn(", no pending start stream request");
202 return std::make_pair(StartRequestState::IDLE, false);
203 case StartRequestState::PENDING_BEFORE_RESUME:
204 log::info("Response before sending PENDING to audio HAL");
205 return std::make_pair(StartRequestState::CONFIRMED, false);
206 case StartRequestState::PENDING_AFTER_RESUME:
207 log::info("Response after sending PENDING to audio HAL");
208 return std::make_pair(StartRequestState::IDLE, true);
209 case StartRequestState::CONFIRMED:
210 case StartRequestState::CANCELED:
211 log::error("Invalid state, start stream already confirmed");
212 return std::make_pair(currect_start_request_state, false);
213 }
214 };
215
216 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
217 auto hidl_instance = hidl::le_audio::LeAudioSinkTransport::instance;
218 if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
219 hidl::le_audio::LeAudioSinkTransport::interface->StreamStarted(
220 hidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
221 }
222
223 return;
224 }
225
226 auto aidl_instance = get_aidl_transport_instance(is_broadcaster_);
227 if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
228 get_aidl_client_interface(is_broadcaster_)
229 ->StreamStarted(aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
230 }
231 }
232
CancelStreamingRequest()233 void LeAudioClientInterface::Sink::CancelStreamingRequest() {
234 auto lambda =
235 [&](StartRequestState currect_start_request_state) -> std::pair<StartRequestState, bool> {
236 switch (currect_start_request_state) {
237 case StartRequestState::IDLE:
238 log::warn(", no pending start stream request");
239 return std::make_pair(StartRequestState::IDLE, false);
240 case StartRequestState::PENDING_BEFORE_RESUME:
241 log::info("Response before sending PENDING to audio HAL");
242 return std::make_pair(StartRequestState::CANCELED, false);
243 case StartRequestState::PENDING_AFTER_RESUME:
244 log::info("Response after sending PENDING to audio HAL");
245 return std::make_pair(StartRequestState::IDLE, true);
246 case StartRequestState::CONFIRMED:
247 case StartRequestState::CANCELED:
248 log::error("Invalid state, start stream already confirmed");
249 return std::make_pair(currect_start_request_state, false);
250 }
251 };
252
253 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
254 auto hidl_instance = hidl::le_audio::LeAudioSinkTransport::instance;
255 if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
256 hidl::le_audio::LeAudioSinkTransport::interface->StreamStarted(
257 hidl::BluetoothAudioCtrlAck::FAILURE);
258 }
259 return;
260 }
261
262 auto aidl_instance = get_aidl_transport_instance(is_broadcaster_);
263 if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
264 get_aidl_client_interface(is_broadcaster_)->StreamStarted(aidl::BluetoothAudioCtrlAck::FAILURE);
265 }
266 }
267
StopSession()268 void LeAudioClientInterface::Sink::StopSession() {
269 log::info("sink");
270 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
271 hidl::le_audio::LeAudioSinkTransport::instance->ClearStartRequestState();
272 hidl::le_audio::LeAudioSinkTransport::interface->EndSession();
273 return;
274 }
275 get_aidl_transport_instance(is_broadcaster_)->ClearStartRequestState();
276 get_aidl_client_interface(is_broadcaster_)->EndSession();
277 }
278
UpdateAudioConfigToHal(const::bluetooth::le_audio::offload_config & offload_config)279 void LeAudioClientInterface::Sink::UpdateAudioConfigToHal(
280 const ::bluetooth::le_audio::offload_config& offload_config) {
281 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
282 return;
283 }
284
285 if (is_broadcaster_ || !is_aidl_offload_encoding_session(is_broadcaster_)) {
286 return;
287 }
288
289 get_aidl_client_interface(is_broadcaster_)
290 ->UpdateAudioConfig(aidl::le_audio::offload_config_to_hal_audio_config(offload_config));
291 }
292
293 std::optional<::bluetooth::le_audio::broadcaster::BroadcastConfiguration>
GetBroadcastConfig(const std::vector<std::pair<::bluetooth::le_audio::types::LeAudioContextType,uint8_t>> & subgroup_quality,const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>> & pacs) const294 LeAudioClientInterface::Sink::GetBroadcastConfig(
295 const std::vector<std::pair<::bluetooth::le_audio::types::LeAudioContextType, uint8_t>>&
296 subgroup_quality,
297 const std::optional<std::vector<::bluetooth::le_audio::types::acs_ac_record>>& pacs) const {
298 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
299 return std::nullopt;
300 }
301
302 if (!is_broadcaster_ || !is_aidl_offload_encoding_session(is_broadcaster_)) {
303 return std::nullopt;
304 }
305
306 auto aidl_pacs = GetAidlLeAudioDeviceCapabilitiesFromStackFormat(pacs);
307 auto reqs = GetAidlLeAudioBroadcastConfigurationRequirementFromStackFormat(subgroup_quality);
308
309 log::assert_that(aidl::le_audio::LeAudioSinkTransport::interface_broadcast_ != nullptr,
310 "LeAudioSourceTransport::interface should not be null");
311 auto aidl_broadcast_config = aidl::le_audio::LeAudioSinkTransport::interface_broadcast_
312 ->getLeAudioBroadcastConfiguration(aidl_pacs, reqs);
313
314 return GetStackBroadcastConfigurationFromAidlFormat(aidl_broadcast_config);
315 }
316
317 // This API is for requesting a single configuration.
318 // Note: We need a bulk API as well to get multiple configurations for caching
319 std::optional<::bluetooth::le_audio::set_configurations::AudioSetConfiguration>
GetUnicastConfig(const::bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements & requirements) const320 LeAudioClientInterface::Sink::GetUnicastConfig(
321 const ::bluetooth::le_audio::CodecManager::UnicastConfigurationRequirements& requirements)
322 const {
323 log::debug("Requirements: {}", requirements);
324
325 auto aidl_sink_pacs = GetAidlLeAudioDeviceCapabilitiesFromStackFormat(requirements.sink_pacs);
326
327 auto aidl_source_pacs = GetAidlLeAudioDeviceCapabilitiesFromStackFormat(requirements.source_pacs);
328
329 std::vector<IBluetoothAudioProvider::LeAudioConfigurationRequirement> reqs;
330 reqs.push_back(GetAidlLeAudioUnicastConfigurationRequirementsFromStackFormat(
331 requirements.audio_context_type, requirements.sink_requirements,
332 requirements.source_requirements));
333
334 log::debug("Making an AIDL call");
335 auto aidl_configs = get_aidl_client_interface(is_broadcaster_)
336 ->GetLeAudioAseConfiguration(aidl_sink_pacs, aidl_source_pacs, reqs);
337
338 log::debug("Received {} configs", aidl_configs.size());
339
340 if (aidl_configs.size() == 0) {
341 log::error("Expecting a single configuration, but received none.");
342 return std::nullopt;
343 }
344
345 /* Given a single requirement we should get a single response config
346 * Note: For a bulk request we need to implement GetUnicastConfigs() method
347 */
348 if (aidl_configs.size() > 1) {
349 log::warn("Expected a single configuration, but received {}", aidl_configs.size());
350 }
351 return GetStackUnicastConfigurationFromAidlFormat(requirements.audio_context_type,
352 aidl_configs.at(0));
353 }
354
UpdateBroadcastAudioConfigToHal(const::bluetooth::le_audio::broadcast_offload_config & offload_config)355 void LeAudioClientInterface::Sink::UpdateBroadcastAudioConfigToHal(
356 const ::bluetooth::le_audio::broadcast_offload_config& offload_config) {
357 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
358 return;
359 }
360
361 if (!is_broadcaster_ || !is_aidl_offload_encoding_session(is_broadcaster_)) {
362 return;
363 }
364
365 get_aidl_transport_instance(is_broadcaster_)->LeAudioSetBroadcastConfig(offload_config);
366 get_aidl_client_interface(is_broadcaster_)
367 ->UpdateAudioConfig(aidl::le_audio::broadcast_config_to_hal_audio_config(
368 get_aidl_transport_instance(is_broadcaster_)->LeAudioGetBroadcastConfig()));
369 }
370
SuspendedForReconfiguration()371 void LeAudioClientInterface::Sink::SuspendedForReconfiguration() {
372 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
373 hidl::le_audio::LeAudioSinkTransport::interface->StreamSuspended(
374 hidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
375 return;
376 }
377
378 get_aidl_client_interface(is_broadcaster_)
379 ->StreamSuspended(aidl::BluetoothAudioCtrlAck::SUCCESS_RECONFIGURATION);
380 }
381
ReconfigurationComplete()382 void LeAudioClientInterface::Sink::ReconfigurationComplete() {
383 // This is needed only for AIDL since SuspendedForReconfiguration()
384 // already calls StreamSuspended(SUCCESS_FINISHED) for HIDL
385 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::AIDL) {
386 // FIXME: For now we have to workaround the missing API and use
387 // StreamSuspended() with SUCCESS_FINISHED ack code.
388 get_aidl_client_interface(is_broadcaster_)
389 ->StreamSuspended(aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
390 }
391 }
392
Read(uint8_t * p_buf,uint32_t len)393 size_t LeAudioClientInterface::Sink::Read(uint8_t* p_buf, uint32_t len) {
394 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
395 return hidl::le_audio::LeAudioSinkTransport::interface->ReadAudioData(p_buf, len);
396 }
397 return get_aidl_client_interface(is_broadcaster_)->ReadAudioData(p_buf, len);
398 }
399
Cleanup()400 void LeAudioClientInterface::Source::Cleanup() {
401 log::info("source");
402 if (hidl::le_audio::LeAudioSourceTransport::interface) {
403 delete hidl::le_audio::LeAudioSourceTransport::interface;
404 hidl::le_audio::LeAudioSourceTransport::interface = nullptr;
405 }
406 if (hidl::le_audio::LeAudioSourceTransport::instance) {
407 delete hidl::le_audio::LeAudioSourceTransport::instance;
408 hidl::le_audio::LeAudioSourceTransport::instance = nullptr;
409 }
410 if (aidl::le_audio::LeAudioSourceTransport::interface) {
411 delete aidl::le_audio::LeAudioSourceTransport::interface;
412 aidl::le_audio::LeAudioSourceTransport::interface = nullptr;
413 }
414 if (aidl::le_audio::LeAudioSourceTransport::instance) {
415 delete aidl::le_audio::LeAudioSourceTransport::instance;
416 aidl::le_audio::LeAudioSourceTransport::instance = nullptr;
417 }
418 }
419
SetPcmParameters(const PcmParameters & params)420 void LeAudioClientInterface::Source::SetPcmParameters(const PcmParameters& params) {
421 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
422 hidl::le_audio::LeAudioSourceTransport::instance->LeAudioSetSelectedHalPcmConfig(
423 params.sample_rate, params.bits_per_sample, params.channels_count,
424 params.data_interval_us);
425 return;
426 }
427 return aidl::le_audio::LeAudioSourceTransport::instance->LeAudioSetSelectedHalPcmConfig(
428 params.sample_rate, params.bits_per_sample, params.channels_count,
429 params.data_interval_us);
430 }
431
SetRemoteDelay(uint16_t delay_report_ms)432 void LeAudioClientInterface::Source::SetRemoteDelay(uint16_t delay_report_ms) {
433 log::info("delay_report_ms={} ms", delay_report_ms);
434 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
435 hidl::le_audio::LeAudioSourceTransport::instance->SetRemoteDelay(delay_report_ms);
436 return;
437 }
438 return aidl::le_audio::LeAudioSourceTransport::instance->SetRemoteDelay(delay_report_ms);
439 }
440
StartSession()441 void LeAudioClientInterface::Source::StartSession() {
442 log::info("");
443 if (HalVersionManager::GetHalVersion() == BluetoothAudioHalVersion::VERSION_2_1) {
444 AudioConfiguration_2_1 audio_config;
445 audio_config.pcmConfig(
446 hidl::le_audio::LeAudioSourceTransport::instance->LeAudioGetSelectedHalPcmConfig());
447 if (!hidl::le_audio::LeAudioSourceTransport::interface->UpdateAudioConfig_2_1(audio_config)) {
448 log::error("cannot update audio config to HAL");
449 return;
450 }
451 hidl::le_audio::LeAudioSourceTransport::interface->StartSession_2_1();
452 return;
453 } else if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::AIDL) {
454 AudioConfigurationAIDL audio_config;
455 if (aidl::le_audio::LeAudioSourceTransport::interface->GetTransportInstance()
456 ->GetSessionType() ==
457 aidl::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
458 aidl::le_audio::LeAudioConfiguration le_audio_config;
459 audio_config.set<AudioConfigurationAIDL::leAudioConfig>(
460 aidl::le_audio::LeAudioConfiguration{});
461 } else {
462 audio_config.set<AudioConfigurationAIDL::pcmConfig>(
463 aidl::le_audio::LeAudioSourceTransport::instance->LeAudioGetSelectedHalPcmConfig());
464 }
465
466 if (!aidl::le_audio::LeAudioSourceTransport::interface->UpdateAudioConfig(audio_config)) {
467 log::error("cannot update audio config to HAL");
468 return;
469 }
470 aidl::le_audio::LeAudioSourceTransport::interface->StartSession();
471 }
472 }
473
SuspendedForReconfiguration()474 void LeAudioClientInterface::Source::SuspendedForReconfiguration() {
475 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
476 hidl::le_audio::LeAudioSourceTransport::interface->StreamSuspended(
477 hidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
478 return;
479 }
480
481 aidl::le_audio::LeAudioSourceTransport::interface->StreamSuspended(
482 aidl::BluetoothAudioCtrlAck::SUCCESS_RECONFIGURATION);
483 }
484
ReconfigurationComplete()485 void LeAudioClientInterface::Source::ReconfigurationComplete() {
486 // This is needed only for AIDL since SuspendedForReconfiguration()
487 // already calls StreamSuspended(SUCCESS_FINISHED) for HIDL
488 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::AIDL) {
489 // FIXME: For now we have to workaround the missing API and use
490 // StreamSuspended() with SUCCESS_FINISHED ack code.
491 aidl::le_audio::LeAudioSourceTransport::interface->StreamSuspended(
492 aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
493 }
494 }
495
ConfirmStreamingRequest()496 void LeAudioClientInterface::Source::ConfirmStreamingRequest() {
497 auto lambda =
498 [&](StartRequestState currect_start_request_state) -> std::pair<StartRequestState, bool> {
499 switch (currect_start_request_state) {
500 case StartRequestState::IDLE:
501 log::warn(", no pending start stream request");
502 return std::make_pair(StartRequestState::IDLE, false);
503 case StartRequestState::PENDING_BEFORE_RESUME:
504 log::info("Response before sending PENDING to audio HAL");
505 return std::make_pair(StartRequestState::CONFIRMED, false);
506 case StartRequestState::PENDING_AFTER_RESUME:
507 log::info("Response after sending PENDING to audio HAL");
508 return std::make_pair(StartRequestState::IDLE, true);
509 case StartRequestState::CONFIRMED:
510 case StartRequestState::CANCELED:
511 log::error("Invalid state, start stream already confirmed");
512 return std::make_pair(currect_start_request_state, false);
513 }
514 };
515
516 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
517 auto hidl_instance = hidl::le_audio::LeAudioSourceTransport::instance;
518
519 if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
520 hidl::le_audio::LeAudioSourceTransport::interface->StreamStarted(
521 hidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
522 }
523 return;
524 }
525
526 auto aidl_instance = aidl::le_audio::LeAudioSourceTransport::instance;
527 if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
528 aidl::le_audio::LeAudioSourceTransport::interface->StreamStarted(
529 aidl::BluetoothAudioCtrlAck::SUCCESS_FINISHED);
530 }
531 }
532
CancelStreamingRequest()533 void LeAudioClientInterface::Source::CancelStreamingRequest() {
534 auto lambda =
535 [&](StartRequestState currect_start_request_state) -> std::pair<StartRequestState, bool> {
536 switch (currect_start_request_state) {
537 case StartRequestState::IDLE:
538 log::warn(", no pending start stream request");
539 return std::make_pair(StartRequestState::IDLE, false);
540 case StartRequestState::PENDING_BEFORE_RESUME:
541 log::info("Response before sending PENDING to audio HAL");
542 return std::make_pair(StartRequestState::CANCELED, false);
543 case StartRequestState::PENDING_AFTER_RESUME:
544 log::info("Response after sending PENDING to audio HAL");
545 return std::make_pair(StartRequestState::IDLE, true);
546 case StartRequestState::CONFIRMED:
547 case StartRequestState::CANCELED:
548 log::error("Invalid state, start stream already confirmed");
549 return std::make_pair(currect_start_request_state, false);
550 }
551 };
552
553 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
554 auto hidl_instance = hidl::le_audio::LeAudioSourceTransport::instance;
555 if (hidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
556 hidl::le_audio::LeAudioSourceTransport::interface->StreamStarted(
557 hidl::BluetoothAudioCtrlAck::FAILURE);
558 }
559 return;
560 }
561
562 auto aidl_instance = aidl::le_audio::LeAudioSourceTransport::instance;
563 if (aidl_instance->IsRequestCompletedAfterUpdate(lambda)) {
564 aidl::le_audio::LeAudioSourceTransport::interface->StreamStarted(
565 aidl::BluetoothAudioCtrlAck::FAILURE);
566 }
567 }
568
StopSession()569 void LeAudioClientInterface::Source::StopSession() {
570 log::info("source");
571 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
572 hidl::le_audio::LeAudioSourceTransport::instance->ClearStartRequestState();
573 hidl::le_audio::LeAudioSourceTransport::interface->EndSession();
574 return;
575 }
576 aidl::le_audio::LeAudioSourceTransport::instance->ClearStartRequestState();
577 aidl::le_audio::LeAudioSourceTransport::interface->EndSession();
578 }
579
UpdateAudioConfigToHal(const::bluetooth::le_audio::offload_config & offload_config)580 void LeAudioClientInterface::Source::UpdateAudioConfigToHal(
581 const ::bluetooth::le_audio::offload_config& offload_config) {
582 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
583 return;
584 }
585
586 if (aidl::le_audio::LeAudioSourceTransport::interface->GetTransportInstance()->GetSessionType() !=
587 aidl::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
588 return;
589 }
590 aidl::le_audio::LeAudioSourceTransport::interface->UpdateAudioConfig(
591 aidl::le_audio::offload_config_to_hal_audio_config(offload_config));
592 }
593
Write(const uint8_t * p_buf,uint32_t len)594 size_t LeAudioClientInterface::Source::Write(const uint8_t* p_buf, uint32_t len) {
595 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
596 return hidl::le_audio::LeAudioSourceTransport::interface->WriteAudioData(p_buf, len);
597 }
598 return aidl::le_audio::LeAudioSourceTransport::interface->WriteAudioData(p_buf, len);
599 }
600
GetSink(StreamCallbacks stream_cb,bluetooth::common::MessageLoopThread * message_loop,bool is_broadcasting_session_type)601 LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink(
602 StreamCallbacks stream_cb, bluetooth::common::MessageLoopThread* message_loop,
603 bool is_broadcasting_session_type) {
604 if (is_broadcasting_session_type &&
605 HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
606 log::warn("No support for broadcasting Le Audio on HIDL");
607 return nullptr;
608 }
609
610 auto& sink = is_broadcasting_session_type ? broadcast_sink_ : unicast_sink_;
611 if (sink == nullptr) {
612 sink = new Sink(is_broadcasting_session_type);
613 } else {
614 log::warn("Sink is already acquired");
615 return nullptr;
616 }
617
618 log::info("");
619
620 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
621 hidl::SessionType_2_1 session_type = hidl::SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
622
623 hidl::le_audio::LeAudioSinkTransport::instance =
624 new hidl::le_audio::LeAudioSinkTransport(session_type, std::move(stream_cb));
625 hidl::le_audio::LeAudioSinkTransport::interface = new hidl::BluetoothAudioSinkClientInterface(
626 hidl::le_audio::LeAudioSinkTransport::instance, message_loop);
627 if (!hidl::le_audio::LeAudioSinkTransport::interface->IsValid()) {
628 log::warn("BluetoothAudio HAL for Le Audio is invalid?!");
629 delete hidl::le_audio::LeAudioSinkTransport::interface;
630 hidl::le_audio::LeAudioSinkTransport::interface = nullptr;
631 delete hidl::le_audio::LeAudioSinkTransport::instance;
632 hidl::le_audio::LeAudioSinkTransport::instance = nullptr;
633 delete sink;
634 sink = nullptr;
635
636 return nullptr;
637 }
638 } else {
639 aidl::SessionType session_type =
640 is_broadcasting_session_type
641 ? aidl::SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
642 : aidl::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
643 if (CodecManager::GetInstance()->GetCodecLocation() != CodecLocation::HOST) {
644 session_type =
645 is_broadcasting_session_type
646 ? aidl::SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
647 : aidl::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
648 }
649
650 if (session_type == aidl::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
651 session_type == aidl::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH) {
652 aidl::le_audio::LeAudioSinkTransport::instance_unicast_ =
653 new aidl::le_audio::LeAudioSinkTransport(session_type, std::move(stream_cb));
654 aidl::le_audio::LeAudioSinkTransport::interface_unicast_ =
655 new aidl::BluetoothAudioSinkClientInterface(
656 aidl::le_audio::LeAudioSinkTransport::instance_unicast_);
657 if (!aidl::le_audio::LeAudioSinkTransport::interface_unicast_->IsValid()) {
658 log::warn("BluetoothAudio HAL for Le Audio is invalid?!");
659 delete aidl::le_audio::LeAudioSinkTransport::interface_unicast_;
660 aidl::le_audio::LeAudioSinkTransport::interface_unicast_ = nullptr;
661 delete aidl::le_audio::LeAudioSinkTransport::instance_unicast_;
662 aidl::le_audio::LeAudioSinkTransport::instance_unicast_ = nullptr;
663 delete sink;
664 sink = nullptr;
665
666 return nullptr;
667 }
668 } else {
669 aidl::le_audio::LeAudioSinkTransport::instance_broadcast_ =
670 new aidl::le_audio::LeAudioSinkTransport(session_type, std::move(stream_cb));
671 aidl::le_audio::LeAudioSinkTransport::interface_broadcast_ =
672 new aidl::BluetoothAudioSinkClientInterface(
673 aidl::le_audio::LeAudioSinkTransport::instance_broadcast_);
674 if (!aidl::le_audio::LeAudioSinkTransport::interface_broadcast_->IsValid()) {
675 log::warn("BluetoothAudio HAL for Le Audio is invalid?!");
676 delete aidl::le_audio::LeAudioSinkTransport::interface_broadcast_;
677 aidl::le_audio::LeAudioSinkTransport::interface_broadcast_ = nullptr;
678 delete aidl::le_audio::LeAudioSinkTransport::instance_broadcast_;
679 aidl::le_audio::LeAudioSinkTransport::instance_broadcast_ = nullptr;
680 delete sink;
681 sink = nullptr;
682
683 return nullptr;
684 }
685 }
686 }
687
688 return sink;
689 }
690
IsUnicastSinkAcquired()691 bool LeAudioClientInterface::IsUnicastSinkAcquired() { return unicast_sink_ != nullptr; }
IsBroadcastSinkAcquired()692 bool LeAudioClientInterface::IsBroadcastSinkAcquired() { return broadcast_sink_ != nullptr; }
693
ReleaseSink(LeAudioClientInterface::Sink * sink)694 bool LeAudioClientInterface::ReleaseSink(LeAudioClientInterface::Sink* sink) {
695 if (sink != unicast_sink_ && sink != broadcast_sink_) {
696 log::warn("can't release not acquired sink");
697 return false;
698 }
699
700 if ((hidl::le_audio::LeAudioSinkTransport::interface &&
701 hidl::le_audio::LeAudioSinkTransport::instance) ||
702 (aidl::le_audio::LeAudioSinkTransport::interface_unicast_ &&
703 aidl::le_audio::LeAudioSinkTransport::instance_unicast_) ||
704 (aidl::le_audio::LeAudioSinkTransport::interface_broadcast_ &&
705 aidl::le_audio::LeAudioSinkTransport::instance_broadcast_)) {
706 sink->Cleanup();
707 }
708
709 if (sink == unicast_sink_) {
710 delete (unicast_sink_);
711 unicast_sink_ = nullptr;
712 } else if (sink == broadcast_sink_) {
713 delete (broadcast_sink_);
714 broadcast_sink_ = nullptr;
715 }
716
717 return true;
718 }
719
GetSource(StreamCallbacks stream_cb,bluetooth::common::MessageLoopThread * message_loop)720 LeAudioClientInterface::Source* LeAudioClientInterface::GetSource(
721 StreamCallbacks stream_cb, bluetooth::common::MessageLoopThread* message_loop) {
722 if (source_ == nullptr) {
723 source_ = new Source();
724 } else {
725 log::warn("Source is already acquired");
726 return nullptr;
727 }
728
729 log::info("");
730
731 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::HIDL) {
732 hidl::SessionType_2_1 session_type = hidl::SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH;
733 if (CodecManager::GetInstance()->GetCodecLocation() != CodecLocation::HOST) {
734 session_type = hidl::SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
735 }
736
737 hidl::le_audio::LeAudioSourceTransport::instance =
738 new hidl::le_audio::LeAudioSourceTransport(session_type, std::move(stream_cb));
739 hidl::le_audio::LeAudioSourceTransport::interface =
740 new hidl::BluetoothAudioSourceClientInterface(
741 hidl::le_audio::LeAudioSourceTransport::instance, message_loop);
742 if (!hidl::le_audio::LeAudioSourceTransport::interface->IsValid()) {
743 log::warn("BluetoothAudio HAL for Le Audio is invalid?!");
744 delete hidl::le_audio::LeAudioSourceTransport::interface;
745 hidl::le_audio::LeAudioSourceTransport::interface = nullptr;
746 delete hidl::le_audio::LeAudioSourceTransport::instance;
747 hidl::le_audio::LeAudioSourceTransport::instance = nullptr;
748 delete source_;
749 source_ = nullptr;
750
751 return nullptr;
752 }
753 } else {
754 aidl::SessionType session_type = aidl::SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH;
755 if (CodecManager::GetInstance()->GetCodecLocation() != CodecLocation::HOST) {
756 session_type = aidl::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
757 }
758
759 aidl::le_audio::LeAudioSourceTransport::instance =
760 new aidl::le_audio::LeAudioSourceTransport(session_type, std::move(stream_cb));
761 aidl::le_audio::LeAudioSourceTransport::interface =
762 new aidl::BluetoothAudioSourceClientInterface(
763 aidl::le_audio::LeAudioSourceTransport::instance);
764 if (!aidl::le_audio::LeAudioSourceTransport::interface->IsValid()) {
765 log::warn("BluetoothAudio HAL for Le Audio is invalid?!");
766 delete aidl::le_audio::LeAudioSourceTransport::interface;
767 aidl::le_audio::LeAudioSourceTransport::interface = nullptr;
768 delete aidl::le_audio::LeAudioSourceTransport::instance;
769 aidl::le_audio::LeAudioSourceTransport::instance = nullptr;
770 delete source_;
771 source_ = nullptr;
772
773 return nullptr;
774 }
775 }
776
777 return source_;
778 }
779
IsSourceAcquired()780 bool LeAudioClientInterface::IsSourceAcquired() { return source_ != nullptr; }
781
ReleaseSource(LeAudioClientInterface::Source * source)782 bool LeAudioClientInterface::ReleaseSource(LeAudioClientInterface::Source* source) {
783 if (source != source_) {
784 log::warn("can't release not acquired source");
785 return false;
786 }
787
788 if ((hidl::le_audio::LeAudioSourceTransport::interface &&
789 hidl::le_audio::LeAudioSourceTransport::instance) ||
790 (aidl::le_audio::LeAudioSourceTransport::interface &&
791 aidl::le_audio::LeAudioSourceTransport::instance)) {
792 source->Cleanup();
793 }
794
795 delete (source_);
796 source_ = nullptr;
797
798 return true;
799 }
800
SetAllowedDsaModes(DsaModes dsa_modes)801 void LeAudioClientInterface::SetAllowedDsaModes(DsaModes dsa_modes) {
802 if (!com::android::bluetooth::flags::leaudio_dynamic_spatial_audio()) {
803 return;
804 }
805
806 if (HalVersionManager::GetHalTransport() == BluetoothAudioHalTransport::AIDL) {
807 if (aidl::le_audio::LeAudioSinkTransport::interface_unicast_ == nullptr ||
808 aidl::le_audio::LeAudioSinkTransport::instance_unicast_ == nullptr) {
809 log::warn("LeAudioSourceTransport::interface is null");
810 return;
811 }
812
813 std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
814 for (auto dsa_mode : dsa_modes) {
815 switch (dsa_mode) {
816 case DsaMode::DISABLED:
817 // Already added
818 break;
819 case DsaMode::ACL:
820 latency_modes.push_back(LatencyMode::LOW_LATENCY);
821 break;
822 case DsaMode::ISO_SW:
823 latency_modes.push_back(LatencyMode::DYNAMIC_SPATIAL_AUDIO_SOFTWARE);
824 break;
825 case DsaMode::ISO_HW:
826 latency_modes.push_back(LatencyMode::DYNAMIC_SPATIAL_AUDIO_HARDWARE);
827 break;
828 default:
829 log::warn("Unsupported latency mode ignored: {}", (int)dsa_mode);
830 break;
831 }
832 }
833 aidl::le_audio::LeAudioSinkTransport::interface_unicast_->SetAllowedLatencyModes(latency_modes);
834 }
835 }
836
837 } // namespace le_audio
838 } // namespace audio
839 } // namespace bluetooth
840