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