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