• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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