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