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 "BTAudioClientIf"
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
StartSession()261 int BluetoothAudioClientInterface::StartSession() {
262 std::lock_guard<std::mutex> guard(internal_mutex_);
263 if (provider_ == nullptr) {
264 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
265 session_started_ = false;
266 return -EINVAL;
267 }
268 if (session_started_) {
269 LOG(ERROR) << __func__ << ": session started already";
270 return -EBUSY;
271 }
272
273 std::shared_ptr<IBluetoothAudioPort> stack_if =
274 ndk::SharedRefBase::make<BluetoothAudioPortImpl>(transport_, provider_);
275
276 std::unique_ptr<DataMQ> data_mq;
277 DataMQDesc mq_desc;
278 std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
279 if (is_low_latency_allowed_) {
280 latency_modes.push_back(LatencyMode::LOW_LATENCY);
281 }
282 auto aidl_retval = provider_->startSession(
283 stack_if, transport_->GetAudioConfiguration(), latency_modes, &mq_desc);
284 if (!aidl_retval.isOk()) {
285 if (aidl_retval.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
286 LOG(ERROR) << __func__ << ": BluetoothAudioHal Error: "
287 << aidl_retval.getDescription() << ", audioConfig="
288 << transport_->GetAudioConfiguration().toString();
289 } else {
290 LOG(FATAL) << __func__ << ": BluetoothAudioHal failure: "
291 << aidl_retval.getDescription();
292 }
293 return -EPROTO;
294 }
295 data_mq.reset(new DataMQ(mq_desc));
296
297 if (data_mq && data_mq->isValid()) {
298 data_mq_ = std::move(data_mq);
299 } else if (transport_->GetSessionType() ==
300 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
301 transport_->GetSessionType() ==
302 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
303 transport_->GetSessionType() ==
304 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
305 transport_->GetSessionType() ==
306 SessionType::
307 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
308 transport_->ResetPresentationPosition();
309 session_started_ = true;
310 return 0;
311 }
312 if (data_mq_ && data_mq_->isValid()) {
313 transport_->ResetPresentationPosition();
314 session_started_ = true;
315 return 0;
316 } else {
317 if (!data_mq_) {
318 LOG(ERROR) << __func__ << "Failed to obtain audio data path";
319 }
320 if (data_mq_ && !data_mq_->isValid()) {
321 LOG(ERROR) << __func__ << "Audio data path is invalid";
322 }
323 session_started_ = false;
324 return -EIO;
325 }
326 }
327
StreamStarted(const BluetoothAudioCtrlAck & ack)328 void BluetoothAudioClientInterface::StreamStarted(
329 const BluetoothAudioCtrlAck& ack) {
330 if (provider_ == nullptr) {
331 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
332 return;
333 }
334 if (ack == BluetoothAudioCtrlAck::PENDING) {
335 LOG(INFO) << __func__ << ": " << ack << " ignored";
336 return;
337 }
338 BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
339
340 auto aidl_retval = provider_->streamStarted(status);
341
342 if (!aidl_retval.isOk()) {
343 LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
344 << aidl_retval.getDescription();
345 }
346 }
347
StreamSuspended(const BluetoothAudioCtrlAck & ack)348 void BluetoothAudioClientInterface::StreamSuspended(
349 const BluetoothAudioCtrlAck& ack) {
350 if (provider_ == nullptr) {
351 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
352 return;
353 }
354 if (ack == BluetoothAudioCtrlAck::PENDING) {
355 LOG(INFO) << __func__ << ": " << ack << " ignored";
356 return;
357 }
358 BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
359
360 auto aidl_retval = provider_->streamSuspended(status);
361
362 if (!aidl_retval.isOk()) {
363 LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
364 << aidl_retval.getDescription();
365 }
366 }
367
EndSession()368 int BluetoothAudioClientInterface::EndSession() {
369 std::lock_guard<std::mutex> guard(internal_mutex_);
370 if (!session_started_) {
371 LOG(INFO) << __func__ << ": session ended already";
372 return 0;
373 }
374
375 session_started_ = false;
376 if (provider_ == nullptr) {
377 LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
378 return -EINVAL;
379 }
380 data_mq_ = nullptr;
381
382 auto aidl_retval = provider_->endSession();
383
384 if (!aidl_retval.isOk()) {
385 LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
386 << aidl_retval.getDescription();
387 return -EPROTO;
388 }
389 return 0;
390 }
391
FlushAudioData()392 void BluetoothAudioClientInterface::FlushAudioData() {
393 if (transport_->GetSessionType() ==
394 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
395 transport_->GetSessionType() ==
396 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
397 transport_->GetSessionType() ==
398 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
399 return;
400 }
401
402 if (data_mq_ == nullptr || !data_mq_->isValid()) {
403 LOG(WARNING) << __func__ << ", data_mq_ invalid";
404 return;
405 }
406 size_t size = data_mq_->availableToRead();
407 std::vector<MqDataType> buffer(size);
408
409 if (data_mq_->read(buffer.data(), size) != size) {
410 LOG(WARNING) << __func__ << ", failed to flush data queue!";
411 }
412 }
413
ReadAudioData(uint8_t * p_buf,uint32_t len)414 size_t BluetoothAudioSinkClientInterface::ReadAudioData(uint8_t* p_buf,
415 uint32_t len) {
416 if (!IsValid()) {
417 LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
418 return 0;
419 }
420 if (p_buf == nullptr || len == 0) return 0;
421
422 std::lock_guard<std::mutex> guard(internal_mutex_);
423
424 size_t total_read = 0;
425 int timeout_ms = kDefaultDataReadTimeoutMs;
426 do {
427 if (data_mq_ == nullptr || !data_mq_->isValid()) break;
428
429 size_t avail_to_read = data_mq_->availableToRead();
430 if (avail_to_read) {
431 if (avail_to_read > len - total_read) {
432 avail_to_read = len - total_read;
433 }
434 if (data_mq_->read((MqDataType*)p_buf + total_read, avail_to_read) == 0) {
435 LOG(WARNING) << __func__ << ": len=" << len
436 << " total_read=" << total_read << " failed";
437 break;
438 }
439 total_read += avail_to_read;
440 } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
441 std::this_thread::sleep_for(
442 std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
443 timeout_ms -= kDefaultDataReadPollIntervalMs;
444 continue;
445 } else {
446 LOG(WARNING) << __func__ << ": " << (len - total_read) << "/" << len
447 << " no data " << (kDefaultDataReadTimeoutMs - timeout_ms)
448 << " ms";
449 break;
450 }
451 } while (total_read < len);
452
453 if (timeout_ms <
454 (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
455 timeout_ms >= kDefaultDataReadPollIntervalMs) {
456 VLOG(1) << __func__ << ": underflow " << len << " -> " << total_read
457 << " read " << (kDefaultDataReadTimeoutMs - timeout_ms) << " ms";
458 } else {
459 VLOG(2) << __func__ << ": " << len << " -> " << total_read << " read";
460 }
461
462 sink_->LogBytesRead(total_read);
463 return total_read;
464 }
465
RenewAudioProviderAndSession()466 void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
467 // NOTE: must be invoked on the same thread where this
468 // BluetoothAudioClientInterface is running
469 FetchAudioProvider();
470
471 if (session_started_) {
472 LOG(INFO) << __func__
473 << ": Restart the session while audio HAL recovering ";
474 session_started_ = false;
475
476 StartSession();
477 }
478 }
479
WriteAudioData(const uint8_t * p_buf,uint32_t len)480 size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf,
481 uint32_t len) {
482 if (!IsValid()) {
483 LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
484 return 0;
485 }
486 if (p_buf == nullptr || len == 0) return 0;
487
488 std::lock_guard<std::mutex> guard(internal_mutex_);
489
490 size_t total_written = 0;
491 int timeout_ms = kDefaultDataWriteTimeoutMs;
492 do {
493 if (data_mq_ == nullptr || !data_mq_->isValid()) break;
494
495 size_t avail_to_write = data_mq_->availableToWrite();
496 if (avail_to_write) {
497 if (avail_to_write > len - total_written) {
498 avail_to_write = len - total_written;
499 }
500 if (data_mq_->write((const MqDataType*)p_buf + total_written,
501 avail_to_write) == 0) {
502 LOG(WARNING) << __func__ << ": len=" << len
503 << " total_written=" << total_written << " failed";
504 break;
505 }
506 total_written += avail_to_write;
507 } else if (timeout_ms >= kDefaultDataWritePollIntervalMs) {
508 std::this_thread::sleep_for(
509 std::chrono::milliseconds(kDefaultDataWritePollIntervalMs));
510 timeout_ms -= kDefaultDataWritePollIntervalMs;
511 continue;
512 } else {
513 LOG(WARNING) << __func__ << ": " << (len - total_written) << "/" << len
514 << " no data " << (kDefaultDataWriteTimeoutMs - timeout_ms)
515 << " ms";
516 break;
517 }
518 } while (total_written < len);
519
520 if (timeout_ms <
521 (kDefaultDataWriteTimeoutMs - kDefaultDataWritePollIntervalMs) &&
522 timeout_ms >= kDefaultDataWritePollIntervalMs) {
523 VLOG(1) << __func__ << ": underflow " << len << " -> " << total_written
524 << " read " << (kDefaultDataWriteTimeoutMs - timeout_ms) << " ms ";
525 } else {
526 VLOG(2) << __func__ << ": " << len << " -> " << total_written
527 << " written ";
528 }
529
530 source_->LogBytesWritten(total_written);
531 return total_written;
532 }
533
534 } // namespace aidl
535 } // namespace audio
536 } // namespace bluetooth
537