1 /*
2 * Copyright 2022 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 "BTAudioClientAIDL"
18
19 #include "client_interface_aidl.h"
20
21 #include <android/binder_manager.h>
22
23 namespace bluetooth {
24 namespace audio {
25 namespace aidl {
26
operator <<(std::ostream & os,const BluetoothAudioCtrlAck & ack)27 std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack) {
28 switch (ack) {
29 case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
30 return os << "SUCCESS_FINISHED";
31 case BluetoothAudioCtrlAck::PENDING:
32 return os << "PENDING";
33 case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
34 return os << "FAILURE_UNSUPPORTED";
35 case BluetoothAudioCtrlAck::FAILURE_BUSY:
36 return os << "FAILURE_BUSY";
37 case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
38 return os << "FAILURE_DISCONNECTING";
39 case BluetoothAudioCtrlAck::FAILURE:
40 return os << "FAILURE";
41 default:
42 return os << "UNDEFINED " << static_cast<int8_t>(ack);
43 }
44 }
45
BluetoothAudioClientInterface(IBluetoothTransportInstance * instance)46 BluetoothAudioClientInterface::BluetoothAudioClientInterface(
47 IBluetoothTransportInstance* instance)
48 : provider_(nullptr),
49 provider_factory_(nullptr),
50 session_started_(false),
51 data_mq_(nullptr),
52 transport_(instance) {
53 death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient(
54 AIBinder_DeathRecipient_new(binderDiedCallbackAidl));
55 }
56
is_aidl_available()57 bool BluetoothAudioClientInterface::is_aidl_available() {
58 return AServiceManager_isDeclared(
59 kDefaultAudioProviderFactoryInterface.c_str());
60 }
61
62 std::vector<AudioCapabilities>
GetAudioCapabilities() const63 BluetoothAudioClientInterface::GetAudioCapabilities() const {
64 return capabilities_;
65 }
66
67 std::vector<AudioCapabilities>
GetAudioCapabilities(SessionType session_type)68 BluetoothAudioClientInterface::GetAudioCapabilities(SessionType session_type) {
69 std::vector<AudioCapabilities> capabilities(0);
70 if (!is_aidl_available()) {
71 return capabilities;
72 }
73 auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
74 ::ndk::SpAIBinder(AServiceManager_waitForService(
75 kDefaultAudioProviderFactoryInterface.c_str())));
76
77 if (provider_factory == nullptr) {
78 LOG(ERROR) << __func__ << ", can't get capability from unknown factory";
79 return capabilities;
80 }
81
82 auto aidl_retval =
83 provider_factory->getProviderCapabilities(session_type, &capabilities);
84 if (!aidl_retval.isOk()) {
85 LOG(FATAL) << __func__
86 << ": BluetoothAudioHal::getProviderCapabilities failure: "
87 << aidl_retval.getDescription();
88 }
89 return capabilities;
90 }
91
FetchAudioProvider()92 void BluetoothAudioClientInterface::FetchAudioProvider() {
93 if (!is_aidl_available()) {
94 LOG(ERROR) << __func__ << ": aidl is not supported on this platform.";
95 return;
96 }
97 if (provider_ != nullptr) {
98 LOG(WARNING) << __func__ << ": refetch";
99 }
100 auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
101 ::ndk::SpAIBinder(AServiceManager_waitForService(
102 kDefaultAudioProviderFactoryInterface.c_str())));
103
104 if (provider_factory == nullptr) {
105 LOG(ERROR) << __func__ << ", can't get capability from unknown factory";
106 return;
107 }
108
109 capabilities_.clear();
110 auto aidl_retval = provider_factory->getProviderCapabilities(
111 transport_->GetSessionType(), &capabilities_);
112 if (!aidl_retval.isOk()) {
113 LOG(FATAL) << __func__
114 << ": BluetoothAudioHal::getProviderCapabilities failure: "
115 << aidl_retval.getDescription();
116 return;
117 }
118 if (capabilities_.empty()) {
119 LOG(WARNING) << __func__
120 << ": SessionType=" << toString(transport_->GetSessionType())
121 << " Not supported by BluetoothAudioHal";
122 return;
123 }
124 LOG(INFO) << __func__ << ": BluetoothAudioHal SessionType="
125 << toString(transport_->GetSessionType()) << " has "
126 << capabilities_.size() << " AudioCapabilities";
127
128 aidl_retval =
129 provider_factory->openProvider(transport_->GetSessionType(), &provider_);
130 if (!aidl_retval.isOk()) {
131 LOG(FATAL) << __func__ << ": BluetoothAudioHal::openProvider failure: "
132 << aidl_retval.getDescription();
133 }
134 CHECK(provider_ != nullptr);
135
136 binder_status_t binder_status = AIBinder_linkToDeath(
137 provider_factory->asBinder().get(), death_recipient_.get(), this);
138 if (binder_status != STATUS_OK) {
139 LOG(ERROR) << "Failed to linkToDeath " << static_cast<int>(binder_status);
140 }
141 provider_factory_ = std::move(provider_factory);
142
143 LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
144 << provider_.get()
145 << (provider_->isRemote() ? " (remote)" : " (local)");
146 }
147
BluetoothAudioSinkClientInterface(IBluetoothSinkTransportInstance * sink,bluetooth::common::MessageLoopThread * message_loop)148 BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface(
149 IBluetoothSinkTransportInstance* sink,
150 bluetooth::common::MessageLoopThread* message_loop)
151 : BluetoothAudioClientInterface{sink}, sink_(sink) {
152 FetchAudioProvider();
153 }
154
~BluetoothAudioSinkClientInterface()155 BluetoothAudioSinkClientInterface::~BluetoothAudioSinkClientInterface() {
156 if (provider_factory_ != nullptr) {
157 AIBinder_unlinkToDeath(provider_factory_->asBinder().get(), death_recipient_.get(),
158 nullptr);
159 }
160 }
161
BluetoothAudioSourceClientInterface(IBluetoothSourceTransportInstance * source,bluetooth::common::MessageLoopThread * message_loop)162 BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface(
163 IBluetoothSourceTransportInstance* source,
164 bluetooth::common::MessageLoopThread* message_loop)
165 : BluetoothAudioClientInterface{source}, source_(source) {
166 FetchAudioProvider();
167 }
168
~BluetoothAudioSourceClientInterface()169 BluetoothAudioSourceClientInterface::~BluetoothAudioSourceClientInterface() {
170 if (provider_factory_ != nullptr) {
171 AIBinder_unlinkToDeath(provider_factory_->asBinder().get(), death_recipient_.get(),
172 nullptr);
173 }
174 }
175
binderDiedCallbackAidl(void * ptr)176 void BluetoothAudioClientInterface::binderDiedCallbackAidl(void* ptr) {
177 LOG(WARNING) << __func__ << ": restarting connection with new Audio Hal";
178 auto client = static_cast<BluetoothAudioClientInterface*>(ptr);
179 if (client == nullptr) {
180 LOG(ERROR) << __func__ << ": null audio HAL died!";
181 return;
182 }
183 client->RenewAudioProviderAndSession();
184 }
185
UpdateAudioConfig(const AudioConfiguration & audio_config)186 bool BluetoothAudioClientInterface::UpdateAudioConfig(
187 const AudioConfiguration& audio_config) {
188 bool is_software_session =
189 (transport_->GetSessionType() ==
190 SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
191 transport_->GetSessionType() ==
192 SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
193 transport_->GetSessionType() ==
194 SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
195 transport_->GetSessionType() ==
196 SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
197 transport_->GetSessionType() ==
198 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
199 bool is_a2dp_offload_session =
200 (transport_->GetSessionType() ==
201 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
202 bool is_leaudio_unicast_offload_session =
203 (transport_->GetSessionType() ==
204 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
205 transport_->GetSessionType() ==
206 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
207 bool is_leaudio_broadcast_offload_session =
208 (transport_->GetSessionType() ==
209 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
210 auto audio_config_tag = audio_config.getTag();
211 bool is_software_audio_config =
212 (is_software_session &&
213 audio_config_tag == AudioConfiguration::pcmConfig);
214 bool is_a2dp_offload_audio_config =
215 (is_a2dp_offload_session &&
216 audio_config_tag == AudioConfiguration::a2dpConfig);
217 bool is_leaudio_unicast_offload_audio_config =
218 (is_leaudio_unicast_offload_session &&
219 audio_config_tag == AudioConfiguration::leAudioConfig);
220 bool is_leaudio_broadcast_offload_audio_config =
221 (is_leaudio_broadcast_offload_session &&
222 audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
223 if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
224 !is_leaudio_unicast_offload_audio_config &&
225 !is_leaudio_broadcast_offload_audio_config) {
226 return false;
227 }
228 transport_->UpdateAudioConfiguration(audio_config);
229
230 if (provider_ == nullptr) {
231 LOG(INFO) << __func__
232 << ": BluetoothAudioHal nullptr, update it as session started";
233 return true;
234 }
235
236 auto aidl_retval = provider_->updateAudioConfiguration(audio_config);
237 if (!aidl_retval.isOk()) {
238 LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
239 << aidl_retval.getDescription();
240 }
241 return true;
242 }
243
SetLowLatencyModeAllowed(bool allowed)244 bool BluetoothAudioClientInterface::SetLowLatencyModeAllowed(bool allowed) {
245 is_low_latency_allowed_ = allowed;
246 if (provider_ == nullptr) {
247 LOG(INFO) << __func__ << ": BluetoothAudioHal nullptr";
248 return false;
249 }
250
251 auto aidl_retval = provider_->setLowLatencyModeAllowed(allowed);
252 if (!aidl_retval.isOk()) {
253 LOG(WARNING) << __func__ << ": BluetoothAudioHal is not ready: "
254 << aidl_retval.getDescription()
255 << ". is_low_latency_allowed_ is saved "
256 <<"and it will be sent to BluetoothAudioHal at StartSession.";
257 }
258 return true;
259 }
260
GetAidlInterfaceVersion()261 int BluetoothAudioClientInterface::GetAidlInterfaceVersion() {
262 int aidl_version = -1;
263 if (!is_aidl_available()) {
264 return aidl_version;
265 }
266
267 auto provider_factory = IBluetoothAudioProviderFactory::fromBinder(
268 ::ndk::SpAIBinder(AServiceManager_waitForService(
269 kDefaultAudioProviderFactoryInterface.c_str())));
270
271 if (provider_factory == nullptr) {
272 LOG(ERROR) << __func__ << ", can't get aidl version from unknown factory";
273 return aidl_version;
274 }
275
276 auto aidl_retval = provider_factory->getInterfaceVersion(&aidl_version);
277 if (!aidl_retval.isOk()) {
278 LOG(FATAL) << __func__
279 << ": BluetoothAudioHal::getInterfaceVersion failure: "
280 << aidl_retval.getDescription();
281 }
282
283 return aidl_version;
284 }
285
StartSession()286 int BluetoothAudioClientInterface::StartSession() {
287 std::lock_guard<std::mutex> guard(internal_mutex_);
288 if (provider_ == nullptr) {
289 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
290 session_started_ = false;
291 return -EINVAL;
292 }
293 if (session_started_) {
294 LOG(ERROR) << __func__ << ": session started already";
295 return -EBUSY;
296 }
297
298 std::shared_ptr<IBluetoothAudioPort> stack_if =
299 ndk::SharedRefBase::make<BluetoothAudioPortImpl>(transport_, provider_);
300
301 std::unique_ptr<DataMQ> data_mq;
302 DataMQDesc mq_desc;
303 std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
304 if (is_low_latency_allowed_) {
305 latency_modes.push_back(LatencyMode::LOW_LATENCY);
306 }
307 auto aidl_retval = provider_->startSession(
308 stack_if, transport_->GetAudioConfiguration(), latency_modes, &mq_desc);
309 if (!aidl_retval.isOk()) {
310 if (aidl_retval.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
311 LOG(ERROR) << __func__ << ": BluetoothAudioHal Error: "
312 << aidl_retval.getDescription() << ", audioConfig="
313 << transport_->GetAudioConfiguration().toString();
314 } else {
315 LOG(FATAL) << __func__ << ": BluetoothAudioHal failure: "
316 << aidl_retval.getDescription();
317 }
318 return -EPROTO;
319 }
320 data_mq.reset(new DataMQ(mq_desc));
321
322 if (data_mq && data_mq->isValid()) {
323 data_mq_ = std::move(data_mq);
324 } else if (transport_->GetSessionType() ==
325 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
326 transport_->GetSessionType() ==
327 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
328 transport_->GetSessionType() ==
329 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
330 transport_->GetSessionType() ==
331 SessionType::
332 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
333 transport_->ResetPresentationPosition();
334 session_started_ = true;
335 return 0;
336 }
337 if (data_mq_ && data_mq_->isValid()) {
338 transport_->ResetPresentationPosition();
339 session_started_ = true;
340 return 0;
341 } else {
342 if (!data_mq_) {
343 LOG(ERROR) << __func__ << "Failed to obtain audio data path";
344 }
345 if (data_mq_ && !data_mq_->isValid()) {
346 LOG(ERROR) << __func__ << "Audio data path is invalid";
347 }
348 session_started_ = false;
349 return -EIO;
350 }
351 }
352
StreamStarted(const BluetoothAudioCtrlAck & ack)353 void BluetoothAudioClientInterface::StreamStarted(
354 const BluetoothAudioCtrlAck& ack) {
355 if (provider_ == nullptr) {
356 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
357 return;
358 }
359 if (ack == BluetoothAudioCtrlAck::PENDING) {
360 LOG(INFO) << __func__ << ": " << ack << " ignored";
361 return;
362 }
363 BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
364
365 auto aidl_retval = provider_->streamStarted(status);
366
367 if (!aidl_retval.isOk()) {
368 LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
369 << aidl_retval.getDescription();
370 }
371 }
372
StreamSuspended(const BluetoothAudioCtrlAck & ack)373 void BluetoothAudioClientInterface::StreamSuspended(
374 const BluetoothAudioCtrlAck& ack) {
375 if (provider_ == nullptr) {
376 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
377 return;
378 }
379 if (ack == BluetoothAudioCtrlAck::PENDING) {
380 LOG(INFO) << __func__ << ": " << ack << " ignored";
381 return;
382 }
383 BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
384
385 auto aidl_retval = provider_->streamSuspended(status);
386
387 if (!aidl_retval.isOk()) {
388 LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
389 << aidl_retval.getDescription();
390 }
391 }
392
EndSession()393 int BluetoothAudioClientInterface::EndSession() {
394 std::lock_guard<std::mutex> guard(internal_mutex_);
395 if (!session_started_) {
396 LOG(INFO) << __func__ << ": session ended already";
397 return 0;
398 }
399
400 session_started_ = false;
401 if (provider_ == nullptr) {
402 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
403 return -EINVAL;
404 }
405 data_mq_ = nullptr;
406
407 auto aidl_retval = provider_->endSession();
408
409 if (!aidl_retval.isOk()) {
410 LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
411 << aidl_retval.getDescription();
412 return -EPROTO;
413 }
414 return 0;
415 }
416
FlushAudioData()417 void BluetoothAudioClientInterface::FlushAudioData() {
418 if (transport_->GetSessionType() ==
419 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
420 transport_->GetSessionType() ==
421 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
422 transport_->GetSessionType() ==
423 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
424 return;
425 }
426
427 if (data_mq_ == nullptr || !data_mq_->isValid()) {
428 LOG(WARNING) << __func__ << ", data_mq_ invalid";
429 return;
430 }
431 size_t size = data_mq_->availableToRead();
432 std::vector<MqDataType> buffer(size);
433
434 if (data_mq_->read(buffer.data(), size) != size) {
435 LOG(WARNING) << __func__ << ", failed to flush data queue!";
436 }
437 }
438
ReadAudioData(uint8_t * p_buf,uint32_t len)439 size_t BluetoothAudioSinkClientInterface::ReadAudioData(uint8_t* p_buf,
440 uint32_t len) {
441 if (!IsValid()) {
442 LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
443 return 0;
444 }
445 if (p_buf == nullptr || len == 0) return 0;
446
447 std::lock_guard<std::mutex> guard(internal_mutex_);
448
449 size_t total_read = 0;
450 int timeout_ms = kDefaultDataReadTimeoutMs;
451 do {
452 if (data_mq_ == nullptr || !data_mq_->isValid()) break;
453
454 size_t avail_to_read = data_mq_->availableToRead();
455 if (avail_to_read) {
456 if (avail_to_read > len - total_read) {
457 avail_to_read = len - total_read;
458 }
459 if (data_mq_->read((MqDataType*)p_buf + total_read, avail_to_read) == 0) {
460 LOG(WARNING) << __func__ << ": len=" << len
461 << " total_read=" << total_read << " failed";
462 break;
463 }
464 total_read += avail_to_read;
465 } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
466 std::this_thread::sleep_for(
467 std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
468 timeout_ms -= kDefaultDataReadPollIntervalMs;
469 continue;
470 } else {
471 LOG(WARNING) << __func__ << ": " << (len - total_read) << "/" << len
472 << " no data " << (kDefaultDataReadTimeoutMs - timeout_ms)
473 << " ms";
474 break;
475 }
476 } while (total_read < len);
477
478 if (timeout_ms <
479 (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
480 timeout_ms >= kDefaultDataReadPollIntervalMs) {
481 VLOG(1) << __func__ << ": underflow " << len << " -> " << total_read
482 << " read " << (kDefaultDataReadTimeoutMs - timeout_ms) << " ms";
483 } else {
484 VLOG(2) << __func__ << ": " << len << " -> " << total_read << " read";
485 }
486
487 sink_->LogBytesRead(total_read);
488 return total_read;
489 }
490
RenewAudioProviderAndSession()491 void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
492 // NOTE: must be invoked on the same thread where this
493 // BluetoothAudioClientInterface is running
494 FetchAudioProvider();
495
496 if (session_started_) {
497 LOG(INFO) << __func__
498 << ": Restart the session while audio HAL recovering ";
499 session_started_ = false;
500
501 StartSession();
502 }
503 }
504
WriteAudioData(const uint8_t * p_buf,uint32_t len)505 size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf,
506 uint32_t len) {
507 if (!IsValid()) {
508 LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
509 return 0;
510 }
511 if (p_buf == nullptr || len == 0) return 0;
512
513 std::lock_guard<std::mutex> guard(internal_mutex_);
514
515 size_t total_written = 0;
516 int timeout_ms = kDefaultDataWriteTimeoutMs;
517 do {
518 if (data_mq_ == nullptr || !data_mq_->isValid()) break;
519
520 size_t avail_to_write = data_mq_->availableToWrite();
521 if (avail_to_write) {
522 if (avail_to_write > len - total_written) {
523 avail_to_write = len - total_written;
524 }
525 if (data_mq_->write((const MqDataType*)p_buf + total_written,
526 avail_to_write) == 0) {
527 LOG(WARNING) << __func__ << ": len=" << len
528 << " total_written=" << total_written << " failed";
529 break;
530 }
531 total_written += avail_to_write;
532 } else if (timeout_ms >= kDefaultDataWritePollIntervalMs) {
533 std::this_thread::sleep_for(
534 std::chrono::milliseconds(kDefaultDataWritePollIntervalMs));
535 timeout_ms -= kDefaultDataWritePollIntervalMs;
536 continue;
537 } else {
538 LOG(WARNING) << __func__ << ": " << (len - total_written) << "/" << len
539 << " no data " << (kDefaultDataWriteTimeoutMs - timeout_ms)
540 << " ms";
541 break;
542 }
543 } while (total_written < len);
544
545 if (timeout_ms <
546 (kDefaultDataWriteTimeoutMs - kDefaultDataWritePollIntervalMs) &&
547 timeout_ms >= kDefaultDataWritePollIntervalMs) {
548 VLOG(1) << __func__ << ": underflow " << len << " -> " << total_written
549 << " read " << (kDefaultDataWriteTimeoutMs - timeout_ms) << " ms ";
550 } else {
551 VLOG(2) << __func__ << ": " << len << " -> " << total_written
552 << " written ";
553 }
554
555 source_->LogBytesWritten(total_written);
556 return total_written;
557 }
558
559 } // namespace aidl
560 } // namespace audio
561 } // namespace bluetooth
562