blob: ee5527e62d41f96489f2fe32c2b6e3f5b18a36da [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:
Alice Kuoadcceec2022-03-28 13:28:43 +080095 case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
Josh Wu75462aa2022-01-21 21:51:21 -080096 return AudioConfiguration(CodecConfiguration{});
Josh Wu20bac522021-12-29 23:52:39 -080097 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
98 case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
Josh Wu75462aa2022-01-21 21:51:21 -080099 return AudioConfiguration(LeAudioConfiguration{});
Alice Kuoe80a5762022-02-09 14:44:29 +0800100 case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
101 return AudioConfiguration(LeAudioBroadcastConfiguration{});
Josh Wu20bac522021-12-29 23:52:39 -0800102 default:
Josh Wu75462aa2022-01-21 21:51:21 -0800103 return AudioConfiguration(PcmConfiguration{});
Josh Wu20bac522021-12-29 23:52:39 -0800104 }
105 }
106 return *audio_config_;
107}
108
109void BluetoothAudioSession::ReportAudioConfigChanged(
110 const AudioConfiguration& audio_config) {
111 if (session_type_ !=
112 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
113 session_type_ !=
Alice Kuo851ef342022-08-25 02:45:02 +0800114 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800115 return;
116 }
Alice Kuo851ef342022-08-25 02:45:02 +0800117
Josh Wu20bac522021-12-29 23:52:39 -0800118 std::lock_guard<std::recursive_mutex> guard(mutex_);
Alice Kuo851ef342022-08-25 02:45:02 +0800119 if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
120 LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
121 << toString(session_type_);
122 return;
123 }
124
Patty Huangf5b38af2023-03-23 23:19:00 +0800125 audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
Alice Kuo851ef342022-08-25 02:45:02 +0800126
Josh Wu20bac522021-12-29 23:52:39 -0800127 if (observers_.empty()) {
128 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
129 << " has NO port state observer";
130 return;
131 }
132 for (auto& observer : observers_) {
133 uint16_t cookie = observer.first;
134 std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
135 LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_)
136 << ", bluetooth_audio=0x"
137 << ::android::base::StringPrintf("%04x", cookie);
Patty Huangf5b38af2023-03-23 23:19:00 +0800138 if (cb->audio_configuration_changed_cb_ != nullptr) {
Josh Wu20bac522021-12-29 23:52:39 -0800139 cb->audio_configuration_changed_cb_(cookie);
140 }
141 }
142}
143
144bool BluetoothAudioSession::IsSessionReady() {
145 std::lock_guard<std::recursive_mutex> guard(mutex_);
146
147 bool is_mq_valid =
148 (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
149 session_type_ ==
150 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
151 session_type_ ==
152 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
Alice Kuoe80a5762022-02-09 14:44:29 +0800153 session_type_ ==
154 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
Alice Kuoadcceec2022-03-28 13:28:43 +0800155 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
Josh Wu20bac522021-12-29 23:52:39 -0800156 (data_mq_ != nullptr && data_mq_->isValid()));
Josh Wu75462aa2022-01-21 21:51:21 -0800157 return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
Josh Wu20bac522021-12-29 23:52:39 -0800158}
159
160/***
161 *
162 * Status callback methods
163 *
164 ***/
165
166uint16_t BluetoothAudioSession::RegisterStatusCback(
167 const PortStatusCallbacks& callbacks) {
168 std::lock_guard<std::recursive_mutex> guard(mutex_);
169 uint16_t cookie = ObserversCookieGetInitValue(session_type_);
170 uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_);
171
172 while (cookie < cookie_upper_bound) {
173 if (observers_.find(cookie) == observers_.end()) {
174 break;
175 }
176 ++cookie;
177 }
178 if (cookie >= cookie_upper_bound) {
179 LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
180 << " has " << observers_.size()
181 << " observers already (No Resource)";
182 return kObserversCookieUndefined;
183 }
184 std::shared_ptr<PortStatusCallbacks> cb =
185 std::make_shared<PortStatusCallbacks>();
186 *cb = callbacks;
187 observers_[cookie] = cb;
188 return cookie;
189}
190
191void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) {
192 std::lock_guard<std::recursive_mutex> guard(mutex_);
193 if (observers_.erase(cookie) != 1) {
194 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
195 << " no such provider=0x"
196 << ::android::base::StringPrintf("%04x", cookie);
197 }
198}
199
200/***
201 *
202 * Stream methods
203 *
204 ***/
205
Cheney Ni6ecbc762022-03-03 00:12:48 +0800206bool BluetoothAudioSession::StartStream(bool is_low_latency) {
Josh Wu20bac522021-12-29 23:52:39 -0800207 std::lock_guard<std::recursive_mutex> guard(mutex_);
208 if (!IsSessionReady()) {
209 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
210 << " has NO session";
211 return false;
212 }
Cheney Ni6ecbc762022-03-03 00:12:48 +0800213 auto hal_retval = stack_iface_->startStream(is_low_latency);
Josh Wu20bac522021-12-29 23:52:39 -0800214 if (!hal_retval.isOk()) {
215 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
216 << toString(session_type_) << " failed";
217 return false;
218 }
219 return true;
220}
221
222bool BluetoothAudioSession::SuspendStream() {
223 std::lock_guard<std::recursive_mutex> guard(mutex_);
224 if (!IsSessionReady()) {
225 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
226 << " has NO session";
227 return false;
228 }
229 auto hal_retval = stack_iface_->suspendStream();
230 if (!hal_retval.isOk()) {
231 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
232 << toString(session_type_) << " failed";
233 return false;
234 }
235 return true;
236}
237
238void BluetoothAudioSession::StopStream() {
239 std::lock_guard<std::recursive_mutex> guard(mutex_);
240 if (!IsSessionReady()) {
241 return;
242 }
243 auto hal_retval = stack_iface_->stopStream();
244 if (!hal_retval.isOk()) {
245 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
246 << toString(session_type_) << " failed";
247 }
248}
249
250/***
251 *
252 * Private methods
253 *
254 ***/
255
256bool BluetoothAudioSession::UpdateDataPath(const DataMQDesc* mq_desc) {
257 if (mq_desc == nullptr) {
258 // usecase of reset by nullptr
259 data_mq_ = nullptr;
260 return true;
261 }
262 std::unique_ptr<DataMQ> temp_mq;
263 temp_mq.reset(new DataMQ(*mq_desc));
264 if (!temp_mq || !temp_mq->isValid()) {
265 data_mq_ = nullptr;
266 return false;
267 }
268 data_mq_ = std::move(temp_mq);
269 return true;
270}
271
272bool BluetoothAudioSession::UpdateAudioConfig(
273 const AudioConfiguration& audio_config) {
274 bool is_software_session =
275 (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
276 session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
277 session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
Alice Kuoe80a5762022-02-09 14:44:29 +0800278 session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
279 session_type_ ==
Alice Kuoadcceec2022-03-28 13:28:43 +0800280 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
281 session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
Josh Wu20bac522021-12-29 23:52:39 -0800282 bool is_offload_a2dp_session =
Alice Kuoadcceec2022-03-28 13:28:43 +0800283 (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
284 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Alice Kuoee398a92022-07-10 23:59:18 +0800285 bool is_offload_le_audio_unicast_session =
Josh Wu20bac522021-12-29 23:52:39 -0800286 (session_type_ ==
287 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
288 session_type_ ==
289 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
Alice Kuoee398a92022-07-10 23:59:18 +0800290 bool is_offload_le_audio_broadcast_session =
291 (session_type_ ==
292 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
Josh Wu20bac522021-12-29 23:52:39 -0800293 auto audio_config_tag = audio_config.getTag();
294 bool is_software_audio_config =
295 (is_software_session &&
296 audio_config_tag == AudioConfiguration::pcmConfig);
297 bool is_a2dp_offload_audio_config =
298 (is_offload_a2dp_session &&
299 audio_config_tag == AudioConfiguration::a2dpConfig);
Alice Kuoee398a92022-07-10 23:59:18 +0800300 bool is_le_audio_offload_unicast_audio_config =
301 (is_offload_le_audio_unicast_session &&
Josh Wu20bac522021-12-29 23:52:39 -0800302 audio_config_tag == AudioConfiguration::leAudioConfig);
Alice Kuoee398a92022-07-10 23:59:18 +0800303 bool is_le_audio_offload_broadcast_audio_config =
304 (is_offload_le_audio_broadcast_session &&
305 audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
Josh Wu20bac522021-12-29 23:52:39 -0800306 if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
Alice Kuoee398a92022-07-10 23:59:18 +0800307 !is_le_audio_offload_unicast_audio_config &&
308 !is_le_audio_offload_broadcast_audio_config) {
Josh Wu20bac522021-12-29 23:52:39 -0800309 return false;
310 }
311 audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
312 return true;
313}
314
315void BluetoothAudioSession::ReportSessionStatus() {
316 // This is locked already by OnSessionStarted / OnSessionEnded
317 if (observers_.empty()) {
318 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
319 << " has NO port state observer";
320 return;
321 }
322 for (auto& observer : observers_) {
323 uint16_t cookie = observer.first;
324 std::shared_ptr<PortStatusCallbacks> callback = observer.second;
325 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
326 << " notify to bluetooth_audio=0x"
327 << ::android::base::StringPrintf("%04x", cookie);
328 callback->session_changed_cb_(cookie);
329 }
330}
331
332/***
333 *
334 * PCM methods
335 *
336 ***/
337
338size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
339 size_t bytes) {
340 if (buffer == nullptr || bytes <= 0) {
341 return 0;
342 }
343 size_t total_written = 0;
344 int timeout_ms = kFmqSendTimeoutMs;
345 do {
346 std::unique_lock<std::recursive_mutex> lock(mutex_);
347 if (!IsSessionReady()) {
348 break;
349 }
350 size_t num_bytes_to_write = data_mq_->availableToWrite();
351 if (num_bytes_to_write) {
352 if (num_bytes_to_write > (bytes - total_written)) {
353 num_bytes_to_write = bytes - total_written;
354 }
355
356 if (!data_mq_->write(
357 static_cast<const MQDataType*>(buffer) + total_written,
358 num_bytes_to_write)) {
359 LOG(ERROR) << "FMQ datapath writing " << total_written << "/" << bytes
360 << " failed";
361 return total_written;
362 }
363 total_written += num_bytes_to_write;
364 } else if (timeout_ms >= kWritePollMs) {
365 lock.unlock();
366 usleep(kWritePollMs * 1000);
367 timeout_ms -= kWritePollMs;
368 } else {
369 LOG(DEBUG) << "Data " << total_written << "/" << bytes << " overflow "
370 << (kFmqSendTimeoutMs - timeout_ms) << " ms";
371 return total_written;
372 }
373 } while (total_written < bytes);
374 return total_written;
375}
376
377size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
378 if (buffer == nullptr || bytes <= 0) {
379 return 0;
380 }
381 size_t total_read = 0;
382 int timeout_ms = kFmqReceiveTimeoutMs;
383 do {
384 std::unique_lock<std::recursive_mutex> lock(mutex_);
385 if (!IsSessionReady()) {
386 break;
387 }
388 size_t num_bytes_to_read = data_mq_->availableToRead();
389 if (num_bytes_to_read) {
390 if (num_bytes_to_read > (bytes - total_read)) {
391 num_bytes_to_read = bytes - total_read;
392 }
393 if (!data_mq_->read(static_cast<MQDataType*>(buffer) + total_read,
394 num_bytes_to_read)) {
395 LOG(ERROR) << "FMQ datapath reading " << total_read << "/" << bytes
396 << " failed";
397 return total_read;
398 }
399 total_read += num_bytes_to_read;
400 } else if (timeout_ms >= kReadPollMs) {
401 lock.unlock();
402 usleep(kReadPollMs * 1000);
403 timeout_ms -= kReadPollMs;
404 continue;
405 } else {
406 LOG(DEBUG) << "Data " << total_read << "/" << bytes << " overflow "
407 << (kFmqReceiveTimeoutMs - timeout_ms) << " ms";
408 return total_read;
409 }
410 } while (total_read < bytes);
411 return total_read;
412}
413
414/***
415 *
416 * Other methods
417 *
418 ***/
419
420void BluetoothAudioSession::ReportControlStatus(bool start_resp,
421 BluetoothAudioStatus status) {
422 std::lock_guard<std::recursive_mutex> guard(mutex_);
423 if (observers_.empty()) {
424 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
425 << " has NO port state observer";
426 return;
427 }
428 for (auto& observer : observers_) {
429 uint16_t cookie = observer.first;
430 std::shared_ptr<PortStatusCallbacks> callback = observer.second;
431 LOG(INFO) << __func__ << " - status=" << toString(status)
432 << " for SessionType=" << toString(session_type_)
433 << ", bluetooth_audio=0x"
434 << ::android::base::StringPrintf("%04x", cookie)
435 << (start_resp ? " started" : " suspended");
436 callback->control_result_cb_(cookie, start_resp, status);
437 }
438}
439
Chen Chen81f38e52022-02-09 13:27:35 -0800440void BluetoothAudioSession::ReportLowLatencyModeAllowedChanged(bool allowed) {
441 std::lock_guard<std::recursive_mutex> guard(mutex_);
Cheney Ni6ecbc762022-03-03 00:12:48 +0800442 low_latency_allowed_ = allowed;
Chen Chen81f38e52022-02-09 13:27:35 -0800443 if (observers_.empty()) {
444 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
445 << " has NO port state observer";
446 return;
447 }
448 for (auto& observer : observers_) {
449 uint16_t cookie = observer.first;
450 std::shared_ptr<PortStatusCallbacks> callback = observer.second;
Greg Kaiser42d931a2022-02-11 06:43:59 -0800451 LOG(INFO) << __func__
452 << " - allowed=" << (allowed ? " allowed" : " disallowed");
Chen Chen3b46c052022-03-14 13:16:44 -0700453 if (callback->low_latency_mode_allowed_cb_ != nullptr) {
454 callback->low_latency_mode_allowed_cb_(cookie, allowed);
455 }
Chen Chen81f38e52022-02-09 13:27:35 -0800456 }
457}
458
Josh Wu20bac522021-12-29 23:52:39 -0800459bool BluetoothAudioSession::GetPresentationPosition(
460 PresentationPosition& presentation_position) {
461 std::lock_guard<std::recursive_mutex> guard(mutex_);
462 if (!IsSessionReady()) {
463 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
464 << " has NO session";
465 return false;
466 }
467 bool retval = false;
468
469 if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) {
470 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
471 << toString(session_type_) << " failed";
472 return false;
473 }
474 return retval;
475}
476
477void BluetoothAudioSession::UpdateSourceMetadata(
478 const struct source_metadata& source_metadata) {
479 std::lock_guard<std::recursive_mutex> guard(mutex_);
480 if (!IsSessionReady()) {
481 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
482 << " has NO session";
483 return;
484 }
485
486 ssize_t track_count = source_metadata.track_count;
487 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
488 << track_count << " track(s)";
489 if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
Alice Kuoadcceec2022-03-28 13:28:43 +0800490 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
491 session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
492 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800493 return;
494 }
495
496 SourceMetadata hal_source_metadata;
497 hal_source_metadata.tracks.resize(track_count);
498 for (int i = 0; i < track_count; i++) {
499 hal_source_metadata.tracks[i].usage =
500 static_cast<media::audio::common::AudioUsage>(
501 source_metadata.tracks[i].usage);
502 hal_source_metadata.tracks[i].contentType =
503 static_cast<media::audio::common::AudioContentType>(
504 source_metadata.tracks[i].content_type);
505 hal_source_metadata.tracks[i].gain = source_metadata.tracks[i].gain;
506 LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_)
507 << ", usage=" << toString(hal_source_metadata.tracks[i].usage)
508 << ", content="
509 << toString(hal_source_metadata.tracks[i].contentType)
510 << ", gain=" << hal_source_metadata.tracks[i].gain;
511 }
512
513 auto hal_retval = stack_iface_->updateSourceMetadata(hal_source_metadata);
514 if (!hal_retval.isOk()) {
515 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
516 << toString(session_type_) << " failed";
517 }
518}
519
520void BluetoothAudioSession::UpdateSinkMetadata(
521 const struct sink_metadata& sink_metadata) {
522 std::lock_guard<std::recursive_mutex> guard(mutex_);
523 if (!IsSessionReady()) {
524 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
525 << " has NO session";
526 return;
527 }
528
529 ssize_t track_count = sink_metadata.track_count;
530 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
531 << track_count << " track(s)";
532 if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
Alice Kuoadcceec2022-03-28 13:28:43 +0800533 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
534 session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
535 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800536 return;
537 }
538
539 SinkMetadata hal_sink_metadata;
540 hal_sink_metadata.tracks.resize(track_count);
541 for (int i = 0; i < track_count; i++) {
542 hal_sink_metadata.tracks[i].source =
543 static_cast<media::audio::common::AudioSource>(
544 sink_metadata.tracks[i].source);
545 hal_sink_metadata.tracks[i].gain = sink_metadata.tracks[i].gain;
546 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
547 << ", source=" << sink_metadata.tracks[i].source
548 << ", dest_device=" << sink_metadata.tracks[i].dest_device
549 << ", gain=" << sink_metadata.tracks[i].gain
550 << ", dest_device_address="
551 << sink_metadata.tracks[i].dest_device_address;
552 }
553
554 auto hal_retval = stack_iface_->updateSinkMetadata(hal_sink_metadata);
555 if (!hal_retval.isOk()) {
556 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
557 << toString(session_type_) << " failed";
558 }
559}
560
Cheney Ni6ecbc762022-03-03 00:12:48 +0800561std::vector<LatencyMode> BluetoothAudioSession::GetSupportedLatencyModes() {
562 std::lock_guard<std::recursive_mutex> guard(mutex_);
563 if (!IsSessionReady()) {
564 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
565 << " has NO session";
566 return std::vector<LatencyMode>();
567 }
568 if (low_latency_allowed_) return latency_modes_;
569 std::vector<LatencyMode> modes;
570 for (LatencyMode mode : latency_modes_) {
571 if (mode == LatencyMode::LOW_LATENCY)
572 // ignore those low latency mode if Bluetooth stack doesn't allow
573 continue;
574 modes.push_back(mode);
575 }
576 return modes;
577}
578
579void BluetoothAudioSession::SetLatencyMode(const LatencyMode& latency_mode) {
Chen Chena4c4c612022-02-07 18:01:05 -0800580 std::lock_guard<std::recursive_mutex> guard(mutex_);
581 if (!IsSessionReady()) {
582 LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
583 << " has NO session";
584 return;
585 }
586
587 auto hal_retval = stack_iface_->setLatencyMode(latency_mode);
588 if (!hal_retval.isOk()) {
589 LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
590 << toString(session_type_) << " failed";
591 }
592}
593
Josh Wu20bac522021-12-29 23:52:39 -0800594bool BluetoothAudioSession::IsAidlAvailable() {
595 if (is_aidl_checked) return is_aidl_available;
596 is_aidl_available =
597 (AServiceManager_checkService(
598 kDefaultAudioProviderFactoryInterface.c_str()) != nullptr);
599 is_aidl_checked = true;
600 return is_aidl_available;
601}
602
603/***
604 *
605 * BluetoothAudioSessionInstance
606 *
607 ***/
608std::mutex BluetoothAudioSessionInstance::mutex_;
609std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>>
610 BluetoothAudioSessionInstance::sessions_map_;
611
612std::shared_ptr<BluetoothAudioSession>
613BluetoothAudioSessionInstance::GetSessionInstance(
614 const SessionType& session_type) {
615 std::lock_guard<std::mutex> guard(mutex_);
616
617 if (!sessions_map_.empty()) {
618 auto entry = sessions_map_.find(session_type);
619 if (entry != sessions_map_.end()) {
620 return entry->second;
621 }
622 }
623 std::shared_ptr<BluetoothAudioSession> session_ptr =
624 std::make_shared<BluetoothAudioSession>(session_type);
625 sessions_map_[session_type] = session_ptr;
626 return session_ptr;
627}
628
629} // namespace audio
630} // namespace bluetooth
631} // namespace hardware
632} // namespace android
Greg Kaiser42d931a2022-02-11 06:43:59 -0800633} // namespace aidl