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