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