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