1 /*
2 * Copyright 2019 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 #pragma once
18
19 #include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvider.h>
20 #include <android/hardware/bluetooth/audio/2.1/types.h>
21 #include <fmq/MessageQueue.h>
22 #include <hardware/audio.h>
23 #include <time.h>
24
25 #include <mutex>
26 #include <vector>
27
28 #include "common/message_loop_thread.h"
29
30 #define BLUETOOTH_AUDIO_HAL_PROP_DISABLED \
31 "persist.bluetooth.bluetooth_audio_hal.disabled"
32
33 namespace bluetooth {
34 namespace audio {
35 namespace hidl {
36
37 using AudioCapabilities =
38 ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
39 using AudioCapabilities_2_1 =
40 ::android::hardware::bluetooth::audio::V2_1::AudioCapabilities;
41 using AudioConfiguration =
42 ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
43 using AudioConfiguration_2_1 =
44 ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
45 using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
46 using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
47 using IBluetoothAudioProvider =
48 ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
49 using IBluetoothAudioProvider_2_1 =
50 ::android::hardware::bluetooth::audio::V2_1::IBluetoothAudioProvider;
51 using PcmParameters =
52 ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
53 using PcmParameters_2_1 =
54 ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
55 using SampleRate = ::android::hardware::bluetooth::audio::V2_0::SampleRate;
56 using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
57 using SessionType = ::android::hardware::bluetooth::audio::V2_0::SessionType;
58 using SessionType_2_1 =
59 ::android::hardware::bluetooth::audio::V2_1::SessionType;
60 using ::android::hardware::bluetooth::audio::V2_0::TimeSpec;
61 using BluetoothAudioStatus =
62 ::android::hardware::bluetooth::audio::V2_0::Status;
63
64 enum class BluetoothAudioCtrlAck : uint8_t {
65 SUCCESS_FINISHED = 0,
66 PENDING,
67 FAILURE_UNSUPPORTED,
68 FAILURE_BUSY,
69 FAILURE_DISCONNECTING,
70 FAILURE
71 };
72
73 std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack);
74
BluetoothAudioCtrlAckToHalStatus(const BluetoothAudioCtrlAck & ack)75 inline BluetoothAudioStatus BluetoothAudioCtrlAckToHalStatus(
76 const BluetoothAudioCtrlAck& ack) {
77 switch (ack) {
78 case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
79 return BluetoothAudioStatus::SUCCESS;
80 case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
81 return BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION;
82 case BluetoothAudioCtrlAck::PENDING:
83 return BluetoothAudioStatus::FAILURE;
84 case BluetoothAudioCtrlAck::FAILURE_BUSY:
85 return BluetoothAudioStatus::FAILURE;
86 case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
87 return BluetoothAudioStatus::FAILURE;
88 default:
89 return BluetoothAudioStatus::FAILURE;
90 }
91 }
92
93 // An IBluetoothTransportInstance needs to be implemented by a Bluetooth
94 // audio transport, such as A2DP or Hearing Aid, to handle callbacks from Audio
95 // HAL.
96 class IBluetoothTransportInstance {
97 public:
IBluetoothTransportInstance(SessionType sessionType,AudioConfiguration audioConfig)98 IBluetoothTransportInstance(SessionType sessionType,
99 AudioConfiguration audioConfig)
100 : session_type_(sessionType),
101 session_type_2_1_(SessionType_2_1::UNKNOWN),
102 audio_config_(std::move(audioConfig)),
103 audio_config_2_1_({}){};
IBluetoothTransportInstance(SessionType_2_1 sessionType_2_1,AudioConfiguration_2_1 audioConfig_2_1)104 IBluetoothTransportInstance(SessionType_2_1 sessionType_2_1,
105 AudioConfiguration_2_1 audioConfig_2_1)
106 : session_type_(SessionType::UNKNOWN),
107 session_type_2_1_(sessionType_2_1),
108 audio_config_({}),
109 audio_config_2_1_(std::move(audioConfig_2_1)){};
110 virtual ~IBluetoothTransportInstance() = default;
111
GetSessionType()112 SessionType GetSessionType() const { return session_type_; }
GetSessionType_2_1()113 SessionType_2_1 GetSessionType_2_1() const { return session_type_2_1_; }
114
GetAudioConfiguration()115 AudioConfiguration GetAudioConfiguration() const { return audio_config_; }
GetAudioConfiguration_2_1()116 AudioConfiguration_2_1 GetAudioConfiguration_2_1() const {
117 return audio_config_2_1_;
118 }
119
UpdateAudioConfiguration(const AudioConfiguration & audio_config)120 void UpdateAudioConfiguration(const AudioConfiguration& audio_config) {
121 audio_config_ = audio_config;
122 }
UpdateAudioConfiguration_2_1(const AudioConfiguration_2_1 & audio_config_2_1)123 void UpdateAudioConfiguration_2_1(
124 const AudioConfiguration_2_1& audio_config_2_1) {
125 audio_config_2_1_ = audio_config_2_1;
126 }
127
128 virtual BluetoothAudioCtrlAck StartRequest() = 0;
129
130 virtual BluetoothAudioCtrlAck SuspendRequest() = 0;
131
132 virtual void StopRequest() = 0;
133
134 virtual bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
135 uint64_t* total_bytes_readed,
136 timespec* data_position) = 0;
137
138 virtual void MetadataChanged(const source_metadata_t& source_metadata) = 0;
139
140 // Invoked when the transport is requested to reset presentation position
141 virtual void ResetPresentationPosition() = 0;
142
143 private:
144 const SessionType session_type_;
145 const SessionType_2_1 session_type_2_1_;
146 AudioConfiguration audio_config_;
147 AudioConfiguration_2_1 audio_config_2_1_;
148 };
149
150 // An IBluetoothSinkTransportInstance needs to be implemented by a Bluetooth
151 // audio transport, such as A2DP, Hearing Aid or LeAudio, to handle callbacks
152 // from Audio HAL.
153 class IBluetoothSinkTransportInstance : public IBluetoothTransportInstance {
154 public:
IBluetoothSinkTransportInstance(SessionType sessionType,AudioConfiguration audioConfig)155 IBluetoothSinkTransportInstance(SessionType sessionType,
156 AudioConfiguration audioConfig)
157 : IBluetoothTransportInstance{sessionType, audioConfig} {}
IBluetoothSinkTransportInstance(SessionType_2_1 sessionType_2_1,AudioConfiguration_2_1 audioConfig_2_1)158 IBluetoothSinkTransportInstance(SessionType_2_1 sessionType_2_1,
159 AudioConfiguration_2_1 audioConfig_2_1)
160 : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
161 virtual ~IBluetoothSinkTransportInstance() = default;
162
163 // Invoked when the transport is requested to log bytes read
164 virtual void LogBytesRead(size_t bytes_readed) = 0;
165 };
166
167 class IBluetoothSourceTransportInstance : public IBluetoothTransportInstance {
168 public:
IBluetoothSourceTransportInstance(SessionType sessionType,AudioConfiguration audioConfig)169 IBluetoothSourceTransportInstance(SessionType sessionType,
170 AudioConfiguration audioConfig)
171 : IBluetoothTransportInstance{sessionType, audioConfig} {}
IBluetoothSourceTransportInstance(SessionType_2_1 sessionType_2_1,AudioConfiguration_2_1 audioConfig_2_1)172 IBluetoothSourceTransportInstance(SessionType_2_1 sessionType_2_1,
173 AudioConfiguration_2_1 audioConfig_2_1)
174 : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
175 virtual ~IBluetoothSourceTransportInstance() = default;
176
177 // Invoked when the transport is requested to log bytes written
178 virtual void LogBytesWritten(size_t bytes_written) = 0;
179 };
180
181 // common object is shared between different kind of SessionType
182 class BluetoothAudioDeathRecipient;
183
184 // The client interface connects an IBluetoothTransportInstance to
185 // IBluetoothAudioProvider and helps to route callbacks to
186 // IBluetoothTransportInstance
187 class BluetoothAudioClientInterface {
188 public:
189 BluetoothAudioClientInterface(
190 android::sp<BluetoothAudioDeathRecipient> death_recipient,
191 IBluetoothTransportInstance* instance);
192 virtual ~BluetoothAudioClientInterface() = default;
193
IsValid()194 bool IsValid() const {
195 return provider_ != nullptr || provider_2_1_ != nullptr;
196 }
197
198 std::vector<AudioCapabilities> GetAudioCapabilities() const;
199 std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1() const;
200 static std::vector<AudioCapabilities> GetAudioCapabilities(
201 SessionType session_type);
202 static std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1(
203 SessionType_2_1 session_type_2_1);
204
205 void StreamStarted(const BluetoothAudioCtrlAck& ack);
206
207 void StreamSuspended(const BluetoothAudioCtrlAck& ack);
208
209 int StartSession();
210 int StartSession_2_1();
211
212 // Renew the connection and usually is used when HIDL restarted
213 void RenewAudioProviderAndSession();
214
215 int EndSession();
216
217 bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
218 bool UpdateAudioConfig_2_1(const AudioConfiguration_2_1& audioConfig_2_1);
219
220 void FlushAudioData();
221
222 static constexpr PcmParameters kInvalidPcmConfiguration = {
223 .sampleRate = SampleRate::RATE_UNKNOWN,
224 .channelMode = ChannelMode::UNKNOWN,
225 .bitsPerSample = BitsPerSample::BITS_UNKNOWN};
226
227 protected:
228 mutable std::mutex internal_mutex_;
229 // Helper function to connect to an IBluetoothAudioProvider
230 void FetchAudioProvider();
231 // Helper function to connect to an IBluetoothAudioProvider 2.1
232 void FetchAudioProvider_2_1();
233
234 android::sp<IBluetoothAudioProvider> provider_;
235 android::sp<IBluetoothAudioProvider_2_1> provider_2_1_;
236 bool session_started_;
237 std::unique_ptr<::android::hardware::MessageQueue<
238 uint8_t, ::android::hardware::kSynchronizedReadWrite>>
239 mDataMQ;
240 android::sp<BluetoothAudioDeathRecipient> death_recipient_;
241
242 private:
243 IBluetoothTransportInstance* transport_;
244 std::vector<AudioCapabilities> capabilities_;
245 std::vector<AudioCapabilities_2_1> capabilities_2_1_;
246 };
247
248 // The client interface connects an IBluetoothTransportInstance to
249 // IBluetoothAudioProvider and helps to route callbacks to
250 // IBluetoothTransportInstance
251 class BluetoothAudioSinkClientInterface : public BluetoothAudioClientInterface {
252 public:
253 // Constructs an BluetoothAudioSinkClientInterface to communicate to
254 // BluetoothAudio HAL. |sink| is the implementation for the transport, and
255 // |message_loop| is the thread where callbacks are invoked.
256 BluetoothAudioSinkClientInterface(
257 IBluetoothSinkTransportInstance* sink,
258 bluetooth::common::MessageLoopThread* message_loop);
259 virtual ~BluetoothAudioSinkClientInterface();
260
GetTransportInstance()261 IBluetoothSinkTransportInstance* GetTransportInstance() const {
262 return sink_;
263 }
264
265 // Read data from audio HAL through fmq
266 size_t ReadAudioData(uint8_t* p_buf, uint32_t len);
267
268 private:
269 IBluetoothSinkTransportInstance* sink_;
270 };
271
272 class BluetoothAudioSourceClientInterface
273 : public BluetoothAudioClientInterface {
274 public:
275 // Constructs an BluetoothAudioSourceClientInterface to communicate to
276 // BluetoothAudio HAL. |source| is the implementation for the transport, and
277 // |message_loop| is the thread where callbacks are invoked.
278 BluetoothAudioSourceClientInterface(
279 IBluetoothSourceTransportInstance* source,
280 bluetooth::common::MessageLoopThread* message_loop);
281 virtual ~BluetoothAudioSourceClientInterface();
282
GetTransportInstance()283 IBluetoothSourceTransportInstance* GetTransportInstance() const {
284 return source_;
285 }
286
287 // Write data to audio HAL through fmq
288 size_t WriteAudioData(const uint8_t* p_buf, uint32_t len);
289
290 private:
291 IBluetoothSourceTransportInstance* source_;
292 };
293
294 } // namespace hidl
295 } // namespace audio
296 } // namespace bluetooth
297