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