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