1 /* 2 * Copyright 2023 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 <condition_variable> 20 #include <mutex> 21 22 #include <android-base/thread_annotations.h> 23 24 #include <aidl/android/hardware/audio/common/SinkMetadata.h> 25 #include <aidl/android/hardware/audio/common/SourceMetadata.h> 26 #include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h> 27 #include <aidl/android/hardware/bluetooth/audio/PcmConfiguration.h> 28 #include <aidl/android/hardware/bluetooth/audio/PresentationPosition.h> 29 #include <aidl/android/hardware/bluetooth/audio/SessionType.h> 30 #include <aidl/android/media/audio/common/AudioDeviceDescription.h> 31 32 namespace android::bluetooth::audio::aidl { 33 34 enum class BluetoothStreamState : uint8_t { 35 DISABLED = 0, // This stream is closing or Bluetooth profiles (A2DP/LE) is disabled 36 STANDBY, 37 STARTING, 38 STARTED, 39 SUSPENDING, 40 UNKNOWN, 41 }; 42 43 std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state); 44 45 /** 46 * Proxy for Bluetooth Audio HW Module to communicate with Bluetooth Audio 47 * Session Control. All methods are not thread safe, so users must acquire a 48 * lock. Note: currently, getState() of DevicePortProxy is only used for 49 * verbose logging, it is not locked, so the state may not be synchronized. 50 */ 51 class BluetoothAudioPort { 52 public: 53 BluetoothAudioPort() = default; 54 virtual ~BluetoothAudioPort() = default; 55 56 /** 57 * Fetch output control / data path of BluetoothAudioPort and setup 58 * callbacks into BluetoothAudioProvider. If registerPort() returns false, the audio 59 * HAL must delete this BluetoothAudioPort and return EINVAL to caller 60 */ 61 virtual bool registerPort( 62 const ::aidl::android::media::audio::common::AudioDeviceDescription&) = 0; 63 64 /** 65 * Unregister this BluetoothAudioPort from BluetoothAudioSessionControl. 66 * Audio HAL must delete this BluetoothAudioPort after calling this. 67 */ 68 virtual void unregisterPort() = 0; 69 70 /** 71 * When the Audio framework / HAL tries to query audio config about format, 72 * channel mask and sample rate, it uses this function to fetch from the 73 * Bluetooth stack 74 */ 75 virtual bool loadAudioConfig( 76 ::aidl::android::hardware::bluetooth::audio::PcmConfiguration&) = 0; 77 78 /** 79 * When the Audio framework / HAL wants to change the stream state, it invokes 80 * these 4 functions to control the Bluetooth stack (Audio Control Path). 81 * Note: standby(), start() and suspend() will return true when there are no errors. 82 83 * Called by Audio framework / HAL to change the state to stand by. When A2DP/LE profile is 84 * disabled, the port is first set to STANDBY by calling suspend and then mState is set to 85 * DISABLED. To reset the state back to STANDBY this method is called. 86 */ 87 virtual bool standby() = 0; 88 89 /** 90 * Called by Audio framework / HAL to start the stream 91 */ 92 virtual bool start() = 0; 93 94 /** 95 * Called by Audio framework / HAL to suspend the stream 96 */ 97 virtual bool suspend() = 0; 98 99 /** 100 * Called by Audio framework / HAL to stop the stream 101 */ 102 virtual void stop() = 0; 103 104 /** 105 * Called by the Audio framework / HAL to fetch information about audio frames 106 * presented to an external sink, or frames presented fror an internal sink 107 */ 108 virtual bool getPresentationPosition( 109 ::aidl::android::hardware::bluetooth::audio::PresentationPosition&) const = 0; 110 111 /** 112 * Called by the Audio framework / HAL when the metadata of the stream's 113 * source has been changed. 114 */ updateSourceMetadata(const::aidl::android::hardware::audio::common::SourceMetadata &)115 virtual bool updateSourceMetadata( 116 const ::aidl::android::hardware::audio::common::SourceMetadata&) const { 117 return false; 118 } 119 120 /** 121 * Called by the Audio framework / HAL when the metadata of the stream's 122 * sink has been changed. 123 */ updateSinkMetadata(const::aidl::android::hardware::audio::common::SinkMetadata &)124 virtual bool updateSinkMetadata( 125 const ::aidl::android::hardware::audio::common::SinkMetadata&) const { 126 return false; 127 } 128 129 /** 130 * Return the current BluetoothStreamState 131 */ 132 virtual BluetoothStreamState getState() const = 0; 133 134 /** 135 * Set the current BluetoothStreamState 136 */ 137 virtual bool setState(BluetoothStreamState) = 0; 138 139 virtual bool isA2dp() const = 0; 140 141 virtual bool isLeAudio() const = 0; 142 143 virtual bool getPreferredDataIntervalUs(size_t&) const = 0; 144 writeData(const void *,size_t)145 virtual size_t writeData(const void*, size_t) const { return 0; } 146 readData(void *,size_t)147 virtual size_t readData(void*, size_t) const { return 0; } 148 }; 149 150 class BluetoothAudioPortAidl : public BluetoothAudioPort { 151 public: 152 BluetoothAudioPortAidl(); 153 virtual ~BluetoothAudioPortAidl(); 154 155 bool registerPort(const ::aidl::android::media::audio::common::AudioDeviceDescription& 156 description) override; 157 158 void unregisterPort() override; 159 160 bool loadAudioConfig( 161 ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override; 162 163 bool standby() override; 164 bool start() override; 165 bool suspend() override; 166 void stop() override; 167 168 bool getPresentationPosition(::aidl::android::hardware::bluetooth::audio::PresentationPosition& 169 presentation_position) const override; 170 171 bool updateSourceMetadata(const ::aidl::android::hardware::audio::common::SourceMetadata& 172 sourceMetadata) const override; 173 174 bool updateSinkMetadata(const ::aidl::android::hardware::audio::common::SinkMetadata& 175 sinkMetadata) const override; 176 177 /** 178 * Return the current BluetoothStreamState 179 * Note: This method is used for logging, does not lock, so value returned may not be latest 180 */ 181 BluetoothStreamState getState() const override NO_THREAD_SAFETY_ANALYSIS; 182 183 bool setState(BluetoothStreamState state) override; 184 185 bool isA2dp() const override; 186 187 bool isLeAudio() const override; 188 189 bool getPreferredDataIntervalUs(size_t& interval_us) const override; 190 191 protected: 192 uint16_t mCookie; 193 BluetoothStreamState mState GUARDED_BY(mCvMutex); 194 ::aidl::android::hardware::bluetooth::audio::SessionType mSessionType; 195 // WR to support Mono: True if fetching Stereo and mixing into Mono 196 bool mIsStereoToMono = false; 197 198 bool inUse() const; 199 200 std::string debugMessage() const; 201 202 private: 203 // start()/suspend() report state change status via callback. Wait until kMaxWaitingTimeMs or a 204 // state change after a call to start()/suspend() and analyse the returned status. Below mutex, 205 // conditional variable serves this purpose. 206 mutable std::mutex mCvMutex; 207 std::condition_variable mInternalCv GUARDED_BY(mCvMutex); 208 209 // Check and initialize session type for |devices| If failed, this 210 // BluetoothAudioPortAidl is not initialized and must be deleted. 211 bool initSessionType( 212 const ::aidl::android::media::audio::common::AudioDeviceDescription& description); 213 214 bool condWaitState(BluetoothStreamState state); 215 216 void controlResultHandler( 217 uint16_t cookie, 218 const ::aidl::android::hardware::bluetooth::audio::BluetoothAudioStatus& status); 219 void sessionChangedHandler(uint16_t cookie); 220 }; 221 222 class BluetoothAudioPortAidlOut : public BluetoothAudioPortAidl { 223 public: 224 bool loadAudioConfig( 225 ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override; 226 227 // The audio data path to the Bluetooth stack (Software encoding) 228 size_t writeData(const void* buffer, size_t bytes) const override; 229 }; 230 231 class BluetoothAudioPortAidlIn : public BluetoothAudioPortAidl { 232 public: 233 // The audio data path from the Bluetooth stack (Software decoded) 234 size_t readData(void* buffer, size_t bytes) const override; 235 }; 236 237 } // namespace android::bluetooth::audio::aidl 238