1 /*
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_2_1.h"
24 #include "BluetoothAudioSupportedCodecsDB_2_1.h"
25 
26 namespace android {
27 namespace hardware {
28 namespace bluetooth {
29 namespace audio {
30 namespace V2_1 {
31 namespace implementation {
32 
33 using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_1;
34 using ::android::hardware::kSynchronizedReadWrite;
35 using ::android::hardware::MessageQueue;
36 using ::android::hardware::Void;
37 
38 using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
39 
serviceDied(uint64_t cookie __unused,const wp<::android::hidl::base::V1_0::IBase> & who __unused)40 void 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 
BluetoothAudioProvider()48 BluetoothAudioProvider::BluetoothAudioProvider()
49     : death_recipient_(new BluetoothAudioDeathRecipient(this)),
50       session_type_(SessionType::UNKNOWN),
51       audio_config_({}) {}
52 
startSession(const sp<IBluetoothAudioPort> & hostIf,const V2_0::AudioConfiguration & audioConfig,startSession_cb _hidl_cb)53 Return<void> BluetoothAudioProvider::startSession(
54     const sp<IBluetoothAudioPort>& hostIf,
55     const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
56   AudioConfiguration audioConfig_2_1;
57 
58   if (audioConfig.getDiscriminator() ==
59       V2_0::AudioConfiguration::hidl_discriminator::pcmConfig) {
60     audioConfig_2_1.pcmConfig({
61         .sampleRate =
62             static_cast<SampleRate>(audioConfig.pcmConfig().sampleRate),
63         .channelMode = audioConfig.pcmConfig().channelMode,
64         .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
65         .dataIntervalUs = 0});
66   } else {
67     audioConfig_2_1.codecConfig(audioConfig.codecConfig());
68   }
69 
70   return startSession_2_1(hostIf, audioConfig_2_1, _hidl_cb);
71 }
72 
startSession_2_1(const sp<IBluetoothAudioPort> & hostIf,const AudioConfiguration & audioConfig,startSession_cb _hidl_cb)73 Return<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 
streamStarted(BluetoothAudioStatus status)98 Return<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_2_1::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 
streamSuspended(BluetoothAudioStatus status)118 Return<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_2_1::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 
endSession()138 Return<void> BluetoothAudioProvider::endSession() {
139   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
140 
141   if (stack_iface_) {
142     BluetoothAudioSessionReport_2_1::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
165