blob: 73fe06c961f2625162a6dd82e5501a8ce8c31a88 [file] [log] [blame]
Grzegorz Kolodziejczykb5f2d232019-10-24 12:31:20 +02001/*
2 * Copyright 2020 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.h"
24#include "BluetoothAudioSupportedCodecsDB.h"
25
26namespace android {
27namespace hardware {
28namespace bluetooth {
29namespace audio {
30namespace V2_1 {
31namespace implementation {
32
33using ::android::bluetooth::audio::BluetoothAudioSessionReport;
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_(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_1;
57
Grzegorz Kołodziejczykd7f04f92020-11-13 12:33:45 +000058 if (audioConfig.getDiscriminator() ==
59 V2_0::AudioConfiguration::hidl_discriminator::pcmConfig) {
Grzegorz Kołodziejczyk0f0c5d12020-11-25 20:42:43 +010060 audioConfig_2_1.pcmConfig({
Grzegorz Kołodziejczykd7f04f92020-11-13 12:33:45 +000061 .sampleRate =
62 static_cast<SampleRate>(audioConfig.pcmConfig().sampleRate),
63 .channelMode = audioConfig.pcmConfig().channelMode,
64 .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
Grzegorz Kołodziejczyk0f0c5d12020-11-25 20:42:43 +010065 .dataIntervalUs = 0});
Grzegorz Kołodziejczykd7f04f92020-11-13 12:33:45 +000066 } else {
Grzegorz Kołodziejczyk0f0c5d12020-11-25 20:42:43 +010067 audioConfig_2_1.codecConfig(audioConfig.codecConfig());
Grzegorz Kołodziejczykd7f04f92020-11-13 12:33:45 +000068 }
Grzegorz Kolodziejczykb5f2d232019-10-24 12:31:20 +020069
70 return startSession_2_1(hostIf, audioConfig_2_1, _hidl_cb);
71}
72
73Return<void> BluetoothAudioProvider::startSession_2_1(
74 const sp<IBluetoothAudioPort>& hostIf,
75 const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
76 if (hostIf == nullptr) {
77 _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
78 return Void();
79 }
80
81 /**
82 * Initialize the audio platform if audioConfiguration is supported.
83 * Save the IBluetoothAudioPort interface, so that it can be used
84 * later to send stream control commands to the HAL client, based on
85 * interaction with Audio framework.
86 */
87 audio_config_ = audioConfig;
88 stack_iface_ = hostIf;
89 stack_iface_->linkToDeath(death_recipient_, 0);
90
91 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
92 << ", AudioConfiguration=[" << toString(audio_config_) << "]";
93
94 onSessionReady(_hidl_cb);
95 return Void();
96}
97
98Return<void> BluetoothAudioProvider::streamStarted(
99 BluetoothAudioStatus status) {
100 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
101 << ", status=" << toString(status);
102
103 /**
104 * Streaming on control path has started,
105 * HAL server should start the streaming on data path.
106 */
107 if (stack_iface_) {
108 BluetoothAudioSessionReport::ReportControlStatus(session_type_, true,
109 status);
110 } else {
111 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
112 << ", status=" << toString(status) << " has NO session";
113 }
114
115 return Void();
116}
117
118Return<void> BluetoothAudioProvider::streamSuspended(
119 BluetoothAudioStatus status) {
120 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
121 << ", status=" << toString(status);
122
123 /**
124 * Streaming on control path has suspend,
125 * HAL server should suspend the streaming on data path.
126 */
127 if (stack_iface_) {
128 BluetoothAudioSessionReport::ReportControlStatus(session_type_, false,
129 status);
130 } else {
131 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
132 << ", status=" << toString(status) << " has NO session";
133 }
134
135 return Void();
136}
137
138Return<void> BluetoothAudioProvider::endSession() {
139 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
140
141 if (stack_iface_) {
142 BluetoothAudioSessionReport::OnSessionEnded(session_type_);
143 stack_iface_->unlinkToDeath(death_recipient_);
144 } else {
145 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
146 << " has NO session";
147 }
148
149 /**
150 * Clean up the audio platform as remote audio device is no
151 * longer active
152 */
153 stack_iface_ = nullptr;
154 audio_config_ = {};
155
156 return Void();
157}
158
159} // namespace implementation
160} // namespace V2_1
161} // namespace audio
162} // namespace bluetooth
163} // namespace hardware
164} // namespace android