blob: 8ee2bb11032029ce5e16ed7875c446b26e8ec93f [file] [log] [blame]
Cheney Niad05f3e2018-11-08 16:41:02 +08001/*
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
Cheney Ni676b2762019-02-24 02:14:20 +080029#define BLUETOOTH_AUDIO_HAL_PROP_DISABLED "persist.bluetooth.bluetooth_audio_hal.disabled"
Cheney Niad05f3e2018-11-08 16:41:02 +080030
31namespace bluetooth {
32namespace audio {
33
34using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
35using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
36using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
37using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
Satish kumar sugasi6c1dec92019-02-07 14:40:35 -080038using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
39using ::android::hardware::bluetooth::audio::V2_0::CodecType;
Cheney Niad05f3e2018-11-08 16:41:02 +080040using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
41using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
42using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
43using ::android::hardware::bluetooth::audio::V2_0::SessionType;
44using ::android::hardware::bluetooth::audio::V2_0::TimeSpec;
45using BluetoothAudioStatus =
46 ::android::hardware::bluetooth::audio::V2_0::Status;
47
48enum class BluetoothAudioCtrlAck : uint8_t {
49 SUCCESS_FINISHED = 0,
50 PENDING,
51 FAILURE_UNSUPPORTED,
52 FAILURE_BUSY,
53 FAILURE_DISCONNECTING,
54 FAILURE
55};
56
57std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack);
58
59inline 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.
79class IBluetoothTransportInstance {
80 public:
81 IBluetoothTransportInstance(SessionType sessionType,
82 AudioConfiguration audioConfig)
83 : session_type_(sessionType), audio_config_(std::move(audioConfig)){};
84 virtual ~IBluetoothTransportInstance() = default;
85
86 SessionType GetSessionType() const { return session_type_; }
87
88 AudioConfiguration GetAudioConfiguration() const { return audio_config_; }
89
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
118class BluetoothAudioDeathRecipient;
119
120// The client interface connects an IBluetoothTransportInstance to
121// IBluetoothAudioProvider and helps to route callbacks to
122// IBluetoothTransportInstance
123class 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
Cheney Ni3abcc012019-03-14 20:58:59 +0800134 bool IsValid() const {
135 return provider_ != nullptr;
136 }
137
Cheney Niad05f3e2018-11-08 16:41:02 +0800138 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,
Nick Desaulniers7ee58352019-10-09 11:06:55 -0700161 .channelMode = ChannelMode::UNKNOWN,
Cheney Niad05f3e2018-11-08 16:41:02 +0800162 .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
Nick Desaulniers7ee58352019-10-09 11:06:55 -0700163 };
Cheney Niad05f3e2018-11-08 16:41:02 +0800164
165 private:
166 // Helper function to connect to an IBluetoothAudioProvider
167 void fetch_audio_provider();
168
169 mutable std::mutex internal_mutex_;
170 IBluetoothTransportInstance* sink_;
171 android::sp<IBluetoothAudioProvider> provider_;
172 std::vector<AudioCapabilities> capabilities_;
173 bool session_started_;
174 std::unique_ptr<::android::hardware::MessageQueue<
175 uint8_t, ::android::hardware::kSynchronizedReadWrite>>
176 mDataMQ;
177 android::sp<BluetoothAudioDeathRecipient> death_recipient_;
178};
179
180} // namespace audio
181} // namespace bluetooth