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