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 #define LOG_TAG "BTAudioClientAIDL"
18
19 #include "client_interface_aidl.h"
20
21 #include <android/binder_manager.h>
22 #include <bluetooth/log.h>
23 #include <com_android_bluetooth_flags.h>
24
25 #include <thread>
26 #include <vector>
27
28 #include "bta/ag/bta_ag_int.h"
29
30 namespace bluetooth {
31 namespace audio {
32 namespace aidl {
33
operator <<(std::ostream & os,const BluetoothAudioCtrlAck & ack)34 std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack) {
35 switch (ack) {
36 case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
37 return os << "SUCCESS_FINISHED";
38 case BluetoothAudioCtrlAck::PENDING:
39 return os << "PENDING";
40 case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
41 return os << "FAILURE_UNSUPPORTED";
42 case BluetoothAudioCtrlAck::FAILURE_BUSY:
43 return os << "FAILURE_BUSY";
44 case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
45 return os << "FAILURE_DISCONNECTING";
46 case BluetoothAudioCtrlAck::FAILURE:
47 return os << "FAILURE";
48 default:
49 return os << "UNDEFINED " << static_cast<int8_t>(ack);
50 }
51 }
52
BluetoothAudioClientInterface(IBluetoothTransportInstance * instance)53 BluetoothAudioClientInterface::BluetoothAudioClientInterface(
54 IBluetoothTransportInstance* instance)
55 : provider_(nullptr),
56 provider_factory_(nullptr),
57 session_started_(false),
58 data_mq_(nullptr),
59 transport_(instance),
60 latency_modes_({LatencyMode::FREE}) {
61 death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient(
62 AIBinder_DeathRecipient_new(binderDiedCallbackAidl));
63 }
64
IsValid() const65 bool BluetoothAudioClientInterface::IsValid() const {
66 return provider_ != nullptr;
67 }
68
is_aidl_available()69 bool BluetoothAudioClientInterface::is_aidl_available() {
70 return AServiceManager_isDeclared(
71 kDefaultAudioProviderFactoryInterface.c_str());
72 }
73
74 std::vector<AudioCapabilities>
GetAudioCapabilities() const75 BluetoothAudioClientInterface::GetAudioCapabilities() const {
76 return capabilities_;
77 }
78
79 std::vector<AudioCapabilities>
GetAudioCapabilities(SessionType session_type)80 BluetoothAudioClientInterface::GetAudioCapabilities(SessionType session_type) {
81 std::vector<AudioCapabilities> capabilities(0);
82 if (!is_aidl_available()) {
83 return capabilities;
84 }
85 auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
86 ::ndk::SpAIBinder(AServiceManager_waitForService(
87 kDefaultAudioProviderFactoryInterface.c_str())));
88
89 if (provider_factory == nullptr) {
90 log::error("can't get capability from unknown factory");
91 return capabilities;
92 }
93
94 auto aidl_retval =
95 provider_factory->getProviderCapabilities(session_type, &capabilities);
96 if (!aidl_retval.isOk()) {
97 log::fatal("BluetoothAudioHal::getProviderCapabilities failure: {}",
98 aidl_retval.getDescription());
99 }
100 return capabilities;
101 }
102
103 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
GetProviderInfo(SessionType session_type,std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory)104 BluetoothAudioClientInterface::GetProviderInfo(
105 SessionType session_type,
106 std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory) {
107 if (!is_aidl_available() ||
108 !com::android::bluetooth::flags::a2dp_offload_codec_extensibility()) {
109 return std::nullopt;
110 }
111
112 if (provider_factory == nullptr) {
113 provider_factory = IBluetoothAudioProviderFactory::fromBinder(
114 ::ndk::SpAIBinder(AServiceManager_waitForService(
115 kDefaultAudioProviderFactoryInterface.c_str())));
116 }
117
118 if (provider_factory == nullptr) {
119 log::error("can't get provider info from unknown factory");
120 return std::nullopt;
121 }
122
123 std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
124 {};
125 auto aidl_retval =
126 provider_factory->getProviderInfo(session_type, &provider_info);
127
128 if (!aidl_retval.isOk()) {
129 log::error("BluetoothAudioHal::getProviderInfo failure: {}",
130 aidl_retval.getDescription());
131 return std::nullopt;
132 }
133
134 return provider_info;
135 }
136
137 std::optional<A2dpConfiguration>
GetA2dpConfiguration(std::vector<A2dpRemoteCapabilities> const & remote_capabilities,A2dpConfigurationHint const & hint) const138 BluetoothAudioClientInterface::GetA2dpConfiguration(
139 std::vector<A2dpRemoteCapabilities> const& remote_capabilities,
140 A2dpConfigurationHint const& hint) const {
141 if (!is_aidl_available() ||
142 !com::android::bluetooth::flags::a2dp_offload_codec_extensibility()) {
143 return std::nullopt;
144 }
145
146 if (provider_ == nullptr) {
147 log::error("can't get a2dp configuration from unknown provider");
148 return std::nullopt;
149 }
150
151 std::optional<A2dpConfiguration> configuration = std::nullopt;
152 auto aidl_retval = provider_->getA2dpConfiguration(remote_capabilities, hint,
153 &configuration);
154
155 if (!aidl_retval.isOk()) {
156 log::error("getA2dpConfiguration failure: {}",
157 aidl_retval.getDescription());
158 return std::nullopt;
159 }
160
161 return configuration;
162 }
163
ParseA2dpConfiguration(const CodecId & codec_id,const std::vector<uint8_t> & configuration,CodecParameters * codec_parameters) const164 std::optional<A2dpStatus> BluetoothAudioClientInterface::ParseA2dpConfiguration(
165 const CodecId& codec_id, const std::vector<uint8_t>& configuration,
166 CodecParameters* codec_parameters) const {
167 A2dpStatus a2dp_status;
168
169 if (provider_ == nullptr) {
170 log::error("can not parse A2DP configuration because of unknown provider");
171 return std::nullopt;
172 }
173
174 auto aidl_retval = provider_->parseA2dpConfiguration(
175 codec_id, configuration, codec_parameters, &a2dp_status);
176
177 if (!aidl_retval.isOk()) {
178 log::error("parseA2dpConfiguration failure: {}",
179 aidl_retval.getDescription());
180 return std::nullopt;
181 }
182
183 return std::make_optional(a2dp_status);
184 }
185
FetchAudioProvider()186 void BluetoothAudioClientInterface::FetchAudioProvider() {
187 if (!is_aidl_available()) {
188 log::error("aidl is not supported on this platform.");
189 return;
190 }
191 if (provider_ != nullptr) {
192 log::warn("refetch");
193 }
194 auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
195 ::ndk::SpAIBinder(AServiceManager_waitForService(
196 kDefaultAudioProviderFactoryInterface.c_str())));
197
198 if (provider_factory == nullptr) {
199 log::error("can't get capability from unknown factory");
200 return;
201 }
202
203 capabilities_.clear();
204 auto aidl_retval = provider_factory->getProviderCapabilities(
205 transport_->GetSessionType(), &capabilities_);
206 if (!aidl_retval.isOk()) {
207 log::fatal("BluetoothAudioHal::getProviderCapabilities failure: {}",
208 aidl_retval.getDescription());
209 return;
210 }
211 if (capabilities_.empty()) {
212 log::warn("SessionType={} Not supported by BluetoothAudioHal",
213 toString(transport_->GetSessionType()));
214 return;
215 }
216 log::info("BluetoothAudioHal SessionType={} has {} AudioCapabilities",
217 toString(transport_->GetSessionType()), capabilities_.size());
218
219 aidl_retval =
220 provider_factory->openProvider(transport_->GetSessionType(), &provider_);
221 if (!aidl_retval.isOk()) {
222 log::fatal("BluetoothAudioHal::openProvider failure: {}",
223 aidl_retval.getDescription());
224 }
225 log::assert_that(provider_ != nullptr, "assert failed: provider_ != nullptr");
226
227 binder_status_t binder_status = AIBinder_linkToDeath(
228 provider_factory->asBinder().get(), death_recipient_.get(), this);
229 if (binder_status != STATUS_OK) {
230 log::error("Failed to linkToDeath {}", static_cast<int>(binder_status));
231 }
232 provider_factory_ = std::move(provider_factory);
233
234 log::info("IBluetoothAudioProvidersFactory::openProvider() returned {}{}",
235 fmt::ptr(provider_.get()),
236 (provider_->isRemote() ? " (remote)" : " (local)"));
237 }
238
BluetoothAudioSinkClientInterface(IBluetoothSinkTransportInstance * sink)239 BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface(
240 IBluetoothSinkTransportInstance* sink)
241 : BluetoothAudioClientInterface{sink}, sink_(sink) {
242 FetchAudioProvider();
243 }
244
~BluetoothAudioSinkClientInterface()245 BluetoothAudioSinkClientInterface::~BluetoothAudioSinkClientInterface() {
246 if (provider_factory_ != nullptr) {
247 AIBinder_unlinkToDeath(provider_factory_->asBinder().get(),
248 death_recipient_.get(), nullptr);
249 }
250 }
251
BluetoothAudioSourceClientInterface(IBluetoothSourceTransportInstance * source)252 BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface(
253 IBluetoothSourceTransportInstance* source)
254 : BluetoothAudioClientInterface{source}, source_(source) {
255 FetchAudioProvider();
256 }
257
~BluetoothAudioSourceClientInterface()258 BluetoothAudioSourceClientInterface::~BluetoothAudioSourceClientInterface() {
259 if (provider_factory_ != nullptr) {
260 AIBinder_unlinkToDeath(provider_factory_->asBinder().get(),
261 death_recipient_.get(), nullptr);
262 }
263 }
264
binderDiedCallbackAidl(void * ptr)265 void BluetoothAudioClientInterface::binderDiedCallbackAidl(void* ptr) {
266 log::warn("restarting connection with new Audio Hal");
267 auto client = static_cast<BluetoothAudioClientInterface*>(ptr);
268 if (client == nullptr) {
269 log::error("null audio HAL died!");
270 return;
271 }
272 client->RenewAudioProviderAndSession();
273 }
274
UpdateAudioConfig(const AudioConfiguration & audio_config)275 bool BluetoothAudioClientInterface::UpdateAudioConfig(
276 const AudioConfiguration& audio_config) {
277 bool is_software_session =
278 (transport_->GetSessionType() ==
279 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
280 transport_->GetSessionType() ==
281 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
282 transport_->GetSessionType() ==
283 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
284 transport_->GetSessionType() ==
285 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
286 transport_->GetSessionType() ==
287 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
288 (bta_ag_is_sco_managed_by_audio() &&
289 (transport_->GetSessionType() ==
290 SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
291 transport_->GetSessionType() ==
292 SessionType::HFP_SOFTWARE_DECODING_DATAPATH)));
293 bool is_a2dp_offload_session =
294 (transport_->GetSessionType() ==
295 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
296 bool is_leaudio_unicast_offload_session =
297 (transport_->GetSessionType() ==
298 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
299 transport_->GetSessionType() ==
300 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
301 bool is_leaudio_broadcast_offload_session =
302 (transport_->GetSessionType() ==
303 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
304 auto audio_config_tag = audio_config.getTag();
305 bool is_software_audio_config =
306 (is_software_session &&
307 audio_config_tag == AudioConfiguration::pcmConfig);
308 bool is_a2dp_offload_audio_config =
309 (is_a2dp_offload_session &&
310 (audio_config_tag == AudioConfiguration::a2dpConfig ||
311 audio_config_tag == AudioConfiguration::a2dp));
312 bool is_leaudio_unicast_offload_audio_config =
313 (is_leaudio_unicast_offload_session &&
314 audio_config_tag == AudioConfiguration::leAudioConfig);
315 bool is_leaudio_broadcast_offload_audio_config =
316 (is_leaudio_broadcast_offload_session &&
317 audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
318 bool is_hfp_offload_audio_config =
319 (bta_ag_is_sco_managed_by_audio() &&
320 transport_->GetSessionType() ==
321 SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH &&
322 audio_config_tag == AudioConfiguration::hfpConfig);
323 if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
324 !is_leaudio_unicast_offload_audio_config &&
325 !is_leaudio_broadcast_offload_audio_config &&
326 !is_hfp_offload_audio_config) {
327 return false;
328 }
329 transport_->UpdateAudioConfiguration(audio_config);
330
331 if (provider_ == nullptr) {
332 log::info("BluetoothAudioHal nullptr, update it as session started");
333 return true;
334 }
335
336 if (!session_started_) {
337 log::info("BluetoothAudioHal session has not started");
338 return true;
339 }
340
341 auto aidl_retval = provider_->updateAudioConfiguration(audio_config);
342 if (!aidl_retval.isOk()) {
343 if (audio_config.getTag() != transport_->GetAudioConfiguration().getTag()) {
344 log::warn(
345 "BluetoothAudioHal audio config type: {} doesn't "
346 "match provider's audio config type: {}",
347 ::aidl::android::hardware::bluetooth::audio::toString(
348 audio_config.getTag()),
349 ::aidl::android::hardware::bluetooth::audio::toString(
350 transport_->GetAudioConfiguration().getTag()));
351 } else {
352 log::warn("BluetoothAudioHal is not ready: {} ",
353 aidl_retval.getDescription());
354 }
355 }
356 return true;
357 }
358
SetAllowedLatencyModes(std::vector<LatencyMode> latency_modes)359 bool BluetoothAudioClientInterface::SetAllowedLatencyModes(
360 std::vector<LatencyMode> latency_modes) {
361 if (provider_ == nullptr) {
362 log::info("BluetoothAudioHal nullptr");
363 return false;
364 }
365
366 if (latency_modes.empty()) {
367 latency_modes_.clear();
368 latency_modes_.push_back(LatencyMode::FREE);
369 } else {
370 /* Ensure that FREE is always included and remove duplicates if any */
371 std::set<LatencyMode> temp_set(latency_modes.begin(), latency_modes.end());
372 temp_set.insert(LatencyMode::FREE);
373 latency_modes_.clear();
374 latency_modes_.assign(temp_set.begin(), temp_set.end());
375 }
376
377 for (auto latency_mode : latency_modes) {
378 log::info(
379 "Latency mode allowed: {}",
380 ::aidl::android::hardware::bluetooth::audio::toString(latency_mode));
381 }
382
383 /* Low latency mode is used if modes other than FREE are present */
384 bool allowed = (latency_modes_.size() > 1);
385 log::info("Latency mode allowed: {}", allowed);
386 auto aidl_retval = provider_->setLowLatencyModeAllowed(allowed);
387 if (!aidl_retval.isOk()) {
388 log::warn(
389 "BluetoothAudioHal is not ready: {}. latency_modes_ is saved and it "
390 "will be sent to BluetoothAudioHal at StartSession.",
391 aidl_retval.getDescription());
392 }
393 return true;
394 }
395
StartSession()396 int BluetoothAudioClientInterface::StartSession() {
397 std::lock_guard<std::mutex> guard(internal_mutex_);
398 if (provider_ == nullptr) {
399 log::error("BluetoothAudioHal nullptr");
400 session_started_ = false;
401 return -EINVAL;
402 }
403 if (session_started_) {
404 log::error("session started already");
405 return -EBUSY;
406 }
407
408 std::shared_ptr<IBluetoothAudioPort> stack_if =
409 ndk::SharedRefBase::make<BluetoothAudioPortImpl>(transport_, provider_);
410
411 std::unique_ptr<DataMQ> data_mq;
412 DataMQDesc mq_desc;
413
414 auto aidl_retval = provider_->startSession(
415 stack_if, transport_->GetAudioConfiguration(), latency_modes_, &mq_desc);
416 if (!aidl_retval.isOk()) {
417 if (aidl_retval.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
418 log::error("BluetoothAudioHal Error: {}, audioConfig={}",
419 aidl_retval.getDescription(),
420 transport_->GetAudioConfiguration().toString());
421 } else {
422 log::fatal("BluetoothAudioHal failure: {}", aidl_retval.getDescription());
423 }
424 return -EPROTO;
425 }
426 data_mq.reset(new DataMQ(mq_desc));
427
428 if (data_mq && data_mq->isValid()) {
429 data_mq_ = std::move(data_mq);
430 } else if (transport_->GetSessionType() ==
431 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
432 transport_->GetSessionType() ==
433 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
434 transport_->GetSessionType() ==
435 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
436 transport_->GetSessionType() ==
437 SessionType::
438 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
439 (bta_ag_is_sco_managed_by_audio() &&
440 transport_->GetSessionType() ==
441 SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH)) {
442 transport_->ResetPresentationPosition();
443 session_started_ = true;
444 return 0;
445 }
446 if (data_mq_ && data_mq_->isValid()) {
447 transport_->ResetPresentationPosition();
448 session_started_ = true;
449 return 0;
450 } else {
451 if (!data_mq_) {
452 log::error("Failed to obtain audio data path");
453 }
454 if (data_mq_ && !data_mq_->isValid()) {
455 log::error("Audio data path is invalid");
456 }
457 session_started_ = false;
458 return -EIO;
459 }
460 }
461
StreamStarted(const BluetoothAudioCtrlAck & ack)462 void BluetoothAudioClientInterface::StreamStarted(
463 const BluetoothAudioCtrlAck& ack) {
464 if (provider_ == nullptr) {
465 log::error("BluetoothAudioHal nullptr");
466 return;
467 }
468 if (ack == BluetoothAudioCtrlAck::PENDING) {
469 log::info("{} ignored", ack);
470 return;
471 }
472 BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
473
474 auto aidl_retval = provider_->streamStarted(status);
475
476 if (!aidl_retval.isOk()) {
477 log::error("BluetoothAudioHal failure: {}", aidl_retval.getDescription());
478 }
479 }
480
StreamSuspended(const BluetoothAudioCtrlAck & ack)481 void BluetoothAudioClientInterface::StreamSuspended(
482 const BluetoothAudioCtrlAck& ack) {
483 if (provider_ == nullptr) {
484 log::error("BluetoothAudioHal nullptr");
485 return;
486 }
487 if (ack == BluetoothAudioCtrlAck::PENDING) {
488 log::info("{} ignored", ack);
489 return;
490 }
491 BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
492
493 auto aidl_retval = provider_->streamSuspended(status);
494
495 if (!aidl_retval.isOk()) {
496 log::error("BluetoothAudioHal failure: {}", aidl_retval.getDescription());
497 }
498 }
499
EndSession()500 int BluetoothAudioClientInterface::EndSession() {
501 std::lock_guard<std::mutex> guard(internal_mutex_);
502 if (!session_started_) {
503 log::info("session ended already");
504 return 0;
505 }
506
507 session_started_ = false;
508 if (provider_ == nullptr) {
509 log::error("BluetoothAudioHal nullptr");
510 return -EINVAL;
511 }
512 data_mq_ = nullptr;
513
514 auto aidl_retval = provider_->endSession();
515
516 if (!aidl_retval.isOk()) {
517 log::error("BluetoothAudioHal failure: {}", aidl_retval.getDescription());
518 return -EPROTO;
519 }
520 return 0;
521 }
522
FlushAudioData()523 void BluetoothAudioClientInterface::FlushAudioData() {
524 if (transport_->GetSessionType() ==
525 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
526 transport_->GetSessionType() ==
527 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
528 transport_->GetSessionType() ==
529 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
530 (bta_ag_is_sco_managed_by_audio() &&
531 transport_->GetSessionType() ==
532 SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH)) {
533 return;
534 }
535
536 if (data_mq_ == nullptr || !data_mq_->isValid()) {
537 log::warn("data_mq_ invalid");
538 return;
539 }
540 size_t size = data_mq_->availableToRead();
541 std::vector<MqDataType> buffer(size);
542
543 if (data_mq_->read(buffer.data(), size) != size) {
544 log::warn("failed to flush data queue!");
545 }
546 }
547
ReadAudioData(uint8_t * p_buf,uint32_t len)548 size_t BluetoothAudioSinkClientInterface::ReadAudioData(uint8_t* p_buf,
549 uint32_t len) {
550 if (!IsValid()) {
551 log::error("BluetoothAudioHal is not valid");
552 return 0;
553 }
554 if (p_buf == nullptr || len == 0) return 0;
555
556 std::lock_guard<std::mutex> guard(internal_mutex_);
557
558 size_t total_read = 0;
559 int timeout_ms = kDefaultDataReadTimeoutMs;
560 do {
561 if (data_mq_ == nullptr || !data_mq_->isValid()) break;
562
563 size_t avail_to_read = data_mq_->availableToRead();
564 if (avail_to_read) {
565 if (avail_to_read > len - total_read) {
566 avail_to_read = len - total_read;
567 }
568 if (data_mq_->read((MqDataType*)p_buf + total_read, avail_to_read) == 0) {
569 log::warn("len={} total_read={} failed", len, total_read);
570 break;
571 }
572 total_read += avail_to_read;
573 } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
574 std::this_thread::sleep_for(
575 std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
576 timeout_ms -= kDefaultDataReadPollIntervalMs;
577 continue;
578 } else {
579 log::warn("{}/{} no data {} ms", len - total_read, len,
580 kDefaultDataReadTimeoutMs - timeout_ms);
581 break;
582 }
583 } while (total_read < len);
584
585 if (timeout_ms <
586 (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
587 timeout_ms >= kDefaultDataReadPollIntervalMs) {
588 log::verbose("underflow {} -> {} read {} ms", len, total_read,
589 kDefaultDataReadTimeoutMs - timeout_ms);
590 } else {
591 log::verbose("{} -> {} read", len, total_read);
592 }
593
594 sink_->LogBytesRead(total_read);
595 return total_read;
596 }
597
RenewAudioProviderAndSession()598 void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
599 // NOTE: must be invoked on the same thread where this
600 // BluetoothAudioClientInterface is running
601 FetchAudioProvider();
602
603 if (session_started_) {
604 log::info("Restart the session while audio HAL recovering");
605 session_started_ = false;
606
607 StartSession();
608 }
609 }
610
WriteAudioData(const uint8_t * p_buf,uint32_t len)611 size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf,
612 uint32_t len) {
613 if (!IsValid()) {
614 log::error("BluetoothAudioHal is not valid");
615 return 0;
616 }
617 if (p_buf == nullptr || len == 0) return 0;
618
619 std::lock_guard<std::mutex> guard(internal_mutex_);
620
621 size_t total_written = 0;
622 int timeout_ms = kDefaultDataWriteTimeoutMs;
623 do {
624 if (data_mq_ == nullptr || !data_mq_->isValid()) break;
625
626 size_t avail_to_write = data_mq_->availableToWrite();
627 if (avail_to_write) {
628 if (avail_to_write > len - total_written) {
629 avail_to_write = len - total_written;
630 }
631 if (data_mq_->write((const MqDataType*)p_buf + total_written,
632 avail_to_write) == 0) {
633 log::warn("len={} total_written={} failed", len, total_written);
634 break;
635 }
636 total_written += avail_to_write;
637 } else if (timeout_ms >= kDefaultDataWritePollIntervalMs) {
638 std::this_thread::sleep_for(
639 std::chrono::milliseconds(kDefaultDataWritePollIntervalMs));
640 timeout_ms -= kDefaultDataWritePollIntervalMs;
641 continue;
642 } else {
643 log::warn("{}/{} no data {} ms", len - total_written, len,
644 kDefaultDataWriteTimeoutMs - timeout_ms);
645 break;
646 }
647 } while (total_written < len);
648
649 if (timeout_ms <
650 (kDefaultDataWriteTimeoutMs - kDefaultDataWritePollIntervalMs) &&
651 timeout_ms >= kDefaultDataWritePollIntervalMs) {
652 log::verbose("underflow {} -> {} read {} ms", len, total_written,
653 kDefaultDataWriteTimeoutMs - timeout_ms);
654 } else {
655 log::verbose("{} -> {} written", len, total_written);
656 }
657
658 source_->LogBytesWritten(total_written);
659 return total_written;
660 }
661
SetCodecPriority(CodecId codec_id,int32_t priority)662 void BluetoothAudioClientInterface::SetCodecPriority(CodecId codec_id,
663 int32_t priority) {
664 log::assert_that(provider_ != nullptr, "assert failed: provider_ != nullptr");
665 auto aidl_retval = provider_->setCodecPriority(codec_id, priority);
666 if (!aidl_retval.isOk()) {
667 log::fatal("BluetoothAudioHal::setCodecPriority failure: {}",
668 aidl_retval.getDescription());
669 }
670 }
671
672 std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
GetLeAudioAseConfiguration(std::optional<std::vector<std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>> & remoteSinkAudioCapabilities,std::optional<std::vector<std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>> & remoteSourceAudioCapabilities,std::vector<IBluetoothAudioProvider::LeAudioConfigurationRequirement> & requirements)673 BluetoothAudioClientInterface::GetLeAudioAseConfiguration(
674 std::optional<std::vector<
675 std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
676 remoteSinkAudioCapabilities,
677 std::optional<std::vector<
678 std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
679 remoteSourceAudioCapabilities,
680 std::vector<IBluetoothAudioProvider::LeAudioConfigurationRequirement>&
681 requirements) {
682 log::assert_that(provider_ != nullptr, "assert failed: provider_ != nullptr");
683
684 std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
685 configurations;
686 auto aidl_retval = provider_->getLeAudioAseConfiguration(
687 remoteSinkAudioCapabilities, remoteSourceAudioCapabilities, requirements,
688 &configurations);
689
690 if (!aidl_retval.isOk()) {
691 log::fatal("BluetoothAudioHal::getLeAudioAseConfiguration failure: {}",
692 aidl_retval.getDescription());
693 }
694
695 log::info(
696 "BluetoothAudioHal::getLeAudioAseConfiguration returned {} "
697 "configurations.",
698 configurations.size());
699 return configurations;
700 }
701
702 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair
getLeAudioAseQosConfiguration(IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement & qosRequirement)703 BluetoothAudioClientInterface::getLeAudioAseQosConfiguration(
704 IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
705 qosRequirement) {
706 log::assert_that(provider_ != nullptr, "assert failed: provider_ != nullptr");
707
708 IBluetoothAudioProvider::LeAudioAseQosConfigurationPair qos_configuration;
709 auto aidl_retval = provider_->getLeAudioAseQosConfiguration(
710 qosRequirement, &qos_configuration);
711
712 if (!aidl_retval.isOk()) {
713 log::fatal("BluetoothAudioHal::getLeAudioAseQosConfiguration failure: {}",
714 aidl_retval.getDescription());
715 }
716 return qos_configuration;
717 }
718
onSinkAseMetadataChanged(IBluetoothAudioProvider::AseState state,int32_t cigId,int32_t cisId,std::optional<std::vector<std::optional<MetadataLtv>>> & metadata)719 void BluetoothAudioClientInterface::onSinkAseMetadataChanged(
720 IBluetoothAudioProvider::AseState state, int32_t cigId, int32_t cisId,
721 std::optional<std::vector<std::optional<MetadataLtv>>>& metadata) {
722 log::assert_that(provider_ != nullptr, "assert failed: provider_ != nullptr");
723
724 auto aidl_retval =
725 provider_->onSinkAseMetadataChanged(state, cigId, cisId, metadata);
726
727 if (!aidl_retval.isOk()) {
728 log::fatal("BluetoothAudioHal::onSinkAseMetadataChanged failure: {}",
729 aidl_retval.getDescription());
730 }
731 }
732
onSourceAseMetadataChanged(IBluetoothAudioProvider::AseState state,int32_t cigId,int32_t cisId,std::optional<std::vector<std::optional<MetadataLtv>>> & metadata)733 void BluetoothAudioClientInterface::onSourceAseMetadataChanged(
734 IBluetoothAudioProvider::AseState state, int32_t cigId, int32_t cisId,
735 std::optional<std::vector<std::optional<MetadataLtv>>>& metadata) {
736 log::assert_that(provider_ != nullptr, "assert failed: provider_ != nullptr");
737
738 auto aidl_retval =
739 provider_->onSourceAseMetadataChanged(state, cigId, cisId, metadata);
740
741 if (!aidl_retval.isOk()) {
742 log::fatal("BluetoothAudioHal::onSinkAseMetadataChanged failure: {}",
743 aidl_retval.getDescription());
744 }
745 }
746
747 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting
getLeAudioBroadcastConfiguration(const std::optional<std::vector<std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>> & remoteSinkAudioCapabilities,const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement & requirement)748 BluetoothAudioClientInterface::getLeAudioBroadcastConfiguration(
749 const std::optional<std::vector<
750 std::optional<IBluetoothAudioProvider::LeAudioDeviceCapabilities>>>&
751 remoteSinkAudioCapabilities,
752 const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement&
753 requirement) {
754 log::assert_that(provider_ != nullptr, "assert failed: provider_ != nullptr");
755
756 IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting setting;
757 auto aidl_retval = provider_->getLeAudioBroadcastConfiguration(
758 remoteSinkAudioCapabilities, requirement, &setting);
759
760 if (!aidl_retval.isOk()) {
761 log::fatal("BluetoothAudioHal::onSinkAseMetadataChanged failure: {}",
762 aidl_retval.getDescription());
763 }
764
765 return setting;
766 }
767
768 } // namespace aidl
769 } // namespace audio
770 } // namespace bluetooth
771