• 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 "BTAudioClientIf"
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 
StartSession()261 int BluetoothAudioClientInterface::StartSession() {
262   std::lock_guard<std::mutex> guard(internal_mutex_);
263   if (provider_ == nullptr) {
264     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
265     session_started_ = false;
266     return -EINVAL;
267   }
268   if (session_started_) {
269     LOG(ERROR) << __func__ << ": session started already";
270     return -EBUSY;
271   }
272 
273   std::shared_ptr<IBluetoothAudioPort> stack_if =
274       ndk::SharedRefBase::make<BluetoothAudioPortImpl>(transport_, provider_);
275 
276   std::unique_ptr<DataMQ> data_mq;
277   DataMQDesc mq_desc;
278   std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
279   if (is_low_latency_allowed_) {
280     latency_modes.push_back(LatencyMode::LOW_LATENCY);
281   }
282   auto aidl_retval = provider_->startSession(
283       stack_if, transport_->GetAudioConfiguration(), latency_modes, &mq_desc);
284   if (!aidl_retval.isOk()) {
285     if (aidl_retval.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
286       LOG(ERROR) << __func__ << ": BluetoothAudioHal Error: "
287                  << aidl_retval.getDescription() << ", audioConfig="
288                  << transport_->GetAudioConfiguration().toString();
289     } else {
290       LOG(FATAL) << __func__ << ": BluetoothAudioHal failure: "
291                  << aidl_retval.getDescription();
292     }
293     return -EPROTO;
294   }
295   data_mq.reset(new DataMQ(mq_desc));
296 
297   if (data_mq && data_mq->isValid()) {
298     data_mq_ = std::move(data_mq);
299   } else if (transport_->GetSessionType() ==
300                  SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
301              transport_->GetSessionType() ==
302                  SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
303              transport_->GetSessionType() ==
304                  SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
305              transport_->GetSessionType() ==
306                  SessionType::
307                      LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
308     transport_->ResetPresentationPosition();
309     session_started_ = true;
310     return 0;
311   }
312   if (data_mq_ && data_mq_->isValid()) {
313     transport_->ResetPresentationPosition();
314     session_started_ = true;
315     return 0;
316   } else {
317     if (!data_mq_) {
318       LOG(ERROR) << __func__ << "Failed to obtain audio data path";
319     }
320     if (data_mq_ && !data_mq_->isValid()) {
321       LOG(ERROR) << __func__ << "Audio data path is invalid";
322     }
323     session_started_ = false;
324     return -EIO;
325   }
326 }
327 
StreamStarted(const BluetoothAudioCtrlAck & ack)328 void BluetoothAudioClientInterface::StreamStarted(
329     const BluetoothAudioCtrlAck& ack) {
330   if (provider_ == nullptr) {
331     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
332     return;
333   }
334   if (ack == BluetoothAudioCtrlAck::PENDING) {
335     LOG(INFO) << __func__ << ": " << ack << " ignored";
336     return;
337   }
338   BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
339 
340   auto aidl_retval = provider_->streamStarted(status);
341 
342   if (!aidl_retval.isOk()) {
343     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
344                << aidl_retval.getDescription();
345   }
346 }
347 
StreamSuspended(const BluetoothAudioCtrlAck & ack)348 void BluetoothAudioClientInterface::StreamSuspended(
349     const BluetoothAudioCtrlAck& ack) {
350   if (provider_ == nullptr) {
351     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
352     return;
353   }
354   if (ack == BluetoothAudioCtrlAck::PENDING) {
355     LOG(INFO) << __func__ << ": " << ack << " ignored";
356     return;
357   }
358   BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
359 
360   auto aidl_retval = provider_->streamSuspended(status);
361 
362   if (!aidl_retval.isOk()) {
363     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
364                << aidl_retval.getDescription();
365   }
366 }
367 
EndSession()368 int BluetoothAudioClientInterface::EndSession() {
369   std::lock_guard<std::mutex> guard(internal_mutex_);
370   if (!session_started_) {
371     LOG(INFO) << __func__ << ": session ended already";
372     return 0;
373   }
374 
375   session_started_ = false;
376   if (provider_ == nullptr) {
377     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
378     return -EINVAL;
379   }
380   data_mq_ = nullptr;
381 
382   auto aidl_retval = provider_->endSession();
383 
384   if (!aidl_retval.isOk()) {
385     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
386                << aidl_retval.getDescription();
387     return -EPROTO;
388   }
389   return 0;
390 }
391 
FlushAudioData()392 void BluetoothAudioClientInterface::FlushAudioData() {
393   if (transport_->GetSessionType() ==
394           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
395       transport_->GetSessionType() ==
396           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
397       transport_->GetSessionType() ==
398           SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
399     return;
400   }
401 
402   if (data_mq_ == nullptr || !data_mq_->isValid()) {
403     LOG(WARNING) << __func__ << ", data_mq_ invalid";
404     return;
405   }
406   size_t size = data_mq_->availableToRead();
407   std::vector<MqDataType> buffer(size);
408 
409   if (data_mq_->read(buffer.data(), size) != size) {
410     LOG(WARNING) << __func__ << ", failed to flush data queue!";
411   }
412 }
413 
ReadAudioData(uint8_t * p_buf,uint32_t len)414 size_t BluetoothAudioSinkClientInterface::ReadAudioData(uint8_t* p_buf,
415                                                         uint32_t len) {
416   if (!IsValid()) {
417     LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
418     return 0;
419   }
420   if (p_buf == nullptr || len == 0) return 0;
421 
422   std::lock_guard<std::mutex> guard(internal_mutex_);
423 
424   size_t total_read = 0;
425   int timeout_ms = kDefaultDataReadTimeoutMs;
426   do {
427     if (data_mq_ == nullptr || !data_mq_->isValid()) break;
428 
429     size_t avail_to_read = data_mq_->availableToRead();
430     if (avail_to_read) {
431       if (avail_to_read > len - total_read) {
432         avail_to_read = len - total_read;
433       }
434       if (data_mq_->read((MqDataType*)p_buf + total_read, avail_to_read) == 0) {
435         LOG(WARNING) << __func__ << ": len=" << len
436                      << " total_read=" << total_read << " failed";
437         break;
438       }
439       total_read += avail_to_read;
440     } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
441       std::this_thread::sleep_for(
442           std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
443       timeout_ms -= kDefaultDataReadPollIntervalMs;
444       continue;
445     } else {
446       LOG(WARNING) << __func__ << ": " << (len - total_read) << "/" << len
447                    << " no data " << (kDefaultDataReadTimeoutMs - timeout_ms)
448                    << " ms";
449       break;
450     }
451   } while (total_read < len);
452 
453   if (timeout_ms <
454           (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
455       timeout_ms >= kDefaultDataReadPollIntervalMs) {
456     VLOG(1) << __func__ << ": underflow " << len << " -> " << total_read
457             << " read " << (kDefaultDataReadTimeoutMs - timeout_ms) << " ms";
458   } else {
459     VLOG(2) << __func__ << ": " << len << " -> " << total_read << " read";
460   }
461 
462   sink_->LogBytesRead(total_read);
463   return total_read;
464 }
465 
RenewAudioProviderAndSession()466 void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
467   // NOTE: must be invoked on the same thread where this
468   // BluetoothAudioClientInterface is running
469   FetchAudioProvider();
470 
471   if (session_started_) {
472     LOG(INFO) << __func__
473               << ": Restart the session while audio HAL recovering ";
474     session_started_ = false;
475 
476     StartSession();
477   }
478 }
479 
WriteAudioData(const uint8_t * p_buf,uint32_t len)480 size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf,
481                                                            uint32_t len) {
482   if (!IsValid()) {
483     LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
484     return 0;
485   }
486   if (p_buf == nullptr || len == 0) return 0;
487 
488   std::lock_guard<std::mutex> guard(internal_mutex_);
489 
490   size_t total_written = 0;
491   int timeout_ms = kDefaultDataWriteTimeoutMs;
492   do {
493     if (data_mq_ == nullptr || !data_mq_->isValid()) break;
494 
495     size_t avail_to_write = data_mq_->availableToWrite();
496     if (avail_to_write) {
497       if (avail_to_write > len - total_written) {
498         avail_to_write = len - total_written;
499       }
500       if (data_mq_->write((const MqDataType*)p_buf + total_written,
501                           avail_to_write) == 0) {
502         LOG(WARNING) << __func__ << ": len=" << len
503                      << " total_written=" << total_written << " failed";
504         break;
505       }
506       total_written += avail_to_write;
507     } else if (timeout_ms >= kDefaultDataWritePollIntervalMs) {
508       std::this_thread::sleep_for(
509           std::chrono::milliseconds(kDefaultDataWritePollIntervalMs));
510       timeout_ms -= kDefaultDataWritePollIntervalMs;
511       continue;
512     } else {
513       LOG(WARNING) << __func__ << ": " << (len - total_written) << "/" << len
514                    << " no data " << (kDefaultDataWriteTimeoutMs - timeout_ms)
515                    << " ms";
516       break;
517     }
518   } while (total_written < len);
519 
520   if (timeout_ms <
521           (kDefaultDataWriteTimeoutMs - kDefaultDataWritePollIntervalMs) &&
522       timeout_ms >= kDefaultDataWritePollIntervalMs) {
523     VLOG(1) << __func__ << ": underflow " << len << " -> " << total_written
524             << " read " << (kDefaultDataWriteTimeoutMs - timeout_ms) << " ms ";
525   } else {
526     VLOG(2) << __func__ << ": " << len << " -> " << total_written
527             << " written ";
528   }
529 
530   source_->LogBytesWritten(total_written);
531   return total_written;
532 }
533 
534 }  // namespace aidl
535 }  // namespace audio
536 }  // namespace bluetooth
537