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 <android/hardware/bluetooth/audio/2.1/types.h>
20 #include <hardware/audio.h>
21 
22 #include <condition_variable>
23 #include <mutex>
24 #include <unordered_map>
25 
26 #include "device_port_proxy.h"
27 
28 enum class BluetoothStreamState : uint8_t;
29 
30 namespace android {
31 namespace bluetooth {
32 namespace audio {
33 namespace hidl {
34 
35 using SessionType_2_1 = ::android::hardware::bluetooth::audio::V2_1::SessionType;
36 
37 class BluetoothAudioPortHidl : public BluetoothAudioPort {
38 public:
39   BluetoothAudioPortHidl();
40   virtual ~BluetoothAudioPortHidl() = default;
41 
42   bool SetUp(audio_devices_t devices) override;
43 
44   void TearDown() override;
45 
ForcePcmStereoToMono(bool force)46   void ForcePcmStereoToMono(bool force) override { is_stereo_to_mono_ = force; }
47 
48   bool Start() override;
49 
50   bool Suspend() override;
51 
52   void Stop() override;
53 
54   bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* bytes,
55                                timespec* timestamp) const override;
56 
57   void UpdateTracksMetadata(const source_metadata* source_metadata) const;
58 
59   BluetoothStreamState GetState() const override;
60 
61   void SetState(BluetoothStreamState state) override;
62 
IsA2dp()63   bool IsA2dp() const override {
64     return session_type_hidl_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
65            session_type_hidl_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH;
66   }
67 
IsLeAudio()68   bool IsLeAudio() const override {
69     return session_type_hidl_ == SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
70            session_type_hidl_ == SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH ||
71            session_type_hidl_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
72            session_type_hidl_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
73   }
74 
75   bool GetPreferredDataIntervalUs(size_t* interval_us) const override;
76 
77 protected:
78   SessionType_2_1 session_type_hidl_;
79   uint16_t cookie_;
80   BluetoothStreamState state_;
81   // WR to support Mono: True if fetching Stereo and mixing into Mono
82   bool is_stereo_to_mono_ = false;
83 
84   bool in_use() const;
85 
86 private:
87   mutable std::mutex cv_mutex_;
88   std::condition_variable internal_cv_;
89 
90   bool init_session_type(audio_devices_t device);
91 
92   bool CondwaitState(BluetoothStreamState state);
93 
94   void ControlResultHandler(const ::android::hardware::bluetooth::audio::V2_0::Status& status);
95 
96   void SessionChangedHandler();
97 };
98 
99 class BluetoothAudioPortHidlOut : public BluetoothAudioPortHidl {
100 public:
101   ~BluetoothAudioPortHidlOut();
102 
103   size_t WriteData(const void* buffer, size_t bytes) const override;
104   bool LoadAudioConfig(audio_config_t* audio_cfg) const override;
105 };
106 
107 class BluetoothAudioPortHidlIn : public BluetoothAudioPortHidl {
108 public:
109   ~BluetoothAudioPortHidlIn();
110 
111   size_t ReadData(void* buffer, size_t bytes) const override;
112   bool LoadAudioConfig(audio_config_t* audio_cfg) const override;
113 };
114 
115 }  // namespace hidl
116 }  // namespace audio
117 }  // namespace bluetooth
118 }  // namespace android
119