• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 namespace bluetooth {
24 namespace audio {
25 namespace aidl {
26 
operator <<(std::ostream & os,const BluetoothAudioCtrlAck & ack)27 std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack) {
28   switch (ack) {
29     case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
30       return os << "SUCCESS_FINISHED";
31     case BluetoothAudioCtrlAck::PENDING:
32       return os << "PENDING";
33     case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
34       return os << "FAILURE_UNSUPPORTED";
35     case BluetoothAudioCtrlAck::FAILURE_BUSY:
36       return os << "FAILURE_BUSY";
37     case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
38       return os << "FAILURE_DISCONNECTING";
39     case BluetoothAudioCtrlAck::FAILURE:
40       return os << "FAILURE";
41     default:
42       return os << "UNDEFINED " << static_cast<int8_t>(ack);
43   }
44 }
45 
BluetoothAudioClientInterface(IBluetoothTransportInstance * instance)46 BluetoothAudioClientInterface::BluetoothAudioClientInterface(
47     IBluetoothTransportInstance* instance)
48     : provider_(nullptr),
49       provider_factory_(nullptr),
50       session_started_(false),
51       data_mq_(nullptr),
52       transport_(instance) {
53   death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient(
54       AIBinder_DeathRecipient_new(binderDiedCallbackAidl));
55 }
56 
is_aidl_available()57 bool BluetoothAudioClientInterface::is_aidl_available() {
58   return AServiceManager_isDeclared(
59       kDefaultAudioProviderFactoryInterface.c_str());
60 }
61 
62 std::vector<AudioCapabilities>
GetAudioCapabilities() const63 BluetoothAudioClientInterface::GetAudioCapabilities() const {
64   return capabilities_;
65 }
66 
67 std::vector<AudioCapabilities>
GetAudioCapabilities(SessionType session_type)68 BluetoothAudioClientInterface::GetAudioCapabilities(SessionType session_type) {
69   std::vector<AudioCapabilities> capabilities(0);
70   if (!is_aidl_available()) {
71     return capabilities;
72   }
73   auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
74       ::ndk::SpAIBinder(AServiceManager_waitForService(
75           kDefaultAudioProviderFactoryInterface.c_str())));
76 
77   if (provider_factory == nullptr) {
78     LOG(ERROR) << __func__ << ", can't get capability from unknown factory";
79     return capabilities;
80   }
81 
82   auto aidl_retval =
83       provider_factory->getProviderCapabilities(session_type, &capabilities);
84   if (!aidl_retval.isOk()) {
85     LOG(FATAL) << __func__
86                << ": BluetoothAudioHal::getProviderCapabilities failure: "
87                << aidl_retval.getDescription();
88   }
89   return capabilities;
90 }
91 
FetchAudioProvider()92 void BluetoothAudioClientInterface::FetchAudioProvider() {
93   if (!is_aidl_available()) {
94     LOG(ERROR) << __func__ << ": aidl is not supported on this platform.";
95     return;
96   }
97   if (provider_ != nullptr) {
98     LOG(WARNING) << __func__ << ": refetch";
99   }
100   auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
101       ::ndk::SpAIBinder(AServiceManager_waitForService(
102           kDefaultAudioProviderFactoryInterface.c_str())));
103 
104   if (provider_factory == nullptr) {
105     LOG(ERROR) << __func__ << ", can't get capability from unknown factory";
106     return;
107   }
108 
109   capabilities_.clear();
110   auto aidl_retval = provider_factory->getProviderCapabilities(
111       transport_->GetSessionType(), &capabilities_);
112   if (!aidl_retval.isOk()) {
113     LOG(FATAL) << __func__
114                << ": BluetoothAudioHal::getProviderCapabilities failure: "
115                << aidl_retval.getDescription();
116     return;
117   }
118   if (capabilities_.empty()) {
119     LOG(WARNING) << __func__
120                  << ": SessionType=" << toString(transport_->GetSessionType())
121                  << " Not supported by BluetoothAudioHal";
122     return;
123   }
124   LOG(INFO) << __func__ << ": BluetoothAudioHal SessionType="
125             << toString(transport_->GetSessionType()) << " has "
126             << capabilities_.size() << " AudioCapabilities";
127 
128   aidl_retval =
129       provider_factory->openProvider(transport_->GetSessionType(), &provider_);
130   if (!aidl_retval.isOk()) {
131     LOG(FATAL) << __func__ << ": BluetoothAudioHal::openProvider failure: "
132                << aidl_retval.getDescription();
133   }
134   CHECK(provider_ != nullptr);
135 
136   binder_status_t binder_status = AIBinder_linkToDeath(
137      provider_factory->asBinder().get(), death_recipient_.get(), this);
138   if (binder_status != STATUS_OK) {
139     LOG(ERROR) << "Failed to linkToDeath " << static_cast<int>(binder_status);
140   }
141   provider_factory_ = std::move(provider_factory);
142 
143   LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
144             << provider_.get()
145             << (provider_->isRemote() ? " (remote)" : " (local)");
146 }
147 
BluetoothAudioSinkClientInterface(IBluetoothSinkTransportInstance * sink,bluetooth::common::MessageLoopThread * message_loop)148 BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface(
149     IBluetoothSinkTransportInstance* sink,
150     bluetooth::common::MessageLoopThread* message_loop)
151     : BluetoothAudioClientInterface{sink}, sink_(sink) {
152   FetchAudioProvider();
153 }
154 
~BluetoothAudioSinkClientInterface()155 BluetoothAudioSinkClientInterface::~BluetoothAudioSinkClientInterface() {
156   if (provider_factory_ != nullptr) {
157     AIBinder_unlinkToDeath(provider_factory_->asBinder().get(), death_recipient_.get(),
158                            nullptr);
159   }
160 }
161 
BluetoothAudioSourceClientInterface(IBluetoothSourceTransportInstance * source,bluetooth::common::MessageLoopThread * message_loop)162 BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface(
163     IBluetoothSourceTransportInstance* source,
164     bluetooth::common::MessageLoopThread* message_loop)
165     : BluetoothAudioClientInterface{source}, source_(source) {
166   FetchAudioProvider();
167 }
168 
~BluetoothAudioSourceClientInterface()169 BluetoothAudioSourceClientInterface::~BluetoothAudioSourceClientInterface() {
170   if (provider_factory_ != nullptr) {
171     AIBinder_unlinkToDeath(provider_factory_->asBinder().get(), death_recipient_.get(),
172                            nullptr);
173   }
174 }
175 
binderDiedCallbackAidl(void * ptr)176 void BluetoothAudioClientInterface::binderDiedCallbackAidl(void* ptr) {
177   LOG(WARNING) << __func__ << ": restarting connection with new Audio Hal";
178   auto client = static_cast<BluetoothAudioClientInterface*>(ptr);
179   if (client == nullptr) {
180     LOG(ERROR) << __func__ << ": null audio HAL died!";
181     return;
182   }
183   client->RenewAudioProviderAndSession();
184 }
185 
UpdateAudioConfig(const AudioConfiguration & audio_config)186 bool BluetoothAudioClientInterface::UpdateAudioConfig(
187     const AudioConfiguration& audio_config) {
188   bool is_software_session =
189       (transport_->GetSessionType() ==
190            SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
191        transport_->GetSessionType() ==
192            SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
193        transport_->GetSessionType() ==
194            SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
195        transport_->GetSessionType() ==
196            SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
197        transport_->GetSessionType() ==
198            SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
199   bool is_a2dp_offload_session =
200       (transport_->GetSessionType() ==
201        SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
202   bool is_leaudio_unicast_offload_session =
203       (transport_->GetSessionType() ==
204            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
205        transport_->GetSessionType() ==
206            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
207   bool is_leaudio_broadcast_offload_session =
208       (transport_->GetSessionType() ==
209        SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
210   auto audio_config_tag = audio_config.getTag();
211   bool is_software_audio_config =
212       (is_software_session &&
213        audio_config_tag == AudioConfiguration::pcmConfig);
214   bool is_a2dp_offload_audio_config =
215       (is_a2dp_offload_session &&
216        audio_config_tag == AudioConfiguration::a2dpConfig);
217   bool is_leaudio_unicast_offload_audio_config =
218       (is_leaudio_unicast_offload_session &&
219        audio_config_tag == AudioConfiguration::leAudioConfig);
220   bool is_leaudio_broadcast_offload_audio_config =
221       (is_leaudio_broadcast_offload_session &&
222        audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
223   if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
224       !is_leaudio_unicast_offload_audio_config &&
225       !is_leaudio_broadcast_offload_audio_config) {
226     return false;
227   }
228   transport_->UpdateAudioConfiguration(audio_config);
229 
230   if (provider_ == nullptr) {
231     LOG(INFO) << __func__
232               << ": BluetoothAudioHal nullptr, update it as session started";
233     return true;
234   }
235 
236   auto aidl_retval = provider_->updateAudioConfiguration(audio_config);
237   if (!aidl_retval.isOk()) {
238     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
239                << aidl_retval.getDescription();
240   }
241   return true;
242 }
243 
SetLowLatencyModeAllowed(bool allowed)244 bool BluetoothAudioClientInterface::SetLowLatencyModeAllowed(bool allowed) {
245   is_low_latency_allowed_ = allowed;
246   if (provider_ == nullptr) {
247     LOG(INFO) << __func__ << ": BluetoothAudioHal nullptr";
248     return false;
249   }
250 
251   auto aidl_retval = provider_->setLowLatencyModeAllowed(allowed);
252   if (!aidl_retval.isOk()) {
253     LOG(WARNING) << __func__ << ": BluetoothAudioHal is not ready: "
254                << aidl_retval.getDescription()
255                << ". is_low_latency_allowed_ is saved "
256                <<"and it will be sent to BluetoothAudioHal at StartSession.";
257   }
258   return true;
259 }
260 
GetAidlInterfaceVersion()261 int BluetoothAudioClientInterface::GetAidlInterfaceVersion() {
262   int aidl_version = -1;
263   if (!is_aidl_available()) {
264     return aidl_version;
265   }
266 
267   auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
268       ::ndk::SpAIBinder(AServiceManager_waitForService(
269           kDefaultAudioProviderFactoryInterface.c_str())));
270 
271   if (provider_factory == nullptr) {
272     LOG(ERROR) << __func__ << ", can't get aidl version from unknown factory";
273     return aidl_version;
274   }
275 
276   auto aidl_retval = provider_factory->getInterfaceVersion(&aidl_version);
277   if (!aidl_retval.isOk()) {
278     LOG(FATAL) << __func__
279                << ": BluetoothAudioHal::getInterfaceVersion failure: "
280                << aidl_retval.getDescription();
281   }
282 
283   return aidl_version;
284 }
285 
StartSession()286 int BluetoothAudioClientInterface::StartSession() {
287   std::lock_guard<std::mutex> guard(internal_mutex_);
288   if (provider_ == nullptr) {
289     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
290     session_started_ = false;
291     return -EINVAL;
292   }
293   if (session_started_) {
294     LOG(ERROR) << __func__ << ": session started already";
295     return -EBUSY;
296   }
297 
298   std::shared_ptr<IBluetoothAudioPort> stack_if =
299       ndk::SharedRefBase::make<BluetoothAudioPortImpl>(transport_, provider_);
300 
301   std::unique_ptr<DataMQ> data_mq;
302   DataMQDesc mq_desc;
303   std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
304   if (is_low_latency_allowed_) {
305     latency_modes.push_back(LatencyMode::LOW_LATENCY);
306   }
307   auto aidl_retval = provider_->startSession(
308       stack_if, transport_->GetAudioConfiguration(), latency_modes, &mq_desc);
309   if (!aidl_retval.isOk()) {
310     if (aidl_retval.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
311       LOG(ERROR) << __func__ << ": BluetoothAudioHal Error: "
312                  << aidl_retval.getDescription() << ", audioConfig="
313                  << transport_->GetAudioConfiguration().toString();
314     } else {
315       LOG(FATAL) << __func__ << ": BluetoothAudioHal failure: "
316                  << aidl_retval.getDescription();
317     }
318     return -EPROTO;
319   }
320   data_mq.reset(new DataMQ(mq_desc));
321 
322   if (data_mq && data_mq->isValid()) {
323     data_mq_ = std::move(data_mq);
324   } else if (transport_->GetSessionType() ==
325                  SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
326              transport_->GetSessionType() ==
327                  SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
328              transport_->GetSessionType() ==
329                  SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
330              transport_->GetSessionType() ==
331                  SessionType::
332                      LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
333     transport_->ResetPresentationPosition();
334     session_started_ = true;
335     return 0;
336   }
337   if (data_mq_ && data_mq_->isValid()) {
338     transport_->ResetPresentationPosition();
339     session_started_ = true;
340     return 0;
341   } else {
342     if (!data_mq_) {
343       LOG(ERROR) << __func__ << "Failed to obtain audio data path";
344     }
345     if (data_mq_ && !data_mq_->isValid()) {
346       LOG(ERROR) << __func__ << "Audio data path is invalid";
347     }
348     session_started_ = false;
349     return -EIO;
350   }
351 }
352 
StreamStarted(const BluetoothAudioCtrlAck & ack)353 void BluetoothAudioClientInterface::StreamStarted(
354     const BluetoothAudioCtrlAck& ack) {
355   if (provider_ == nullptr) {
356     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
357     return;
358   }
359   if (ack == BluetoothAudioCtrlAck::PENDING) {
360     LOG(INFO) << __func__ << ": " << ack << " ignored";
361     return;
362   }
363   BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
364 
365   auto aidl_retval = provider_->streamStarted(status);
366 
367   if (!aidl_retval.isOk()) {
368     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
369                << aidl_retval.getDescription();
370   }
371 }
372 
StreamSuspended(const BluetoothAudioCtrlAck & ack)373 void BluetoothAudioClientInterface::StreamSuspended(
374     const BluetoothAudioCtrlAck& ack) {
375   if (provider_ == nullptr) {
376     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
377     return;
378   }
379   if (ack == BluetoothAudioCtrlAck::PENDING) {
380     LOG(INFO) << __func__ << ": " << ack << " ignored";
381     return;
382   }
383   BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
384 
385   auto aidl_retval = provider_->streamSuspended(status);
386 
387   if (!aidl_retval.isOk()) {
388     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
389                << aidl_retval.getDescription();
390   }
391 }
392 
EndSession()393 int BluetoothAudioClientInterface::EndSession() {
394   std::lock_guard<std::mutex> guard(internal_mutex_);
395   if (!session_started_) {
396     LOG(INFO) << __func__ << ": session ended already";
397     return 0;
398   }
399 
400   session_started_ = false;
401   if (provider_ == nullptr) {
402     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
403     return -EINVAL;
404   }
405   data_mq_ = nullptr;
406 
407   auto aidl_retval = provider_->endSession();
408 
409   if (!aidl_retval.isOk()) {
410     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
411                << aidl_retval.getDescription();
412     return -EPROTO;
413   }
414   return 0;
415 }
416 
FlushAudioData()417 void BluetoothAudioClientInterface::FlushAudioData() {
418   if (transport_->GetSessionType() ==
419           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
420       transport_->GetSessionType() ==
421           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
422       transport_->GetSessionType() ==
423           SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
424     return;
425   }
426 
427   if (data_mq_ == nullptr || !data_mq_->isValid()) {
428     LOG(WARNING) << __func__ << ", data_mq_ invalid";
429     return;
430   }
431   size_t size = data_mq_->availableToRead();
432   std::vector<MqDataType> buffer(size);
433 
434   if (data_mq_->read(buffer.data(), size) != size) {
435     LOG(WARNING) << __func__ << ", failed to flush data queue!";
436   }
437 }
438 
ReadAudioData(uint8_t * p_buf,uint32_t len)439 size_t BluetoothAudioSinkClientInterface::ReadAudioData(uint8_t* p_buf,
440                                                         uint32_t len) {
441   if (!IsValid()) {
442     LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
443     return 0;
444   }
445   if (p_buf == nullptr || len == 0) return 0;
446 
447   std::lock_guard<std::mutex> guard(internal_mutex_);
448 
449   size_t total_read = 0;
450   int timeout_ms = kDefaultDataReadTimeoutMs;
451   do {
452     if (data_mq_ == nullptr || !data_mq_->isValid()) break;
453 
454     size_t avail_to_read = data_mq_->availableToRead();
455     if (avail_to_read) {
456       if (avail_to_read > len - total_read) {
457         avail_to_read = len - total_read;
458       }
459       if (data_mq_->read((MqDataType*)p_buf + total_read, avail_to_read) == 0) {
460         LOG(WARNING) << __func__ << ": len=" << len
461                      << " total_read=" << total_read << " failed";
462         break;
463       }
464       total_read += avail_to_read;
465     } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
466       std::this_thread::sleep_for(
467           std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
468       timeout_ms -= kDefaultDataReadPollIntervalMs;
469       continue;
470     } else {
471       LOG(WARNING) << __func__ << ": " << (len - total_read) << "/" << len
472                    << " no data " << (kDefaultDataReadTimeoutMs - timeout_ms)
473                    << " ms";
474       break;
475     }
476   } while (total_read < len);
477 
478   if (timeout_ms <
479           (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
480       timeout_ms >= kDefaultDataReadPollIntervalMs) {
481     VLOG(1) << __func__ << ": underflow " << len << " -> " << total_read
482             << " read " << (kDefaultDataReadTimeoutMs - timeout_ms) << " ms";
483   } else {
484     VLOG(2) << __func__ << ": " << len << " -> " << total_read << " read";
485   }
486 
487   sink_->LogBytesRead(total_read);
488   return total_read;
489 }
490 
RenewAudioProviderAndSession()491 void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
492   // NOTE: must be invoked on the same thread where this
493   // BluetoothAudioClientInterface is running
494   FetchAudioProvider();
495 
496   if (session_started_) {
497     LOG(INFO) << __func__
498               << ": Restart the session while audio HAL recovering ";
499     session_started_ = false;
500 
501     StartSession();
502   }
503 }
504 
WriteAudioData(const uint8_t * p_buf,uint32_t len)505 size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf,
506                                                            uint32_t len) {
507   if (!IsValid()) {
508     LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
509     return 0;
510   }
511   if (p_buf == nullptr || len == 0) return 0;
512 
513   std::lock_guard<std::mutex> guard(internal_mutex_);
514 
515   size_t total_written = 0;
516   int timeout_ms = kDefaultDataWriteTimeoutMs;
517   do {
518     if (data_mq_ == nullptr || !data_mq_->isValid()) break;
519 
520     size_t avail_to_write = data_mq_->availableToWrite();
521     if (avail_to_write) {
522       if (avail_to_write > len - total_written) {
523         avail_to_write = len - total_written;
524       }
525       if (data_mq_->write((const MqDataType*)p_buf + total_written,
526                           avail_to_write) == 0) {
527         LOG(WARNING) << __func__ << ": len=" << len
528                      << " total_written=" << total_written << " failed";
529         break;
530       }
531       total_written += avail_to_write;
532     } else if (timeout_ms >= kDefaultDataWritePollIntervalMs) {
533       std::this_thread::sleep_for(
534           std::chrono::milliseconds(kDefaultDataWritePollIntervalMs));
535       timeout_ms -= kDefaultDataWritePollIntervalMs;
536       continue;
537     } else {
538       LOG(WARNING) << __func__ << ": " << (len - total_written) << "/" << len
539                    << " no data " << (kDefaultDataWriteTimeoutMs - timeout_ms)
540                    << " ms";
541       break;
542     }
543   } while (total_written < len);
544 
545   if (timeout_ms <
546           (kDefaultDataWriteTimeoutMs - kDefaultDataWritePollIntervalMs) &&
547       timeout_ms >= kDefaultDataWritePollIntervalMs) {
548     VLOG(1) << __func__ << ": underflow " << len << " -> " << total_written
549             << " read " << (kDefaultDataWriteTimeoutMs - timeout_ms) << " ms ";
550   } else {
551     VLOG(2) << __func__ << ": " << len << " -> " << total_written
552             << " written ";
553   }
554 
555   source_->LogBytesWritten(total_written);
556   return total_written;
557 }
558 
559 }  // namespace aidl
560 }  // namespace audio
561 }  // namespace bluetooth
562