1 /*
2 * Copyright 2018 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 <android-base/logging.h>
20
21 #include "BluetoothAudioProvider.h"
22 #include "BluetoothAudioSessionReport.h"
23 #include "BluetoothAudioSupportedCodecsDB.h"
24
25 namespace android {
26 namespace hardware {
27 namespace bluetooth {
28 namespace audio {
29 namespace V2_0 {
30 namespace implementation {
31
32 using ::android::bluetooth::audio::BluetoothAudioSessionReport;
33 using ::android::hardware::kSynchronizedReadWrite;
34 using ::android::hardware::MessageQueue;
35 using ::android::hardware::Void;
36
37 using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
38
serviceDied(uint64_t cookie __unused,const wp<::android::hidl::base::V1_0::IBase> & who __unused)39 void BluetoothAudioDeathRecipient::serviceDied(
40 uint64_t cookie __unused,
41 const wp<::android::hidl::base::V1_0::IBase>& who __unused) {
42 LOG(ERROR) << "BluetoothAudioDeathRecipient::" << __func__
43 << " - BluetoothAudio Service died";
44 provider_->endSession();
45 }
46
BluetoothAudioProvider()47 BluetoothAudioProvider::BluetoothAudioProvider()
48 : death_recipient_(new BluetoothAudioDeathRecipient(this)),
49 session_type_(SessionType::UNKNOWN),
50 audio_config_({}) {}
51
startSession(const sp<IBluetoothAudioPort> & hostIf,const AudioConfiguration & audioConfig,startSession_cb _hidl_cb)52 Return<void> BluetoothAudioProvider::startSession(
53 const sp<IBluetoothAudioPort>& hostIf,
54 const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
55 if (hostIf == nullptr) {
56 _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
57 return Void();
58 }
59
60 /**
61 * Initialize the audio platform if audioConfiguration is supported.
62 * Save the the IBluetoothAudioPort interface, so that it can be used
63 * later to send stream control commands to the HAL client, based on
64 * interaction with Audio framework.
65 */
66 audio_config_ = audioConfig;
67 stack_iface_ = hostIf;
68 stack_iface_->linkToDeath(death_recipient_, 0);
69
70 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
71 << ", AudioConfiguration=[" << toString(audio_config_) << "]";
72
73 onSessionReady(_hidl_cb);
74 return Void();
75 }
76
streamStarted(BluetoothAudioStatus status)77 Return<void> BluetoothAudioProvider::streamStarted(
78 BluetoothAudioStatus status) {
79 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
80 << ", status=" << toString(status);
81
82 /**
83 * Streaming on control path has started,
84 * HAL server should start the streaming on data path.
85 */
86 if (stack_iface_) {
87 BluetoothAudioSessionReport::ReportControlStatus(session_type_, true,
88 status);
89 } else {
90 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
91 << ", status=" << toString(status) << " has NO session";
92 }
93
94 return Void();
95 }
96
streamSuspended(BluetoothAudioStatus status)97 Return<void> BluetoothAudioProvider::streamSuspended(
98 BluetoothAudioStatus status) {
99 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
100 << ", status=" << toString(status);
101
102 /**
103 * Streaming on control path has suspend,
104 * HAL server should suspend the streaming on data path.
105 */
106 if (stack_iface_) {
107 BluetoothAudioSessionReport::ReportControlStatus(session_type_, false,
108 status);
109 } else {
110 LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
111 << ", status=" << toString(status) << " has NO session";
112 }
113
114 return Void();
115 }
116
endSession()117 Return<void> BluetoothAudioProvider::endSession() {
118 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
119
120 if (stack_iface_) {
121 BluetoothAudioSessionReport::OnSessionEnded(session_type_);
122 stack_iface_->unlinkToDeath(death_recipient_);
123 } else {
124 LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
125 << " has NO session";
126 }
127
128 /**
129 * Clean up the audio platform as remote audio device is no
130 * longer active
131 */
132 stack_iface_ = nullptr;
133 audio_config_ = {};
134
135 return Void();
136 }
137
138 } // namespace implementation
139 } // namespace V2_0
140 } // namespace audio
141 } // namespace bluetooth
142 } // namespace hardware
143 } // namespace android
144