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