blob: cdee520b1197258370bad15c236d8e3bd0593365 [file] [log] [blame]
Josh Wu20bac522021-12-29 23:52:39 -08001/*
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
24#include "BluetoothAudioSession.h"
25
26namespace aidl {
27namespace android {
28namespace hardware {
29namespace bluetooth {
30namespace audio {
31
32static constexpr int kFmqSendTimeoutMs = 1000; // 1000 ms timeout for sending
33static constexpr int kFmqReceiveTimeoutMs =
34 1000; // 1000 ms timeout for receiving
35static constexpr int kWritePollMs = 1; // polled non-blocking interval
36static constexpr int kReadPollMs = 1; // polled non-blocking interval
37
Josh Wu20bac522021-12-29 23:52:39 -080038BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type)
Josh Wu75462aa2022-01-21 21:51:21 -080039 : session_type_(session_type), stack_iface_(nullptr), data_mq_(nullptr) {}
Josh Wu20bac522021-12-29 23:52:39 -080040
41/***
42 *
43 * Callback methods
44 *
45 ***/
46
47void BluetoothAudioSession::OnSessionStarted(
48 const std::shared_ptr<IBluetoothAudioPort> stack_iface,
Cheney Ni6ecbc762022-03-03 00:12:48 +080049 const DataMQDesc* mq_desc, const AudioConfiguration& audio_config,
50 const std::vector<LatencyMode>& latency_modes) {
Josh Wu20bac522021-12-29 23:52:39 -080051 std::lock_guard<std::recursive_mutex> guard(mutex_);
52 if (stack_iface == nullptr) {
53 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
54 << ", IBluetoothAudioPort Invalid";
55 } else if (!UpdateAudioConfig(audio_config)) {
56 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
57 << ", AudioConfiguration=" << audio_config.toString()
58 << " Invalid";
59 } else if (!UpdateDataPath(mq_desc)) {
60 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
61 << " MqDescriptor Invalid";
Josh Wu75462aa2022-01-21 21:51:21 -080062 audio_config_ = nullptr;
Josh Wu20bac522021-12-29 23:52:39 -080063 } else {
64 stack_iface_ = stack_iface;
Cheney Ni6ecbc762022-03-03 00:12:48 +080065 latency_modes_ = latency_modes;
Josh Wu20bac522021-12-29 23:52:39 -080066 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
67 << ", AudioConfiguration=" << audio_config.toString();
68 ReportSessionStatus();
69 }
70}
71
72void BluetoothAudioSession::OnSessionEnded() {
73 std::lock_guard<std::recursive_mutex> guard(mutex_);
74 bool toggled = IsSessionReady();
75 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
Josh Wu75462aa2022-01-21 21:51:21 -080076 audio_config_ = nullptr;
Josh Wu20bac522021-12-29 23:52:39 -080077 stack_iface_ = nullptr;
78 UpdateDataPath(nullptr);
79 if (toggled) {
80 ReportSessionStatus();
81 }
82}
83
84/***
85 *
86 * Util methods
87 *
88 ***/
89
Josh Wu75462aa2022-01-21 21:51:21 -080090const AudioConfiguration BluetoothAudioSession::GetAudioConfig() {
Josh Wu20bac522021-12-29 23:52:39 -080091 std::lock_guard<std::recursive_mutex> guard(mutex_);
92 if (!IsSessionReady()) {
Josh Wu20bac522021-12-29 23:52:39 -080093 switch (session_type_) {
94 case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
Josh Wu75462aa2022-01-21 21:51:21 -080095 return AudioConfiguration(CodecConfiguration{});
Josh Wu20bac522021-12-29 23:52:39 -080096 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
97 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
Josh Wu75462aa2022-01-21 21:51:21 -080098 return AudioConfiguration(LeAudioConfiguration{});
Alice Kuoe80a5762022-02-09 14:44:29 +080099 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
100 return AudioConfiguration(LeAudioBroadcastConfiguration{});
Josh Wu20bac522021-12-29 23:52:39 -0800101 default:
Josh Wu75462aa2022-01-21 21:51:21 -0800102 return AudioConfiguration(PcmConfiguration{});
Josh Wu20bac522021-12-29 23:52:39 -0800103 }
104 }
105 return *audio_config_;
106}
107
108void BluetoothAudioSession::ReportAudioConfigChanged(
109 const AudioConfiguration& audio_config) {
110 if (session_type_ !=
111 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
112 session_type_ !=
113 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
114 return;
115 }
116 std::lock_guard<std::recursive_mutex> guard(mutex_);
117 audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
118 if (observers_.empty()) {
119 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
120 << " has NO port state observer";
121 return;
122 }
123 for (auto& observer : observers_) {
124 uint16_t cookie = observer.first;
125 std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
126 LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_)
127 << ", bluetooth_audio=0x"
128 << ::android::base::StringPrintf("%04x", cookie);
129 if (cb->audio_configuration_changed_cb_ != nullptr) {
130 cb->audio_configuration_changed_cb_(cookie);
131 }
132 }
133}
134
135bool BluetoothAudioSession::IsSessionReady() {
136 std::lock_guard<std::recursive_mutex> guard(mutex_);
137
138 bool is_mq_valid =
139 (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
140 session_type_ ==
141 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
142 session_type_ ==
143 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
Alice Kuoe80a5762022-02-09 14:44:29 +0800144 session_type_ ==
145 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
Josh Wu20bac522021-12-29 23:52:39 -0800146 (data_mq_ != nullptr && data_mq_->isValid()));
Josh Wu75462aa2022-01-21 21:51:21 -0800147 return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
Josh Wu20bac522021-12-29 23:52:39 -0800148}
149
150/***
151 *
152 * Status callback methods
153 *
154 ***/
155
156uint16_t BluetoothAudioSession::RegisterStatusCback(
157 const PortStatusCallbacks& callbacks) {
158 std::lock_guard<std::recursive_mutex> guard(mutex_);
159 uint16_t cookie = ObserversCookieGetInitValue(session_type_);
160 uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_);
161
162 while (cookie < cookie_upper_bound) {
163 if (observers_.find(cookie) == observers_.end()) {
164 break;
165 }
166 ++cookie;
167 }
168 if (cookie >= cookie_upper_bound) {
169 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
170 << " has " << observers_.size()
171 << " observers already (No Resource)";
172 return kObserversCookieUndefined;
173 }
174 std::shared_ptr<PortStatusCallbacks> cb =
175 std::make_shared<PortStatusCallbacks>();
176 *cb = callbacks;
177 observers_[cookie] = cb;
178 return cookie;
179}
180
181void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) {
182 std::lock_guard<std::recursive_mutex> guard(mutex_);
183 if (observers_.erase(cookie) != 1) {
184 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
185 << " no such provider=0x"
186 << ::android::base::StringPrintf("%04x", cookie);
187 }
188}
189
190/***
191 *
192 * Stream methods
193 *
194 ***/
195
Cheney Ni6ecbc762022-03-03 00:12:48 +0800196bool BluetoothAudioSession::StartStream(bool is_low_latency) {
Josh Wu20bac522021-12-29 23:52:39 -0800197 std::lock_guard<std::recursive_mutex> guard(mutex_);
198 if (!IsSessionReady()) {
199 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
200 << " has NO session";
201 return false;
202 }
Cheney Ni6ecbc762022-03-03 00:12:48 +0800203 auto hal_retval = stack_iface_->startStream(is_low_latency);
Josh Wu20bac522021-12-29 23:52:39 -0800204 if (!hal_retval.isOk()) {
205 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
206 << toString(session_type_) << " failed";
207 return false;
208 }
209 return true;
210}
211
212bool BluetoothAudioSession::SuspendStream() {
213 std::lock_guard<std::recursive_mutex> guard(mutex_);
214 if (!IsSessionReady()) {
215 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
216 << " has NO session";
217 return false;
218 }
219 auto hal_retval = stack_iface_->suspendStream();
220 if (!hal_retval.isOk()) {
221 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
222 << toString(session_type_) << " failed";
223 return false;
224 }
225 return true;
226}
227
228void BluetoothAudioSession::StopStream() {
229 std::lock_guard<std::recursive_mutex> guard(mutex_);
230 if (!IsSessionReady()) {
231 return;
232 }
233 auto hal_retval = stack_iface_->stopStream();
234 if (!hal_retval.isOk()) {
235 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
236 << toString(session_type_) << " failed";
237 }
238}
239
240/***
241 *
242 * Private methods
243 *
244 ***/
245
246bool BluetoothAudioSession::UpdateDataPath(const DataMQDesc* mq_desc) {
247 if (mq_desc == nullptr) {
248 // usecase of reset by nullptr
249 data_mq_ = nullptr;
250 return true;
251 }
252 std::unique_ptr<DataMQ> temp_mq;
253 temp_mq.reset(new DataMQ(*mq_desc));
254 if (!temp_mq || !temp_mq->isValid()) {
255 data_mq_ = nullptr;
256 return false;
257 }
258 data_mq_ = std::move(temp_mq);
259 return true;
260}
261
262bool BluetoothAudioSession::UpdateAudioConfig(
263 const AudioConfiguration& audio_config) {
264 bool is_software_session =
265 (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
266 session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
267 session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
Alice Kuoe80a5762022-02-09 14:44:29 +0800268 session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
269 session_type_ ==
270 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
Josh Wu20bac522021-12-29 23:52:39 -0800271 bool is_offload_a2dp_session =
272 (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
273 bool is_offload_le_audio_session =
274 (session_type_ ==
275 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
276 session_type_ ==
277 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
278 auto audio_config_tag = audio_config.getTag();
279 bool is_software_audio_config =
280 (is_software_session &&
281 audio_config_tag == AudioConfiguration::pcmConfig);
282 bool is_a2dp_offload_audio_config =
283 (is_offload_a2dp_session &&
284 audio_config_tag == AudioConfiguration::a2dpConfig);
285 bool is_le_audio_offload_audio_config =
286 (is_offload_le_audio_session &&
287 audio_config_tag == AudioConfiguration::leAudioConfig);
288 if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
289 !is_le_audio_offload_audio_config) {
290 return false;
291 }
292 audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
293 return true;
294}
295
296void BluetoothAudioSession::ReportSessionStatus() {
297 // This is locked already by OnSessionStarted / OnSessionEnded
298 if (observers_.empty()) {
299 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
300 << " has NO port state observer";
301 return;
302 }
303 for (auto& observer : observers_) {
304 uint16_t cookie = observer.first;
305 std::shared_ptr<PortStatusCallbacks> callback = observer.second;
306 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
307 << " notify to bluetooth_audio=0x"
308 << ::android::base::StringPrintf("%04x", cookie);
309 callback->session_changed_cb_(cookie);
310 }
311}
312
313/***
314 *
315 * PCM methods
316 *
317 ***/
318
319size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
320 size_t bytes) {
321 if (buffer == nullptr || bytes <= 0) {
322 return 0;
323 }
324 size_t total_written = 0;
325 int timeout_ms = kFmqSendTimeoutMs;
326 do {
327 std::unique_lock<std::recursive_mutex> lock(mutex_);
328 if (!IsSessionReady()) {
329 break;
330 }
331 size_t num_bytes_to_write = data_mq_->availableToWrite();
332 if (num_bytes_to_write) {
333 if (num_bytes_to_write > (bytes - total_written)) {
334 num_bytes_to_write = bytes - total_written;
335 }
336
337 if (!data_mq_->write(
338 static_cast<const MQDataType*>(buffer) + total_written,
339 num_bytes_to_write)) {
340 LOG(ERROR) << "FMQ datapath writing " << total_written << "/" << bytes
341 << " failed";
342 return total_written;
343 }
344 total_written += num_bytes_to_write;
345 } else if (timeout_ms >= kWritePollMs) {
346 lock.unlock();
347 usleep(kWritePollMs * 1000);
348 timeout_ms -= kWritePollMs;
349 } else {
350 LOG(DEBUG) << "Data " << total_written << "/" << bytes << " overflow "
351 << (kFmqSendTimeoutMs - timeout_ms) << " ms";
352 return total_written;
353 }
354 } while (total_written < bytes);
355 return total_written;
356}
357
358size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
359 if (buffer == nullptr || bytes <= 0) {
360 return 0;
361 }
362 size_t total_read = 0;
363 int timeout_ms = kFmqReceiveTimeoutMs;
364 do {
365 std::unique_lock<std::recursive_mutex> lock(mutex_);
366 if (!IsSessionReady()) {
367 break;
368 }
369 size_t num_bytes_to_read = data_mq_->availableToRead();
370 if (num_bytes_to_read) {
371 if (num_bytes_to_read > (bytes - total_read)) {
372 num_bytes_to_read = bytes - total_read;
373 }
374 if (!data_mq_->read(static_cast<MQDataType*>(buffer) + total_read,
375 num_bytes_to_read)) {
376 LOG(ERROR) << "FMQ datapath reading " << total_read << "/" << bytes
377 << " failed";
378 return total_read;
379 }
380 total_read += num_bytes_to_read;
381 } else if (timeout_ms >= kReadPollMs) {
382 lock.unlock();
383 usleep(kReadPollMs * 1000);
384 timeout_ms -= kReadPollMs;
385 continue;
386 } else {
387 LOG(DEBUG) << "Data " << total_read << "/" << bytes << " overflow "
388 << (kFmqReceiveTimeoutMs - timeout_ms) << " ms";
389 return total_read;
390 }
391 } while (total_read < bytes);
392 return total_read;
393}
394
395/***
396 *
397 * Other methods
398 *
399 ***/
400
401void BluetoothAudioSession::ReportControlStatus(bool start_resp,
402 BluetoothAudioStatus status) {
403 std::lock_guard<std::recursive_mutex> guard(mutex_);
404 if (observers_.empty()) {
405 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
406 << " has NO port state observer";
407 return;
408 }
409 for (auto& observer : observers_) {
410 uint16_t cookie = observer.first;
411 std::shared_ptr<PortStatusCallbacks> callback = observer.second;
412 LOG(INFO) << __func__ << " - status=" << toString(status)
413 << " for SessionType=" << toString(session_type_)
414 << ", bluetooth_audio=0x"
415 << ::android::base::StringPrintf("%04x", cookie)
416 << (start_resp ? " started" : " suspended");
417 callback->control_result_cb_(cookie, start_resp, status);
418 }
419}
420
Chen Chen81f38e52022-02-09 13:27:35 -0800421void BluetoothAudioSession::ReportLowLatencyModeAllowedChanged(bool allowed) {
422 std::lock_guard<std::recursive_mutex> guard(mutex_);
Cheney Ni6ecbc762022-03-03 00:12:48 +0800423 low_latency_allowed_ = allowed;
Chen Chen81f38e52022-02-09 13:27:35 -0800424 if (observers_.empty()) {
425 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
426 << " has NO port state observer";
427 return;
428 }
429 for (auto& observer : observers_) {
430 uint16_t cookie = observer.first;
431 std::shared_ptr<PortStatusCallbacks> callback = observer.second;
Greg Kaiser42d931a2022-02-11 06:43:59 -0800432 LOG(INFO) << __func__
433 << " - allowed=" << (allowed ? " allowed" : " disallowed");
Chen Chen3b46c052022-03-14 13:16:44 -0700434 if (callback->low_latency_mode_allowed_cb_ != nullptr) {
435 callback->low_latency_mode_allowed_cb_(cookie, allowed);
436 }
Chen Chen81f38e52022-02-09 13:27:35 -0800437 }
438}
439
Josh Wu20bac522021-12-29 23:52:39 -0800440bool BluetoothAudioSession::GetPresentationPosition(
441 PresentationPosition& presentation_position) {
442 std::lock_guard<std::recursive_mutex> guard(mutex_);
443 if (!IsSessionReady()) {
444 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
445 << " has NO session";
446 return false;
447 }
448 bool retval = false;
449
450 if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) {
451 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
452 << toString(session_type_) << " failed";
453 return false;
454 }
455 return retval;
456}
457
458void BluetoothAudioSession::UpdateSourceMetadata(
459 const struct source_metadata& source_metadata) {
460 std::lock_guard<std::recursive_mutex> guard(mutex_);
461 if (!IsSessionReady()) {
462 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
463 << " has NO session";
464 return;
465 }
466
467 ssize_t track_count = source_metadata.track_count;
468 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
469 << track_count << " track(s)";
470 if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
471 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
472 return;
473 }
474
475 SourceMetadata hal_source_metadata;
476 hal_source_metadata.tracks.resize(track_count);
477 for (int i = 0; i < track_count; i++) {
478 hal_source_metadata.tracks[i].usage =
479 static_cast<media::audio::common::AudioUsage>(
480 source_metadata.tracks[i].usage);
481 hal_source_metadata.tracks[i].contentType =
482 static_cast<media::audio::common::AudioContentType>(
483 source_metadata.tracks[i].content_type);
484 hal_source_metadata.tracks[i].gain = source_metadata.tracks[i].gain;
485 LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_)
486 << ", usage=" << toString(hal_source_metadata.tracks[i].usage)
487 << ", content="
488 << toString(hal_source_metadata.tracks[i].contentType)
489 << ", gain=" << hal_source_metadata.tracks[i].gain;
490 }
491
492 auto hal_retval = stack_iface_->updateSourceMetadata(hal_source_metadata);
493 if (!hal_retval.isOk()) {
494 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
495 << toString(session_type_) << " failed";
496 }
497}
498
499void BluetoothAudioSession::UpdateSinkMetadata(
500 const struct sink_metadata& sink_metadata) {
501 std::lock_guard<std::recursive_mutex> guard(mutex_);
502 if (!IsSessionReady()) {
503 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
504 << " has NO session";
505 return;
506 }
507
508 ssize_t track_count = sink_metadata.track_count;
509 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
510 << track_count << " track(s)";
511 if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
512 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
513 return;
514 }
515
516 SinkMetadata hal_sink_metadata;
517 hal_sink_metadata.tracks.resize(track_count);
518 for (int i = 0; i < track_count; i++) {
519 hal_sink_metadata.tracks[i].source =
520 static_cast<media::audio::common::AudioSource>(
521 sink_metadata.tracks[i].source);
522 hal_sink_metadata.tracks[i].gain = sink_metadata.tracks[i].gain;
523 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
524 << ", source=" << sink_metadata.tracks[i].source
525 << ", dest_device=" << sink_metadata.tracks[i].dest_device
526 << ", gain=" << sink_metadata.tracks[i].gain
527 << ", dest_device_address="
528 << sink_metadata.tracks[i].dest_device_address;
529 }
530
531 auto hal_retval = stack_iface_->updateSinkMetadata(hal_sink_metadata);
532 if (!hal_retval.isOk()) {
533 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
534 << toString(session_type_) << " failed";
535 }
536}
537
Cheney Ni6ecbc762022-03-03 00:12:48 +0800538std::vector<LatencyMode> BluetoothAudioSession::GetSupportedLatencyModes() {
539 std::lock_guard<std::recursive_mutex> guard(mutex_);
540 if (!IsSessionReady()) {
541 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
542 << " has NO session";
543 return std::vector<LatencyMode>();
544 }
545 if (low_latency_allowed_) return latency_modes_;
546 std::vector<LatencyMode> modes;
547 for (LatencyMode mode : latency_modes_) {
548 if (mode == LatencyMode::LOW_LATENCY)
549 // ignore those low latency mode if Bluetooth stack doesn't allow
550 continue;
551 modes.push_back(mode);
552 }
553 return modes;
554}
555
556void BluetoothAudioSession::SetLatencyMode(const LatencyMode& latency_mode) {
Chen Chena4c4c612022-02-07 18:01:05 -0800557 std::lock_guard<std::recursive_mutex> guard(mutex_);
558 if (!IsSessionReady()) {
559 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
560 << " has NO session";
561 return;
562 }
563
564 auto hal_retval = stack_iface_->setLatencyMode(latency_mode);
565 if (!hal_retval.isOk()) {
566 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
567 << toString(session_type_) << " failed";
568 }
569}
570
Josh Wu20bac522021-12-29 23:52:39 -0800571bool BluetoothAudioSession::IsAidlAvailable() {
572 if (is_aidl_checked) return is_aidl_available;
573 is_aidl_available =
574 (AServiceManager_checkService(
575 kDefaultAudioProviderFactoryInterface.c_str()) != nullptr);
576 is_aidl_checked = true;
577 return is_aidl_available;
578}
579
580/***
581 *
582 * BluetoothAudioSessionInstance
583 *
584 ***/
585std::mutex BluetoothAudioSessionInstance::mutex_;
586std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>>
587 BluetoothAudioSessionInstance::sessions_map_;
588
589std::shared_ptr<BluetoothAudioSession>
590BluetoothAudioSessionInstance::GetSessionInstance(
591 const SessionType& session_type) {
592 std::lock_guard<std::mutex> guard(mutex_);
593
594 if (!sessions_map_.empty()) {
595 auto entry = sessions_map_.find(session_type);
596 if (entry != sessions_map_.end()) {
597 return entry->second;
598 }
599 }
600 std::shared_ptr<BluetoothAudioSession> session_ptr =
601 std::make_shared<BluetoothAudioSession>(session_type);
602 sessions_map_[session_type] = session_ptr;
603 return session_ptr;
604}
605
606} // namespace audio
607} // namespace bluetooth
608} // namespace hardware
609} // namespace android
Greg Kaiser42d931a2022-02-11 06:43:59 -0800610} // namespace aidl