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