1 //
2 // Copyright 2017 Google, Inc.
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 #include "service/hal/bluetooth_av_interface.h"
18
19 #include <base/logging.h>
20 #include <base/memory/ptr_util.h>
21 #include <base/observer_list.h>
22
23 #include <shared_mutex>
24
25 #include "abstract_observer_list.h"
26 #include "service/hal/bluetooth_interface.h"
27 #include "types/raw_address.h"
28
29 namespace bluetooth {
30 namespace hal {
31
32 namespace {
33
34 BluetoothAvInterface* g_interface = nullptr;
35
36 #if defined(OS_GENERIC) && defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION < 3500)
37 using shared_mutex_impl = std::shared_mutex;
38 #else
39 using shared_mutex_impl = std::shared_timed_mutex;
40 #endif
41
42 // Mutex used by callbacks to access |g_interface|. If we initialize or clean it
43 // use unique_lock. If only accessing |g_interface| use shared lock.
44 shared_mutex_impl g_instance_lock;
45
46 btbase::AbstractObserverList<BluetoothAvInterface::A2dpSourceObserver>*
47 GetA2dpSourceObservers();
48 btbase::AbstractObserverList<BluetoothAvInterface::A2dpSinkObserver>*
49 GetA2dpSinkObservers();
50
51 #define VERIFY_INTERFACE_OR_RETURN(...) \
52 do { \
53 if (!g_interface) { \
54 LOG(WARNING) << "Callback received while |g_interface| is NULL"; \
55 return __VA_ARGS__; \
56 } \
57 } while (0)
58
59 } // namespace
60
SourceConnectionStateCallback(const RawAddress & bd_addr,btav_connection_state_t state)61 void SourceConnectionStateCallback(const RawAddress& bd_addr,
62 btav_connection_state_t state) {
63 std::shared_lock<shared_mutex_impl> lock(g_instance_lock);
64 VERIFY_INTERFACE_OR_RETURN();
65
66 for (auto& observer : *GetA2dpSourceObservers()) {
67 observer.ConnectionStateCallback(g_interface, bd_addr, state);
68 }
69 }
70
SourceAudioStateCallback(const RawAddress & bd_addr,btav_audio_state_t state)71 void SourceAudioStateCallback(const RawAddress& bd_addr,
72 btav_audio_state_t state) {
73 std::shared_lock<shared_mutex_impl> lock(g_instance_lock);
74 VERIFY_INTERFACE_OR_RETURN();
75 for (auto& observer : *GetA2dpSourceObservers()) {
76 observer.AudioStateCallback(g_interface, bd_addr, state);
77 }
78 }
79
SourceAudioConfigCallback(const RawAddress & bd_addr,btav_a2dp_codec_config_t codec_config,std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities,std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities)80 void SourceAudioConfigCallback(
81 const RawAddress& bd_addr, btav_a2dp_codec_config_t codec_config,
82 std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities,
83 std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities) {
84 std::shared_lock<shared_mutex_impl> lock(g_instance_lock);
85 VERIFY_INTERFACE_OR_RETURN();
86 for (auto& observer : *GetA2dpSourceObservers()) {
87 observer.AudioConfigCallback(g_interface, bd_addr, codec_config,
88 codecs_local_capabilities,
89 codecs_selectable_capabilities);
90 }
91 }
92
SourceMandatoryCodecPreferredCallback(const RawAddress & bd_addr)93 bool SourceMandatoryCodecPreferredCallback(const RawAddress& bd_addr) {
94 VERIFY_INTERFACE_OR_RETURN(false);
95 // The mandatory codec is preferred only when all observers disable their
96 // optional codecs.
97 for (auto& observer : *GetA2dpSourceObservers()) {
98 if (!observer.MandatoryCodecPreferredCallback(g_interface, bd_addr))
99 return false;
100 }
101 return true;
102 }
103
SinkConnectionStateCallback(const RawAddress & bd_addr,btav_connection_state_t state)104 void SinkConnectionStateCallback(const RawAddress& bd_addr,
105 btav_connection_state_t state) {
106 std::shared_lock<shared_mutex_impl> lock(g_instance_lock);
107 VERIFY_INTERFACE_OR_RETURN();
108 for (auto& observer : *GetA2dpSinkObservers()) {
109 observer.ConnectionStateCallback(g_interface, bd_addr, state);
110 }
111 }
112
SinkAudioStateCallback(const RawAddress & bd_addr,btav_audio_state_t state)113 void SinkAudioStateCallback(const RawAddress& bd_addr,
114 btav_audio_state_t state) {
115 std::shared_lock<shared_mutex_impl> lock(g_instance_lock);
116 VERIFY_INTERFACE_OR_RETURN();
117 for (auto& observer : *GetA2dpSinkObservers()) {
118 observer.AudioStateCallback(g_interface, bd_addr, state);
119 }
120 }
121
SinkAudioConfigCallback(const RawAddress & bd_addr,uint32_t sample_rate,uint8_t channel_count)122 void SinkAudioConfigCallback(const RawAddress& bd_addr, uint32_t sample_rate,
123 uint8_t channel_count) {
124 std::shared_lock<shared_mutex_impl> lock(g_instance_lock);
125 VERIFY_INTERFACE_OR_RETURN();
126 for (auto& observer : *GetA2dpSinkObservers()) {
127 observer.AudioConfigCallback(g_interface, bd_addr, sample_rate,
128 channel_count);
129 }
130 }
131
132 btav_source_callbacks_t av_source_callbacks = {
133 .size = sizeof(btav_source_callbacks_t),
134 .connection_state_cb = SourceConnectionStateCallback,
135 .audio_state_cb = SourceAudioStateCallback,
136 .audio_config_cb = SourceAudioConfigCallback,
137 .mandatory_codec_preferred_cb = SourceMandatoryCodecPreferredCallback,
138 };
139
140 btav_sink_callbacks_t av_sink_callbacks = {
141 .size = sizeof(btav_sink_callbacks_t),
142 .connection_state_cb = SinkConnectionStateCallback,
143 .audio_state_cb = SinkAudioStateCallback,
144 .audio_config_cb = SinkAudioConfigCallback,
145 };
146
147 class BluetoothAvInterfaceImpl : public BluetoothAvInterface {
148 public:
149 BluetoothAvInterfaceImpl() = default;
150 BluetoothAvInterfaceImpl(const BluetoothAvInterfaceImpl&) = delete;
151 BluetoothAvInterfaceImpl& operator=(const BluetoothAvInterfaceImpl&) = delete;
152
~BluetoothAvInterfaceImpl()153 ~BluetoothAvInterfaceImpl() override {
154 A2dpSinkDisable();
155 A2dpSourceDisable();
156 }
157
A2dpSourceEnable(std::vector<btav_a2dp_codec_config_t> codec_priorities)158 bool A2dpSourceEnable(
159 std::vector<btav_a2dp_codec_config_t> codec_priorities) override {
160 if (source_enabled_) {
161 return true;
162 }
163
164 // Right now we only support one connected audio device.
165 int max_connected_audio_devices = 1;
166 std::vector<btav_a2dp_codec_config_t> offloading_preference(0);
167 if (hal_source_iface_->init(
168 &av_source_callbacks, max_connected_audio_devices,
169 std::move(codec_priorities),
170 std::move(offloading_preference)) != BT_STATUS_SUCCESS) {
171 LOG(ERROR) << "Failed to initialize HAL A2DP source interface";
172 return false;
173 }
174 source_enabled_ = true;
175 return true;
176 }
177
A2dpSourceDisable()178 void A2dpSourceDisable() override {
179 if (!source_enabled_) {
180 return;
181 }
182
183 hal_source_iface_->cleanup();
184 source_enabled_ = false;
185 }
186
A2dpSinkEnable()187 bool A2dpSinkEnable() override {
188 if (sink_enabled_) {
189 return true;
190 }
191
192 // Right now we only support one connected audio device.
193 int max_connected_audio_devices = 1;
194 if (hal_sink_iface_->init(&av_sink_callbacks,
195 max_connected_audio_devices) !=
196 BT_STATUS_SUCCESS) {
197 LOG(ERROR) << "Failed to initialize HAL A2DP sink interface";
198 return false;
199 }
200 sink_enabled_ = true;
201 return true;
202 }
203
A2dpSinkDisable()204 void A2dpSinkDisable() override {
205 if (!sink_enabled_) {
206 return;
207 }
208 hal_sink_iface_->cleanup();
209 sink_enabled_ = false;
210 }
211
AddA2dpSourceObserver(A2dpSourceObserver * observer)212 void AddA2dpSourceObserver(A2dpSourceObserver* observer) override {
213 a2dp_source_observers_.AddObserver(observer);
214 }
215
RemoveA2dpSourceObserver(A2dpSourceObserver * observer)216 void RemoveA2dpSourceObserver(A2dpSourceObserver* observer) override {
217 a2dp_source_observers_.RemoveObserver(observer);
218 }
219
AddA2dpSinkObserver(A2dpSinkObserver * observer)220 void AddA2dpSinkObserver(A2dpSinkObserver* observer) override {
221 a2dp_sink_observers_.AddObserver(observer);
222 }
223
RemoveA2dpSinkObserver(A2dpSinkObserver * observer)224 void RemoveA2dpSinkObserver(A2dpSinkObserver* observer) override {
225 a2dp_sink_observers_.RemoveObserver(observer);
226 }
227
GetA2dpSourceHALInterface()228 const btav_source_interface_t* GetA2dpSourceHALInterface() override {
229 return hal_source_iface_;
230 }
231
GetA2dpSinkHALInterface()232 const btav_sink_interface_t* GetA2dpSinkHALInterface() override {
233 return hal_sink_iface_;
234 }
235
Initialize()236 bool Initialize() {
237 const bt_interface_t* bt_iface =
238 BluetoothInterface::Get()->GetHALInterface();
239 CHECK(bt_iface);
240
241 const auto* hal_source_iface =
242 reinterpret_cast<const btav_source_interface_t*>(
243 bt_iface->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID));
244 if (!hal_source_iface) {
245 LOG(ERROR) << "Failed to obtain A2DP source interface handle";
246 return false;
247 }
248
249 const auto* hal_sink_iface = reinterpret_cast<const btav_sink_interface_t*>(
250 bt_iface->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_SINK_ID));
251 if (!hal_sink_iface) {
252 LOG(ERROR) << "Failed to obtain A2DP sink interface handle";
253 return false;
254 }
255
256 hal_sink_iface_ = hal_sink_iface;
257 hal_source_iface_ = hal_source_iface;
258
259 // Only initialize the sink interface.
260 return A2dpSinkEnable();
261 }
262
source_observers()263 btbase::AbstractObserverList<A2dpSourceObserver>* source_observers() {
264 return &a2dp_source_observers_;
265 }
266
sink_observers()267 btbase::AbstractObserverList<A2dpSinkObserver>* sink_observers() {
268 return &a2dp_sink_observers_;
269 }
270
271 private:
272 btbase::AbstractObserverList<A2dpSourceObserver> a2dp_source_observers_;
273 btbase::AbstractObserverList<A2dpSinkObserver> a2dp_sink_observers_;
274
275 const btav_source_interface_t* hal_source_iface_ = nullptr;
276 const btav_sink_interface_t* hal_sink_iface_ = nullptr;
277
278 bool source_enabled_ = false;
279 bool sink_enabled_ = false;
280 };
281
282 namespace {
283
284 btbase::AbstractObserverList<BluetoothAvInterface::A2dpSourceObserver>*
GetA2dpSourceObservers()285 GetA2dpSourceObservers() {
286 CHECK(g_interface);
287 return static_cast<BluetoothAvInterfaceImpl*>(g_interface)
288 ->source_observers();
289 }
290
291 btbase::AbstractObserverList<BluetoothAvInterface::A2dpSinkObserver>*
GetA2dpSinkObservers()292 GetA2dpSinkObservers() {
293 CHECK(g_interface);
294 return static_cast<BluetoothAvInterfaceImpl*>(g_interface)->sink_observers();
295 }
296
297 } // namespace
298
ConnectionStateCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr,btav_connection_state_t state)299 void BluetoothAvInterface::A2dpSourceObserver::ConnectionStateCallback(
300 BluetoothAvInterface* iface, const RawAddress& bd_addr,
301 btav_connection_state_t state) {
302 // Do nothing.
303 }
304
AudioStateCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr,btav_audio_state_t state)305 void BluetoothAvInterface::A2dpSourceObserver::AudioStateCallback(
306 BluetoothAvInterface* iface, const RawAddress& bd_addr,
307 btav_audio_state_t state) {
308 // Do nothing.
309 }
310
AudioConfigCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr,const btav_a2dp_codec_config_t & codec_config,const std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities,const std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities)311 void BluetoothAvInterface::A2dpSourceObserver::AudioConfigCallback(
312 BluetoothAvInterface* iface, const RawAddress& bd_addr,
313 const btav_a2dp_codec_config_t& codec_config,
314 const std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities,
315 const std::vector<btav_a2dp_codec_config_t>
316 codecs_selectable_capabilities) {
317 // Do nothing.
318 }
319
MandatoryCodecPreferredCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr)320 bool BluetoothAvInterface::A2dpSourceObserver::MandatoryCodecPreferredCallback(
321 BluetoothAvInterface* iface, const RawAddress& bd_addr) {
322 // Do nothing.
323 return false;
324 }
325
ConnectionStateCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr,btav_connection_state_t state)326 void BluetoothAvInterface::A2dpSinkObserver::ConnectionStateCallback(
327 BluetoothAvInterface* iface, const RawAddress& bd_addr,
328 btav_connection_state_t state) {
329 // Do nothing.
330 }
331
AudioStateCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr,btav_audio_state_t state)332 void BluetoothAvInterface::A2dpSinkObserver::AudioStateCallback(
333 BluetoothAvInterface* iface, const RawAddress& bd_addr,
334 btav_audio_state_t state) {
335 // Do nothing.
336 }
337
AudioConfigCallback(BluetoothAvInterface * iface,const RawAddress & bd_addr,uint32_t sample_rate,uint8_t channel_count)338 void BluetoothAvInterface::A2dpSinkObserver::AudioConfigCallback(
339 BluetoothAvInterface* iface, const RawAddress& bd_addr,
340 uint32_t sample_rate, uint8_t channel_count) {
341 // Do nothing.
342 }
343
344 // static
Initialize()345 bool BluetoothAvInterface::Initialize() {
346 std::unique_lock<shared_mutex_impl> lock(g_instance_lock);
347 CHECK(!g_interface);
348
349 auto impl = std::make_unique<BluetoothAvInterfaceImpl>();
350 if (!impl->Initialize()) {
351 LOG(ERROR) << "Failed to initialize BluetoothAvInterface";
352 return false;
353 }
354
355 g_interface = impl.release();
356 return true;
357 }
358
359 // static
CleanUp()360 void BluetoothAvInterface::CleanUp() {
361 std::unique_lock<shared_mutex_impl> lock(g_instance_lock);
362 CHECK(g_interface);
363
364 delete g_interface;
365 g_interface = nullptr;
366 }
367
368 // static
IsInitialized()369 bool BluetoothAvInterface::IsInitialized() {
370 std::shared_lock<shared_mutex_impl> lock(g_instance_lock);
371 return g_interface != nullptr;
372 }
373
374 // static
InitializeForTesting(BluetoothAvInterface * test_instance)375 void BluetoothAvInterface::InitializeForTesting(
376 BluetoothAvInterface* test_instance) {
377 std::unique_lock<shared_mutex_impl> lock(g_instance_lock);
378 CHECK(test_instance);
379 CHECK(!g_interface);
380
381 g_interface = test_instance;
382 }
383
384 // static
Get()385 BluetoothAvInterface* BluetoothAvInterface::Get() {
386 std::shared_lock<shared_mutex_impl> lock(g_instance_lock);
387 CHECK(g_interface);
388 return g_interface;
389 }
390
391 } // namespace hal
392 } // namespace bluetooth
393