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