1 /* 2 * Copyright 2019 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 <android/hardware/bluetooth/audio/2.1/types.h> 20 #include <hardware/audio.h> 21 #include <condition_variable> 22 #include <mutex> 23 #include <unordered_map> 24 25 enum class BluetoothStreamState : uint8_t; 26 27 namespace android { 28 namespace bluetooth { 29 namespace audio { 30 31 using SessionType_2_1 = 32 ::android::hardware::bluetooth::audio::V2_1::SessionType; 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 class BluetoothAudioPort { 39 public: 40 BluetoothAudioPort(); 41 virtual ~BluetoothAudioPort() = default; 42 43 // Fetch output control / data path of BluetoothAudioPort and setup 44 // callbacks into BluetoothAudioProvider. If SetUp() returns false, the audio 45 // HAL must delete this BluetoothAudioPort and return EINVAL to caller 46 bool SetUp(audio_devices_t devices); 47 48 // Unregister this BluetoothAudioPort from BluetoothAudioSessionControl. 49 // Audio HAL must delete this BluetoothAudioPort after calling this. 50 void TearDown(); 51 52 // When the Audio framework / HAL tries to query audio config about format, 53 // channel mask and sample rate, it uses this function to fetch from the 54 // Bluetooth stack 55 virtual bool LoadAudioConfig(audio_config_t* audio_cfg) const = 0; 56 57 // WAR to support Mono mode / 16 bits per sample ForcePcmStereoToMono(bool force)58 void ForcePcmStereoToMono(bool force) { 59 is_stereo_to_mono_ = force; 60 } 61 62 // When the Audio framework / HAL wants to change the stream state, it invokes 63 // these 3 functions to control the Bluetooth stack (Audio Control Path). 64 // Note: Both Start() and Suspend() will return ture when there are no errors. 65 // Called by Audio framework / HAL to start the stream 66 bool Start(); 67 // Called by Audio framework / HAL to suspend the stream 68 bool Suspend(); 69 // Called by Audio framework / HAL to stop the stream 70 void Stop(); 71 72 // Called by the Audio framework / HAL to fetch informaiton about audio frames 73 // presented to an external sink, or frames presented fror an internal sink 74 bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* bytes, 75 timespec* timestamp) const; 76 77 // Called by the Audio framework / HAL when the metadata of the stream's 78 // source has been changed. 79 void UpdateMetadata(const source_metadata* source_metadata) const; 80 81 // Return the current BluetoothStreamState 82 BluetoothStreamState GetState() const; 83 84 // Set the current BluetoothStreamState 85 void SetState(BluetoothStreamState state); 86 IsA2dp()87 bool IsA2dp() const { 88 return session_type_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH || 89 session_type_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH; 90 } 91 92 protected: 93 uint16_t cookie_; 94 BluetoothStreamState state_; 95 SessionType_2_1 session_type_; 96 // WR to support Mono: True if fetching Stereo and mixing into Mono 97 bool is_stereo_to_mono_ = false; 98 bool in_use() const; 99 100 private: 101 mutable std::mutex cv_mutex_; 102 std::condition_variable internal_cv_; 103 104 // Check and initialize session type for |devices| If failed, this 105 // BluetoothAudioPort is not initialized and must be deleted. 106 bool init_session_type(audio_devices_t device); 107 108 bool CondwaitState(BluetoothStreamState state); 109 110 void ControlResultHandler( 111 const ::android::hardware::bluetooth::audio::V2_0::Status& status); 112 void SessionChangedHandler(); 113 }; 114 115 class BluetoothAudioPortOut : public BluetoothAudioPort { 116 public: 117 ~BluetoothAudioPortOut() = default; 118 119 // The audio data path to the Bluetooth stack (Software encoding) 120 size_t WriteData(const void* buffer, size_t bytes) const; 121 bool LoadAudioConfig(audio_config_t* audio_cfg) const; 122 }; 123 124 class BluetoothAudioPortIn : public BluetoothAudioPort { 125 public: 126 ~BluetoothAudioPortIn() = default; 127 128 // The audio data path from the Bluetooth stack (Software decoded) 129 size_t ReadData(void* buffer, size_t bytes) const; 130 bool LoadAudioConfig(audio_config_t* audio_cfg) const; 131 }; 132 133 } // namespace audio 134 } // namespace bluetooth 135 } // namespace android 136