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