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