1 /*
2 * Copyright 2023 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 "AHAL_BluetoothPortProxy"
18
19 #include <android-base/logging.h>
20 #include <android-base/stringprintf.h>
21 #include <audio_utils/primitives.h>
22 #include <inttypes.h>
23 #include <log/log.h>
24
25 #include "core-impl/DevicePortProxy.h"
26
27 namespace android::bluetooth::audio::aidl {
28
29 namespace {
30
31 // The maximum time to wait in std::condition_variable::wait_for()
32 constexpr unsigned int kMaxWaitingTimeMs = 4500;
33
34 } // namespace
35
36 using ::aidl::android::hardware::audio::common::SinkMetadata;
37 using ::aidl::android::hardware::audio::common::SourceMetadata;
38 using ::aidl::android::hardware::bluetooth::audio::AudioConfiguration;
39 using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioSessionControl;
40 using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioStatus;
41 using ::aidl::android::hardware::bluetooth::audio::ChannelMode;
42 using ::aidl::android::hardware::bluetooth::audio::PcmConfiguration;
43 using ::aidl::android::hardware::bluetooth::audio::PortStatusCallbacks;
44 using ::aidl::android::hardware::bluetooth::audio::PresentationPosition;
45 using ::aidl::android::hardware::bluetooth::audio::SessionType;
46 using ::aidl::android::media::audio::common::AudioDeviceDescription;
47 using ::aidl::android::media::audio::common::AudioDeviceType;
48 using ::android::base::StringPrintf;
49
operator <<(std::ostream & os,const BluetoothStreamState & state)50 std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state) {
51 switch (state) {
52 case BluetoothStreamState::DISABLED:
53 return os << "DISABLED";
54 case BluetoothStreamState::STANDBY:
55 return os << "STANDBY";
56 case BluetoothStreamState::STARTING:
57 return os << "STARTING";
58 case BluetoothStreamState::STARTED:
59 return os << "STARTED";
60 case BluetoothStreamState::SUSPENDING:
61 return os << "SUSPENDING";
62 case BluetoothStreamState::UNKNOWN:
63 return os << "UNKNOWN";
64 default:
65 return os << android::base::StringPrintf("%#hhx", state);
66 }
67 }
68
BluetoothAudioPortAidl()69 BluetoothAudioPortAidl::BluetoothAudioPortAidl()
70 : mCookie(::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined),
71 mState(BluetoothStreamState::DISABLED),
72 mSessionType(SessionType::UNKNOWN) {}
73
~BluetoothAudioPortAidl()74 BluetoothAudioPortAidl::~BluetoothAudioPortAidl() {
75 unregisterPort();
76 }
77
registerPort(const AudioDeviceDescription & description)78 bool BluetoothAudioPortAidl::registerPort(const AudioDeviceDescription& description) {
79 if (inUse()) {
80 LOG(ERROR) << __func__ << debugMessage() << " already in use";
81 return false;
82 }
83
84 if (!initSessionType(description)) return false;
85
86 auto control_result_cb = [port = this](uint16_t cookie, bool start_resp,
87 const BluetoothAudioStatus& status) {
88 (void)start_resp;
89 port->controlResultHandler(cookie, status);
90 };
91 auto session_changed_cb = [port = this](uint16_t cookie) {
92 port->sessionChangedHandler(cookie);
93 };
94 // TODO: Add audio_config_changed_cb
95 PortStatusCallbacks cbacks = {
96 .control_result_cb_ = control_result_cb,
97 .session_changed_cb_ = session_changed_cb,
98 };
99 mCookie = BluetoothAudioSessionControl::RegisterControlResultCback(mSessionType, cbacks);
100 auto isOk = (mCookie != ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined);
101 if (isOk) {
102 std::lock_guard guard(mCvMutex);
103 mState = BluetoothStreamState::STANDBY;
104 }
105 LOG(DEBUG) << __func__ << debugMessage();
106 return isOk;
107 }
108
initSessionType(const AudioDeviceDescription & description)109 bool BluetoothAudioPortAidl::initSessionType(const AudioDeviceDescription& description) {
110 if (description.connection == AudioDeviceDescription::CONNECTION_BT_A2DP &&
111 (description.type == AudioDeviceType::OUT_DEVICE ||
112 description.type == AudioDeviceType::OUT_HEADPHONE ||
113 description.type == AudioDeviceType::OUT_SPEAKER)) {
114 LOG(VERBOSE) << __func__
115 << ": device=AUDIO_DEVICE_OUT_BLUETOOTH_A2DP (HEADPHONES/SPEAKER) ("
116 << description.toString() << ")";
117 mSessionType = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
118 } else if (description.connection == AudioDeviceDescription::CONNECTION_WIRELESS &&
119 description.type == AudioDeviceType::OUT_HEARING_AID) {
120 LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_HEARING_AID (MEDIA/VOICE) ("
121 << description.toString() << ")";
122 mSessionType = SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
123 } else if (description.connection == AudioDeviceDescription::CONNECTION_BT_LE &&
124 description.type == AudioDeviceType::OUT_HEADSET) {
125 LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_BLE_HEADSET (MEDIA/VOICE) ("
126 << description.toString() << ")";
127 mSessionType = SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
128 } else if (description.connection == AudioDeviceDescription::CONNECTION_BT_LE &&
129 description.type == AudioDeviceType::OUT_SPEAKER) {
130 LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_BLE_SPEAKER (MEDIA) ("
131 << description.toString() << ")";
132 mSessionType = SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
133 } else if (description.connection == AudioDeviceDescription::CONNECTION_BT_LE &&
134 description.type == AudioDeviceType::IN_HEADSET) {
135 LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_IN_BLE_HEADSET (VOICE) ("
136 << description.toString() << ")";
137 mSessionType = SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH;
138 } else if (description.connection == AudioDeviceDescription::CONNECTION_BT_LE &&
139 description.type == AudioDeviceType::OUT_BROADCAST) {
140 LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_BLE_BROADCAST (MEDIA) ("
141 << description.toString() << ")";
142 mSessionType = SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH;
143 } else {
144 LOG(ERROR) << __func__ << ": unknown device=" << description.toString();
145 return false;
146 }
147
148 if (!BluetoothAudioSessionControl::IsSessionReady(mSessionType)) {
149 LOG(ERROR) << __func__ << ": device=" << description.toString()
150 << ", session_type=" << toString(mSessionType) << " is not ready";
151 return false;
152 }
153 return true;
154 }
155
unregisterPort()156 void BluetoothAudioPortAidl::unregisterPort() {
157 if (!inUse()) {
158 LOG(WARNING) << __func__ << ": BluetoothAudioPortAidl is not in use";
159 return;
160 }
161 BluetoothAudioSessionControl::UnregisterControlResultCback(mSessionType, mCookie);
162 mCookie = ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined;
163 LOG(VERBOSE) << __func__ << debugMessage() << " port unregistered";
164 }
165
controlResultHandler(uint16_t cookie,const BluetoothAudioStatus & status)166 void BluetoothAudioPortAidl::controlResultHandler(uint16_t cookie,
167 const BluetoothAudioStatus& status) {
168 std::lock_guard guard(mCvMutex);
169 if (!inUse()) {
170 LOG(ERROR) << "control_result_cb: BluetoothAudioPortAidl is not in use";
171 return;
172 }
173 if (mCookie != cookie) {
174 LOG(ERROR) << "control_result_cb: proxy of device port (cookie="
175 << StringPrintf("%#hx", cookie) << ") is corrupted";
176 return;
177 }
178 BluetoothStreamState previous_state = mState;
179 LOG(INFO) << "control_result_cb:" << debugMessage() << ", previous_state=" << previous_state
180 << ", status=" << toString(status);
181
182 switch (previous_state) {
183 case BluetoothStreamState::STARTED:
184 /* Only Suspend signal can be send in STARTED state*/
185 if (status == BluetoothAudioStatus::RECONFIGURATION ||
186 status == BluetoothAudioStatus::SUCCESS) {
187 mState = BluetoothStreamState::STANDBY;
188 } else {
189 LOG(WARNING) << StringPrintf(
190 "control_result_cb: status=%s failure for session_type= %s, cookie=%#hx, "
191 "previous_state=%#hhx",
192 toString(status).c_str(), toString(mSessionType).c_str(), mCookie,
193 previous_state);
194 }
195 break;
196 case BluetoothStreamState::STARTING:
197 if (status == BluetoothAudioStatus::SUCCESS) {
198 mState = BluetoothStreamState::STARTED;
199 } else {
200 // Set to standby since the stack may be busy switching between outputs
201 LOG(WARNING) << StringPrintf(
202 "control_result_cb: status=%s failure for session_type= %s, cookie=%#hx, "
203 "previous_state=%#hhx",
204 toString(status).c_str(), toString(mSessionType).c_str(), mCookie,
205 previous_state);
206 mState = BluetoothStreamState::STANDBY;
207 }
208 break;
209 case BluetoothStreamState::SUSPENDING:
210 if (status == BluetoothAudioStatus::SUCCESS) {
211 mState = BluetoothStreamState::STANDBY;
212 } else {
213 // It will be failed if the headset is disconnecting, and set to disable
214 // to wait for re-init again
215 LOG(WARNING) << StringPrintf(
216 "control_result_cb: status=%s failure for session_type= %s, cookie=%#hx, "
217 "previous_state=%#hhx",
218 toString(status).c_str(), toString(mSessionType).c_str(), mCookie,
219 previous_state);
220 mState = BluetoothStreamState::DISABLED;
221 }
222 break;
223 default:
224 LOG(ERROR) << "control_result_cb: unexpected previous_state="
225 << StringPrintf(
226 "control_result_cb: status=%s failure for session_type= %s, "
227 "cookie=%#hx, previous_state=%#hhx",
228 toString(status).c_str(), toString(mSessionType).c_str(), mCookie,
229 previous_state);
230 return;
231 }
232 mInternalCv.notify_all();
233 }
234
sessionChangedHandler(uint16_t cookie)235 void BluetoothAudioPortAidl::sessionChangedHandler(uint16_t cookie) {
236 std::lock_guard guard(mCvMutex);
237 if (!inUse()) {
238 LOG(ERROR) << "session_changed_cb: BluetoothAudioPortAidl is not in use";
239 return;
240 }
241 if (mCookie != cookie) {
242 LOG(ERROR) << "session_changed_cb: proxy of device port (cookie="
243 << StringPrintf("%#hx", cookie) << ") is corrupted";
244 return;
245 }
246 BluetoothStreamState previous_state = mState;
247 LOG(VERBOSE) << "session_changed_cb:" << debugMessage()
248 << ", previous_state=" << previous_state;
249 mState = BluetoothStreamState::DISABLED;
250 mInternalCv.notify_all();
251 }
252
inUse() const253 bool BluetoothAudioPortAidl::inUse() const {
254 return (mCookie != ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined);
255 }
256
getPreferredDataIntervalUs(size_t * interval_us) const257 bool BluetoothAudioPortAidl::getPreferredDataIntervalUs(size_t* interval_us) const {
258 if (!interval_us) {
259 LOG(ERROR) << __func__ << ": bad input arg";
260 return false;
261 }
262
263 if (!inUse()) {
264 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
265 return false;
266 }
267
268 const AudioConfiguration& hal_audio_cfg =
269 BluetoothAudioSessionControl::GetAudioConfig(mSessionType);
270 if (hal_audio_cfg.getTag() != AudioConfiguration::pcmConfig) {
271 LOG(ERROR) << __func__ << ": unsupported audio cfg tag";
272 return false;
273 }
274
275 *interval_us = hal_audio_cfg.get<AudioConfiguration::pcmConfig>().dataIntervalUs;
276 return true;
277 }
278
loadAudioConfig(PcmConfiguration * audio_cfg) const279 bool BluetoothAudioPortAidl::loadAudioConfig(PcmConfiguration* audio_cfg) const {
280 if (!audio_cfg) {
281 LOG(ERROR) << __func__ << ": bad input arg";
282 return false;
283 }
284
285 if (!inUse()) {
286 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
287 return false;
288 }
289
290 const AudioConfiguration& hal_audio_cfg =
291 BluetoothAudioSessionControl::GetAudioConfig(mSessionType);
292 if (hal_audio_cfg.getTag() != AudioConfiguration::pcmConfig) {
293 LOG(ERROR) << __func__ << ": unsupported audio cfg tag";
294 return false;
295 }
296 *audio_cfg = hal_audio_cfg.get<AudioConfiguration::pcmConfig>();
297 LOG(VERBOSE) << __func__ << debugMessage() << ", state*=" << getState() << ", PcmConfig=["
298 << audio_cfg->toString() << "]";
299 if (audio_cfg->channelMode == ChannelMode::UNKNOWN) {
300 return false;
301 }
302 return true;
303 }
304
standby()305 bool BluetoothAudioPortAidl::standby() {
306 if (!inUse()) {
307 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
308 return false;
309 }
310 std::lock_guard guard(mCvMutex);
311 LOG(VERBOSE) << __func__ << debugMessage() << ", state=" << getState() << " request";
312 if (mState == BluetoothStreamState::DISABLED) {
313 mState = BluetoothStreamState::STANDBY;
314 LOG(VERBOSE) << __func__ << debugMessage() << ", state=" << getState() << " done";
315 return true;
316 }
317 return false;
318 }
319
condWaitState(BluetoothStreamState state)320 bool BluetoothAudioPortAidl::condWaitState(BluetoothStreamState state) {
321 const auto waitTime = std::chrono::milliseconds(kMaxWaitingTimeMs);
322 std::unique_lock lock(mCvMutex);
323 base::ScopedLockAssertion lock_assertion(mCvMutex);
324 switch (state) {
325 case BluetoothStreamState::STARTING: {
326 LOG(VERBOSE) << __func__ << debugMessage() << " waiting for STARTED";
327 mInternalCv.wait_for(lock, waitTime, [this] {
328 base::ScopedLockAssertion lock_assertion(mCvMutex);
329 return mState != BluetoothStreamState::STARTING;
330 });
331 return mState == BluetoothStreamState::STARTED;
332 }
333 case BluetoothStreamState::SUSPENDING: {
334 LOG(VERBOSE) << __func__ << debugMessage() << " waiting for SUSPENDED";
335 mInternalCv.wait_for(lock, waitTime, [this] {
336 base::ScopedLockAssertion lock_assertion(mCvMutex);
337 return mState != BluetoothStreamState::SUSPENDING;
338 });
339 return mState == BluetoothStreamState::STANDBY;
340 }
341 default:
342 LOG(WARNING) << __func__ << debugMessage() << " waiting for KNOWN";
343 return false;
344 }
345 return false;
346 }
347
start()348 bool BluetoothAudioPortAidl::start() {
349 if (!inUse()) {
350 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
351 return false;
352 }
353 LOG(VERBOSE) << __func__ << debugMessage() << ", state=" << getState()
354 << ", mono=" << (mIsStereoToMono ? "true" : "false") << " request";
355
356 {
357 std::unique_lock lock(mCvMutex);
358 base::ScopedLockAssertion lock_assertion(mCvMutex);
359 if (mState == BluetoothStreamState::STARTED) {
360 return true; // nop, return
361 } else if (mState == BluetoothStreamState::SUSPENDING ||
362 mState == BluetoothStreamState::STARTING) {
363 /* If port is in transient state, give some time to respond */
364 auto state_ = mState;
365 lock.unlock();
366 if (!condWaitState(state_)) {
367 LOG(ERROR) << __func__ << debugMessage() << ", state=" << getState() << " failure";
368 return false;
369 }
370 }
371 }
372
373 bool retval = false;
374 {
375 std::unique_lock lock(mCvMutex);
376 base::ScopedLockAssertion lock_assertion(mCvMutex);
377 if (mState == BluetoothStreamState::STARTED) {
378 retval = true;
379 } else if (mState == BluetoothStreamState::STANDBY) {
380 mState = BluetoothStreamState::STARTING;
381 lock.unlock();
382 if (BluetoothAudioSessionControl::StartStream(mSessionType)) {
383 retval = condWaitState(BluetoothStreamState::STARTING);
384 } else {
385 LOG(ERROR) << __func__ << debugMessage() << ", state=" << getState()
386 << " Hal fails";
387 }
388 }
389 }
390
391 if (retval) {
392 LOG(INFO) << __func__ << debugMessage() << ", state=" << getState()
393 << ", mono=" << (mIsStereoToMono ? "true" : "false") << " done";
394 } else {
395 LOG(ERROR) << __func__ << debugMessage() << ", state=" << getState() << " failure";
396 }
397
398 return retval; // false if any failure like timeout
399 }
400
suspend()401 bool BluetoothAudioPortAidl::suspend() {
402 if (!inUse()) {
403 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
404 return false;
405 }
406 LOG(VERBOSE) << __func__ << debugMessage() << ", state=" << getState() << " request";
407
408 {
409 std::unique_lock lock(mCvMutex);
410 base::ScopedLockAssertion lock_assertion(mCvMutex);
411 if (mState == BluetoothStreamState::STANDBY) {
412 return true; // nop, return
413 } else if (mState == BluetoothStreamState::SUSPENDING ||
414 mState == BluetoothStreamState::STARTING) {
415 /* If port is in transient state, give some time to respond */
416 auto state_ = mState;
417 lock.unlock();
418 if (!condWaitState(state_)) {
419 LOG(ERROR) << __func__ << debugMessage() << ", state=" << getState() << " failure";
420 return false;
421 }
422 }
423 }
424
425 bool retval = false;
426 {
427 std::unique_lock lock(mCvMutex);
428 base::ScopedLockAssertion lock_assertion(mCvMutex);
429 if (mState == BluetoothStreamState::STANDBY) {
430 retval = true;
431 } else if (mState == BluetoothStreamState::STARTED) {
432 mState = BluetoothStreamState::SUSPENDING;
433 lock.unlock();
434 if (BluetoothAudioSessionControl::SuspendStream(mSessionType)) {
435 retval = condWaitState(BluetoothStreamState::SUSPENDING);
436 } else {
437 LOG(ERROR) << __func__ << debugMessage() << ", state=" << getState()
438 << " Hal fails";
439 }
440 }
441 }
442
443 if (retval) {
444 LOG(INFO) << __func__ << debugMessage() << ", state=" << getState() << " done";
445 } else {
446 LOG(ERROR) << __func__ << debugMessage() << ", state=" << getState() << " failure";
447 }
448
449 return retval; // false if any failure like timeout
450 }
451
stop()452 void BluetoothAudioPortAidl::stop() {
453 if (!inUse()) {
454 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
455 return;
456 }
457 std::lock_guard guard(mCvMutex);
458 LOG(VERBOSE) << __func__ << debugMessage() << ", state=" << getState() << " request";
459 if (mState != BluetoothStreamState::DISABLED) {
460 BluetoothAudioSessionControl::StopStream(mSessionType);
461 mState = BluetoothStreamState::DISABLED;
462 }
463 LOG(VERBOSE) << __func__ << debugMessage() << ", state=" << getState() << " done";
464 }
465
writeData(const void * buffer,size_t bytes) const466 size_t BluetoothAudioPortAidlOut::writeData(const void* buffer, size_t bytes) const {
467 if (!buffer) {
468 LOG(ERROR) << __func__ << ": bad input arg";
469 return 0;
470 }
471
472 if (!inUse()) {
473 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
474 return 0;
475 }
476
477 if (!mIsStereoToMono) {
478 return BluetoothAudioSessionControl::OutWritePcmData(mSessionType, buffer, bytes);
479 }
480
481 // WAR to mix the stereo into Mono (16 bits per sample)
482 const size_t write_frames = bytes >> 2;
483 if (write_frames == 0) return 0;
484 auto src = static_cast<const int16_t*>(buffer);
485 std::unique_ptr<int16_t[]> dst{new int16_t[write_frames]};
486 downmix_to_mono_i16_from_stereo_i16(dst.get(), src, write_frames);
487 // a frame is 16 bits, and the size of a mono frame is equal to half a stereo.
488 auto totalWrite = BluetoothAudioSessionControl::OutWritePcmData(mSessionType, dst.get(),
489 write_frames * 2);
490 return totalWrite * 2;
491 }
492
readData(void * buffer,size_t bytes) const493 size_t BluetoothAudioPortAidlIn::readData(void* buffer, size_t bytes) const {
494 if (!buffer) {
495 LOG(ERROR) << __func__ << ": bad input arg";
496 return 0;
497 }
498
499 if (!inUse()) {
500 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
501 return 0;
502 }
503
504 return BluetoothAudioSessionControl::InReadPcmData(mSessionType, buffer, bytes);
505 }
506
getPresentationPosition(PresentationPosition & presentation_position) const507 bool BluetoothAudioPortAidl::getPresentationPosition(
508 PresentationPosition& presentation_position) const {
509 if (!inUse()) {
510 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
511 return false;
512 }
513 bool retval = BluetoothAudioSessionControl::GetPresentationPosition(mSessionType,
514 presentation_position);
515 LOG(VERBOSE) << __func__ << debugMessage() << ", state=" << getState()
516 << presentation_position.toString();
517
518 return retval;
519 }
520
updateSourceMetadata(const SourceMetadata & source_metadata) const521 bool BluetoothAudioPortAidl::updateSourceMetadata(const SourceMetadata& source_metadata) const {
522 if (!inUse()) {
523 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
524 return false;
525 }
526 LOG(DEBUG) << __func__ << debugMessage() << ", state=" << getState() << ", "
527 << source_metadata.tracks.size() << " track(s)";
528 if (source_metadata.tracks.size() == 0) return true;
529 return BluetoothAudioSessionControl::UpdateSourceMetadata(mSessionType, source_metadata);
530 }
531
updateSinkMetadata(const SinkMetadata & sink_metadata) const532 bool BluetoothAudioPortAidl::updateSinkMetadata(const SinkMetadata& sink_metadata) const {
533 if (!inUse()) {
534 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
535 return false;
536 }
537 LOG(DEBUG) << __func__ << debugMessage() << ", state=" << getState() << ", "
538 << sink_metadata.tracks.size() << " track(s)";
539 if (sink_metadata.tracks.size() == 0) return true;
540 return BluetoothAudioSessionControl::UpdateSinkMetadata(mSessionType, sink_metadata);
541 }
542
getState() const543 BluetoothStreamState BluetoothAudioPortAidl::getState() const {
544 return mState;
545 }
546
setState(BluetoothStreamState state)547 bool BluetoothAudioPortAidl::setState(BluetoothStreamState state) {
548 if (!inUse()) {
549 LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
550 return false;
551 }
552 std::lock_guard guard(mCvMutex);
553 LOG(DEBUG) << __func__ << ": BluetoothAudioPortAidl old state = " << mState
554 << " new state = " << state;
555 mState = state;
556 return true;
557 }
558
isA2dp() const559 bool BluetoothAudioPortAidl::isA2dp() const {
560 return mSessionType == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
561 mSessionType == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
562 }
563
isLeAudio() const564 bool BluetoothAudioPortAidl::isLeAudio() const {
565 return mSessionType == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
566 mSessionType == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
567 mSessionType == SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
568 mSessionType == SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
569 mSessionType == SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
570 mSessionType == SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
571 }
572
debugMessage() const573 std::string BluetoothAudioPortAidl::debugMessage() const {
574 return StringPrintf(": session_type=%s, cookie=%#hx", toString(mSessionType).c_str(), mCookie);
575 }
576
577 } // namespace android::bluetooth::audio::aidl
578