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