• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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