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.0/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 ::android::hardware::bluetooth::audio::V2_0::SessionType; 32 33 // Proxy for Bluetooth Audio HW Module to communicate with Bluetooth Audio 34 // Session Control. All methods are not thread safe, so users must acquire a 35 // lock. Note: currently, in stream_apis.cc, if GetState() is only used for 36 // verbose logging, it is not locked, so the state may not be synchronized. 37 class BluetoothAudioPortOut { 38 public: 39 BluetoothAudioPortOut(); 40 ~BluetoothAudioPortOut() = default; 41 42 // Fetch output control / data path of BluetoothAudioPortOut and setup 43 // callbacks into BluetoothAudioProvider. If SetUp() returns false, the audio 44 // HAL must delete this BluetoothAudioPortOut and return EINVAL to caller 45 bool SetUp(audio_devices_t devices); 46 47 // Unregister this BluetoothAudioPortOut from BluetoothAudioSessionControl. 48 // Audio HAL must delete this BluetoothAudioPortOut after calling this. 49 void TearDown(); 50 51 // When the Audio framework / HAL tries to query audio config about format, 52 // channel mask and sample rate, it uses this function to fetch from the 53 // Bluetooth stack 54 bool LoadAudioConfig(audio_config_t* audio_cfg) const; 55 56 // WAR to support Mono mode / 16 bits per sample ForcePcmStereoToMono(bool force)57 void ForcePcmStereoToMono(bool force) { 58 is_stereo_to_mono_ = force; 59 } 60 61 // When the Audio framework / HAL wants to change the stream state, it invokes 62 // these 3 functions to control the Bluetooth stack (Audio Control Path). 63 // Note: Both Start() and Suspend() will return ture when there are no errors. 64 // Called by Audio framework / HAL to start the stream 65 bool Start(); 66 // Called by Audio framework / HAL to suspend the stream 67 bool Suspend(); 68 // Called by Audio framework / HAL to stop the stream 69 void Stop(); 70 71 // The audio data path to the Bluetooth stack (Software encoding) 72 size_t WriteData(const void* buffer, size_t bytes) const; 73 74 // Called by the Audio framework / HAL to fetch informaiton about audio frames 75 // presented to an external sink. 76 bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* bytes, 77 timespec* timestamp) const; 78 79 // Called by the Audio framework / HAL when the metadata of the stream's 80 // source has been changed. 81 void UpdateMetadata(const source_metadata* source_metadata) const; 82 83 // Return the current BluetoothStreamState 84 BluetoothStreamState GetState() const; 85 86 // Set the current BluetoothStreamState 87 void SetState(BluetoothStreamState state); 88 IsA2dp()89 bool IsA2dp() const { 90 return session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH || 91 session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH; 92 } 93 94 private: 95 BluetoothStreamState state_; 96 SessionType session_type_; 97 uint16_t cookie_; 98 mutable std::mutex cv_mutex_; 99 std::condition_variable internal_cv_; 100 // WR to support Mono: True if fetching Stereo and mixing into Mono 101 bool is_stereo_to_mono_ = false; 102 103 // Check and initialize session type for |devices| If failed, this 104 // BluetoothAudioPortOut is not initialized and must be deleted. 105 bool init_session_type(audio_devices_t device); 106 107 bool in_use() const; 108 109 bool CondwaitState(BluetoothStreamState state); 110 111 void ControlResultHandler( 112 const ::android::hardware::bluetooth::audio::V2_0::Status& status); 113 void SessionChangedHandler(); 114 }; 115 116 } // namespace audio 117 } // namespace bluetooth 118 } // namespace android 119