1 /*
2 * Copyright (C) 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 #include <sys/types.h>
18 #define LOG_TAG "BTAudioSessionAidl"
19
20 #include <android-base/logging.h>
21 #include <android-base/stringprintf.h>
22 #include <android/binder_manager.h>
23 #include <com_android_btaudio_hal_flags.h>
24 #include <hardware/audio.h>
25
26 #include "BluetoothAudioSession.h"
27
28 namespace aidl {
29 namespace android {
30 namespace hardware {
31 namespace bluetooth {
32 namespace audio {
33
34 static constexpr int kFmqSendTimeoutMs = 1000; // 1000 ms timeout for sending
35 static constexpr int kFmqReceiveTimeoutMs =
36 1000; // 1000 ms timeout for receiving
37 static constexpr int kWritePollMs = 1; // polled non-blocking interval
38 static constexpr int kReadPollMs = 1; // polled non-blocking interval
39
toString(const std::vector<LatencyMode> & latencies)40 static std::string toString(const std::vector<LatencyMode>& latencies) {
41 std::stringstream latencyModesStr;
42 for (LatencyMode mode : latencies) {
43 latencyModesStr << " " << toString(mode);
44 }
45 return latencyModesStr.str();
46 }
47
BluetoothAudioSession(const SessionType & session_type)48 BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type)
49 : session_type_(session_type), stack_iface_(nullptr), data_mq_(nullptr) {}
50
51 /***
52 *
53 * Callback methods
54 *
55 ***/
56
OnSessionStarted(const std::shared_ptr<IBluetoothAudioPort> stack_iface,const DataMQDesc * mq_desc,const AudioConfiguration & audio_config,const std::vector<LatencyMode> & latency_modes)57 void BluetoothAudioSession::OnSessionStarted(
58 const std::shared_ptr<IBluetoothAudioPort> stack_iface,
59 const DataMQDesc* mq_desc, const AudioConfiguration& audio_config,
60 const std::vector<LatencyMode>& latency_modes) {
61 std::lock_guard<std::recursive_mutex> guard(mutex_);
62 if (stack_iface == nullptr) {
63 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
64 << ", IBluetoothAudioPort Invalid";
65 } else if (!UpdateAudioConfig(audio_config)) {
66 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
67 << ", AudioConfiguration=" << audio_config.toString()
68 << " Invalid";
69 } else if (!UpdateDataPath(mq_desc)) {
70 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
71 << " MqDescriptor Invalid";
72 audio_config_ = nullptr;
73 } else {
74 stack_iface_ = stack_iface;
75 latency_modes_ = latency_modes;
76 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
77 << " - All LatencyModes=" << toString(latency_modes)
78 << ", AudioConfiguration=" << audio_config.toString();
79 ReportSessionStatus();
80 }
81 }
82
OnSessionEnded()83 void BluetoothAudioSession::OnSessionEnded() {
84 std::lock_guard<std::recursive_mutex> guard(mutex_);
85 bool toggled = IsSessionReady();
86 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
87 audio_config_ = nullptr;
88 stack_iface_ = nullptr;
89 UpdateDataPath(nullptr);
90 if (toggled) {
91 ReportSessionStatus();
92 }
93 }
94
95 /***
96 *
97 * Util methods
98 *
99 ***/
100
GetAudioConfig()101 const AudioConfiguration BluetoothAudioSession::GetAudioConfig() {
102 std::lock_guard<std::recursive_mutex> guard(mutex_);
103 if (!IsSessionReady()) {
104 switch (session_type_) {
105 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
106 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
107 return AudioConfiguration(CodecConfiguration{});
108 case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
109 return AudioConfiguration(HfpConfiguration{});
110 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
111 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
112 return AudioConfiguration(LeAudioConfiguration{});
113 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
114 return AudioConfiguration(LeAudioBroadcastConfiguration{});
115 default:
116 return AudioConfiguration(PcmConfiguration{});
117 }
118 }
119 return *audio_config_;
120 }
121
ReportAudioConfigChanged(const AudioConfiguration & audio_config)122 void BluetoothAudioSession::ReportAudioConfigChanged(
123 const AudioConfiguration& audio_config) {
124 std::lock_guard<std::recursive_mutex> guard(mutex_);
125 if (com::android::btaudio::hal::flags::leaudio_report_broadcast_ac_to_hal()) {
126 if (session_type_ ==
127 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
128 session_type_ ==
129 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
130 if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
131 LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
132 << toString(session_type_);
133 return;
134 }
135 } else if (session_type_ ==
136 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
137 if (audio_config.getTag() != AudioConfiguration::leAudioBroadcastConfig) {
138 LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
139 << toString(session_type_);
140 return;
141 }
142 } else if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
143 if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
144 LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
145 << toString(session_type_);
146 return;
147 }
148 } else if (session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
149 session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH) {
150 if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
151 LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
152 << toString(session_type_);
153 return;
154 }
155 } else {
156 LOG(ERROR) << __func__ << " invalid SessionType ="
157 << toString(session_type_);
158 return;
159 }
160 } else {
161 if (session_type_ ==
162 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
163 session_type_ ==
164 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
165 if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
166 LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
167 << toString(session_type_);
168 return;
169 }
170 } else if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
171 if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
172 LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
173 << toString(session_type_);
174 return;
175 }
176 } else if (session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
177 session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH) {
178 if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
179 LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
180 << toString(session_type_);
181 return;
182 }
183 } else {
184 LOG(ERROR) << __func__
185 << " invalid SessionType =" << toString(session_type_);
186 return;
187 }
188 }
189
190 audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
191
192 if (observers_.empty()) {
193 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
194 << " has NO port state observer";
195 return;
196 }
197 for (auto& observer : observers_) {
198 uint16_t cookie = observer.first;
199 std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
200 LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_)
201 << ", bluetooth_audio=0x"
202 << ::android::base::StringPrintf("%04x", cookie);
203 if (cb->audio_configuration_changed_cb_ != nullptr) {
204 cb->audio_configuration_changed_cb_(cookie);
205 }
206 }
207 }
208
IsSessionReady()209 bool BluetoothAudioSession::IsSessionReady() {
210 std::lock_guard<std::recursive_mutex> guard(mutex_);
211
212 bool is_mq_valid =
213 (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
214 session_type_ ==
215 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
216 session_type_ ==
217 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
218 session_type_ ==
219 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
220 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
221 session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
222 (data_mq_ != nullptr && data_mq_->isValid()));
223 return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
224 }
225
226 /***
227 *
228 * Status callback methods
229 *
230 ***/
231
RegisterStatusCback(const PortStatusCallbacks & callbacks)232 uint16_t BluetoothAudioSession::RegisterStatusCback(
233 const PortStatusCallbacks& callbacks) {
234 std::lock_guard<std::recursive_mutex> guard(mutex_);
235 uint16_t cookie = ObserversCookieGetInitValue(session_type_);
236 uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_);
237
238 while (cookie < cookie_upper_bound) {
239 if (observers_.find(cookie) == observers_.end()) {
240 break;
241 }
242 ++cookie;
243 }
244 if (cookie >= cookie_upper_bound) {
245 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
246 << " has " << observers_.size()
247 << " observers already (No Resource)";
248 return kObserversCookieUndefined;
249 }
250 std::shared_ptr<PortStatusCallbacks> cb =
251 std::make_shared<PortStatusCallbacks>();
252 *cb = callbacks;
253 observers_[cookie] = cb;
254 return cookie;
255 }
256
UnregisterStatusCback(uint16_t cookie)257 void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) {
258 std::lock_guard<std::recursive_mutex> guard(mutex_);
259 if (observers_.erase(cookie) != 1) {
260 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
261 << " no such provider=0x"
262 << ::android::base::StringPrintf("%04x", cookie);
263 }
264 }
265
266 /***
267 *
268 * Stream methods
269 *
270 ***/
271
StartStream(bool is_low_latency)272 bool BluetoothAudioSession::StartStream(bool is_low_latency) {
273 std::lock_guard<std::recursive_mutex> guard(mutex_);
274 if (!IsSessionReady()) {
275 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
276 << " has NO session";
277 return false;
278 }
279 auto hal_retval = stack_iface_->startStream(is_low_latency);
280 if (!hal_retval.isOk()) {
281 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
282 << toString(session_type_) << " failed";
283 return false;
284 }
285 return true;
286 }
287
SuspendStream()288 bool BluetoothAudioSession::SuspendStream() {
289 std::lock_guard<std::recursive_mutex> guard(mutex_);
290 if (!IsSessionReady()) {
291 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
292 << " has NO session";
293 return false;
294 }
295 auto hal_retval = stack_iface_->suspendStream();
296 if (!hal_retval.isOk()) {
297 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
298 << toString(session_type_) << " failed";
299 return false;
300 }
301 return true;
302 }
303
StopStream()304 void BluetoothAudioSession::StopStream() {
305 std::lock_guard<std::recursive_mutex> guard(mutex_);
306 if (!IsSessionReady()) {
307 return;
308 }
309 auto hal_retval = stack_iface_->stopStream();
310 if (!hal_retval.isOk()) {
311 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
312 << toString(session_type_) << " failed";
313 }
314 }
315
316 /***
317 *
318 * Private methods
319 *
320 ***/
321
UpdateDataPath(const DataMQDesc * mq_desc)322 bool BluetoothAudioSession::UpdateDataPath(const DataMQDesc* mq_desc) {
323 if (mq_desc == nullptr) {
324 // usecase of reset by nullptr
325 data_mq_ = nullptr;
326 return true;
327 }
328 std::unique_ptr<DataMQ> temp_mq;
329 temp_mq.reset(new DataMQ(*mq_desc));
330 if (!temp_mq || !temp_mq->isValid()) {
331 data_mq_ = nullptr;
332 return false;
333 }
334 data_mq_ = std::move(temp_mq);
335 return true;
336 }
337
UpdateAudioConfig(const AudioConfiguration & audio_config)338 bool BluetoothAudioSession::UpdateAudioConfig(
339 const AudioConfiguration& audio_config) {
340 bool is_software_session =
341 (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
342 session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
343 session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
344 session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
345 session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
346 session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
347 session_type_ ==
348 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
349 session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
350 bool is_offload_a2dp_session =
351 (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
352 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
353 bool is_offload_hfp_session =
354 session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH;
355 bool is_offload_le_audio_unicast_session =
356 (session_type_ ==
357 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
358 session_type_ ==
359 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
360 bool is_offload_le_audio_broadcast_session =
361 (session_type_ ==
362 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
363 auto audio_config_tag = audio_config.getTag();
364 bool is_software_audio_config =
365 (is_software_session &&
366 audio_config_tag == AudioConfiguration::pcmConfig);
367 bool is_a2dp_offload_audio_config =
368 (is_offload_a2dp_session &&
369 (audio_config_tag == AudioConfiguration::a2dp ||
370 audio_config_tag == AudioConfiguration::a2dpConfig));
371 bool is_hfp_offload_audio_config =
372 (is_offload_hfp_session &&
373 audio_config_tag == AudioConfiguration::hfpConfig);
374 bool is_le_audio_offload_unicast_audio_config =
375 (is_offload_le_audio_unicast_session &&
376 audio_config_tag == AudioConfiguration::leAudioConfig);
377 bool is_le_audio_offload_broadcast_audio_config =
378 (is_offload_le_audio_broadcast_session &&
379 audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
380 if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
381 !is_hfp_offload_audio_config &&
382 !is_le_audio_offload_unicast_audio_config &&
383 !is_le_audio_offload_broadcast_audio_config) {
384 return false;
385 }
386 audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
387 return true;
388 }
389
ReportSessionStatus()390 void BluetoothAudioSession::ReportSessionStatus() {
391 // This is locked already by OnSessionStarted / OnSessionEnded
392 if (observers_.empty()) {
393 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
394 << " has NO port state observer";
395 return;
396 }
397 for (auto& observer : observers_) {
398 uint16_t cookie = observer.first;
399 std::shared_ptr<PortStatusCallbacks> callback = observer.second;
400 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
401 << " notify to bluetooth_audio=0x"
402 << ::android::base::StringPrintf("%04x", cookie);
403 callback->session_changed_cb_(cookie);
404 }
405 }
406
407 /***
408 *
409 * PCM methods
410 *
411 ***/
412
OutWritePcmData(const void * buffer,size_t bytes)413 size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
414 size_t bytes) {
415 if (buffer == nullptr || bytes <= 0) {
416 return 0;
417 }
418 size_t total_written = 0;
419 int timeout_ms = kFmqSendTimeoutMs;
420 do {
421 std::unique_lock<std::recursive_mutex> lock(mutex_);
422 if (!IsSessionReady()) {
423 break;
424 }
425 size_t num_bytes_to_write = data_mq_->availableToWrite();
426 if (num_bytes_to_write) {
427 if (num_bytes_to_write > (bytes - total_written)) {
428 num_bytes_to_write = bytes - total_written;
429 }
430
431 if (!data_mq_->write(
432 static_cast<const MQDataType*>(buffer) + total_written,
433 num_bytes_to_write)) {
434 LOG(ERROR) << "FMQ datapath writing " << total_written << "/" << bytes
435 << " failed";
436 return total_written;
437 }
438 total_written += num_bytes_to_write;
439 } else if (timeout_ms >= kWritePollMs) {
440 lock.unlock();
441 usleep(kWritePollMs * 1000);
442 timeout_ms -= kWritePollMs;
443 } else {
444 LOG(DEBUG) << "Data " << total_written << "/" << bytes << " overflow "
445 << (kFmqSendTimeoutMs - timeout_ms) << " ms";
446 return total_written;
447 }
448 } while (total_written < bytes);
449 return total_written;
450 }
451
InReadPcmData(void * buffer,size_t bytes)452 size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
453 if (buffer == nullptr || bytes <= 0) {
454 return 0;
455 }
456 size_t total_read = 0;
457 int timeout_ms = kFmqReceiveTimeoutMs;
458 do {
459 std::unique_lock<std::recursive_mutex> lock(mutex_);
460 if (!IsSessionReady()) {
461 break;
462 }
463 size_t num_bytes_to_read = data_mq_->availableToRead();
464 if (num_bytes_to_read) {
465 if (num_bytes_to_read > (bytes - total_read)) {
466 num_bytes_to_read = bytes - total_read;
467 }
468 if (!data_mq_->read(static_cast<MQDataType*>(buffer) + total_read,
469 num_bytes_to_read)) {
470 LOG(ERROR) << "FMQ datapath reading " << total_read << "/" << bytes
471 << " failed";
472 return total_read;
473 }
474 total_read += num_bytes_to_read;
475 } else if (timeout_ms >= kReadPollMs) {
476 lock.unlock();
477 usleep(kReadPollMs * 1000);
478 timeout_ms -= kReadPollMs;
479 continue;
480 } else {
481 LOG(DEBUG) << "Data " << total_read << "/" << bytes << " overflow "
482 << (kFmqReceiveTimeoutMs - timeout_ms) << " ms";
483 return total_read;
484 }
485 } while (total_read < bytes);
486 return total_read;
487 }
488
489 /***
490 *
491 * Other methods
492 *
493 ***/
494
ReportControlStatus(bool start_resp,BluetoothAudioStatus status)495 void BluetoothAudioSession::ReportControlStatus(bool start_resp,
496 BluetoothAudioStatus status) {
497 std::lock_guard<std::recursive_mutex> guard(mutex_);
498 if (observers_.empty()) {
499 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
500 << " has NO port state observer";
501 return;
502 }
503 for (auto& observer : observers_) {
504 uint16_t cookie = observer.first;
505 std::shared_ptr<PortStatusCallbacks> callback = observer.second;
506 LOG(INFO) << __func__ << " - status=" << toString(status)
507 << " for SessionType=" << toString(session_type_)
508 << ", bluetooth_audio=0x"
509 << ::android::base::StringPrintf("%04x", cookie)
510 << (start_resp ? " started" : " suspended");
511 callback->control_result_cb_(cookie, start_resp, status);
512 }
513 }
514
ReportLowLatencyModeAllowedChanged(bool allowed)515 void BluetoothAudioSession::ReportLowLatencyModeAllowedChanged(bool allowed) {
516 if (session_type_ != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
517 return;
518 }
519 std::lock_guard<std::recursive_mutex> guard(mutex_);
520 low_latency_allowed_ = allowed;
521 // TODO(b/294498919): Remove this after there is API to update latency mode
522 // after audio session started. If low_latency_allowed_ is true, the session
523 // can support LOW_LATENCY and FREE LatencyMode.
524 if (low_latency_allowed_) {
525 if (std::find(latency_modes_.begin(), latency_modes_.end(),
526 LatencyMode::LOW_LATENCY) == latency_modes_.end()) {
527 LOG(INFO) << __func__ << " - insert LOW_LATENCY LatencyMode";
528 latency_modes_.push_back(LatencyMode::LOW_LATENCY);
529 }
530 }
531 if (observers_.empty()) {
532 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
533 << " has NO port state observer";
534 return;
535 }
536 for (auto& observer : observers_) {
537 uint16_t cookie = observer.first;
538 std::shared_ptr<PortStatusCallbacks> callback = observer.second;
539 LOG(INFO) << __func__
540 << " - allowed=" << (allowed ? " allowed" : " disallowed");
541 if (callback->low_latency_mode_allowed_cb_ != nullptr) {
542 callback->low_latency_mode_allowed_cb_(cookie, allowed);
543 }
544 }
545 }
546
GetPresentationPosition(PresentationPosition & presentation_position)547 bool BluetoothAudioSession::GetPresentationPosition(
548 PresentationPosition& presentation_position) {
549 std::lock_guard<std::recursive_mutex> guard(mutex_);
550 if (!IsSessionReady()) {
551 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
552 << " has NO session";
553 return false;
554 }
555 if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) {
556 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
557 << toString(session_type_) << " failed";
558 return false;
559 }
560 return true;
561 }
562
UpdateSourceMetadata(const struct source_metadata & source_metadata)563 void BluetoothAudioSession::UpdateSourceMetadata(
564 const struct source_metadata& source_metadata) {
565 ssize_t track_count = source_metadata.track_count;
566 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
567 << track_count << " track(s)";
568 SourceMetadata hal_source_metadata;
569 hal_source_metadata.tracks.resize(track_count);
570 for (int i = 0; i < track_count; i++) {
571 hal_source_metadata.tracks[i].usage =
572 static_cast<media::audio::common::AudioUsage>(
573 source_metadata.tracks[i].usage);
574 hal_source_metadata.tracks[i].contentType =
575 static_cast<media::audio::common::AudioContentType>(
576 source_metadata.tracks[i].content_type);
577 hal_source_metadata.tracks[i].gain = source_metadata.tracks[i].gain;
578 LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_)
579 << ", usage=" << toString(hal_source_metadata.tracks[i].usage)
580 << ", content="
581 << toString(hal_source_metadata.tracks[i].contentType)
582 << ", gain=" << hal_source_metadata.tracks[i].gain;
583 }
584 UpdateSourceMetadata(hal_source_metadata);
585 }
586
UpdateSinkMetadata(const struct sink_metadata & sink_metadata)587 void BluetoothAudioSession::UpdateSinkMetadata(
588 const struct sink_metadata& sink_metadata) {
589 ssize_t track_count = sink_metadata.track_count;
590 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
591 << track_count << " track(s)";
592 SinkMetadata hal_sink_metadata;
593 hal_sink_metadata.tracks.resize(track_count);
594 for (int i = 0; i < track_count; i++) {
595 hal_sink_metadata.tracks[i].source =
596 static_cast<media::audio::common::AudioSource>(
597 sink_metadata.tracks[i].source);
598 hal_sink_metadata.tracks[i].gain = sink_metadata.tracks[i].gain;
599 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
600 << ", source=" << sink_metadata.tracks[i].source
601 << ", dest_device=" << sink_metadata.tracks[i].dest_device
602 << ", gain=" << sink_metadata.tracks[i].gain
603 << ", dest_device_address="
604 << sink_metadata.tracks[i].dest_device_address;
605 }
606 UpdateSinkMetadata(hal_sink_metadata);
607 }
608
UpdateSourceMetadata(const SourceMetadata & hal_source_metadata)609 bool BluetoothAudioSession::UpdateSourceMetadata(
610 const SourceMetadata& hal_source_metadata) {
611 std::lock_guard<std::recursive_mutex> guard(mutex_);
612 if (!IsSessionReady()) {
613 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
614 << " has NO session";
615 return false;
616 }
617
618 if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
619 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
620 session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
621 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
622 session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
623 session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH) {
624 return false;
625 }
626
627 auto hal_retval = stack_iface_->updateSourceMetadata(hal_source_metadata);
628 if (!hal_retval.isOk()) {
629 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
630 << toString(session_type_) << " failed";
631 return false;
632 }
633 return true;
634 }
635
UpdateSinkMetadata(const SinkMetadata & hal_sink_metadata)636 bool BluetoothAudioSession::UpdateSinkMetadata(
637 const SinkMetadata& hal_sink_metadata) {
638 std::lock_guard<std::recursive_mutex> guard(mutex_);
639 if (!IsSessionReady()) {
640 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
641 << " has NO session";
642 return false;
643 }
644
645 if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
646 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
647 session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
648 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
649 session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
650 session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH) {
651 return false;
652 }
653
654 auto hal_retval = stack_iface_->updateSinkMetadata(hal_sink_metadata);
655 if (!hal_retval.isOk()) {
656 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
657 << toString(session_type_) << " failed";
658 return false;
659 }
660 return true;
661 }
662
GetSupportedLatencyModes()663 std::vector<LatencyMode> BluetoothAudioSession::GetSupportedLatencyModes() {
664 std::lock_guard<std::recursive_mutex> guard(mutex_);
665 if (!IsSessionReady()) {
666 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
667 << " has NO session";
668 return std::vector<LatencyMode>();
669 }
670
671 if (com::android::btaudio::hal::flags::dsa_lea()) {
672 std::vector<LatencyMode> supported_latency_modes;
673 if (session_type_ ==
674 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
675 for (LatencyMode mode : latency_modes_) {
676 if (mode == LatencyMode::LOW_LATENCY) {
677 // LOW_LATENCY is not supported for LE_HARDWARE_OFFLOAD_ENC sessions
678 continue;
679 }
680 supported_latency_modes.push_back(mode);
681 }
682 } else {
683 for (LatencyMode mode : latency_modes_) {
684 if (!low_latency_allowed_ && mode == LatencyMode::LOW_LATENCY) {
685 // ignore LOW_LATENCY mode if Bluetooth stack doesn't allow
686 continue;
687 }
688 if (mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_SOFTWARE ||
689 mode == LatencyMode::DYNAMIC_SPATIAL_AUDIO_HARDWARE) {
690 // DSA_SW and DSA_HW only supported for LE_HARDWARE_OFFLOAD_ENC
691 // sessions
692 continue;
693 }
694 supported_latency_modes.push_back(mode);
695 }
696 }
697 LOG(DEBUG) << __func__ << " - Supported LatencyMode="
698 << toString(supported_latency_modes);
699 return supported_latency_modes;
700 }
701
702 if (low_latency_allowed_) return latency_modes_;
703 std::vector<LatencyMode> modes;
704 for (LatencyMode mode : latency_modes_) {
705 if (mode == LatencyMode::LOW_LATENCY)
706 // ignore those low latency mode if Bluetooth stack doesn't allow
707 continue;
708 modes.push_back(mode);
709 }
710 return modes;
711 }
712
SetLatencyMode(const LatencyMode & latency_mode)713 void BluetoothAudioSession::SetLatencyMode(const LatencyMode& latency_mode) {
714 std::lock_guard<std::recursive_mutex> guard(mutex_);
715 if (!IsSessionReady()) {
716 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
717 << " has NO session";
718 return;
719 }
720
721 auto hal_retval = stack_iface_->setLatencyMode(latency_mode);
722 if (!hal_retval.isOk()) {
723 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
724 << toString(session_type_) << " failed";
725 }
726 }
727
IsAidlAvailable()728 bool BluetoothAudioSession::IsAidlAvailable() {
729 if (is_aidl_checked) return is_aidl_available;
730 is_aidl_available =
731 (AServiceManager_checkService(
732 kDefaultAudioProviderFactoryInterface.c_str()) != nullptr);
733 is_aidl_checked = true;
734 return is_aidl_available;
735 }
736
737 /***
738 *
739 * BluetoothAudioSessionInstance
740 *
741 ***/
742 std::mutex BluetoothAudioSessionInstance::mutex_;
743 std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>>
744 BluetoothAudioSessionInstance::sessions_map_;
745
746 std::shared_ptr<BluetoothAudioSession>
GetSessionInstance(const SessionType & session_type)747 BluetoothAudioSessionInstance::GetSessionInstance(
748 const SessionType& session_type) {
749 std::lock_guard<std::mutex> guard(mutex_);
750
751 if (!sessions_map_.empty()) {
752 auto entry = sessions_map_.find(session_type);
753 if (entry != sessions_map_.end()) {
754 return entry->second;
755 }
756 }
757 std::shared_ptr<BluetoothAudioSession> session_ptr =
758 std::make_shared<BluetoothAudioSession>(session_type);
759 sessions_map_[session_type] = session_ptr;
760 return session_ptr;
761 }
762
763 } // namespace audio
764 } // namespace bluetooth
765 } // namespace hardware
766 } // namespace android
767 } // namespace aidl
768