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 "BTAudioClientHIDL"
18
19 #include "client_interface_hidl.h"
20
21 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
22 #include <base/logging.h>
23 #include <hidl/MQDescriptor.h>
24
25 #include <future>
26
27 #include "common/stop_watch_legacy.h"
28 #include "hal_version_manager.h"
29 #include "osi/include/log.h"
30
31 namespace bluetooth {
32 namespace audio {
33 namespace hidl {
34
35 using ::android::hardware::hidl_vec;
36 using ::android::hardware::Return;
37 using ::android::hardware::Void;
38 using ::android::hardware::audio::common::V5_0::SourceMetadata;
39 using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
40 using ::bluetooth::common::StopWatchLegacy;
41
42 using DataMQ = ::android::hardware::MessageQueue<
43 uint8_t, ::android::hardware::kSynchronizedReadWrite>;
44
45 static constexpr int kDefaultDataReadTimeoutMs = 10; // 10 ms
46 static constexpr int kDefaultDataWriteTimeoutMs = 10; // 10 ms
47 static constexpr int kDefaultDataReadPollIntervalMs = 1; // non-blocking poll
48 static constexpr int kDefaultDataWritePollIntervalMs = 1; // non-blocking poll
49
operator <<(std::ostream & os,const BluetoothAudioCtrlAck & ack)50 std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack) {
51 switch (ack) {
52 case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
53 return os << "SUCCESS_FINISHED";
54 case BluetoothAudioCtrlAck::PENDING:
55 return os << "PENDING";
56 case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
57 return os << "FAILURE_UNSUPPORTED";
58 case BluetoothAudioCtrlAck::FAILURE_BUSY:
59 return os << "FAILURE_BUSY";
60 case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
61 return os << "FAILURE_DISCONNECTING";
62 case BluetoothAudioCtrlAck::FAILURE:
63 return os << "FAILURE";
64 default:
65 return os << "UNDEFINED " << static_cast<int8_t>(ack);
66 }
67 }
68
69 class BluetoothAudioPortImpl : public IBluetoothAudioPort {
70 public:
BluetoothAudioPortImpl(IBluetoothTransportInstance * transport_instance,const android::sp<IBluetoothAudioProvider> & provider)71 BluetoothAudioPortImpl(IBluetoothTransportInstance* transport_instance,
72 const android::sp<IBluetoothAudioProvider>& provider)
73 : transport_instance_(transport_instance), provider_(provider) {}
74
startStream()75 Return<void> startStream() override {
76 StopWatchLegacy stop_watch(__func__);
77 BluetoothAudioCtrlAck ack = transport_instance_->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: "
83 << hidl_retval.description();
84 }
85 }
86 return Void();
87 }
88
suspendStream()89 Return<void> suspendStream() override {
90 StopWatchLegacy stop_watch(__func__);
91 BluetoothAudioCtrlAck ack = transport_instance_->SuspendRequest();
92 if (ack != BluetoothAudioCtrlAck::PENDING) {
93 auto hidl_retval =
94 provider_->streamSuspended(BluetoothAudioCtrlAckToHalStatus(ack));
95 if (!hidl_retval.isOk()) {
96 LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
97 << hidl_retval.description();
98 }
99 }
100 return Void();
101 }
102
stopStream()103 Return<void> stopStream() override {
104 StopWatchLegacy stop_watch(__func__);
105 transport_instance_->StopRequest();
106 return Void();
107 }
108
getPresentationPosition(getPresentationPosition_cb _hidl_cb)109 Return<void> getPresentationPosition(
110 getPresentationPosition_cb _hidl_cb) override {
111 StopWatchLegacy stop_watch(__func__);
112 uint64_t remote_delay_report_ns;
113 uint64_t total_bytes_read;
114 timespec data_position;
115 bool retval = transport_instance_->GetPresentationPosition(
116 &remote_delay_report_ns, &total_bytes_read, &data_position);
117
118 TimeSpec transmittedOctetsTimeStamp;
119 if (retval) {
120 transmittedOctetsTimeStamp = timespec_convert_to_hal(data_position);
121 } else {
122 remote_delay_report_ns = 0;
123 total_bytes_read = 0;
124 transmittedOctetsTimeStamp = {};
125 }
126 VLOG(2) << __func__ << ": result=" << retval
127 << ", delay=" << remote_delay_report_ns
128 << ", data=" << total_bytes_read
129 << " byte(s), timestamp=" << toString(transmittedOctetsTimeStamp);
130 _hidl_cb((retval ? BluetoothAudioStatus::SUCCESS
131 : BluetoothAudioStatus::FAILURE),
132 remote_delay_report_ns, total_bytes_read,
133 transmittedOctetsTimeStamp);
134 return Void();
135 }
136
updateMetadata(const SourceMetadata & sourceMetadata)137 Return<void> updateMetadata(const SourceMetadata& sourceMetadata) override {
138 StopWatchLegacy stop_watch(__func__);
139 LOG(INFO) << __func__ << ": " << sourceMetadata.tracks.size()
140 << " track(s)";
141 // refer to StreamOut.impl.h within Audio HAL (AUDIO_HAL_VERSION_5_0)
142 std::vector<playback_track_metadata> metadata_vec;
143 metadata_vec.reserve(sourceMetadata.tracks.size());
144 for (const auto& metadata : sourceMetadata.tracks) {
145 metadata_vec.push_back({
146 .usage = static_cast<audio_usage_t>(metadata.usage),
147 .content_type =
148 static_cast<audio_content_type_t>(metadata.contentType),
149 .gain = metadata.gain,
150 });
151 }
152 const source_metadata_t source_metadata = {
153 .track_count = metadata_vec.size(), .tracks = metadata_vec.data()};
154 transport_instance_->MetadataChanged(source_metadata);
155 return Void();
156 }
157
158 private:
159 IBluetoothTransportInstance* transport_instance_;
160 const android::sp<IBluetoothAudioProvider> provider_;
timespec_convert_to_hal(const timespec & ts)161 TimeSpec timespec_convert_to_hal(const timespec& ts) {
162 return {.tvSec = static_cast<uint64_t>(ts.tv_sec),
163 .tvNSec = static_cast<uint64_t>(ts.tv_nsec)};
164 }
165 };
166
167 class BluetoothAudioDeathRecipient
168 : public ::android::hardware::hidl_death_recipient {
169 public:
BluetoothAudioDeathRecipient(BluetoothAudioClientInterface * clientif,bluetooth::common::MessageLoopThread * message_loop)170 BluetoothAudioDeathRecipient(
171 BluetoothAudioClientInterface* clientif,
172 bluetooth::common::MessageLoopThread* message_loop)
173 : bluetooth_audio_clientif_(clientif), message_loop_(message_loop) {}
serviceDied(uint64_t,const::android::wp<::android::hidl::base::V1_0::IBase> &)174 void serviceDied(
175 uint64_t /*cookie*/,
176 const ::android::wp<::android::hidl::base::V1_0::IBase>& /*who*/)
177 override {
178 LOG(WARNING) << __func__ << ": restarting connection with new Audio Hal";
179 if (bluetooth_audio_clientif_ != nullptr && message_loop_ != nullptr) {
180 // restart the session on the correct thread
181 message_loop_->DoInThread(
182 FROM_HERE,
183 base::BindOnce(
184 &BluetoothAudioClientInterface::RenewAudioProviderAndSession,
185 base::Unretained(bluetooth_audio_clientif_)));
186 } else {
187 LOG(ERROR) << __func__ << ": BluetoothAudioClientInterface corrupted";
188 }
189 }
190
191 private:
192 BluetoothAudioClientInterface* bluetooth_audio_clientif_;
193 bluetooth::common::MessageLoopThread* message_loop_;
194 };
195
196 // Constructs an BluetoothAudioClientInterface to communicate to
197 // BluetoothAudio HAL. |message_loop| is the thread where callbacks are
198 // invoked.
BluetoothAudioClientInterface(android::sp<BluetoothAudioDeathRecipient> death_recipient,IBluetoothTransportInstance * instance)199 BluetoothAudioClientInterface::BluetoothAudioClientInterface(
200 android::sp<BluetoothAudioDeathRecipient> death_recipient,
201 IBluetoothTransportInstance* instance)
202 : provider_(nullptr),
203 provider_2_1_(nullptr),
204 session_started_(false),
205 mDataMQ(nullptr),
206 transport_(instance) {
207 death_recipient_ = death_recipient;
208 }
209
210 std::vector<AudioCapabilities>
GetAudioCapabilities() const211 BluetoothAudioClientInterface::GetAudioCapabilities() const {
212 return capabilities_;
213 }
214
215 std::vector<AudioCapabilities_2_1>
GetAudioCapabilities_2_1() const216 BluetoothAudioClientInterface::GetAudioCapabilities_2_1() const {
217 return capabilities_2_1_;
218 }
219
220 std::vector<AudioCapabilities>
GetAudioCapabilities(SessionType session_type)221 BluetoothAudioClientInterface::GetAudioCapabilities(SessionType session_type) {
222 std::vector<AudioCapabilities> capabilities(0);
223
224 if (HalVersionManager::GetHalVersion() ==
225 BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
226 LOG(ERROR) << __func__ << ", can't get capability from unknown factory";
227 return capabilities;
228 }
229
230 android::sp<IBluetoothAudioProvidersFactory_2_0> providersFactory =
231 HalVersionManager::GetProvidersFactory_2_0();
232 CHECK(providersFactory != nullptr)
233 << "IBluetoothAudioProvidersFactory::getService() failed";
234
235 auto getProviderCapabilities_cb =
236 [&capabilities](const hidl_vec<AudioCapabilities>& audioCapabilities) {
237 for (auto capability : audioCapabilities) {
238 capabilities.push_back(capability);
239 }
240 };
241 auto hidl_retval = providersFactory->getProviderCapabilities(
242 session_type, getProviderCapabilities_cb);
243 if (!hidl_retval.isOk()) {
244 LOG(FATAL) << __func__
245 << ": BluetoothAudioHal::getProviderCapabilities failure: "
246 << hidl_retval.description();
247 }
248 return capabilities;
249 }
250
251 std::vector<AudioCapabilities_2_1>
GetAudioCapabilities_2_1(SessionType_2_1 session_type_2_1)252 BluetoothAudioClientInterface::GetAudioCapabilities_2_1(
253 SessionType_2_1 session_type_2_1) {
254 std::vector<AudioCapabilities_2_1> capabilities_2_1(0);
255 if (HalVersionManager::GetHalVersion() !=
256 BluetoothAudioHalVersion::VERSION_2_1) {
257 LOG(ERROR) << __func__ << ", can't get capability for HAL 2.1";
258 return capabilities_2_1;
259 }
260
261 android::sp<IBluetoothAudioProvidersFactory_2_1> providersFactory =
262 HalVersionManager::GetProvidersFactory_2_1();
263 CHECK(providersFactory != nullptr)
264 << "IBluetoothAudioProvidersFactory::getService() failed";
265
266 auto getProviderCapabilities_cb =
267 [&capabilities_2_1](
268 const hidl_vec<AudioCapabilities_2_1>& audioCapabilities_2_1) {
269 for (auto capability_2_1 : audioCapabilities_2_1) {
270 capabilities_2_1.push_back(capability_2_1);
271 }
272 };
273 auto hidl_retval = providersFactory->getProviderCapabilities_2_1(
274 session_type_2_1, getProviderCapabilities_cb);
275 if (!hidl_retval.isOk()) {
276 LOG(FATAL) << __func__
277 << ": BluetoothAudioHal::getProviderCapabilities failure: "
278 << hidl_retval.description();
279 }
280 return capabilities_2_1;
281 }
282
FetchAudioProvider()283 void BluetoothAudioClientInterface::FetchAudioProvider() {
284 if (provider_ != nullptr) {
285 LOG(WARNING) << __func__ << ": reflash";
286 }
287
288 android::sp<IBluetoothAudioProvidersFactory_2_0> providersFactory =
289 HalVersionManager::GetProvidersFactory_2_0();
290 CHECK(providersFactory != nullptr)
291 << "IBluetoothAudioProvidersFactory::getService() failed";
292
293 auto getProviderCapabilities_cb =
294 [&capabilities = this->capabilities_](
295 const hidl_vec<AudioCapabilities>& audioCapabilities) {
296 capabilities.clear();
297 for (auto capability : audioCapabilities) {
298 capabilities.push_back(capability);
299 }
300 };
301 auto hidl_retval = providersFactory->getProviderCapabilities(
302 transport_->GetSessionType(), getProviderCapabilities_cb);
303 if (!hidl_retval.isOk()) {
304 LOG(FATAL) << __func__
305 << ": BluetoothAudioHal::getProviderCapabilities failure: "
306 << hidl_retval.description();
307 return;
308 }
309 if (capabilities_.empty()) {
310 LOG(WARNING) << __func__
311 << ": SessionType=" << toString(transport_->GetSessionType())
312 << " Not supported by BluetoothAudioHal";
313 return;
314 }
315 LOG(INFO) << __func__ << ": BluetoothAudioHal SessionType="
316 << toString(transport_->GetSessionType()) << " has "
317 << capabilities_.size() << " AudioCapabilities";
318
319 std::promise<void> openProvider_promise;
320 auto openProvider_future = openProvider_promise.get_future();
321 auto openProvider_cb =
322 [&provider_ = this->provider_, &openProvider_promise](
323 BluetoothAudioStatus status,
324 const android::sp<IBluetoothAudioProvider>& provider) {
325 LOG(INFO) << "openProvider_cb(" << toString(status) << ")";
326 if (status == BluetoothAudioStatus::SUCCESS) {
327 provider_ = provider;
328 }
329 ALOGE_IF(!provider_, "Failed to open BluetoothAudio provider");
330 openProvider_promise.set_value();
331 };
332 hidl_retval = providersFactory->openProvider(transport_->GetSessionType(),
333 openProvider_cb);
334 openProvider_future.get();
335 if (!hidl_retval.isOk()) {
336 LOG(FATAL) << __func__ << ": BluetoothAudioHal::openProvider failure: "
337 << hidl_retval.description();
338 }
339 CHECK(provider_ != nullptr);
340
341 if (!provider_->linkToDeath(death_recipient_, 0).isOk()) {
342 LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
343 << hidl_retval.description();
344 }
345
346 LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
347 << provider_.get()
348 << (provider_->isRemote() ? " (remote)" : " (local)");
349 }
350
FetchAudioProvider_2_1()351 void BluetoothAudioClientInterface::FetchAudioProvider_2_1() {
352 if (provider_2_1_ != nullptr) {
353 LOG(WARNING) << __func__ << ": reflash";
354 }
355
356 android::sp<IBluetoothAudioProvidersFactory_2_1> providersFactory =
357 HalVersionManager::GetProvidersFactory_2_1();
358 CHECK(providersFactory != nullptr)
359 << "IBluetoothAudioProvidersFactory_2_1::getService() failed";
360
361 auto getProviderCapabilities_cb =
362 [&capabilities_2_1 = this->capabilities_2_1_](
363 const hidl_vec<AudioCapabilities_2_1>& audioCapabilities_2_1) {
364 capabilities_2_1.clear();
365 for (auto capability_2_1 : audioCapabilities_2_1) {
366 capabilities_2_1.push_back(capability_2_1);
367 }
368 };
369 auto hidl_retval = providersFactory->getProviderCapabilities_2_1(
370 transport_->GetSessionType_2_1(), getProviderCapabilities_cb);
371 if (!hidl_retval.isOk()) {
372 LOG(FATAL) << __func__
373 << ": BluetoothAudioHal::getProviderCapabilities failure: "
374 << hidl_retval.description();
375 return;
376 }
377 if (capabilities_2_1_.empty()) {
378 LOG(WARNING) << __func__ << ": SessionType="
379 << toString(transport_->GetSessionType_2_1())
380 << " Not supported by BluetoothAudioHal";
381 return;
382 }
383 LOG(INFO) << __func__ << ": BluetoothAudioHal SessionType="
384 << toString(transport_->GetSessionType_2_1()) << " has "
385 << capabilities_2_1_.size() << " AudioCapabilities";
386
387 std::promise<void> openProvider_promise;
388 auto openProvider_future = openProvider_promise.get_future();
389 auto openProvider_cb =
390 [&provider_2_1_ = this->provider_2_1_, &openProvider_promise](
391 BluetoothAudioStatus status,
392 const android::sp<IBluetoothAudioProvider_2_1>& provider_2_1) {
393 LOG(INFO) << "openProvider_cb(" << toString(status) << ")";
394 if (status == BluetoothAudioStatus::SUCCESS) {
395 provider_2_1_ = provider_2_1;
396 }
397 ALOGE_IF(!provider_2_1_, "Failed to open BluetoothAudio provider_2_1");
398 openProvider_promise.set_value();
399 };
400 hidl_retval = providersFactory->openProvider_2_1(
401 transport_->GetSessionType_2_1(), openProvider_cb);
402 openProvider_future.get();
403 if (!hidl_retval.isOk()) {
404 LOG(FATAL) << __func__ << ": BluetoothAudioHal::openProvider failure: "
405 << hidl_retval.description();
406 }
407 CHECK(provider_2_1_ != nullptr);
408
409 if (!provider_2_1_->linkToDeath(death_recipient_, 0).isOk()) {
410 LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
411 << hidl_retval.description();
412 }
413
414 LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
415 << provider_2_1_.get()
416 << (provider_2_1_->isRemote() ? " (remote)" : " (local)");
417 }
418
BluetoothAudioSinkClientInterface(IBluetoothSinkTransportInstance * sink,bluetooth::common::MessageLoopThread * message_loop)419 BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface(
420 IBluetoothSinkTransportInstance* sink,
421 bluetooth::common::MessageLoopThread* message_loop)
422 : BluetoothAudioClientInterface{new BluetoothAudioDeathRecipient(
423 this, message_loop),
424 sink},
425 sink_(sink) {
426 if (HalVersionManager::GetHalVersion() ==
427 BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
428 return;
429 }
430
431 if ((HalVersionManager::GetHalVersion() ==
432 BluetoothAudioHalVersion::VERSION_2_1) &&
433 (sink_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
434 FetchAudioProvider_2_1();
435 return;
436 }
437 FetchAudioProvider();
438 }
439
~BluetoothAudioSinkClientInterface()440 BluetoothAudioSinkClientInterface::~BluetoothAudioSinkClientInterface() {
441 if (provider_ != nullptr) {
442 auto hidl_retval = provider_->unlinkToDeath(death_recipient_);
443 if (!hidl_retval.isOk()) {
444 LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
445 << hidl_retval.description();
446 }
447 }
448 if (provider_2_1_ != nullptr) {
449 auto hidl_retval = provider_2_1_->unlinkToDeath(death_recipient_);
450 if (!hidl_retval.isOk()) {
451 LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
452 << hidl_retval.description();
453 }
454 }
455 }
456
BluetoothAudioSourceClientInterface(IBluetoothSourceTransportInstance * source,bluetooth::common::MessageLoopThread * message_loop)457 BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface(
458 IBluetoothSourceTransportInstance* source,
459 bluetooth::common::MessageLoopThread* message_loop)
460 : BluetoothAudioClientInterface{new BluetoothAudioDeathRecipient(
461 this, message_loop),
462 source},
463 source_(source) {
464 if (HalVersionManager::GetHalVersion() ==
465 BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
466 return;
467 }
468
469 if ((HalVersionManager::GetHalVersion() ==
470 BluetoothAudioHalVersion::VERSION_2_1) &&
471 (source_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
472 FetchAudioProvider_2_1();
473 return;
474 }
475 FetchAudioProvider();
476 }
477
~BluetoothAudioSourceClientInterface()478 BluetoothAudioSourceClientInterface::~BluetoothAudioSourceClientInterface() {
479 if (provider_ != nullptr) {
480 auto hidl_retval = provider_->unlinkToDeath(death_recipient_);
481 if (!hidl_retval.isOk()) {
482 LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
483 << hidl_retval.description();
484 }
485 }
486 if (provider_2_1_ != nullptr) {
487 auto hidl_retval = provider_2_1_->unlinkToDeath(death_recipient_);
488 if (!hidl_retval.isOk()) {
489 LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
490 << hidl_retval.description();
491 }
492 }
493 }
494
UpdateAudioConfig(const AudioConfiguration & audio_config)495 bool BluetoothAudioClientInterface::UpdateAudioConfig(
496 const AudioConfiguration& audio_config) {
497 bool is_software_session =
498 (transport_->GetSessionType() ==
499 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
500 transport_->GetSessionType() ==
501 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
502 bool is_offload_session = (transport_->GetSessionType() ==
503 SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
504 auto audio_config_discriminator = audio_config.getDiscriminator();
505 bool is_software_audio_config =
506 (is_software_session &&
507 audio_config_discriminator ==
508 AudioConfiguration::hidl_discriminator::pcmConfig);
509 bool is_offload_audio_config =
510 (is_offload_session &&
511 audio_config_discriminator ==
512 AudioConfiguration::hidl_discriminator::codecConfig);
513 if (!is_software_audio_config && !is_offload_audio_config) {
514 return false;
515 }
516 transport_->UpdateAudioConfiguration(audio_config);
517 return true;
518 }
519
UpdateAudioConfig_2_1(const AudioConfiguration_2_1 & audio_config_2_1)520 bool BluetoothAudioClientInterface::UpdateAudioConfig_2_1(
521 const AudioConfiguration_2_1& audio_config_2_1) {
522 bool is_software_session =
523 (transport_->GetSessionType_2_1() ==
524 SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
525 transport_->GetSessionType_2_1() ==
526 SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
527 transport_->GetSessionType_2_1() ==
528 SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
529 transport_->GetSessionType_2_1() ==
530 SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
531 bool is_offload_session = (transport_->GetSessionType_2_1() ==
532 SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
533 auto audio_config_discriminator = audio_config_2_1.getDiscriminator();
534 bool is_software_audio_config =
535 (is_software_session &&
536 audio_config_discriminator ==
537 AudioConfiguration_2_1::hidl_discriminator::pcmConfig);
538 bool is_offload_audio_config =
539 (is_offload_session &&
540 audio_config_discriminator ==
541 AudioConfiguration_2_1::hidl_discriminator::codecConfig);
542 if (!is_software_audio_config && !is_offload_audio_config) {
543 return false;
544 }
545 transport_->UpdateAudioConfiguration_2_1(audio_config_2_1);
546 return true;
547 }
548
StartSession()549 int BluetoothAudioClientInterface::StartSession() {
550 std::lock_guard<std::mutex> guard(internal_mutex_);
551 if (provider_ == nullptr) {
552 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
553 session_started_ = false;
554 return -EINVAL;
555 }
556 if (session_started_) {
557 LOG(ERROR) << __func__ << ": session started already";
558 return -EBUSY;
559 }
560
561 android::sp<IBluetoothAudioPort> stack_if =
562 new BluetoothAudioPortImpl(transport_, provider_);
563
564 std::unique_ptr<DataMQ> tempDataMQ;
565 BluetoothAudioStatus session_status;
566
567 std::promise<void> hidl_startSession_promise;
568 auto hidl_startSession_future = hidl_startSession_promise.get_future();
569 auto hidl_cb = [&session_status, &tempDataMQ, &hidl_startSession_promise](
570 BluetoothAudioStatus status,
571 const DataMQ::Descriptor& dataMQ) {
572 LOG(INFO) << "startSession_cb(" << toString(status) << ")";
573 session_status = status;
574 if (status == BluetoothAudioStatus::SUCCESS && dataMQ.isHandleValid()) {
575 tempDataMQ.reset(new DataMQ(dataMQ));
576 }
577 hidl_startSession_promise.set_value();
578 };
579 auto hidl_retval = provider_->startSession(
580 stack_if, transport_->GetAudioConfiguration(), hidl_cb);
581 hidl_startSession_future.get();
582 if (!hidl_retval.isOk()) {
583 LOG(FATAL) << __func__
584 << ": BluetoothAudioHal failure: " << hidl_retval.description();
585 return -EPROTO;
586 }
587
588 if (tempDataMQ && tempDataMQ->isValid()) {
589 mDataMQ = std::move(tempDataMQ);
590 } else if (transport_->GetSessionType() ==
591 SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH &&
592 session_status == BluetoothAudioStatus::SUCCESS) {
593 transport_->ResetPresentationPosition();
594 session_started_ = true;
595 return 0;
596 }
597 if (mDataMQ && mDataMQ->isValid()) {
598 transport_->ResetPresentationPosition();
599 session_started_ = true;
600 return 0;
601 } else {
602 ALOGE_IF(!mDataMQ, "Failed to obtain audio data path");
603 ALOGE_IF(mDataMQ && !mDataMQ->isValid(), "Audio data path is invalid");
604 session_started_ = false;
605 return -EIO;
606 }
607 }
608
StartSession_2_1()609 int BluetoothAudioClientInterface::StartSession_2_1() {
610 std::lock_guard<std::mutex> guard(internal_mutex_);
611 if (provider_2_1_ == nullptr) {
612 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
613 session_started_ = false;
614 return -EINVAL;
615 }
616 if (session_started_) {
617 LOG(ERROR) << __func__ << ": session started already";
618 return -EBUSY;
619 }
620
621 android::sp<IBluetoothAudioPort> stack_if =
622 new BluetoothAudioPortImpl(transport_, provider_2_1_);
623
624 std::unique_ptr<DataMQ> tempDataMQ;
625 BluetoothAudioStatus session_status;
626
627 std::promise<void> hidl_startSession_promise;
628 auto hidl_startSession_future = hidl_startSession_promise.get_future();
629 auto hidl_cb = [&session_status, &tempDataMQ, &hidl_startSession_promise](
630 BluetoothAudioStatus status,
631 const DataMQ::Descriptor& dataMQ) {
632 LOG(INFO) << "startSession_cb(" << toString(status) << ")";
633 session_status = status;
634 if (status == BluetoothAudioStatus::SUCCESS && dataMQ.isHandleValid()) {
635 tempDataMQ.reset(new DataMQ(dataMQ));
636 }
637 hidl_startSession_promise.set_value();
638 };
639 auto hidl_retval = provider_2_1_->startSession_2_1(
640 stack_if, transport_->GetAudioConfiguration_2_1(), hidl_cb);
641 hidl_startSession_future.get();
642 if (!hidl_retval.isOk()) {
643 LOG(FATAL) << __func__
644 << ": BluetoothAudioHal failure: " << hidl_retval.description();
645 return -EPROTO;
646 }
647
648 if (tempDataMQ && tempDataMQ->isValid()) {
649 mDataMQ = std::move(tempDataMQ);
650 } else if (transport_->GetSessionType_2_1() ==
651 SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH &&
652 session_status == BluetoothAudioStatus::SUCCESS) {
653 transport_->ResetPresentationPosition();
654 session_started_ = true;
655 return 0;
656 }
657 if (mDataMQ && mDataMQ->isValid()) {
658 transport_->ResetPresentationPosition();
659 session_started_ = true;
660 return 0;
661 } else {
662 ALOGE_IF(!mDataMQ, "Failed to obtain audio data path");
663 ALOGE_IF(mDataMQ && !mDataMQ->isValid(), "Audio data path is invalid");
664 session_started_ = false;
665 return -EIO;
666 }
667 }
668
StreamStarted(const BluetoothAudioCtrlAck & ack)669 void BluetoothAudioClientInterface::StreamStarted(
670 const BluetoothAudioCtrlAck& ack) {
671 if (ack == BluetoothAudioCtrlAck::PENDING) {
672 LOG(INFO) << __func__ << ": " << ack << " ignored";
673 return;
674 }
675 BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
676
677 ::android::hardware::Return<void> hidl_retval;
678 if (provider_2_1_ != nullptr) {
679 hidl_retval = provider_2_1_->streamStarted(status);
680 } else if (provider_ != nullptr) {
681 hidl_retval = provider_->streamStarted(status);
682 } else {
683 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
684 return;
685 }
686
687 if (!hidl_retval.isOk()) {
688 LOG(ERROR) << __func__
689 << ": BluetoothAudioHal failure: " << hidl_retval.description();
690 }
691 }
692
StreamSuspended(const BluetoothAudioCtrlAck & ack)693 void BluetoothAudioClientInterface::StreamSuspended(
694 const BluetoothAudioCtrlAck& ack) {
695 if (ack == BluetoothAudioCtrlAck::PENDING) {
696 LOG(INFO) << __func__ << ": " << ack << " ignored";
697 return;
698 }
699 BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
700
701 ::android::hardware::Return<void> hidl_retval;
702 if (provider_2_1_ != nullptr) {
703 hidl_retval = provider_2_1_->streamSuspended(status);
704 } else if (provider_ != nullptr) {
705 hidl_retval = provider_->streamSuspended(status);
706 } else {
707 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
708 return;
709 }
710
711 if (!hidl_retval.isOk()) {
712 LOG(ERROR) << __func__
713 << ": BluetoothAudioHal failure: " << hidl_retval.description();
714 }
715 }
716
EndSession()717 int BluetoothAudioClientInterface::EndSession() {
718 std::lock_guard<std::mutex> guard(internal_mutex_);
719 if (!session_started_) {
720 LOG(INFO) << __func__ << ": session ended already";
721 return 0;
722 }
723
724 session_started_ = false;
725 mDataMQ = nullptr;
726
727 ::android::hardware::Return<void> hidl_retval;
728 if (provider_2_1_ != nullptr) {
729 hidl_retval = provider_2_1_->endSession();
730 } else if (provider_ != nullptr) {
731 hidl_retval = provider_->endSession();
732 } else {
733 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
734 return -EINVAL;
735 }
736
737 if (!hidl_retval.isOk()) {
738 LOG(ERROR) << __func__
739 << ": BluetoothAudioHal failure: " << hidl_retval.description();
740 return -EPROTO;
741 }
742 return 0;
743 }
744
FlushAudioData()745 void BluetoothAudioClientInterface::FlushAudioData() {
746 if (transport_->GetSessionType_2_1() ==
747 SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
748 transport_->GetSessionType_2_1() ==
749 SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH)
750 return;
751
752 if (mDataMQ == nullptr || !mDataMQ->isValid()) {
753 LOG(WARNING) << __func__ << ", mDataMQ invalid";
754 return;
755 }
756 size_t size = mDataMQ->availableToRead();
757 uint8_t p_buf[size];
758
759 if (mDataMQ->read(p_buf, size) != size)
760 LOG(WARNING) << __func__ << ", failed to flush data queue!";
761 }
762
ReadAudioData(uint8_t * p_buf,uint32_t len)763 size_t BluetoothAudioSinkClientInterface::ReadAudioData(uint8_t* p_buf,
764 uint32_t len) {
765 if (!IsValid()) {
766 LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
767 return 0;
768 }
769 if (p_buf == nullptr || len == 0) return 0;
770
771 std::lock_guard<std::mutex> guard(internal_mutex_);
772
773 size_t total_read = 0;
774 int timeout_ms = kDefaultDataReadTimeoutMs;
775 do {
776 if (mDataMQ == nullptr || !mDataMQ->isValid()) break;
777
778 size_t avail_to_read = mDataMQ->availableToRead();
779 if (avail_to_read) {
780 if (avail_to_read > len - total_read) {
781 avail_to_read = len - total_read;
782 }
783 if (mDataMQ->read(p_buf + total_read, avail_to_read) == 0) {
784 LOG(WARNING) << __func__ << ": len=" << len
785 << " total_read=" << total_read << " failed";
786 break;
787 }
788 total_read += avail_to_read;
789 } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
790 std::this_thread::sleep_for(
791 std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
792 timeout_ms -= kDefaultDataReadPollIntervalMs;
793 continue;
794 } else {
795 LOG(WARNING) << __func__ << ": " << (len - total_read) << "/" << len
796 << " no data " << (kDefaultDataReadTimeoutMs - timeout_ms)
797 << " ms";
798 break;
799 }
800 } while (total_read < len);
801
802 if (timeout_ms <
803 (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
804 timeout_ms >= kDefaultDataReadPollIntervalMs) {
805 VLOG(1) << __func__ << ": underflow " << len << " -> " << total_read
806 << " read " << (kDefaultDataReadTimeoutMs - timeout_ms) << " ms";
807 } else {
808 VLOG(2) << __func__ << ": " << len << " -> " << total_read << " read";
809 }
810
811 sink_->LogBytesRead(total_read);
812 return total_read;
813 }
814
RenewAudioProviderAndSession()815 void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
816 // NOTE: must be invoked on the same thread where this
817 // BluetoothAudioClientInterface is running
818 auto hal_version = HalVersionManager::GetHalVersion();
819 if ((hal_version == BluetoothAudioHalVersion::VERSION_2_1) &&
820 (transport_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
821 FetchAudioProvider_2_1();
822 } else if (transport_->GetSessionType() != SessionType::UNKNOWN) {
823 FetchAudioProvider();
824 } else {
825 LOG(FATAL) << __func__ << ", cannot renew audio provider";
826 return;
827 }
828
829 if (session_started_) {
830 LOG(INFO) << __func__ << ": Restart the session while audio HAL recovering";
831 session_started_ = false;
832
833 if (provider_2_1_ != nullptr)
834 StartSession_2_1();
835 else
836 StartSession();
837 }
838 }
839
WriteAudioData(const uint8_t * p_buf,uint32_t len)840 size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf,
841 uint32_t len) {
842 if (!IsValid()) {
843 LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
844 return 0;
845 }
846 if (p_buf == nullptr || len == 0) return 0;
847
848 std::lock_guard<std::mutex> guard(internal_mutex_);
849
850 size_t total_written = 0;
851 int timeout_ms = kDefaultDataWriteTimeoutMs;
852 do {
853 if (mDataMQ == nullptr || !mDataMQ->isValid()) break;
854
855 size_t avail_to_write = mDataMQ->availableToWrite();
856 if (avail_to_write) {
857 if (avail_to_write > len - total_written) {
858 avail_to_write = len - total_written;
859 }
860 if (mDataMQ->write(p_buf + total_written, avail_to_write) == 0) {
861 LOG(WARNING) << __func__ << ": len=" << len
862 << " total_written=" << total_written << " failed";
863 break;
864 }
865 total_written += avail_to_write;
866 } else if (timeout_ms >= kDefaultDataWritePollIntervalMs) {
867 std::this_thread::sleep_for(
868 std::chrono::milliseconds(kDefaultDataWritePollIntervalMs));
869 timeout_ms -= kDefaultDataWritePollIntervalMs;
870 continue;
871 } else {
872 LOG(WARNING) << __func__ << ": " << (len - total_written) << "/" << len
873 << " no data " << (kDefaultDataWriteTimeoutMs - timeout_ms)
874 << " ms";
875 break;
876 }
877 } while (total_written < len);
878
879 if (timeout_ms <
880 (kDefaultDataWriteTimeoutMs - kDefaultDataWritePollIntervalMs) &&
881 timeout_ms >= kDefaultDataWritePollIntervalMs) {
882 VLOG(1) << __func__ << ": underflow " << len << " -> " << total_written
883 << " read " << (kDefaultDataWriteTimeoutMs - timeout_ms) << " ms";
884 } else {
885 VLOG(2) << __func__ << ": " << len << " -> " << total_written << " written";
886 }
887
888 source_->LogBytesWritten(total_written);
889 return total_written;
890 }
891
892 } // namespace hidl
893 } // namespace audio
894 } // namespace bluetooth
895