• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h>
20 #include <aidl/android/hardware/bluetooth/audio/SessionType.h>
21 #include <hardware/audio.h>
22 
23 #include <condition_variable>
24 #include <mutex>
25 #include <unordered_map>
26 
27 enum class BluetoothStreamState : uint8_t;
28 
29 namespace android {
30 namespace bluetooth {
31 namespace audio {
32 
33 /***
34  * Proxy for Bluetooth Audio HW Module to communicate with Bluetooth Audio
35  * Session Control. All methods are not thread safe, so users must acquire a
36  * lock. Note: currently, in stream_apis.cc, if GetState() is only used for
37  * verbose logging, it is not locked, so the state may not be synchronized.
38  ***/
39 class BluetoothAudioPort {
40  public:
BluetoothAudioPort()41   BluetoothAudioPort(){};
42   virtual ~BluetoothAudioPort() = default;
43 
44   /***
45    * Fetch output control / data path of BluetoothAudioPort and setup
46    * callbacks into BluetoothAudioProvider. If SetUp() returns false, the audio
47    * HAL must delete this BluetoothAudioPort and return EINVAL to caller
48    ***/
SetUp(audio_devices_t)49   virtual bool SetUp(audio_devices_t) { return false; }
50 
51   /***
52    * Unregister this BluetoothAudioPort from BluetoothAudioSessionControl.
53    * Audio HAL must delete this BluetoothAudioPort after calling this.
54    ***/
TearDown()55   virtual void TearDown() {}
56 
57   /***
58    * When the Audio framework / HAL tries to query audio config about format,
59    * channel mask and sample rate, it uses this function to fetch from the
60    * Bluetooth stack
61    ***/
LoadAudioConfig(audio_config_t *)62   virtual bool LoadAudioConfig(audio_config_t*) const { return false; };
63 
64   /***
65    * WAR to support Mono mode / 16 bits per sample
66    ***/
ForcePcmStereoToMono(bool)67   virtual void ForcePcmStereoToMono(bool) {}
68 
69   /***
70    * When the Audio framework / HAL wants to change the stream state, it invokes
71    * these 3 functions to control the Bluetooth stack (Audio Control Path).
72    * Note: Both Start() and Suspend() will return true when there are no errors.
73    * Called by Audio framework / HAL to start the stream
74    ***/
Start()75   virtual bool Start() { return false; }
76 
77   /***
78    * Called by Audio framework / HAL to suspend the stream
79    ***/
Suspend()80   virtual bool Suspend() { return false; };
81 
82   /***
83     virtual bool Suspend() { return false; }
84     * Called by Audio framework / HAL to stop the stream
85   ***/
Stop()86   virtual void Stop() {}
87 
88   /***
89    * Called by the Audio framework / HAL to fetch information about audio frames
90    * presented to an external sink, or frames presented fror an internal sink
91    ***/
GetPresentationPosition(uint64_t *,uint64_t *,timespec *)92   virtual bool GetPresentationPosition(uint64_t*, uint64_t*, timespec*) const {
93     return false;
94   }
95 
96   /***
97    * Called by the Audio framework / HAL when the metadata of the stream's
98    * source has been changed.
99    ***/
UpdateSourceMetadata(const source_metadata *)100   virtual void UpdateSourceMetadata(const source_metadata*) const {};
101 
102   /***
103    * Return the current BluetoothStreamState
104    ***/
GetState()105   virtual BluetoothStreamState GetState() const {
106     return static_cast<BluetoothStreamState>(0);
107   }
108 
109   /***
110    * Set the current BluetoothStreamState
111    ***/
SetState(BluetoothStreamState state)112   virtual void SetState(BluetoothStreamState state) {}
113 
IsA2dp()114   virtual bool IsA2dp() const { return false; }
115 
IsLeAudio()116   virtual bool IsLeAudio() const { return false; }
117 
GetPreferredDataIntervalUs(size_t * interval_us)118   virtual bool GetPreferredDataIntervalUs(size_t* interval_us) const {
119     return false;
120   };
121 
WriteData(const void * buffer,size_t bytes)122   virtual size_t WriteData(const void* buffer, size_t bytes) const {
123     return 0;
124   };
ReadData(void * buffer,size_t bytes)125   virtual size_t ReadData(void* buffer, size_t bytes) const { return 0; };
126 };
127 
128 namespace aidl {
129 
130 using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioStatus;
131 using ::aidl::android::hardware::bluetooth::audio::SessionType;
132 
133 class BluetoothAudioPortAidl : public BluetoothAudioPort {
134  public:
135   BluetoothAudioPortAidl();
136   virtual ~BluetoothAudioPortAidl() = default;
137 
138   bool SetUp(audio_devices_t devices) override;
139 
140   void TearDown() override;
141 
ForcePcmStereoToMono(bool force)142   void ForcePcmStereoToMono(bool force) override { is_stereo_to_mono_ = force; }
143 
144   bool Start() override;
145   bool Suspend() override;
146   void Stop() override;
147 
148   bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* byte,
149                                timespec* timestamp) const override;
150 
151   void UpdateSourceMetadata(
152       const source_metadata* source_metadata) const override;
153 
154   /***
155    * Called by the Audio framework / HAL when the metadata of the stream's
156    * sink has been changed.
157    ***/
158   virtual void UpdateSinkMetadata(const sink_metadata* sink_metadata) const;
159 
160   BluetoothStreamState GetState() const override;
161 
162   void SetState(BluetoothStreamState state) override;
163 
IsA2dp()164   bool IsA2dp() const override {
165     return session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
166            session_type_ ==
167                SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
168   }
169 
IsLeAudio()170   bool IsLeAudio() const override {
171     return session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
172            session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
173            session_type_ ==
174                SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
175            session_type_ ==
176                SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
177            session_type_ ==
178                SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH ||
179            session_type_ ==
180                SessionType::
181                    LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
182   }
183 
184   bool GetPreferredDataIntervalUs(size_t* interval_us) const override;
185 
186  protected:
187   uint16_t cookie_;
188   BluetoothStreamState state_;
189   SessionType session_type_;
190   // WR to support Mono: True if fetching Stereo and mixing into Mono
191   bool is_stereo_to_mono_ = false;
192   virtual bool in_use() const;
193 
194  private:
195   mutable std::mutex cv_mutex_;
196   std::condition_variable internal_cv_;
197 
198   // Check and initialize session type for |devices| If failed, this
199   // BluetoothAudioPortAidl is not initialized and must be deleted.
200   bool init_session_type(audio_devices_t device);
201 
202   bool CondwaitState(BluetoothStreamState state);
203 
204   void ControlResultHandler(const BluetoothAudioStatus& status);
205   void SessionChangedHandler();
206 };
207 
208 class BluetoothAudioPortAidlOut : public BluetoothAudioPortAidl {
209  public:
210   ~BluetoothAudioPortAidlOut();
211 
212   // The audio data path to the Bluetooth stack (Software encoding)
213   size_t WriteData(const void* buffer, size_t bytes) const override;
214   bool LoadAudioConfig(audio_config_t* audio_cfg) const override;
215 };
216 
217 class BluetoothAudioPortAidlIn : public BluetoothAudioPortAidl {
218  public:
219   ~BluetoothAudioPortAidlIn();
220 
221   // The audio data path from the Bluetooth stack (Software decoded)
222   size_t ReadData(void* buffer, size_t bytes) const override;
223   bool LoadAudioConfig(audio_config_t* audio_cfg) const override;
224 };
225 
226 }  // namespace aidl
227 }  // namespace audio
228 }  // namespace bluetooth
229 }  // namespace android
230