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