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/a2dp/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 namespace a2dp {
39 
BluetoothAudioClientInterface(IBluetoothTransportInstance * instance)40 BluetoothAudioClientInterface::BluetoothAudioClientInterface(IBluetoothTransportInstance* instance)
41     : provider_(nullptr),
42       provider_factory_(nullptr),
43       session_started_(false),
44       data_mq_(nullptr),
45       transport_(instance),
46       latency_modes_({LatencyMode::FREE}) {
47   death_recipient_ =
48           ::ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(binderDiedCallbackAidl));
49   FetchAudioProvider();
50 }
51 
~BluetoothAudioClientInterface()52 BluetoothAudioClientInterface::~BluetoothAudioClientInterface() {
53   if (provider_factory_ != nullptr) {
54     AIBinder_unlinkToDeath(provider_factory_->asBinder().get(), death_recipient_.get(), nullptr);
55   }
56 }
57 
IsValid() const58 bool BluetoothAudioClientInterface::IsValid() const { return provider_ != nullptr; }
59 
is_aidl_available()60 bool BluetoothAudioClientInterface::is_aidl_available() {
61   return AServiceManager_isDeclared(kDefaultAudioProviderFactoryInterface.c_str());
62 }
63 
GetAudioCapabilities() const64 std::vector<AudioCapabilities> BluetoothAudioClientInterface::GetAudioCapabilities() const {
65   return capabilities_;
66 }
67 
GetAudioCapabilities(SessionType session_type)68 std::vector<AudioCapabilities> BluetoothAudioClientInterface::GetAudioCapabilities(
69         SessionType session_type) {
70   std::vector<AudioCapabilities> capabilities(0);
71   if (!is_aidl_available()) {
72     return capabilities;
73   }
74   auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(::ndk::SpAIBinder(
75           AServiceManager_waitForService(kDefaultAudioProviderFactoryInterface.c_str())));
76 
77   if (provider_factory == nullptr) {
78     log::error("can't get capability from unknown factory");
79     return capabilities;
80   }
81 
82   auto aidl_retval = provider_factory->getProviderCapabilities(session_type, &capabilities);
83   if (!aidl_retval.isOk()) {
84     log::fatal("BluetoothAudioHal::getProviderCapabilities failure: {}",
85                aidl_retval.getDescription());
86   }
87   return capabilities;
88 }
89 
90 std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
GetProviderInfo(SessionType session_type,std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory)91 BluetoothAudioClientInterface::GetProviderInfo(
92         SessionType session_type,
93         std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory) {
94   if (!is_aidl_available()) {
95     return std::nullopt;
96   }
97 
98   if (provider_factory == nullptr) {
99     provider_factory = IBluetoothAudioProviderFactory::fromBinder(::ndk::SpAIBinder(
100             AServiceManager_waitForService(kDefaultAudioProviderFactoryInterface.c_str())));
101   }
102 
103   if (provider_factory == nullptr) {
104     log::error("can't get provider info from unknown factory");
105     return std::nullopt;
106   }
107 
108   std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info = {};
109   auto aidl_retval = provider_factory->getProviderInfo(session_type, &provider_info);
110 
111   if (!aidl_retval.isOk()) {
112     log::error("BluetoothAudioHal::getProviderInfo failure: {}", aidl_retval.getDescription());
113     return std::nullopt;
114   }
115 
116   return provider_info;
117 }
118 
GetA2dpConfiguration(std::vector<A2dpRemoteCapabilities> const & remote_capabilities,A2dpConfigurationHint const & hint) const119 std::optional<A2dpConfiguration> BluetoothAudioClientInterface::GetA2dpConfiguration(
120         std::vector<A2dpRemoteCapabilities> const& remote_capabilities,
121         A2dpConfigurationHint const& hint) const {
122   if (!is_aidl_available()) {
123     return std::nullopt;
124   }
125 
126   if (provider_ == nullptr) {
127     log::error("can't get a2dp configuration from unknown provider");
128     return std::nullopt;
129   }
130 
131   std::optional<A2dpConfiguration> configuration = std::nullopt;
132   auto aidl_retval = provider_->getA2dpConfiguration(remote_capabilities, hint, &configuration);
133 
134   if (!aidl_retval.isOk()) {
135     log::error("getA2dpConfiguration failure: {}", aidl_retval.getDescription());
136     return std::nullopt;
137   }
138 
139   return configuration;
140 }
141 
ParseA2dpConfiguration(const CodecId & codec_id,const std::vector<uint8_t> & configuration,CodecParameters * codec_parameters) const142 std::optional<A2dpStatus> BluetoothAudioClientInterface::ParseA2dpConfiguration(
143         const CodecId& codec_id, const std::vector<uint8_t>& configuration,
144         CodecParameters* codec_parameters) const {
145   A2dpStatus a2dp_status;
146 
147   if (provider_ == nullptr) {
148     log::error("can not parse A2DP configuration because of unknown provider");
149     return std::nullopt;
150   }
151 
152   auto aidl_retval = provider_->parseA2dpConfiguration(codec_id, configuration, codec_parameters,
153                                                        &a2dp_status);
154 
155   if (!aidl_retval.isOk()) {
156     log::error("parseA2dpConfiguration failure: {}", aidl_retval.getDescription());
157     return std::nullopt;
158   }
159 
160   return std::make_optional(a2dp_status);
161 }
162 
FetchAudioProvider()163 void BluetoothAudioClientInterface::FetchAudioProvider() {
164   if (!is_aidl_available()) {
165     log::error("aidl is not supported on this platform.");
166     return;
167   }
168   if (provider_ != nullptr) {
169     log::warn("refetch");
170   }
171   // Retry if audioserver restarts in the middle of fetching.
172   // When audioserver restarts, IBluetoothAudioProviderFactory service is also
173   // re-registered, so we need to re-fetch the service.
174   for (int retry_no = 0; retry_no < kFetchAudioProviderRetryNumber; ++retry_no) {
175     auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(::ndk::SpAIBinder(
176             AServiceManager_waitForService(kDefaultAudioProviderFactoryInterface.c_str())));
177 
178     if (provider_factory == nullptr) {
179       log::error("can't get capability from unknown factory");
180       return;
181     }
182 
183     capabilities_.clear();
184     auto aidl_retval =
185             provider_factory->getProviderCapabilities(transport_->GetSessionType(), &capabilities_);
186     if (!aidl_retval.isOk()) {
187       log::error("BluetoothAudioHal::getProviderCapabilities failure: {}, retry number {}",
188                  aidl_retval.getDescription(), retry_no + 1);
189       continue;
190     }
191     if (capabilities_.empty()) {
192       log::warn("SessionType={} Not supported by BluetoothAudioHal",
193                 toString(transport_->GetSessionType()));
194       return;
195     }
196     log::info("BluetoothAudioHal SessionType={} has {} AudioCapabilities",
197               toString(transport_->GetSessionType()), capabilities_.size());
198 
199     aidl_retval = provider_factory->openProvider(transport_->GetSessionType(), &provider_);
200     if (!aidl_retval.isOk() || provider_ == nullptr) {
201       log::error("BluetoothAudioHal::openProvider failure: {}, retry number {}",
202                  aidl_retval.getDescription(), retry_no + 1);
203     } else {
204       provider_factory_ = std::move(provider_factory);
205       break;
206     }
207   }
208   log::assert_that(provider_factory_ != nullptr, "assert failed: provider_factory_ != nullptr");
209   log::assert_that(provider_ != nullptr, "assert failed: provider_ != nullptr");
210 
211   binder_status_t binder_status =
212           AIBinder_linkToDeath(provider_factory_->asBinder().get(), death_recipient_.get(), this);
213   if (binder_status != STATUS_OK) {
214     log::error("Failed to linkToDeath {}", static_cast<int>(binder_status));
215   }
216 
217   log::info("IBluetoothAudioProvidersFactory::openProvider() returned {}{}",
218             std::format_ptr(provider_.get()), (provider_->isRemote() ? " (remote)" : " (local)"));
219 }
220 
binderDiedCallbackAidl(void * ptr)221 void BluetoothAudioClientInterface::binderDiedCallbackAidl(void* ptr) {
222   log::warn("restarting connection with new Audio Hal");
223   auto client = static_cast<BluetoothAudioClientInterface*>(ptr);
224   if (client == nullptr) {
225     log::error("null audio HAL died!");
226     return;
227   }
228   client->RenewAudioProviderAndSession();
229 }
230 
UpdateAudioConfig(const AudioConfiguration & audio_config)231 bool BluetoothAudioClientInterface::UpdateAudioConfig(const AudioConfiguration& audio_config) {
232   bool is_software_session =
233           (transport_->GetSessionType() == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
234            transport_->GetSessionType() == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
235            transport_->GetSessionType() == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
236            transport_->GetSessionType() == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
237            transport_->GetSessionType() ==
238                    SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
239            (bta_ag_is_sco_managed_by_audio() &&
240             (transport_->GetSessionType() == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
241              transport_->GetSessionType() == SessionType::HFP_SOFTWARE_DECODING_DATAPATH)));
242   bool is_a2dp_offload_session =
243           (transport_->GetSessionType() == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
244   bool is_leaudio_unicast_offload_session =
245           (transport_->GetSessionType() ==
246                    SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
247            transport_->GetSessionType() ==
248                    SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
249   bool is_leaudio_broadcast_offload_session =
250           (transport_->GetSessionType() ==
251            SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
252   auto audio_config_tag = audio_config.getTag();
253   bool is_software_audio_config =
254           (is_software_session && audio_config_tag == AudioConfiguration::pcmConfig);
255   bool is_a2dp_offload_audio_config =
256           (is_a2dp_offload_session && (audio_config_tag == AudioConfiguration::a2dpConfig ||
257                                        audio_config_tag == AudioConfiguration::a2dp));
258   bool is_leaudio_unicast_offload_audio_config =
259           (is_leaudio_unicast_offload_session &&
260            audio_config_tag == AudioConfiguration::leAudioConfig);
261   bool is_leaudio_broadcast_offload_audio_config =
262           (is_leaudio_broadcast_offload_session &&
263            audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
264   bool is_hfp_offload_audio_config =
265           (bta_ag_is_sco_managed_by_audio() &&
266            transport_->GetSessionType() == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH &&
267            audio_config_tag == AudioConfiguration::hfpConfig);
268   if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
269       !is_leaudio_unicast_offload_audio_config && !is_leaudio_broadcast_offload_audio_config &&
270       !is_hfp_offload_audio_config) {
271     return false;
272   }
273   transport_->UpdateAudioConfiguration(audio_config);
274 
275   if (provider_ == nullptr) {
276     log::info("BluetoothAudioHal nullptr, update it as session started");
277     return true;
278   }
279 
280   if (!session_started_) {
281     log::info("BluetoothAudioHal session has not started");
282     return true;
283   }
284 
285   auto aidl_retval = provider_->updateAudioConfiguration(audio_config);
286   if (!aidl_retval.isOk()) {
287     if (audio_config.getTag() != transport_->GetAudioConfiguration().getTag()) {
288       log::warn(
289               "BluetoothAudioHal audio config type: {} doesn't "
290               "match provider's audio config type: {}",
291               ::aidl::android::hardware::bluetooth::audio::toString(audio_config.getTag()),
292               ::aidl::android::hardware::bluetooth::audio::toString(
293                       transport_->GetAudioConfiguration().getTag()));
294     } else {
295       log::warn("BluetoothAudioHal is not ready: {} ", aidl_retval.getDescription());
296     }
297   }
298   return true;
299 }
300 
SetAllowedLatencyModes(std::vector<LatencyMode> latency_modes)301 bool BluetoothAudioClientInterface::SetAllowedLatencyModes(std::vector<LatencyMode> latency_modes) {
302   if (provider_ == nullptr) {
303     log::info("BluetoothAudioHal nullptr");
304     return false;
305   }
306 
307   if (latency_modes.empty()) {
308     latency_modes_.clear();
309     latency_modes_.push_back(LatencyMode::FREE);
310   } else {
311     /* Ensure that FREE is always included and remove duplicates if any */
312     std::set<LatencyMode> temp_set(latency_modes.begin(), latency_modes.end());
313     temp_set.insert(LatencyMode::FREE);
314     latency_modes_.clear();
315     latency_modes_.assign(temp_set.begin(), temp_set.end());
316   }
317 
318   for (auto latency_mode : latency_modes) {
319     log::info("Latency mode allowed: {}",
320               ::aidl::android::hardware::bluetooth::audio::toString(latency_mode));
321   }
322 
323   /* Low latency mode is used if modes other than FREE are present */
324   bool allowed = (latency_modes_.size() > 1);
325   log::info("Latency mode allowed: {}", allowed);
326   auto aidl_retval = provider_->setLowLatencyModeAllowed(allowed);
327   if (!aidl_retval.isOk()) {
328     log::warn(
329             "BluetoothAudioHal is not ready: {}. latency_modes_ is saved and it "
330             "will be sent to BluetoothAudioHal at StartSession.",
331             aidl_retval.getDescription());
332   }
333   return true;
334 }
335 
StartSession()336 int BluetoothAudioClientInterface::StartSession() {
337   std::lock_guard<std::mutex> guard(internal_mutex_);
338   if (provider_ == nullptr) {
339     log::error("BluetoothAudioHal nullptr");
340     session_started_ = false;
341     return -EINVAL;
342   }
343   if (session_started_) {
344     log::error("session started already");
345     return -EBUSY;
346   }
347 
348   std::shared_ptr<IBluetoothAudioPort> stack_if =
349           ndk::SharedRefBase::make<BluetoothAudioPortImpl>(transport_, provider_);
350 
351   std::unique_ptr<DataMQ> data_mq;
352   DataMQDesc mq_desc;
353 
354   auto aidl_retval = provider_->startSession(stack_if, transport_->GetAudioConfiguration(),
355                                              latency_modes_, &mq_desc);
356   if (!aidl_retval.isOk()) {
357     if (aidl_retval.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
358       log::error("BluetoothAudioHal Error: {}, audioConfig={}", aidl_retval.getDescription(),
359                  transport_->GetAudioConfiguration().toString());
360     } else {
361       log::fatal("BluetoothAudioHal failure: {}", aidl_retval.getDescription());
362     }
363     return -EPROTO;
364   }
365   data_mq.reset(new DataMQ(mq_desc));
366 
367   if (data_mq && data_mq->isValid()) {
368     data_mq_ = std::move(data_mq);
369   } else if (transport_->GetSessionType() == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
370              transport_->GetSessionType() ==
371                      SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
372              transport_->GetSessionType() ==
373                      SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
374              transport_->GetSessionType() ==
375                      SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
376              (bta_ag_is_sco_managed_by_audio() &&
377               transport_->GetSessionType() == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH)) {
378     transport_->ResetPresentationPosition();
379     session_started_ = true;
380     return 0;
381   }
382   if (data_mq_ && data_mq_->isValid()) {
383     transport_->ResetPresentationPosition();
384     session_started_ = true;
385     return 0;
386   } else {
387     if (!data_mq_) {
388       log::error("Failed to obtain audio data path");
389     }
390     if (data_mq_ && !data_mq_->isValid()) {
391       log::error("Audio data path is invalid");
392     }
393     session_started_ = false;
394     return -EIO;
395   }
396 }
397 
StreamStarted(const Status & ack)398 void BluetoothAudioClientInterface::StreamStarted(const Status& ack) {
399   if (provider_ == nullptr) {
400     log::error("BluetoothAudioHal nullptr");
401     return;
402   }
403   if (ack == Status::PENDING) {
404     log::info("{} ignored", ack);
405     return;
406   }
407 
408   auto status = StatusToHalStatus(ack);
409   auto aidl_retval = provider_->streamStarted(status);
410 
411   if (!aidl_retval.isOk()) {
412     log::error("BluetoothAudioHal failure: {}", aidl_retval.getDescription());
413   }
414 }
415 
StreamSuspended(const Status & ack)416 void BluetoothAudioClientInterface::StreamSuspended(const Status& ack) {
417   if (provider_ == nullptr) {
418     log::error("BluetoothAudioHal nullptr");
419     return;
420   }
421   if (ack == Status::PENDING) {
422     log::info("{} ignored", ack);
423     return;
424   }
425 
426   auto status = StatusToHalStatus(ack);
427   auto aidl_retval = provider_->streamSuspended(status);
428 
429   if (!aidl_retval.isOk()) {
430     log::error("BluetoothAudioHal failure: {}", aidl_retval.getDescription());
431   }
432 }
433 
EndSession()434 int BluetoothAudioClientInterface::EndSession() {
435   std::lock_guard<std::mutex> guard(internal_mutex_);
436   if (!session_started_) {
437     log::info("session ended already");
438     return 0;
439   }
440 
441   session_started_ = false;
442   if (provider_ == nullptr) {
443     log::error("BluetoothAudioHal nullptr");
444     return -EINVAL;
445   }
446   data_mq_ = nullptr;
447 
448   auto aidl_retval = provider_->endSession();
449 
450   if (!aidl_retval.isOk()) {
451     log::error("BluetoothAudioHal failure: {}", aidl_retval.getDescription());
452     return -EPROTO;
453   }
454   return 0;
455 }
456 
ReadAudioData(uint8_t * p_buf,uint32_t len)457 size_t BluetoothAudioClientInterface::ReadAudioData(uint8_t* p_buf, uint32_t len) {
458   if (!IsValid()) {
459     log::error("BluetoothAudioHal is not valid");
460     return 0;
461   }
462   if (p_buf == nullptr || len == 0) {
463     return 0;
464   }
465 
466   std::lock_guard<std::mutex> guard(internal_mutex_);
467 
468   size_t total_read = 0;
469   int timeout_ms = kDefaultDataReadTimeoutMs;
470   do {
471     if (data_mq_ == nullptr || !data_mq_->isValid()) {
472       break;
473     }
474 
475     size_t avail_to_read = data_mq_->availableToRead();
476     if (avail_to_read) {
477       if (avail_to_read > len - total_read) {
478         avail_to_read = len - total_read;
479       }
480       if (data_mq_->read(reinterpret_cast<MqDataType*>(p_buf) + total_read, avail_to_read) == 0) {
481         log::warn("len={} total_read={} failed", len, total_read);
482         break;
483       }
484       total_read += avail_to_read;
485     } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
486       std::this_thread::sleep_for(std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
487       timeout_ms -= kDefaultDataReadPollIntervalMs;
488       continue;
489     } else {
490       log::warn("{}/{} no data {} ms", len - total_read, len,
491                 kDefaultDataReadTimeoutMs - timeout_ms);
492       break;
493     }
494   } while (total_read < len);
495 
496   if (timeout_ms < (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
497       timeout_ms >= kDefaultDataReadPollIntervalMs) {
498     log::verbose("underflow {} -> {} read {} ms", len, total_read,
499                  kDefaultDataReadTimeoutMs - timeout_ms);
500   } else {
501     log::verbose("{} -> {} read", len, total_read);
502   }
503 
504   transport_->LogBytesRead(total_read);
505   return total_read;
506 }
507 
RenewAudioProviderAndSession()508 void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
509   // NOTE: must be invoked on the same thread where this
510   // BluetoothAudioClientInterface is running
511   FetchAudioProvider();
512 
513   if (session_started_) {
514     log::info("Restart the session while audio HAL recovering");
515     session_started_ = false;
516 
517     StartSession();
518   }
519 }
520 
521 }  // namespace a2dp
522 }  // namespace aidl
523 }  // namespace audio
524 }  // namespace bluetooth
525