blob: 202cfb9f90e6938c0f0c8fca63524ccd51dc1a75 [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
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010023#include "AudioPort_2_0_to_2_2_Wrapper.h"
Alice Kuo84e87672021-10-28 12:53:38 +080024#include "BluetoothAudioSessionReport_2_2.h"
Alice Kuo79c02162021-12-16 14:13:25 +080025#include "BluetoothAudioSupportedCodecsDB_2_2.h"
Alice Kuo84e87672021-10-28 12:53:38 +080026
27namespace android {
28namespace hardware {
29namespace bluetooth {
30namespace audio {
31namespace V2_2 {
32namespace implementation {
33
34using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
35using ::android::hardware::kSynchronizedReadWrite;
36using ::android::hardware::MessageQueue;
37using ::android::hardware::Void;
38
39using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
40
41void BluetoothAudioDeathRecipient::serviceDied(
42 uint64_t cookie __unused,
43 const wp<::android::hidl::base::V1_0::IBase>& who __unused) {
44 LOG(ERROR) << "BluetoothAudioDeathRecipient::" << __func__
45 << " - BluetoothAudio Service died";
46 provider_->endSession();
47}
48
49BluetoothAudioProvider::BluetoothAudioProvider()
50 : death_recipient_(new BluetoothAudioDeathRecipient(this)),
51 session_type_(V2_1::SessionType::UNKNOWN),
52 audio_config_({}) {}
53
54Return<void> BluetoothAudioProvider::startSession(
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010055 const sp<V2_0::IBluetoothAudioPort>& hostIf,
Alice Kuo84e87672021-10-28 12:53:38 +080056 const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
57 AudioConfiguration audioConfig_2_2;
58
59 if (audioConfig.getDiscriminator() ==
60 V2_0::AudioConfiguration::hidl_discriminator::pcmConfig) {
61 audioConfig_2_2.pcmConfig(
62 {.sampleRate =
63 static_cast<V2_1::SampleRate>(audioConfig.pcmConfig().sampleRate),
64 .channelMode = audioConfig.pcmConfig().channelMode,
65 .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
66 .dataIntervalUs = 0});
67 } else {
68 audioConfig_2_2.codecConfig(audioConfig.codecConfig());
69 }
70
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010071 sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
72 new AudioPort_2_0_to_2_2_Wrapper(hostIf);
73 return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
Alice Kuo84e87672021-10-28 12:53:38 +080074}
75
76Return<void> BluetoothAudioProvider::startSession_2_1(
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010077 const sp<V2_0::IBluetoothAudioPort>& hostIf,
Alice Kuo84e87672021-10-28 12:53:38 +080078 const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
79 AudioConfiguration audioConfig_2_2;
80 if (audioConfig.getDiscriminator() ==
81 V2_1::AudioConfiguration::hidl_discriminator::leAudioCodecConfig) {
82 audioConfig_2_2.leAudioConfig().mode = LeAudioMode::UNKNOWN;
83 audioConfig_2_2.leAudioConfig().config.unicastConfig() = {
84 .streamMap = {{
85 .streamHandle = 0xFFFF,
86 .audioChannelAllocation =
87 audioConfig.leAudioCodecConfig().audioChannelAllocation,
88 }},
89 .peerDelay = 0,
90 .lc3Config = audioConfig.leAudioCodecConfig().lc3Config};
91 } else if (audioConfig.getDiscriminator() ==
92 V2_1::AudioConfiguration::hidl_discriminator::pcmConfig) {
93 audioConfig_2_2.pcmConfig(audioConfig.pcmConfig());
94 } else {
95 audioConfig_2_2.codecConfig(audioConfig.codecConfig());
96 }
97
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +010098 sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
99 new AudioPort_2_0_to_2_2_Wrapper(hostIf);
100 return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
Alice Kuo84e87672021-10-28 12:53:38 +0800101}
102
103Return<void> BluetoothAudioProvider::startSession_2_2(
Jakub Pawlowski8d87eb72021-12-06 15:22:03 +0100104 const sp<V2_2::IBluetoothAudioPort>& hostIf,
Alice Kuo84e87672021-10-28 12:53:38 +0800105 const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
106 if (hostIf == nullptr) {
107 _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
108 return Void();
109 }
110
111 /**
112 * Initialize the audio platform if audioConfiguration is supported.
113 * Save the IBluetoothAudioPort interface, so that it can be used
114 * later to send stream control commands to the HAL client, based on
115 * interaction with Audio framework.
116 */
117 audio_config_ = audioConfig;
118 stack_iface_ = hostIf;
119 stack_iface_->linkToDeath(death_recipient_, 0);
120
121 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
122 << ", AudioConfiguration=[" << toString(audio_config_) << "]";
123
124 onSessionReady(_hidl_cb);
125 return Void();
126}
127
128Return<void> BluetoothAudioProvider::streamStarted(
129 BluetoothAudioStatus status) {
130 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
131 << ", status=" << toString(status);
132
133 /**
134 * Streaming on control path has started,
135 * HAL server should start the streaming on data path.
136 */
137 if (stack_iface_) {
138 BluetoothAudioSessionReport_2_2::ReportControlStatus(session_type_, true,
139 status);
140 } else {
141 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
142 << ", status=" << toString(status) << " has NO session";
143 }
144
145 return Void();
146}
147
148Return<void> BluetoothAudioProvider::streamSuspended(
149 BluetoothAudioStatus status) {
150 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
151 << ", status=" << toString(status);
152
153 /**
154 * Streaming on control path has suspend,
155 * HAL server should suspend the streaming on data path.
156 */
157 if (stack_iface_) {
158 BluetoothAudioSessionReport_2_2::ReportControlStatus(session_type_, false,
159 status);
160 } else {
161 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
162 << ", status=" << toString(status) << " has NO session";
163 }
164
165 return Void();
166}
167
168Return<void> BluetoothAudioProvider::endSession() {
169 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
170
171 if (stack_iface_) {
172 BluetoothAudioSessionReport_2_2::OnSessionEnded(session_type_);
173 stack_iface_->unlinkToDeath(death_recipient_);
174 } else {
175 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
176 << " has NO session";
177 }
178
179 /**
180 * Clean up the audio platform as remote audio device is no
181 * longer active
182 */
183 stack_iface_ = nullptr;
184 audio_config_ = {};
185
186 return Void();
187}
188
Alice Kuo3f9f41f2021-12-28 10:31:28 +0800189Return<void> BluetoothAudioProvider::updateAudioConfiguration(
190 const AudioConfiguration& audioConfig) {
191 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
192
193 if (stack_iface_ == nullptr) {
194 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
195 << " has NO session";
196 return Void();
197 }
198
199 if (audioConfig.getDiscriminator() != audio_config_.getDiscriminator()) {
200 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
201 << " audio config type is not match";
202 return Void();
203 }
204
205 audio_config_ = audioConfig;
206 BluetoothAudioSessionReport_2_2::ReportAudioConfigChanged(session_type_,
207 audio_config_);
208
209 return Void();
210}
211
Alice Kuo84e87672021-10-28 12:53:38 +0800212} // namespace implementation
213} // namespace V2_2
214} // namespace audio
215} // namespace bluetooth
216} // namespace hardware
217} // namespace android