blob: 3655bc08bc8ce006db41269e6cae3dd21e723079 [file] [log] [blame]
Alice Kuo84e87672021-10-28 12:53:38 +08001/*
2 * Copyright 2021 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 "BTAudioProviderStub"
18
19#include "BluetoothAudioProvider.h"
20
21#include <android-base/logging.h>
22
23#include "BluetoothAudioSessionReport_2_2.h"
24#include "BluetoothAudioSupportedCodecsDB_2_1.h"
25
26namespace android {
27namespace hardware {
28namespace bluetooth {
29namespace audio {
30namespace V2_2 {
31namespace implementation {
32
33using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
34using ::android::hardware::kSynchronizedReadWrite;
35using ::android::hardware::MessageQueue;
36using ::android::hardware::Void;
37
38using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
39
40void BluetoothAudioDeathRecipient::serviceDied(
41 uint64_t cookie __unused,
42 const wp<::android::hidl::base::V1_0::IBase>& who __unused) {
43 LOG(ERROR) << "BluetoothAudioDeathRecipient::" << __func__
44 << " - BluetoothAudio Service died";
45 provider_->endSession();
46}
47
48BluetoothAudioProvider::BluetoothAudioProvider()
49 : death_recipient_(new BluetoothAudioDeathRecipient(this)),
50 session_type_(V2_1::SessionType::UNKNOWN),
51 audio_config_({}) {}
52
53Return<void> BluetoothAudioProvider::startSession(
54 const sp<IBluetoothAudioPort>& hostIf,
55 const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
56 AudioConfiguration audioConfig_2_2;
57
58 if (audioConfig.getDiscriminator() ==
59 V2_0::AudioConfiguration::hidl_discriminator::pcmConfig) {
60 audioConfig_2_2.pcmConfig(
61 {.sampleRate =
62 static_cast<V2_1::SampleRate>(audioConfig.pcmConfig().sampleRate),
63 .channelMode = audioConfig.pcmConfig().channelMode,
64 .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
65 .dataIntervalUs = 0});
66 } else {
67 audioConfig_2_2.codecConfig(audioConfig.codecConfig());
68 }
69
70 return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
71}
72
73Return<void> BluetoothAudioProvider::startSession_2_1(
74 const sp<IBluetoothAudioPort>& hostIf,
75 const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
76 AudioConfiguration audioConfig_2_2;
77 if (audioConfig.getDiscriminator() ==
78 V2_1::AudioConfiguration::hidl_discriminator::leAudioCodecConfig) {
79 audioConfig_2_2.leAudioConfig().mode = LeAudioMode::UNKNOWN;
80 audioConfig_2_2.leAudioConfig().config.unicastConfig() = {
81 .streamMap = {{
82 .streamHandle = 0xFFFF,
83 .audioChannelAllocation =
84 audioConfig.leAudioCodecConfig().audioChannelAllocation,
85 }},
86 .peerDelay = 0,
87 .lc3Config = audioConfig.leAudioCodecConfig().lc3Config};
88 } else if (audioConfig.getDiscriminator() ==
89 V2_1::AudioConfiguration::hidl_discriminator::pcmConfig) {
90 audioConfig_2_2.pcmConfig(audioConfig.pcmConfig());
91 } else {
92 audioConfig_2_2.codecConfig(audioConfig.codecConfig());
93 }
94
95 return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
96}
97
98Return<void> BluetoothAudioProvider::startSession_2_2(
99 const sp<IBluetoothAudioPort>& hostIf,
100 const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
101 if (hostIf == nullptr) {
102 _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
103 return Void();
104 }
105
106 /**
107 * Initialize the audio platform if audioConfiguration is supported.
108 * Save the IBluetoothAudioPort interface, so that it can be used
109 * later to send stream control commands to the HAL client, based on
110 * interaction with Audio framework.
111 */
112 audio_config_ = audioConfig;
113 stack_iface_ = hostIf;
114 stack_iface_->linkToDeath(death_recipient_, 0);
115
116 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
117 << ", AudioConfiguration=[" << toString(audio_config_) << "]";
118
119 onSessionReady(_hidl_cb);
120 return Void();
121}
122
123Return<void> BluetoothAudioProvider::streamStarted(
124 BluetoothAudioStatus status) {
125 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
126 << ", status=" << toString(status);
127
128 /**
129 * Streaming on control path has started,
130 * HAL server should start the streaming on data path.
131 */
132 if (stack_iface_) {
133 BluetoothAudioSessionReport_2_2::ReportControlStatus(session_type_, true,
134 status);
135 } else {
136 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
137 << ", status=" << toString(status) << " has NO session";
138 }
139
140 return Void();
141}
142
143Return<void> BluetoothAudioProvider::streamSuspended(
144 BluetoothAudioStatus status) {
145 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
146 << ", status=" << toString(status);
147
148 /**
149 * Streaming on control path has suspend,
150 * HAL server should suspend the streaming on data path.
151 */
152 if (stack_iface_) {
153 BluetoothAudioSessionReport_2_2::ReportControlStatus(session_type_, false,
154 status);
155 } else {
156 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
157 << ", status=" << toString(status) << " has NO session";
158 }
159
160 return Void();
161}
162
163Return<void> BluetoothAudioProvider::endSession() {
164 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
165
166 if (stack_iface_) {
167 BluetoothAudioSessionReport_2_2::OnSessionEnded(session_type_);
168 stack_iface_->unlinkToDeath(death_recipient_);
169 } else {
170 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
171 << " has NO session";
172 }
173
174 /**
175 * Clean up the audio platform as remote audio device is no
176 * longer active
177 */
178 stack_iface_ = nullptr;
179 audio_config_ = {};
180
181 return Void();
182}
183
184} // namespace implementation
185} // namespace V2_2
186} // namespace audio
187} // namespace bluetooth
188} // namespace hardware
189} // namespace android