1 /*
2  * Copyright 2019 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.h"
20 
21 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
22 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.h>
23 #include <android/hidl/manager/1.2/IServiceManager.h>
24 #include <base/logging.h>
25 #include <hidl/MQDescriptor.h>
26 #include <hidl/ServiceManagement.h>
27 #include <future>
28 
29 #include "osi/include/log.h"
30 
31 namespace bluetooth {
32 namespace audio {
33 
34 using ::android::hardware::hidl_vec;
35 using ::android::hardware::Return;
36 using ::android::hardware::Void;
37 using ::android::hardware::audio::common::V5_0::SourceMetadata;
38 using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
39 using ::android::hardware::bluetooth::audio::V2_0::
40     IBluetoothAudioProvidersFactory;
41 using DataMQ = ::android::hardware::MessageQueue<
42     uint8_t, ::android::hardware::kSynchronizedReadWrite>;
43 
44 static constexpr int kDefaultDataReadTimeoutMs = 10;      // 10 ms
45 static constexpr int kDefaultDataReadPollIntervalMs = 1;  // non-blocking poll
46 static constexpr char kFullyQualifiedInterfaceName[] =
47     "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory";
48 
operator <<(std::ostream & os,const BluetoothAudioCtrlAck & ack)49 std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack) {
50   switch (ack) {
51     case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
52       return os << "SUCCESS_FINISHED";
53     case BluetoothAudioCtrlAck::PENDING:
54       return os << "PENDING";
55     case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
56       return os << "FAILURE_UNSUPPORTED";
57     case BluetoothAudioCtrlAck::FAILURE_BUSY:
58       return os << "FAILURE_BUSY";
59     case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
60       return os << "FAILURE_DISCONNECTING";
61     case BluetoothAudioCtrlAck::FAILURE:
62       return os << "FAILURE";
63     default:
64       return os << "UNDEFINED " << static_cast<int8_t>(ack);
65   }
66 }
67 
68 // Internal class within BluetoothAudioClientInterfaceace to implement
69 // IBluetoothAudioPort (control interface used by Bluetooth Audio HAL)
70 class BluetoothAudioPortImpl : public IBluetoothAudioPort {
71  public:
BluetoothAudioPortImpl(IBluetoothTransportInstance * sink,const android::sp<IBluetoothAudioProvider> & provider)72   BluetoothAudioPortImpl(IBluetoothTransportInstance* sink,
73                          const android::sp<IBluetoothAudioProvider>& provider)
74       : sink_(sink), provider_(provider){};
75 
startStream()76   Return<void> startStream() override {
77     BluetoothAudioCtrlAck ack = sink_->StartRequest();
78     if (ack != BluetoothAudioCtrlAck::PENDING) {
79       auto hidl_retval =
80           provider_->streamStarted(BluetoothAudioCtrlAckToHalStatus(ack));
81       if (!hidl_retval.isOk()) {
82         LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: " << hidl_retval.description();
83       }
84     }
85     return Void();
86   }
87 
suspendStream()88   Return<void> suspendStream() override {
89     BluetoothAudioCtrlAck ack = sink_->SuspendRequest();
90     if (ack != BluetoothAudioCtrlAck::PENDING) {
91       auto hidl_retval =
92           provider_->streamSuspended(BluetoothAudioCtrlAckToHalStatus(ack));
93       if (!hidl_retval.isOk()) {
94         LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: " << hidl_retval.description();
95       }
96     }
97     return Void();
98   }
99 
stopStream()100   Return<void> stopStream() override {
101     sink_->StopRequest();
102     return Void();
103   }
104 
getPresentationPosition(getPresentationPosition_cb _hidl_cb)105   Return<void> getPresentationPosition(
106       getPresentationPosition_cb _hidl_cb) override {
107     uint64_t remote_delay_report_ns;
108     uint64_t total_bytes_read;
109     timespec data_position;
110     bool retval = sink_->GetPresentationPosition(
111         &remote_delay_report_ns, &total_bytes_read, &data_position);
112 
113     TimeSpec transmittedOctetsTimeStamp;
114     if (retval) {
115       transmittedOctetsTimeStamp = timespec_convert_to_hal(data_position);
116     } else {
117       remote_delay_report_ns = 0;
118       total_bytes_read = 0;
119       transmittedOctetsTimeStamp = {};
120     }
121     VLOG(2) << __func__ << ": result=" << retval
122             << ", delay=" << remote_delay_report_ns
123             << ", data=" << total_bytes_read
124             << " byte(s), timestamp=" << toString(transmittedOctetsTimeStamp);
125     _hidl_cb((retval ? BluetoothAudioStatus::SUCCESS
126                      : BluetoothAudioStatus::FAILURE),
127              remote_delay_report_ns, total_bytes_read,
128              transmittedOctetsTimeStamp);
129     return Void();
130   }
131 
updateMetadata(const SourceMetadata & sourceMetadata)132   Return<void> updateMetadata(const SourceMetadata& sourceMetadata) override {
133     LOG(INFO) << __func__ << ": " << sourceMetadata.tracks.size()
134               << " track(s)";
135     // refer to StreamOut.impl.h within Audio HAL (AUDIO_HAL_VERSION_5_0)
136     std::vector<playback_track_metadata> metadata_vec;
137     metadata_vec.reserve(sourceMetadata.tracks.size());
138     for (const auto& metadata : sourceMetadata.tracks) {
139       metadata_vec.push_back({
140           .usage = static_cast<audio_usage_t>(metadata.usage),
141           .content_type =
142               static_cast<audio_content_type_t>(metadata.contentType),
143           .gain = metadata.gain,
144       });
145     }
146     const source_metadata_t source_metadata = {
147         .track_count = metadata_vec.size(), .tracks = metadata_vec.data()};
148     sink_->MetadataChanged(source_metadata);
149     return Void();
150   }
151 
152  private:
153   IBluetoothTransportInstance* sink_;
154   const android::sp<IBluetoothAudioProvider> provider_;
timespec_convert_to_hal(const timespec & ts)155   TimeSpec timespec_convert_to_hal(const timespec& ts) {
156     return {.tvSec = static_cast<uint64_t>(ts.tv_sec),
157             .tvNSec = static_cast<uint64_t>(ts.tv_nsec)};
158   }
159 };
160 
161 class BluetoothAudioDeathRecipient
162     : public ::android::hardware::hidl_death_recipient {
163  public:
BluetoothAudioDeathRecipient(BluetoothAudioClientInterface * clientif,bluetooth::common::MessageLoopThread * message_loop)164   BluetoothAudioDeathRecipient(
165       BluetoothAudioClientInterface* clientif,
166       bluetooth::common::MessageLoopThread* message_loop)
167       : bluetooth_audio_clientif_(clientif), message_loop_(message_loop) {}
serviceDied(uint64_t,const::android::wp<::android::hidl::base::V1_0::IBase> &)168   void serviceDied(
169       uint64_t /*cookie*/,
170       const ::android::wp<::android::hidl::base::V1_0::IBase>& /*who*/)
171       override {
172     LOG(WARNING) << __func__ << ": restarting connection with new Audio Hal";
173     if (bluetooth_audio_clientif_ != nullptr && message_loop_ != nullptr) {
174       // restart the session on the correct thread
175       message_loop_->DoInThread(
176           FROM_HERE,
177           base::BindOnce(
178               &BluetoothAudioClientInterface::RenewAudioProviderAndSession,
179               base::Unretained(bluetooth_audio_clientif_)));
180     } else {
181       LOG(ERROR) << __func__ << ": BluetoothAudioClientInterface corrupted";
182     }
183   }
184 
185  private:
186   BluetoothAudioClientInterface* bluetooth_audio_clientif_;
187   bluetooth::common::MessageLoopThread* message_loop_;
188 };
189 
BluetoothAudioClientInterface(IBluetoothTransportInstance * sink,bluetooth::common::MessageLoopThread * message_loop)190 BluetoothAudioClientInterface::BluetoothAudioClientInterface(IBluetoothTransportInstance* sink,
191                                                              bluetooth::common::MessageLoopThread* message_loop)
192     : sink_(sink), provider_(nullptr), session_started_(false), mDataMQ(nullptr),
193       death_recipient_(new BluetoothAudioDeathRecipient(this, message_loop)) {
194   if (IsSupported()) {
195     FetchAudioProvider();
196   } else {
197     LOG(WARNING) << "IBluetoothAudioProvidersFactory not declared";
198   }
199 }
200 
~BluetoothAudioClientInterface()201 BluetoothAudioClientInterface::~BluetoothAudioClientInterface() {
202   if (provider_ != nullptr) {
203     auto hidl_retval = provider_->unlinkToDeath(death_recipient_);
204     if (!hidl_retval.isOk()) {
205       LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: " << hidl_retval.description();
206     }
207   }
208 }
209 
210 std::vector<AudioCapabilities>
GetAudioCapabilities() const211 BluetoothAudioClientInterface::GetAudioCapabilities() const {
212   return capabilities_;
213 }
214 
IsSupported()215 bool BluetoothAudioClientInterface::IsSupported() {
216   auto service_manager = android::hardware::defaultServiceManager1_2();
217   CHECK(service_manager != nullptr);
218   size_t instance_count = 0;
219   auto listManifestByInterface_cb =
220       [&instance_count](
221           const hidl_vec<android::hardware::hidl_string>& instanceNames) {
222         instance_count = instanceNames.size();
223         LOG(INFO) << "listManifestByInterface_cb returns " << instance_count
224                   << " instance(s)";
225       };
226   auto hidl_retval = service_manager->listManifestByInterface(
227       kFullyQualifiedInterfaceName, listManifestByInterface_cb);
228   if (!hidl_retval.isOk()) {
229     LOG(FATAL) << __func__ << ": IServiceManager::listByInterface failure: "
230                << hidl_retval.description();
231     return false;
232   }
233   return (instance_count > 0);
234 }
235 
236 std::vector<AudioCapabilities>
GetAudioCapabilities(SessionType session_type)237 BluetoothAudioClientInterface::GetAudioCapabilities(SessionType session_type) {
238   std::vector<AudioCapabilities> capabilities(0);
239   if (!IsSupported()) return capabilities;
240 
241   android::sp<IBluetoothAudioProvidersFactory> providersFactory =
242       IBluetoothAudioProvidersFactory::getService();
243   CHECK(providersFactory != nullptr)
244       << "IBluetoothAudioProvidersFactory::getService() failed";
245   LOG(INFO) << "IBluetoothAudioProvidersFactory::getService() returned "
246             << providersFactory.get()
247             << (providersFactory->isRemote() ? " (remote)" : " (local)");
248 
249   auto getProviderCapabilities_cb =
250       [&capabilities](const hidl_vec<AudioCapabilities>& audioCapabilities) {
251         for (auto capability : audioCapabilities) {
252           capabilities.push_back(capability);
253         }
254       };
255   auto hidl_retval = providersFactory->getProviderCapabilities(
256       session_type, getProviderCapabilities_cb);
257   if (!hidl_retval.isOk()) {
258     LOG(FATAL) << __func__
259                << ": BluetoothAudioHal::getProviderCapabilities failure: "
260                << hidl_retval.description();
261   }
262   return capabilities;
263 }
264 
FetchAudioProvider()265 void BluetoothAudioClientInterface::FetchAudioProvider() {
266   if (provider_ != nullptr) {
267     LOG(WARNING) << __func__ << ": reflash";
268   }
269 
270   android::sp<IBluetoothAudioProvidersFactory> providersFactory =
271       IBluetoothAudioProvidersFactory::getService();
272   CHECK(providersFactory != nullptr) << "IBluetoothAudioProvidersFactory::getService() failed";
273   LOG(INFO) << "IBluetoothAudioProvidersFactory::getService() returned "
274             << providersFactory.get()
275             << (providersFactory->isRemote() ? " (remote)" : " (local)");
276 
277   auto getProviderCapabilities_cb =
278       [& capabilities = this->capabilities_](
279           const hidl_vec<AudioCapabilities>& audioCapabilities) {
280         capabilities.clear();
281         for (auto capability : audioCapabilities) {
282           capabilities.push_back(capability);
283         }
284       };
285   auto hidl_retval = providersFactory->getProviderCapabilities(
286       sink_->GetSessionType(), getProviderCapabilities_cb);
287   if (!hidl_retval.isOk()) {
288     LOG(FATAL) << __func__ << ": BluetoothAudioHal::getProviderCapabilities failure: " << hidl_retval.description();
289     return;
290   }
291   if (capabilities_.empty()) {
292     LOG(WARNING) << __func__
293                  << ": SessionType=" << toString(sink_->GetSessionType())
294                  << " Not supported by BluetoothAudioHal";
295     return;
296   }
297   LOG(INFO) << __func__ << ": BluetoothAudioHal SessionType="
298             << toString(sink_->GetSessionType()) << " has "
299             << capabilities_.size() << " AudioCapabilities";
300 
301   std::promise<void> openProvider_promise;
302   auto openProvider_future = openProvider_promise.get_future();
303   auto openProvider_cb =
304       [& provider_ = this->provider_, &openProvider_promise](
305           BluetoothAudioStatus status,
306           const android::sp<IBluetoothAudioProvider>& provider) {
307         LOG(INFO) << "openProvider_cb(" << toString(status) << ")";
308         if (status == BluetoothAudioStatus::SUCCESS) {
309           provider_ = provider;
310         }
311         ALOGE_IF(!provider_, "Failed to open BluetoothAudio provider");
312         openProvider_promise.set_value();
313       };
314   hidl_retval =
315       providersFactory->openProvider(sink_->GetSessionType(), openProvider_cb);
316   openProvider_future.get();
317   if (!hidl_retval.isOk()) {
318     LOG(FATAL) << __func__ << ": BluetoothAudioHal::openProvider failure: " << hidl_retval.description();
319   }
320   CHECK(provider_ != nullptr);
321 
322   if (!provider_->linkToDeath(death_recipient_, 0).isOk()) {
323     LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: " << hidl_retval.description();
324   }
325 
326   LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
327             << provider_.get()
328             << (provider_->isRemote() ? " (remote)" : " (local)");
329 }
330 
UpdateAudioConfig(const AudioConfiguration & audio_config)331 bool BluetoothAudioClientInterface::UpdateAudioConfig(
332     const AudioConfiguration& audio_config) {
333   bool is_software_session =
334       (sink_->GetSessionType() ==
335            SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
336        sink_->GetSessionType() ==
337            SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
338   bool is_offload_session =
339       (sink_->GetSessionType() == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
340   auto audio_config_discriminator = audio_config.getDiscriminator();
341   bool is_software_audio_config =
342       (is_software_session &&
343        audio_config_discriminator ==
344            AudioConfiguration::hidl_discriminator::pcmConfig);
345   bool is_offload_audio_config =
346       (is_offload_session &&
347        audio_config_discriminator ==
348            AudioConfiguration::hidl_discriminator::codecConfig);
349   if (!is_software_audio_config && !is_offload_audio_config) {
350     return false;
351   }
352   sink_->UpdateAudioConfiguration(audio_config);
353   return true;
354 }
355 
StartSession()356 int BluetoothAudioClientInterface::StartSession() {
357   std::lock_guard<std::mutex> guard(internal_mutex_);
358   if (provider_ == nullptr) {
359     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
360     session_started_ = false;
361     return -EINVAL;
362   }
363   if (session_started_) {
364     LOG(ERROR) << __func__ << ": session started already";
365     return -EBUSY;
366   }
367 
368   android::sp<IBluetoothAudioPort> stack_if =
369       new BluetoothAudioPortImpl(sink_, provider_);
370   std::unique_ptr<DataMQ> tempDataMQ;
371   BluetoothAudioStatus session_status;
372 
373   std::promise<void> hidl_startSession_promise;
374   auto hidl_startSession_future = hidl_startSession_promise.get_future();
375   auto hidl_cb = [&session_status, &tempDataMQ, &hidl_startSession_promise](
376                      BluetoothAudioStatus status,
377                      const DataMQ::Descriptor& dataMQ) {
378     LOG(INFO) << "startSession_cb(" << toString(status) << ")";
379     session_status = status;
380     if (status == BluetoothAudioStatus::SUCCESS && dataMQ.isHandleValid()) {
381       tempDataMQ.reset(new DataMQ(dataMQ));
382     }
383     hidl_startSession_promise.set_value();
384   };
385   auto hidl_retval = provider_->startSession(
386       stack_if, sink_->GetAudioConfiguration(), hidl_cb);
387   hidl_startSession_future.get();
388   if (!hidl_retval.isOk()) {
389     LOG(FATAL) << __func__ << ": BluetoothAudioHal failure: " << hidl_retval.description();
390     return -EPROTO;
391   }
392 
393   if (tempDataMQ && tempDataMQ->isValid()) {
394     mDataMQ = std::move(tempDataMQ);
395   } else if (sink_->GetSessionType() ==
396                  SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH &&
397              session_status == BluetoothAudioStatus::SUCCESS) {
398     sink_->ResetPresentationPosition();
399     session_started_ = true;
400     return 0;
401   }
402   if (mDataMQ && mDataMQ->isValid()) {
403     sink_->ResetPresentationPosition();
404     session_started_ = true;
405     return 0;
406   } else {
407     ALOGE_IF(!mDataMQ, "Failed to obtain audio data path");
408     ALOGE_IF(mDataMQ && !mDataMQ->isValid(), "Audio data path is invalid");
409     session_started_ = false;
410     return -EIO;
411   }
412 }
413 
StreamStarted(const BluetoothAudioCtrlAck & ack)414 void BluetoothAudioClientInterface::StreamStarted(
415     const BluetoothAudioCtrlAck& ack) {
416   if (provider_ == nullptr) {
417     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
418     return;
419   }
420   if (ack == BluetoothAudioCtrlAck::PENDING) {
421     LOG(INFO) << __func__ << ": " << ack << " ignored";
422     return;
423   }
424   BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
425   auto hidl_retval = provider_->streamStarted(status);
426   if (!hidl_retval.isOk()) {
427     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: " << hidl_retval.description();
428   }
429 }
430 
StreamSuspended(const BluetoothAudioCtrlAck & ack)431 void BluetoothAudioClientInterface::StreamSuspended(
432     const BluetoothAudioCtrlAck& ack) {
433   if (provider_ == nullptr) {
434     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
435     return;
436   }
437   if (ack == BluetoothAudioCtrlAck::PENDING) {
438     LOG(INFO) << __func__ << ": " << ack << " ignored";
439     return;
440   }
441   BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
442   auto hidl_retval = provider_->streamSuspended(status);
443   if (!hidl_retval.isOk()) {
444     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: " << hidl_retval.description();
445   }
446 }
447 
EndSession()448 int BluetoothAudioClientInterface::EndSession() {
449   std::lock_guard<std::mutex> guard(internal_mutex_);
450   if (!session_started_) {
451     LOG(INFO) << __func__ << ": sessoin ended already";
452     return 0;
453   }
454 
455   session_started_ = false;
456   if (provider_ == nullptr) {
457     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
458     return -EINVAL;
459   }
460   mDataMQ = nullptr;
461   auto hidl_retval = provider_->endSession();
462   if (!hidl_retval.isOk()) {
463     LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: " << hidl_retval.description();
464     return -EPROTO;
465   }
466   return 0;
467 }
468 
ReadAudioData(uint8_t * p_buf,uint32_t len)469 size_t BluetoothAudioClientInterface::ReadAudioData(uint8_t* p_buf,
470                                                     uint32_t len) {
471   if (provider_ == nullptr) {
472     LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
473     return 0;
474   }
475   if (p_buf == nullptr || len == 0) return 0;
476 
477   std::lock_guard<std::mutex> guard(internal_mutex_);
478 
479   size_t total_read = 0;
480   int timeout_ms = kDefaultDataReadTimeoutMs;
481   do {
482     if (mDataMQ == nullptr || !mDataMQ->isValid()) break;
483 
484     size_t avail_to_read = mDataMQ->availableToRead();
485     if (avail_to_read) {
486       if (avail_to_read > len - total_read) {
487         avail_to_read = len - total_read;
488       }
489       if (mDataMQ->read(p_buf + total_read, avail_to_read) == 0) {
490         LOG(WARNING) << __func__ << ": len=" << len
491                      << " total_read=" << total_read << " failed";
492         break;
493       }
494       total_read += avail_to_read;
495     } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
496       std::this_thread::sleep_for(
497           std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
498       timeout_ms -= kDefaultDataReadPollIntervalMs;
499       continue;
500     } else {
501       LOG(WARNING) << __func__ << ": " << (len - total_read) << "/" << len
502                    << " no data " << (kDefaultDataReadTimeoutMs - timeout_ms)
503                    << " ms";
504       break;
505     }
506   } while (total_read < len);
507 
508   if (timeout_ms <
509           (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
510       timeout_ms >= kDefaultDataReadPollIntervalMs) {
511     VLOG(1) << __func__ << ": underflow " << len << " -> " << total_read
512             << " read " << (kDefaultDataReadTimeoutMs - timeout_ms) << " ms";
513   } else {
514     VLOG(2) << __func__ << ": " << len << " -> " << total_read << " read";
515   }
516 
517   sink_->LogBytesRead(total_read);
518   return total_read;
519 }
520 
WriteAudioData(uint8_t * p_buf,uint32_t len)521 size_t BluetoothAudioClientInterface::WriteAudioData(uint8_t* p_buf,
522                                                      uint32_t len) {
523   // Not implemented!
524   return 0;
525 }
526 
RenewAudioProviderAndSession()527 void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
528   // NOTE: must be invoked on the same thread where this
529   // BluetoothAudioClientInterface is running
530   FetchAudioProvider();
531   if (session_started_) {
532     LOG(INFO) << __func__ << ": Restart the session while audio HAL recovering";
533     session_started_ = false;
534     StartSession();
535   }
536 }
537 
538 }  // namespace audio
539 }  // namespace bluetooth
540