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