1 //
2 // Copyright 2015 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_avrcp_interface.h"
18
19 #include <mutex>
20 #include <shared_mutex>
21
22 #include <base/logging.h>
23 #include <base/observer_list.h>
24
25 #include "abstract_observer_list.h"
26 #include "service/hal/bluetooth_interface.h"
27 #include "service/logging_helpers.h"
28
29 using std::lock_guard;
30 using std::mutex;
31 using std::shared_lock;
32 using std::unique_lock;
33 #if defined(OS_GENERIC) && defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION < 3500)
34 using shared_mutex_impl = std::shared_mutex;
35 #else
36 using shared_mutex_impl = std::shared_timed_mutex;
37 #endif
38
39 namespace bluetooth {
40 namespace hal {
41
42 namespace {
43
44 // The global BluetoothAvrcpInterface instance.
45 BluetoothAvrcpInterface* g_interface = nullptr;
46
47 // Mutex used by callbacks to access |g_interface|. If we initialize or clean it
48 // use unique_lock. If only accessing |g_interface| use shared lock.
49 // TODO(jpawlowski): this should be just shared_mutex, as we currently don't use
50 // timed methods. Change to shared_mutex when we upgrade to C++14
51 shared_mutex_impl g_instance_lock;
52
53 // Helper for obtaining the observer lists. This is forward declared here
54 // and defined below since it depends on BluetoothInterfaceImpl.
55 btbase::AbstractObserverList<BluetoothAvrcpInterface::TargetObserver>*
56 GetTargetObservers();
57
58 btbase::AbstractObserverList<BluetoothAvrcpInterface::ControlObserver>*
59 GetControlObservers();
60
61 #define VERIFY_INTERFACE_OR_RETURN() \
62 do { \
63 if (!g_interface) { \
64 LOG(WARNING) << "Callback received while |g_interface| is NULL"; \
65 return; \
66 } \
67 } while (0)
68
RemoteFeaturesCallback(const RawAddress & bd_addr,btrc_remote_features_t features)69 void RemoteFeaturesCallback(const RawAddress& bd_addr,
70 btrc_remote_features_t features) {
71 shared_lock<shared_mutex_impl> lock(g_instance_lock);
72 VLOG(2) << __func__;
73 VERIFY_INTERFACE_OR_RETURN();
74 for (auto& observer : *GetTargetObservers()) {
75 observer.RemoteFeaturesCallback(bd_addr, features);
76 }
77 }
78
GetPlayStatusCallback(const RawAddress & bd_addr)79 void GetPlayStatusCallback(const RawAddress& bd_addr) {
80 shared_lock<shared_mutex_impl> lock(g_instance_lock);
81 VLOG(2) << __func__;
82 VERIFY_INTERFACE_OR_RETURN();
83 for (auto& observer : *GetTargetObservers()) {
84 observer.GetPlayStatusCallback(bd_addr);
85 }
86 }
87
ListPlayerAppAttrCallback(const RawAddress & bd_addr)88 void ListPlayerAppAttrCallback(const RawAddress& bd_addr) {
89 shared_lock<shared_mutex_impl> lock(g_instance_lock);
90 VLOG(2) << __func__;
91 VERIFY_INTERFACE_OR_RETURN();
92 for (auto& observer : *GetTargetObservers()) {
93 observer.ListPlayerAppAttrCallback(bd_addr);
94 }
95 }
96
ListPlayerAppValuesCallback(btrc_player_attr_t attr_id,const RawAddress & bd_addr)97 void ListPlayerAppValuesCallback(btrc_player_attr_t attr_id,
98 const RawAddress& bd_addr) {
99 shared_lock<shared_mutex_impl> lock(g_instance_lock);
100 VLOG(2) << __func__;
101 VERIFY_INTERFACE_OR_RETURN();
102 for (auto& observer : *GetTargetObservers()) {
103 observer.ListPlayerAppValuesCallback(attr_id, bd_addr);
104 }
105 }
106
GetPlayerAppValueCallback(uint8_t num_attr,btrc_player_attr_t * p_attrs,const RawAddress & bd_addr)107 void GetPlayerAppValueCallback(uint8_t num_attr, btrc_player_attr_t* p_attrs,
108 const RawAddress& bd_addr) {
109 shared_lock<shared_mutex_impl> lock(g_instance_lock);
110 VLOG(2) << __func__;
111 VERIFY_INTERFACE_OR_RETURN();
112 for (auto& observer : *GetTargetObservers()) {
113 observer.GetPlayerAppValueCallback(num_attr, p_attrs, bd_addr);
114 }
115 }
116
GetPlayerAppAttrsTextCallback(uint8_t num_attr,btrc_player_attr_t * p_attrs,const RawAddress & bd_addr)117 void GetPlayerAppAttrsTextCallback(uint8_t num_attr,
118 btrc_player_attr_t* p_attrs,
119 const RawAddress& bd_addr) {
120 shared_lock<shared_mutex_impl> lock(g_instance_lock);
121 VLOG(2) << __func__;
122 VERIFY_INTERFACE_OR_RETURN();
123 for (auto& observer : *GetTargetObservers()) {
124 observer.GetPlayerAppAttrsTextCallback(num_attr, p_attrs, bd_addr);
125 }
126 }
127
GetPlayerAppValuesTextCallback(uint8_t attr_id,uint8_t num_val,uint8_t * p_vals,const RawAddress & bd_addr)128 void GetPlayerAppValuesTextCallback(uint8_t attr_id, uint8_t num_val,
129 uint8_t* p_vals,
130 const RawAddress& bd_addr) {
131 shared_lock<shared_mutex_impl> lock(g_instance_lock);
132 VLOG(2) << __func__;
133 VERIFY_INTERFACE_OR_RETURN();
134 for (auto& observer : *GetTargetObservers()) {
135 observer.GetPlayerAppValuesTextCallback(attr_id, num_val, p_vals, bd_addr);
136 }
137 }
138
SetPlayerAppValueCallback(btrc_player_settings_t * p_vals,const RawAddress & bd_addr)139 void SetPlayerAppValueCallback(btrc_player_settings_t* p_vals,
140 const RawAddress& bd_addr) {
141 shared_lock<shared_mutex_impl> lock(g_instance_lock);
142 VLOG(2) << __func__;
143 VERIFY_INTERFACE_OR_RETURN();
144 for (auto& observer : *GetTargetObservers()) {
145 observer.SetPlayerAppValueCallback(p_vals, bd_addr);
146 }
147 }
148
GetElementAttrCallback(uint8_t num_attr,btrc_media_attr_t * p_attrs,const RawAddress & bd_addr)149 void GetElementAttrCallback(uint8_t num_attr, btrc_media_attr_t* p_attrs,
150 const RawAddress& bd_addr) {
151 shared_lock<shared_mutex_impl> lock(g_instance_lock);
152 VLOG(2) << __func__;
153 VERIFY_INTERFACE_OR_RETURN();
154 for (auto& observer : *GetTargetObservers()) {
155 observer.GetElementAttrCallback(num_attr, p_attrs, bd_addr);
156 }
157 }
158
RegisterNotificationCallback(btrc_event_id_t event_id,uint32_t param,const RawAddress & bd_addr)159 void RegisterNotificationCallback(btrc_event_id_t event_id, uint32_t param,
160 const RawAddress& bd_addr) {
161 shared_lock<shared_mutex_impl> lock(g_instance_lock);
162 VLOG(2) << __func__;
163 VERIFY_INTERFACE_OR_RETURN();
164 for (auto& observer : *GetTargetObservers()) {
165 observer.RegisterNotificationCallback(event_id, param, bd_addr);
166 }
167 }
168
VolumeChangeCallback(uint8_t volume,uint8_t ctype,const RawAddress & bd_addr)169 void VolumeChangeCallback(uint8_t volume, uint8_t ctype,
170 const RawAddress& bd_addr) {
171 shared_lock<shared_mutex_impl> lock(g_instance_lock);
172 VLOG(2) << __func__;
173 VERIFY_INTERFACE_OR_RETURN();
174 for (auto& observer : *GetTargetObservers()) {
175 observer.VolumeChangeCallback(volume, ctype, bd_addr);
176 }
177 }
178
PassthroughCmdCallback(int id,int key_state,const RawAddress & bd_addr)179 void PassthroughCmdCallback(int id, int key_state, const RawAddress& bd_addr) {
180 shared_lock<shared_mutex_impl> lock(g_instance_lock);
181 VLOG(2) << __func__;
182 VERIFY_INTERFACE_OR_RETURN();
183 for (auto& observer : *GetTargetObservers()) {
184 observer.PassthroughCmdCallback(id, key_state, bd_addr);
185 }
186 }
187
SetAddressedPlayerCallback(uint16_t player_id,const RawAddress & bd_addr)188 void SetAddressedPlayerCallback(uint16_t player_id, const RawAddress& bd_addr) {
189 shared_lock<shared_mutex_impl> lock(g_instance_lock);
190 VLOG(2) << __func__;
191 VERIFY_INTERFACE_OR_RETURN();
192 for (auto& observer : *GetTargetObservers()) {
193 observer.SetAddressedPlayerCallback(player_id, bd_addr);
194 }
195 }
196
SetBrowsedPlayerCallback(uint16_t player_id,const RawAddress & bd_addr)197 void SetBrowsedPlayerCallback(uint16_t player_id, const RawAddress& bd_addr) {
198 shared_lock<shared_mutex_impl> lock(g_instance_lock);
199 VLOG(2) << __func__;
200 VERIFY_INTERFACE_OR_RETURN();
201 for (auto& observer : *GetTargetObservers()) {
202 observer.SetBrowsedPlayerCallback(player_id, bd_addr);
203 }
204 }
205
GetFolderItemsCallback(uint8_t scope,uint32_t start_item,uint32_t end_item,uint8_t num_attr,uint32_t * p_attr_ids,const RawAddress & bd_addr)206 void GetFolderItemsCallback(uint8_t scope, uint32_t start_item,
207 uint32_t end_item, uint8_t num_attr,
208 uint32_t* p_attr_ids, const RawAddress& bd_addr) {
209 shared_lock<shared_mutex_impl> lock(g_instance_lock);
210 VLOG(2) << __func__;
211 VERIFY_INTERFACE_OR_RETURN();
212 for (auto& observer : *GetTargetObservers()) {
213 observer.GetFolderItemsCallback(scope, start_item, end_item, num_attr,
214 p_attr_ids, bd_addr);
215 }
216 }
217
ChangePathCallback(uint8_t direction,uint8_t * folder_uid,const RawAddress & bd_addr)218 void ChangePathCallback(uint8_t direction, uint8_t* folder_uid,
219 const RawAddress& bd_addr) {
220 shared_lock<shared_mutex_impl> lock(g_instance_lock);
221 VLOG(2) << __func__;
222 VERIFY_INTERFACE_OR_RETURN();
223 for (auto& observer : *GetTargetObservers()) {
224 observer.ChangePathCallback(direction, folder_uid, bd_addr);
225 }
226 }
227
GetItemAttrCallback(uint8_t scope,uint8_t * uid,uint16_t uid_counter,uint8_t num_attr,btrc_media_attr_t * p_attrs,const RawAddress & bd_addr)228 void GetItemAttrCallback(uint8_t scope, uint8_t* uid, uint16_t uid_counter,
229 uint8_t num_attr, btrc_media_attr_t* p_attrs,
230 const RawAddress& bd_addr) {
231 shared_lock<shared_mutex_impl> lock(g_instance_lock);
232 VLOG(2) << __func__;
233 VERIFY_INTERFACE_OR_RETURN();
234 for (auto& observer : *GetTargetObservers()) {
235 observer.GetItemAttrCallback(scope, uid, uid_counter, num_attr, p_attrs,
236 bd_addr);
237 }
238 }
239
PlayItemCallback(uint8_t scope,uint16_t uid_counter,uint8_t * uid,const RawAddress & bd_addr)240 void PlayItemCallback(uint8_t scope, uint16_t uid_counter, uint8_t* uid,
241 const RawAddress& bd_addr) {
242 shared_lock<shared_mutex_impl> lock(g_instance_lock);
243 VLOG(2) << __func__;
244 VERIFY_INTERFACE_OR_RETURN();
245 for (auto& observer : *GetTargetObservers()) {
246 observer.PlayItemCallback(scope, uid_counter, uid, bd_addr);
247 }
248 }
249
GetTotalNumOfItemsCallback(uint8_t scope,const RawAddress & bd_addr)250 void GetTotalNumOfItemsCallback(uint8_t scope, const RawAddress& bd_addr) {
251 shared_lock<shared_mutex_impl> lock(g_instance_lock);
252 VLOG(2) << __func__;
253 VERIFY_INTERFACE_OR_RETURN();
254 for (auto& observer : *GetTargetObservers()) {
255 observer.GetTotalNumOfItemsCallback(scope, bd_addr);
256 }
257 }
258
SearchCallback(uint16_t charset_id,uint16_t str_len,uint8_t * p_str,const RawAddress & bd_addr)259 void SearchCallback(uint16_t charset_id, uint16_t str_len, uint8_t* p_str,
260 const RawAddress& bd_addr) {
261 shared_lock<shared_mutex_impl> lock(g_instance_lock);
262 VLOG(2) << __func__;
263 VERIFY_INTERFACE_OR_RETURN();
264 for (auto& observer : *GetTargetObservers()) {
265 observer.SearchCallback(str_len, p_str, bd_addr);
266 }
267 }
268
AddToNowPlayingCallback(uint8_t scope,uint8_t * uid,uint16_t uid_counter,const RawAddress & bd_addr)269 void AddToNowPlayingCallback(uint8_t scope, uint8_t* uid, uint16_t uid_counter,
270 const RawAddress& bd_addr) {
271 shared_lock<shared_mutex_impl> lock(g_instance_lock);
272 VLOG(2) << __func__;
273 VERIFY_INTERFACE_OR_RETURN();
274 for (auto& observer : *GetTargetObservers()) {
275 observer.AddToNowPlayingCallback(scope, uid, uid_counter, bd_addr);
276 }
277 }
278
PassthroughRspCallback(const RawAddress & bd_addr,int id,int key_state)279 void PassthroughRspCallback(const RawAddress& bd_addr, int id, int key_state) {
280 shared_lock<shared_mutex_impl> lock(g_instance_lock);
281 VLOG(2) << __func__;
282 VERIFY_INTERFACE_OR_RETURN();
283 for (auto& observer : *GetControlObservers()) {
284 observer.PassthroughRspCallback(bd_addr, id, key_state);
285 }
286 }
287
GroupnavigationRspCallback(int id,int key_state)288 void GroupnavigationRspCallback(int id, int key_state) {
289 shared_lock<shared_mutex_impl> lock(g_instance_lock);
290 VLOG(2) << __func__;
291 VERIFY_INTERFACE_OR_RETURN();
292 for (auto& observer : *GetControlObservers()) {
293 observer.GroupnavigationRspCallback(id, key_state);
294 }
295 }
296
ConnectionStateCallback(bool rc_connect,bool bt_connect,const RawAddress & bd_addr)297 void ConnectionStateCallback(bool rc_connect, bool bt_connect,
298 const RawAddress& bd_addr) {
299 shared_lock<shared_mutex_impl> lock(g_instance_lock);
300 VLOG(2) << __func__;
301 VERIFY_INTERFACE_OR_RETURN();
302 for (auto& observer : *GetControlObservers()) {
303 observer.ConnectionStateCallback(rc_connect, bt_connect, bd_addr);
304 }
305 }
306
CtrlGetrcfeaturesCallback(const RawAddress & bd_addr,int features)307 void CtrlGetrcfeaturesCallback(const RawAddress& bd_addr, int features) {
308 shared_lock<shared_mutex_impl> lock(g_instance_lock);
309 VLOG(2) << __func__;
310 VERIFY_INTERFACE_OR_RETURN();
311 for (auto& observer : *GetControlObservers()) {
312 observer.CtrlGetrcfeaturesCallback(bd_addr, features);
313 }
314 }
315
CtrlSetplayerapplicationsettingRspCallback(const RawAddress & bd_addr,uint8_t accepted)316 void CtrlSetplayerapplicationsettingRspCallback(const RawAddress& bd_addr,
317 uint8_t accepted) {
318 shared_lock<shared_mutex_impl> lock(g_instance_lock);
319 VLOG(2) << __func__;
320 VERIFY_INTERFACE_OR_RETURN();
321
322 for (auto& observer : *GetControlObservers()) {
323 observer.CtrlSetplayerapplicationsettingRspCallback(bd_addr, accepted);
324 }
325 }
326
CtrlPlayerapplicationsettingCallback(const RawAddress & bd_addr,uint8_t num_attr,btrc_player_app_attr_t * app_attrs,uint8_t num_ext_attr,btrc_player_app_ext_attr_t * ext_attrs)327 void CtrlPlayerapplicationsettingCallback(
328 const RawAddress& bd_addr, uint8_t num_attr,
329 btrc_player_app_attr_t* app_attrs, uint8_t num_ext_attr,
330 btrc_player_app_ext_attr_t* ext_attrs) {
331 shared_lock<shared_mutex_impl> lock(g_instance_lock);
332 VLOG(2) << __func__;
333 VERIFY_INTERFACE_OR_RETURN();
334 for (auto& observer : *GetControlObservers()) {
335 observer.CtrlPlayerapplicationsettingCallback(bd_addr, num_attr, app_attrs,
336 num_ext_attr, ext_attrs);
337 }
338 }
339
CtrlPlayerapplicationsettingChangedCallback(const RawAddress & bd_addr,const btrc_player_settings_t & vals)340 void CtrlPlayerapplicationsettingChangedCallback(
341 const RawAddress& bd_addr, const btrc_player_settings_t& vals) {
342 shared_lock<shared_mutex_impl> lock(g_instance_lock);
343 VLOG(2) << __func__;
344 VERIFY_INTERFACE_OR_RETURN();
345 for (auto& observer : *GetControlObservers()) {
346 observer.CtrlPlayerapplicationsettingChangedCallback(bd_addr, vals);
347 }
348 }
349
CtrlSetabsvolCmdCallback(const RawAddress & bd_addr,uint8_t abs_vol,uint8_t label)350 void CtrlSetabsvolCmdCallback(const RawAddress& bd_addr, uint8_t abs_vol,
351 uint8_t label) {
352 shared_lock<shared_mutex_impl> lock(g_instance_lock);
353 VLOG(2) << __func__;
354 VERIFY_INTERFACE_OR_RETURN();
355 for (auto& observer : *GetControlObservers()) {
356 observer.CtrlSetabsvolCmdCallback(bd_addr, abs_vol, label);
357 }
358 }
359
CtrlRegisternotificationAbsVolCallback(const RawAddress & bd_addr,uint8_t label)360 void CtrlRegisternotificationAbsVolCallback(const RawAddress& bd_addr,
361 uint8_t label) {
362 shared_lock<shared_mutex_impl> lock(g_instance_lock);
363 VLOG(2) << __func__;
364 VERIFY_INTERFACE_OR_RETURN();
365 for (auto& observer : *GetControlObservers()) {
366 observer.CtrlRegisternotificationAbsVolCallback(bd_addr, label);
367 }
368 }
369
CtrlTrackChangedCallback(const RawAddress & bd_addr,uint8_t num_attr,btrc_element_attr_val_t * p_attrs)370 void CtrlTrackChangedCallback(const RawAddress& bd_addr, uint8_t num_attr,
371 btrc_element_attr_val_t* p_attrs) {
372 shared_lock<shared_mutex_impl> lock(g_instance_lock);
373 VLOG(2) << __func__;
374 VERIFY_INTERFACE_OR_RETURN();
375 for (auto& observer : *GetControlObservers()) {
376 observer.CtrlTrackChangedCallback(bd_addr, num_attr, p_attrs);
377 }
378 }
379
CtrlPlayPositionChangedCallback(const RawAddress & bd_addr,uint32_t song_len,uint32_t song_pos)380 void CtrlPlayPositionChangedCallback(const RawAddress& bd_addr,
381 uint32_t song_len, uint32_t song_pos) {
382 shared_lock<shared_mutex_impl> lock(g_instance_lock);
383 VLOG(2) << __func__;
384 VERIFY_INTERFACE_OR_RETURN();
385 for (auto& observer : *GetControlObservers()) {
386 observer.CtrlPlayPositionChangedCallback(bd_addr, song_len, song_pos);
387 }
388 }
389
CtrlPlayStatusChangedCallback(const RawAddress & bd_addr,btrc_play_status_t play_status)390 void CtrlPlayStatusChangedCallback(const RawAddress& bd_addr,
391 btrc_play_status_t play_status) {
392 shared_lock<shared_mutex_impl> lock(g_instance_lock);
393 VLOG(2) << __func__;
394 VERIFY_INTERFACE_OR_RETURN();
395 for (auto& observer : *GetControlObservers()) {
396 observer.CtrlPlayStatusChangedCallback(bd_addr, play_status);
397 }
398 }
399
CtrlGetFolderItemsCallback(const RawAddress & bd_addr,btrc_status_t status,const btrc_folder_items_t * folder_items,uint8_t count)400 void CtrlGetFolderItemsCallback(const RawAddress& bd_addr, btrc_status_t status,
401 const btrc_folder_items_t* folder_items,
402 uint8_t count) {
403 shared_lock<shared_mutex_impl> lock(g_instance_lock);
404 VLOG(2) << __func__;
405 VERIFY_INTERFACE_OR_RETURN();
406 for (auto& observer : *GetControlObservers()) {
407 observer.CtrlGetFolderItemsCallback(bd_addr, status, folder_items, count);
408 }
409 }
410
CtrlChangePathCallback(const RawAddress & bd_addr,uint32_t count)411 void CtrlChangePathCallback(const RawAddress& bd_addr, uint32_t count) {
412 shared_lock<shared_mutex_impl> lock(g_instance_lock);
413 VLOG(2) << __func__;
414 VERIFY_INTERFACE_OR_RETURN();
415 for (auto& observer : *GetControlObservers()) {
416 observer.CtrlChangePathCallback(bd_addr, count);
417 }
418 }
419
CtrlSetBrowsedPlayerCallback(const RawAddress & bd_addr,uint8_t num_items,uint8_t depth)420 void CtrlSetBrowsedPlayerCallback(const RawAddress& bd_addr, uint8_t num_items,
421 uint8_t depth) {
422 shared_lock<shared_mutex_impl> lock(g_instance_lock);
423 VLOG(2) << __func__;
424 VERIFY_INTERFACE_OR_RETURN();
425 for (auto& observer : *GetControlObservers()) {
426 observer.CtrlSetBrowsedPlayerCallback(bd_addr, num_items, depth);
427 }
428 }
429
CtrlSetAddressedPlayerCallback(const RawAddress & bd_addr,uint8_t status)430 void CtrlSetAddressedPlayerCallback(const RawAddress& bd_addr, uint8_t status) {
431 shared_lock<shared_mutex_impl> lock(g_instance_lock);
432 VLOG(2) << __func__;
433 VERIFY_INTERFACE_OR_RETURN();
434 for (auto& observer : *GetControlObservers()) {
435 observer.CtrlSetAddressedPlayerCallback(bd_addr, status);
436 }
437 }
438
439 btrc_callbacks_t target_callbacks = {
440 .size = sizeof(btrc_callbacks_t),
441 .remote_features_cb = RemoteFeaturesCallback,
442 .get_play_status_cb = GetPlayStatusCallback,
443 .list_player_app_attr_cb = ListPlayerAppAttrCallback,
444 .list_player_app_values_cb = ListPlayerAppValuesCallback,
445 .get_player_app_value_cb = GetPlayerAppValueCallback,
446 .get_player_app_attrs_text_cb = GetPlayerAppAttrsTextCallback,
447 .get_player_app_values_text_cb = GetPlayerAppValuesTextCallback,
448 .set_player_app_value_cb = SetPlayerAppValueCallback,
449 .get_element_attr_cb = GetElementAttrCallback,
450 .register_notification_cb = RegisterNotificationCallback,
451 .volume_change_cb = VolumeChangeCallback,
452 .passthrough_cmd_cb = PassthroughCmdCallback,
453 .set_addressed_player_cb = SetAddressedPlayerCallback,
454 .set_browsed_player_cb = SetBrowsedPlayerCallback,
455 .get_folder_items_cb = GetFolderItemsCallback,
456 .change_path_cb = ChangePathCallback,
457 .get_item_attr_cb = GetItemAttrCallback,
458 .play_item_cb = PlayItemCallback,
459 .get_total_num_of_items_cb = GetTotalNumOfItemsCallback,
460 .search_cb = SearchCallback,
461 .add_to_now_playing_cb = AddToNowPlayingCallback,
462 };
463
464 btrc_ctrl_callbacks_t control_callbacks = {
465 .size = sizeof(btrc_ctrl_callbacks_t),
466 .passthrough_rsp_cb = PassthroughRspCallback,
467 .groupnavigation_rsp_cb = GroupnavigationRspCallback,
468 .connection_state_cb = ConnectionStateCallback,
469 .getrcfeatures_cb = CtrlGetrcfeaturesCallback,
470 .setplayerappsetting_rsp_cb = CtrlSetplayerapplicationsettingRspCallback,
471 .playerapplicationsetting_cb = CtrlPlayerapplicationsettingCallback,
472 .playerapplicationsetting_changed_cb =
473 CtrlPlayerapplicationsettingChangedCallback,
474 .setabsvol_cmd_cb = CtrlSetabsvolCmdCallback,
475 .registernotification_absvol_cb = CtrlRegisternotificationAbsVolCallback,
476 .track_changed_cb = CtrlTrackChangedCallback,
477 .play_position_changed_cb = CtrlPlayPositionChangedCallback,
478 .play_status_changed_cb = CtrlPlayStatusChangedCallback,
479 .get_folder_items_cb = CtrlGetFolderItemsCallback,
480 .change_folder_path_cb = CtrlChangePathCallback,
481 .set_browsed_player_cb = CtrlSetBrowsedPlayerCallback,
482 .set_addressed_player_cb = CtrlSetAddressedPlayerCallback,
483 };
484
485 } // namespace
486
487 // BluetoothAvrcpInterface implementation for production.
488 class BluetoothAvrcpInterfaceImpl : public BluetoothAvrcpInterface {
489 public:
BluetoothAvrcpInterfaceImpl()490 BluetoothAvrcpInterfaceImpl() : control_iface_(nullptr) {}
491
~BluetoothAvrcpInterfaceImpl()492 ~BluetoothAvrcpInterfaceImpl() override {
493 if (control_iface_) control_iface_->cleanup();
494 }
495
AvrcpControlEnable()496 bool AvrcpControlEnable() override {
497 if (control_enabled_) {
498 return true;
499 }
500
501 if (control_iface_->init(&control_callbacks) != BT_STATUS_SUCCESS) {
502 LOG(ERROR) << "Failed to initialize HAL AVRCP control interface";
503 return false;
504 }
505
506 control_enabled_ = true;
507 return true;
508 }
509
AvrcpControlDisable()510 void AvrcpControlDisable() override {
511 if (!control_enabled_) {
512 return;
513 }
514
515 control_iface_->cleanup();
516 control_enabled_ = false;
517 }
518
AvrcpTargetEnable()519 bool AvrcpTargetEnable() override {
520 if (target_enabled_) {
521 return true;
522 }
523
524 if (target_iface_->init(&target_callbacks) != BT_STATUS_SUCCESS) {
525 LOG(ERROR) << "Failed to initialize HAL AVRCP target interface";
526 return false;
527 }
528
529 target_enabled_ = true;
530 return true;
531 }
532
AvrcpTargetDisable()533 void AvrcpTargetDisable() override {
534 if (!target_enabled_) {
535 return;
536 }
537
538 target_iface_->cleanup();
539 target_enabled_ = false;
540 }
541
AddTargetObserver(TargetObserver * observer)542 void AddTargetObserver(TargetObserver* observer) override {
543 target_observers_.AddObserver(observer);
544 }
545
RemoveTargetObserver(TargetObserver * observer)546 void RemoveTargetObserver(TargetObserver* observer) override {
547 target_observers_.RemoveObserver(observer);
548 }
549
AddControlObserver(ControlObserver * observer)550 void AddControlObserver(ControlObserver* observer) override {
551 control_observers_.AddObserver(observer);
552 }
553
RemoveControlObserver(ControlObserver * observer)554 void RemoveControlObserver(ControlObserver* observer) override {
555 control_observers_.RemoveObserver(observer);
556 }
557
GetTargetHALInterface() const558 const btrc_interface_t* GetTargetHALInterface() const override {
559 return target_iface_;
560 }
561
GetControlHALInterface() const562 const btrc_ctrl_interface_t* GetControlHALInterface() const override {
563 return control_iface_;
564 }
565
566 // Initialize the interface.
Initialize()567 bool Initialize() {
568 const bt_interface_t* bt_iface =
569 BluetoothInterface::Get()->GetHALInterface();
570 CHECK(bt_iface);
571
572 auto* target_iface = reinterpret_cast<const btrc_interface_t*>(
573 bt_iface->get_profile_interface(BT_PROFILE_AV_RC_ID));
574 if (!target_iface) {
575 LOG(ERROR) << "Failed to obtain HAL AVRCP target interface handle";
576 return false;
577 }
578
579 auto* control_iface = reinterpret_cast<const btrc_ctrl_interface_t*>(
580 bt_iface->get_profile_interface(BT_PROFILE_AV_RC_CTRL_ID));
581 if (!control_iface) {
582 LOG(ERROR) << "Failed to obtain HAL AVRCP control interface handle";
583 return false;
584 }
585
586 control_iface_ = control_iface;
587 target_iface_ = target_iface;
588
589 // Only initialize the control interface.
590 return AvrcpControlEnable();
591 }
592
target_observers()593 btbase::AbstractObserverList<TargetObserver>* target_observers() {
594 return &target_observers_;
595 }
596
control_observers()597 btbase::AbstractObserverList<ControlObserver>* control_observers() {
598 return &control_observers_;
599 }
600
601 private:
602 // List of observers that are interested in notifications from us.
603 // We're not using a base::ObserverListThreadSafe, which it posts observer
604 // events automatically on the origin threads, as we want to avoid that
605 // overhead and simply forward the events to the upper layer.
606 btbase::AbstractObserverList<TargetObserver> target_observers_;
607 btbase::AbstractObserverList<ControlObserver> control_observers_;
608
609 // The HAL handle obtained from the shared library. We hold a weak reference
610 // to this since the actual data resides in the shared Bluetooth library.
611 const btrc_interface_t* target_iface_ = nullptr;
612 const btrc_ctrl_interface_t* control_iface_ = nullptr;
613
614 bool control_enabled_ = false;
615 bool target_enabled_ = false;
616
617 DISALLOW_COPY_AND_ASSIGN(BluetoothAvrcpInterfaceImpl);
618 };
619
620 namespace {
621
622 btbase::AbstractObserverList<BluetoothAvrcpInterface::TargetObserver>*
GetTargetObservers()623 GetTargetObservers() {
624 CHECK(g_interface);
625 return static_cast<BluetoothAvrcpInterfaceImpl*>(g_interface)
626 ->target_observers();
627 }
628
629 btbase::AbstractObserverList<BluetoothAvrcpInterface::ControlObserver>*
GetControlObservers()630 GetControlObservers() {
631 CHECK(g_interface);
632 return static_cast<BluetoothAvrcpInterfaceImpl*>(g_interface)
633 ->control_observers();
634 }
635
636 } // namespace
637
RemoteFeaturesCallback(const RawAddress & bd_addr,btrc_remote_features_t features)638 void BluetoothAvrcpInterface::TargetObserver::RemoteFeaturesCallback(
639 const RawAddress& bd_addr, btrc_remote_features_t features) {
640 // Do nothing.
641 }
642
GetPlayStatusCallback(const RawAddress & bd_addr)643 void BluetoothAvrcpInterface::TargetObserver::GetPlayStatusCallback(
644 const RawAddress& bd_addr) {
645 // Do nothing.
646 }
647
ListPlayerAppAttrCallback(const RawAddress & bd_addr)648 void BluetoothAvrcpInterface::TargetObserver::ListPlayerAppAttrCallback(
649 const RawAddress& bd_addr) {
650 // Do nothing.
651 }
652
ListPlayerAppValuesCallback(btrc_player_attr_t attr_id,const RawAddress & bd_addr)653 void BluetoothAvrcpInterface::TargetObserver::ListPlayerAppValuesCallback(
654 btrc_player_attr_t attr_id, const RawAddress& bd_addr) {
655 // Do nothing.
656 }
657
GetPlayerAppValueCallback(uint8_t num_attr,btrc_player_attr_t * p_attrs,const RawAddress & bd_addr)658 void BluetoothAvrcpInterface::TargetObserver::GetPlayerAppValueCallback(
659 uint8_t num_attr, btrc_player_attr_t* p_attrs, const RawAddress& bd_addr) {
660 // Do nothing.
661 }
662
GetPlayerAppAttrsTextCallback(uint8_t num_attr,btrc_player_attr_t * p_attrs,const RawAddress & bd_addr)663 void BluetoothAvrcpInterface::TargetObserver::GetPlayerAppAttrsTextCallback(
664 uint8_t num_attr, btrc_player_attr_t* p_attrs, const RawAddress& bd_addr) {
665 // Do nothing.
666 }
667
GetPlayerAppValuesTextCallback(uint8_t attr_id,uint8_t num_val,uint8_t * p_vals,const RawAddress & bd_addr)668 void BluetoothAvrcpInterface::TargetObserver::GetPlayerAppValuesTextCallback(
669 uint8_t attr_id, uint8_t num_val, uint8_t* p_vals,
670 const RawAddress& bd_addr) {
671 // Do nothing.
672 }
673
SetPlayerAppValueCallback(btrc_player_settings_t * p_vals,const RawAddress & bd_addr)674 void BluetoothAvrcpInterface::TargetObserver::SetPlayerAppValueCallback(
675 btrc_player_settings_t* p_vals, const RawAddress& bd_addr) {
676 // Do nothing.
677 }
678
GetElementAttrCallback(uint8_t num_attr,btrc_media_attr_t * p_attrs,const RawAddress & bd_addr)679 void BluetoothAvrcpInterface::TargetObserver::GetElementAttrCallback(
680 uint8_t num_attr, btrc_media_attr_t* p_attrs, const RawAddress& bd_addr) {
681 // Do nothing.
682 }
683
RegisterNotificationCallback(btrc_event_id_t event_id,uint32_t param,const RawAddress & bd_addr)684 void BluetoothAvrcpInterface::TargetObserver::RegisterNotificationCallback(
685 btrc_event_id_t event_id, uint32_t param, const RawAddress& bd_addr) {
686 // Do nothing.
687 }
688
VolumeChangeCallback(uint8_t volume,uint8_t ctype,const RawAddress & bd_addr)689 void BluetoothAvrcpInterface::TargetObserver::VolumeChangeCallback(
690 uint8_t volume, uint8_t ctype, const RawAddress& bd_addr) {
691 // Do nothing.
692 }
693
PassthroughCmdCallback(int id,int key_state,const RawAddress & bd_addr)694 void BluetoothAvrcpInterface::TargetObserver::PassthroughCmdCallback(
695 int id, int key_state, const RawAddress& bd_addr) {
696 // Do nothing.
697 }
698
SetAddressedPlayerCallback(uint16_t player_id,const RawAddress & bd_addr)699 void BluetoothAvrcpInterface::TargetObserver::SetAddressedPlayerCallback(
700 uint16_t player_id, const RawAddress& bd_addr) {
701 // Do nothing.
702 }
703
SetBrowsedPlayerCallback(uint16_t player_id,const RawAddress & bd_addr)704 void BluetoothAvrcpInterface::TargetObserver::SetBrowsedPlayerCallback(
705 uint16_t player_id, const RawAddress& bd_addr) {
706 // Do nothing.
707 }
708
GetFolderItemsCallback(uint8_t scope,uint32_t start_item,uint32_t end_item,uint8_t num_attr,uint32_t * p_attr_ids,const RawAddress & bd_addr)709 void BluetoothAvrcpInterface::TargetObserver::GetFolderItemsCallback(
710 uint8_t scope, uint32_t start_item, uint32_t end_item, uint8_t num_attr,
711 uint32_t* p_attr_ids, const RawAddress& bd_addr) {
712 // Do nothing.
713 }
714
ChangePathCallback(uint8_t direction,uint8_t * folder_uid,const RawAddress & bd_addr)715 void BluetoothAvrcpInterface::TargetObserver::ChangePathCallback(
716 uint8_t direction, uint8_t* folder_uid, const RawAddress& bd_addr) {
717 // Do nothing.
718 }
719
GetItemAttrCallback(uint8_t scope,uint8_t * uid,uint16_t uid_counter,uint8_t num_attr,btrc_media_attr_t * p_attrs,const RawAddress & bd_addr)720 void BluetoothAvrcpInterface::TargetObserver::GetItemAttrCallback(
721 uint8_t scope, uint8_t* uid, uint16_t uid_counter, uint8_t num_attr,
722 btrc_media_attr_t* p_attrs, const RawAddress& bd_addr) {
723 // Do nothing.
724 }
725
PlayItemCallback(uint8_t scope,uint16_t uid_counter,uint8_t * uid,const RawAddress & bd_addr)726 void BluetoothAvrcpInterface::TargetObserver::PlayItemCallback(
727 uint8_t scope, uint16_t uid_counter, uint8_t* uid,
728 const RawAddress& bd_addr) {
729 // Do nothing.
730 }
731
GetTotalNumOfItemsCallback(uint8_t scope,const RawAddress & bd_addr)732 void BluetoothAvrcpInterface::TargetObserver::GetTotalNumOfItemsCallback(
733 uint8_t scope, const RawAddress& bd_addr) {
734 // Do nothing.
735 }
736
SearchCallback(uint16_t str_len,uint8_t * p_str,const RawAddress & bd_addr)737 void BluetoothAvrcpInterface::TargetObserver::SearchCallback(
738 uint16_t str_len, uint8_t* p_str, const RawAddress& bd_addr) {
739 // Do nothing.
740 }
741
AddToNowPlayingCallback(uint8_t scope,uint8_t * uid,uint16_t uid_counter,const RawAddress & bd_addr)742 void BluetoothAvrcpInterface::TargetObserver::AddToNowPlayingCallback(
743 uint8_t scope, uint8_t* uid, uint16_t uid_counter,
744 const RawAddress& bd_addr) {
745 // Do nothing.
746 }
747
PassthroughRspCallback(const RawAddress &,int,int)748 void BluetoothAvrcpInterface::ControlObserver::PassthroughRspCallback(
749 const RawAddress& /* bd_addr */, int /* id */, int /* key_state */) {
750 // Do nothing.
751 }
752
GroupnavigationRspCallback(int,int)753 void BluetoothAvrcpInterface::ControlObserver::GroupnavigationRspCallback(
754 int /* id */, int /* key_state */) {
755 // Do nothing.
756 }
757
ConnectionStateCallback(bool,bool,const RawAddress &)758 void BluetoothAvrcpInterface::ControlObserver::ConnectionStateCallback(
759 bool /* rc_connect */, bool /* bt_connect */,
760 const RawAddress& /* bd_addr */) {
761 // Do nothing.
762 }
763
CtrlGetrcfeaturesCallback(const RawAddress &,int)764 void BluetoothAvrcpInterface::ControlObserver::CtrlGetrcfeaturesCallback(
765 const RawAddress& /* bd_addr */, int /* features */) {
766 // Do nothing.
767 }
768
769 void BluetoothAvrcpInterface::ControlObserver::
CtrlSetplayerapplicationsettingRspCallback(const RawAddress &,uint8_t)770 CtrlSetplayerapplicationsettingRspCallback(const RawAddress& /* bd_addr */,
771 uint8_t /* accepted */) {
772 // Do nothing.
773 }
774
775 void BluetoothAvrcpInterface::ControlObserver::
CtrlPlayerapplicationsettingCallback(const RawAddress &,uint8_t,btrc_player_app_attr_t *,uint8_t,btrc_player_app_ext_attr_t *)776 CtrlPlayerapplicationsettingCallback(
777 const RawAddress& /* bd_addr */, uint8_t /* num_attr */,
778 btrc_player_app_attr_t* /* app_attrs */, uint8_t /* num_ext_attr */,
779 btrc_player_app_ext_attr_t* /* ext_attrs */) {
780 // Do nothing.
781 }
782
783 void BluetoothAvrcpInterface::ControlObserver::
CtrlPlayerapplicationsettingChangedCallback(const RawAddress &,const btrc_player_settings_t &)784 CtrlPlayerapplicationsettingChangedCallback(
785 const RawAddress& /* bd_addr*/,
786 const btrc_player_settings_t& /* vals */) {
787 // Do nothing.
788 }
789
CtrlSetabsvolCmdCallback(const RawAddress &,uint8_t,uint8_t)790 void BluetoothAvrcpInterface::ControlObserver::CtrlSetabsvolCmdCallback(
791 const RawAddress& /* bd_addr */, uint8_t /* abs_vol */,
792 uint8_t /* label */) {
793 // Do nothing.
794 }
795
796 void BluetoothAvrcpInterface::ControlObserver::
CtrlRegisternotificationAbsVolCallback(const RawAddress &,uint8_t)797 CtrlRegisternotificationAbsVolCallback(const RawAddress& /* bd_addr */,
798 uint8_t /* label */) {
799 // Do nothing.
800 }
801
CtrlTrackChangedCallback(const RawAddress &,uint8_t,btrc_element_attr_val_t *)802 void BluetoothAvrcpInterface::ControlObserver::CtrlTrackChangedCallback(
803 const RawAddress& /*bd_addr */, uint8_t /* num_attr */,
804 btrc_element_attr_val_t* /* p_attrs */) {
805 // Do nothing.
806 }
807
CtrlPlayPositionChangedCallback(const RawAddress &,uint32_t,uint32_t)808 void BluetoothAvrcpInterface::ControlObserver::CtrlPlayPositionChangedCallback(
809 const RawAddress& /* bd_addr */, uint32_t /* song_len */,
810 uint32_t /* song_pos */) {
811 // Do nothing.
812 }
813
CtrlPlayStatusChangedCallback(const RawAddress &,btrc_play_status_t)814 void BluetoothAvrcpInterface::ControlObserver::CtrlPlayStatusChangedCallback(
815 const RawAddress& /* bd_addr */, btrc_play_status_t /* play_status */) {
816 // Do nothing.
817 }
818
CtrlGetFolderItemsCallback(const RawAddress &,btrc_status_t,const btrc_folder_items_t *,uint8_t)819 void BluetoothAvrcpInterface::ControlObserver::CtrlGetFolderItemsCallback(
820 const RawAddress& /* bd_addr */, btrc_status_t /* status */,
821 const btrc_folder_items_t* /*folder_items */, uint8_t /* count */) {
822 // Do nothing.
823 }
824
CtrlChangePathCallback(const RawAddress &,uint32_t)825 void BluetoothAvrcpInterface::ControlObserver::CtrlChangePathCallback(
826 const RawAddress& /* bd_addr */, uint32_t /* count */) {
827 // Do nothing.
828 }
829
CtrlSetBrowsedPlayerCallback(const RawAddress &,uint8_t,uint8_t)830 void BluetoothAvrcpInterface::ControlObserver::CtrlSetBrowsedPlayerCallback(
831 const RawAddress& /* bd_addr */, uint8_t /* num_items */,
832 uint8_t /* depth */) {
833 // Do nothing.
834 }
835
CtrlSetAddressedPlayerCallback(const RawAddress &,uint8_t)836 void BluetoothAvrcpInterface::ControlObserver::CtrlSetAddressedPlayerCallback(
837 const RawAddress& /* bd_addr */, uint8_t /* status */) {
838 // Do nothing.
839 }
840
841 // static
Initialize()842 bool BluetoothAvrcpInterface::Initialize() {
843 unique_lock<shared_mutex_impl> lock(g_instance_lock);
844 CHECK(!g_interface);
845
846 std::unique_ptr<BluetoothAvrcpInterfaceImpl> impl(
847 new BluetoothAvrcpInterfaceImpl());
848 if (!impl->Initialize()) {
849 LOG(ERROR) << "Failed to initialize BluetoothAvrcpInterface";
850 return false;
851 }
852
853 g_interface = impl.release();
854
855 return true;
856 }
857
858 // static
CleanUp()859 void BluetoothAvrcpInterface::CleanUp() {
860 unique_lock<shared_mutex_impl> lock(g_instance_lock);
861 CHECK(g_interface);
862
863 delete g_interface;
864 g_interface = nullptr;
865 }
866
867 // static
IsInitialized()868 bool BluetoothAvrcpInterface::IsInitialized() {
869 shared_lock<shared_mutex_impl> lock(g_instance_lock);
870
871 return g_interface != nullptr;
872 }
873
874 // static
Get()875 BluetoothAvrcpInterface* BluetoothAvrcpInterface::Get() {
876 shared_lock<shared_mutex_impl> lock(g_instance_lock);
877 CHECK(g_interface);
878 return g_interface;
879 }
880
881 // static
InitializeForTesting(BluetoothAvrcpInterface * test_instance)882 void BluetoothAvrcpInterface::InitializeForTesting(
883 BluetoothAvrcpInterface* test_instance) {
884 unique_lock<shared_mutex_impl> lock(g_instance_lock);
885 CHECK(test_instance);
886 CHECK(!g_interface);
887
888 g_interface = test_instance;
889 }
890
891 } // namespace hal
892 } // namespace bluetooth
893