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 ***/ Start()77 virtual bool Start() { 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 { 95 return false; 96 } 97 98 /*** 99 * Return the current BluetoothStreamState 100 ***/ GetState()101 virtual BluetoothStreamState GetState() const { 102 return static_cast<BluetoothStreamState>(0); 103 } 104 105 /*** 106 * Set the current BluetoothStreamState 107 ***/ SetState(BluetoothStreamState state)108 virtual void SetState(BluetoothStreamState state) {} 109 IsA2dp()110 virtual bool IsA2dp() const { return false; } 111 IsLeAudio()112 virtual bool IsLeAudio() const { return false; } 113 GetPreferredDataIntervalUs(size_t * interval_us)114 virtual bool GetPreferredDataIntervalUs(size_t* interval_us) const { 115 return false; 116 }; 117 WriteData(const void * buffer,size_t bytes)118 virtual size_t WriteData(const void* buffer, size_t bytes) const { 119 return 0; 120 }; ReadData(void * buffer,size_t bytes)121 virtual size_t ReadData(void* buffer, size_t bytes) const { return 0; }; 122 }; 123 124 namespace aidl { 125 126 using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioStatus; 127 using ::aidl::android::hardware::bluetooth::audio::SessionType; 128 129 class BluetoothAudioPortAidl : public BluetoothAudioPort { 130 public: 131 BluetoothAudioPortAidl(); 132 virtual ~BluetoothAudioPortAidl() = default; 133 134 bool SetUp(audio_devices_t devices) override; 135 136 void TearDown() override; 137 ForcePcmStereoToMono(bool force)138 void ForcePcmStereoToMono(bool force) override { is_stereo_to_mono_ = force; } 139 140 bool Start() override; 141 bool Suspend() override; 142 void Stop() override; 143 144 bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* byte, 145 timespec* timestamp) const override; 146 147 void UpdateSourceMetadata(const source_metadata_v7* source_metadata) const; 148 149 /*** 150 * Called by the Audio framework / HAL when the metadata of the stream's 151 * sink has been changed. 152 ***/ 153 virtual void UpdateSinkMetadata(const sink_metadata_v7* sink_metadata) const; 154 155 BluetoothStreamState GetState() const override; 156 157 void SetState(BluetoothStreamState state) override; 158 IsA2dp()159 bool IsA2dp() const override { 160 return session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || 161 session_type_ == 162 SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH; 163 } 164 IsLeAudio()165 bool IsLeAudio() const override { 166 return session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH || 167 session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH || 168 session_type_ == 169 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || 170 session_type_ == 171 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH || 172 session_type_ == 173 SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH || 174 session_type_ == 175 SessionType:: 176 LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH; 177 } 178 179 bool GetPreferredDataIntervalUs(size_t* interval_us) const override; 180 181 protected: 182 uint16_t cookie_; 183 BluetoothStreamState state_; 184 SessionType session_type_; 185 // WR to support Mono: True if fetching Stereo and mixing into Mono 186 bool is_stereo_to_mono_ = false; 187 virtual bool in_use() const; 188 189 private: 190 mutable std::mutex cv_mutex_; 191 std::condition_variable internal_cv_; 192 193 // Check and initialize session type for |devices| If failed, this 194 // BluetoothAudioPortAidl is not initialized and must be deleted. 195 bool init_session_type(audio_devices_t device); 196 197 bool CondwaitState(BluetoothStreamState state); 198 199 void ControlResultHandler(const BluetoothAudioStatus& status); 200 void SessionChangedHandler(); 201 }; 202 203 class BluetoothAudioPortAidlOut : public BluetoothAudioPortAidl { 204 public: 205 ~BluetoothAudioPortAidlOut(); 206 207 // The audio data path to the Bluetooth stack (Software encoding) 208 size_t WriteData(const void* buffer, size_t bytes) const override; 209 bool LoadAudioConfig(audio_config_t* audio_cfg) const override; 210 }; 211 212 class BluetoothAudioPortAidlIn : public BluetoothAudioPortAidl { 213 public: 214 ~BluetoothAudioPortAidlIn(); 215 216 // The audio data path from the Bluetooth stack (Software decoded) 217 size_t ReadData(void* buffer, size_t bytes) const override; 218 bool LoadAudioConfig(audio_config_t* audio_cfg) const override; 219 }; 220 221 } // namespace aidl 222 } // namespace audio 223 } // namespace bluetooth 224 } // namespace android 225