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 <time.h>
20 #include <mutex>
21 #include <vector>
22 
23 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvider.h>
24 #include <android/hardware/bluetooth/audio/2.0/types.h>
25 #include <fmq/MessageQueue.h>
26 #include <hardware/audio.h>
27 
28 #include "common/message_loop_thread.h"
29 
30 #define BLUETOOTH_AUDIO_HAL_PROP_DISABLED "persist.bluetooth.bluetooth_audio_hal.disabled"
31 
32 namespace bluetooth {
33 namespace audio {
34 
35 using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
36 using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
37 using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
38 using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
39 using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
40 using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
41 using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
42 using ::android::hardware::bluetooth::audio::V2_0::SessionType;
43 using ::android::hardware::bluetooth::audio::V2_0::TimeSpec;
44 using BluetoothAudioStatus =
45     ::android::hardware::bluetooth::audio::V2_0::Status;
46 
47 enum class BluetoothAudioCtrlAck : uint8_t {
48   SUCCESS_FINISHED = 0,
49   PENDING,
50   FAILURE_UNSUPPORTED,
51   FAILURE_BUSY,
52   FAILURE_DISCONNECTING,
53   FAILURE
54 };
55 
56 std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack);
57 
BluetoothAudioCtrlAckToHalStatus(const BluetoothAudioCtrlAck & ack)58 inline BluetoothAudioStatus BluetoothAudioCtrlAckToHalStatus(
59     const BluetoothAudioCtrlAck& ack) {
60   switch (ack) {
61     case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
62       return BluetoothAudioStatus::SUCCESS;
63     case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
64       return BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION;
65     case BluetoothAudioCtrlAck::PENDING:
66       return BluetoothAudioStatus::FAILURE;
67     case BluetoothAudioCtrlAck::FAILURE_BUSY:
68       return BluetoothAudioStatus::FAILURE;
69     case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
70       return BluetoothAudioStatus::FAILURE;
71     default:
72       return BluetoothAudioStatus::FAILURE;
73   }
74 }
75 
76 // An IBluetoothTransportInstance needs to be implemented by a Bluetooth audio
77 // transport, such as A2DP or Hearing Aid, to handle callbacks from Audio HAL.
78 class IBluetoothTransportInstance {
79  public:
IBluetoothTransportInstance(SessionType sessionType,AudioConfiguration audioConfig)80   IBluetoothTransportInstance(SessionType sessionType,
81                               AudioConfiguration audioConfig)
82       : session_type_(sessionType), audio_config_(std::move(audioConfig)){};
83   virtual ~IBluetoothTransportInstance() = default;
84 
GetSessionType()85   SessionType GetSessionType() const { return session_type_; }
86 
GetAudioConfiguration()87   AudioConfiguration GetAudioConfiguration() const { return audio_config_; }
88 
UpdateAudioConfiguration(const AudioConfiguration & audio_config)89   void UpdateAudioConfiguration(const AudioConfiguration& audio_config) {
90     audio_config_ = audio_config;
91   }
92 
93   virtual BluetoothAudioCtrlAck StartRequest() = 0;
94 
95   virtual BluetoothAudioCtrlAck SuspendRequest() = 0;
96 
97   virtual void StopRequest() = 0;
98 
99   virtual bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
100                                        uint64_t* total_bytes_readed,
101                                        timespec* data_position) = 0;
102 
103   virtual void MetadataChanged(const source_metadata_t& source_metadata) = 0;
104 
105   // Invoked when the transport is requested to reset presentation position
106   virtual void ResetPresentationPosition() = 0;
107 
108   // Invoked when the transport is requested to log bytes read
109   virtual void LogBytesRead(size_t bytes_readed) = 0;
110 
111  private:
112   const SessionType session_type_;
113   AudioConfiguration audio_config_;
114 };
115 
116 // common object is shared between different kind of SessionType
117 class BluetoothAudioDeathRecipient;
118 
119 // The client interface connects an IBluetoothTransportInstance to
120 // IBluetoothAudioProvider and helps to route callbacks to
121 // IBluetoothTransportInstance
122 class BluetoothAudioClientInterface {
123  public:
124   // Constructs an BluetoothAudioClientInterface to communicate to
125   // BluetoothAudio HAL. |sink| is the implementation for the transport, and
126   // |message_loop| is the thread where callbacks are invoked.
127   BluetoothAudioClientInterface(
128       IBluetoothTransportInstance* sink,
129       bluetooth::common::MessageLoopThread* message_loop);
130 
131   ~BluetoothAudioClientInterface();
132 
IsValid()133   bool IsValid() const {
134     return provider_ != nullptr;
135   }
136 
GetTransportInstance()137   IBluetoothTransportInstance* GetTransportInstance() const { return sink_; }
138 
139   std::vector<AudioCapabilities> GetAudioCapabilities() const;
140   static std::vector<AudioCapabilities> GetAudioCapabilities(
141       SessionType session_type);
142 
143   bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
144 
145   int StartSession();
146 
147   void StreamStarted(const BluetoothAudioCtrlAck& ack);
148 
149   void StreamSuspended(const BluetoothAudioCtrlAck& ack);
150 
151   int EndSession();
152 
153   // Read data from audio  HAL through fmq
154   size_t ReadAudioData(uint8_t* p_buf, uint32_t len);
155 
156   // Write data to audio HAL through fmq
157   size_t WriteAudioData(uint8_t* p_buf, uint32_t len);
158 
159   // Renew the connection and usually is used when HIDL restarted
160   void RenewAudioProviderAndSession();
161 
162   static constexpr PcmParameters kInvalidPcmConfiguration = {
163       .sampleRate = SampleRate::RATE_UNKNOWN,
164       .channelMode = ChannelMode::UNKNOWN,
165       .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
166   };
167 
168  private:
169   static bool IsSupported();
170 
171   // Helper function to connect to an IBluetoothAudioProvider
172   void FetchAudioProvider();
173 
174   mutable std::mutex internal_mutex_;
175   IBluetoothTransportInstance* sink_;
176   android::sp<IBluetoothAudioProvider> provider_;
177   std::vector<AudioCapabilities> capabilities_;
178   bool session_started_;
179   std::unique_ptr<::android::hardware::MessageQueue<
180       uint8_t, ::android::hardware::kSynchronizedReadWrite>>
181       mDataMQ;
182   android::sp<BluetoothAudioDeathRecipient> death_recipient_;
183 };
184 
185 }  // namespace audio
186 }  // namespace bluetooth
187