1 /*
2  * Copyright 2018 The Android Open Source Project
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 "avrcp_service.h"
18 
19 #include <base/functional/bind.h>
20 #include <base/task/cancelable_task_tracker.h>
21 #include <base/threading/thread.h>
22 #include <bluetooth/log.h>
23 
24 #include <mutex>
25 #include <sstream>
26 
27 #include "bta/sys/bta_sys.h"
28 #include "btif_av.h"
29 #include "btif_common.h"
30 #include "device.h"
31 #include "osi/include/osi.h"
32 #include "stack/include/a2dp_api.h"
33 #include "stack/include/bt_hdr.h"
34 #include "stack/include/bt_uuid16.h"
35 #include "stack/include/main_thread.h"
36 #include "stack/include/sdp_api.h"
37 #include "types/bluetooth/uuid.h"
38 #include "types/raw_address.h"
39 
40 using namespace bluetooth::legacy::stack::sdp;
41 
42 namespace bluetooth {
43 namespace avrcp {
44 // Static variables and interface definitions
45 AvrcpService* AvrcpService::instance_ = nullptr;
46 AvrcpService::ServiceInterfaceImpl* AvrcpService::service_interface_ = nullptr;
47 
48 class A2dpInterfaceImpl : public A2dpInterface {
active_peer()49   RawAddress active_peer() override { return btif_av_source_active_peer(); }
50 
is_peer_in_silence_mode(const RawAddress & peer_address)51   bool is_peer_in_silence_mode(const RawAddress& peer_address) override {
52     return btif_av_is_peer_silenced(peer_address);
53   }
54 
connect_audio_sink_delayed(uint8_t handle,const RawAddress & peer_address)55   void connect_audio_sink_delayed(uint8_t handle,
56                                   const RawAddress& peer_address) override {
57     btif_av_connect_sink_delayed(handle, peer_address);
58   }
59 
find_audio_sink_service(const RawAddress & peer_address,tA2DP_FIND_CBACK p_cback)60   uint16_t find_audio_sink_service(const RawAddress& peer_address,
61                                    tA2DP_FIND_CBACK p_cback) override {
62     uint16_t attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
63                             ATTR_ID_BT_PROFILE_DESC_LIST,
64                             ATTR_ID_SUPPORTED_FEATURES};
65 
66     tA2DP_SDP_DB_PARAMS db_params = {
67         .db_len = BT_DEFAULT_BUFFER_SIZE,
68         .num_attr = ARRAY_SIZE(attr_list),
69         .p_attrs = attr_list,
70     };
71 
72     return A2DP_FindService(UUID_SERVCLASS_AUDIO_SINK, peer_address, &db_params,
73                             p_cback);
74   }
75 
76 } a2dp_interface_;
77 
78 class AvrcpInterfaceImpl : public AvrcpInterface {
79  public:
GetAvrcpControlVersion()80   uint16_t GetAvrcpControlVersion() { return AVRC_GetControlProfileVersion(); }
81 
GetAvrcpVersion()82   uint16_t GetAvrcpVersion() {
83     return AVRC_GetProfileVersion();
84   }
85 
AddRecord(uint16_t service_uuid,const char * p_service_name,const char * p_provider_name,uint16_t categories,uint32_t sdp_handle,bool browse_supported,uint16_t profile_version,uint16_t cover_art_psm)86   uint16_t AddRecord(uint16_t service_uuid, const char* p_service_name,
87                      const char* p_provider_name, uint16_t categories,
88                      uint32_t sdp_handle, bool browse_supported,
89                      uint16_t profile_version,
90                      uint16_t cover_art_psm) override {
91     return AVRC_AddRecord(service_uuid, p_service_name, p_provider_name,
92                           categories, sdp_handle, browse_supported,
93                           profile_version, cover_art_psm);
94   }
95 
RemoveRecord(uint32_t sdp_handle)96   uint16_t RemoveRecord(uint32_t sdp_handle) {
97     return AVRC_RemoveRecord(sdp_handle);
98   }
99 
FindService(uint16_t service_uuid,const RawAddress & bd_addr,tAVRC_SDP_DB_PARAMS * p_db,tAVRC_FIND_CBACK p_cback)100   uint16_t FindService(uint16_t service_uuid, const RawAddress& bd_addr,
101                        tAVRC_SDP_DB_PARAMS* p_db,
102                        tAVRC_FIND_CBACK p_cback) override {
103     return AVRC_FindService(service_uuid, bd_addr, p_db, p_cback);
104   }
105 
Open(uint8_t * p_handle,tAVRC_CONN_CB * p_ccb,const RawAddress & bd_addr)106   uint16_t Open(uint8_t* p_handle, tAVRC_CONN_CB* p_ccb,
107                 const RawAddress& bd_addr) override {
108     return AVRC_Open(p_handle, p_ccb, bd_addr);
109   }
110 
OpenBrowse(uint8_t handle,uint8_t conn_role)111   uint16_t OpenBrowse(uint8_t handle, uint8_t conn_role) override {
112     return AVRC_OpenBrowse(handle, conn_role);
113   }
114 
GetPeerMtu(uint8_t handle)115   uint16_t GetPeerMtu(uint8_t handle) override {
116     return AVCT_GetPeerMtu(handle);
117   }
118 
GetBrowseMtu(uint8_t handle)119   uint16_t GetBrowseMtu(uint8_t handle) override {
120     return AVCT_GetBrowseMtu(handle);
121   }
122 
Close(uint8_t handle)123   uint16_t Close(uint8_t handle) override { return AVRC_Close(handle); }
124 
CloseBrowse(uint8_t handle)125   uint16_t CloseBrowse(uint8_t handle) override {
126     return AVRC_CloseBrowse(handle);
127   }
128 
MsgReq(uint8_t handle,uint8_t label,uint8_t ctype,BT_HDR * p_pkt)129   uint16_t MsgReq(uint8_t handle, uint8_t label, uint8_t ctype,
130                   BT_HDR* p_pkt) override {
131     return AVRC_MsgReq(handle, label, ctype, p_pkt, true);
132   }
133 
SaveControllerVersion(const RawAddress & bdaddr,uint16_t version)134   void SaveControllerVersion(const RawAddress& bdaddr,
135                              uint16_t version) override {
136     AVRC_SaveControllerVersion(bdaddr, version);
137   }
138 
139 } avrcp_interface_;
140 
141 class SdpInterfaceImpl : public SdpInterface {
142  public:
InitDiscoveryDb(tSDP_DISCOVERY_DB * a,uint32_t b,uint16_t c,const bluetooth::Uuid * d,uint16_t e,uint16_t * f)143   bool InitDiscoveryDb(tSDP_DISCOVERY_DB* a, uint32_t b, uint16_t c,
144                        const bluetooth::Uuid* d, uint16_t e,
145                        uint16_t* f) override {
146     return get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(a, b, c, d,
147                                                                    e, f);
148   }
149 
ServiceSearchAttributeRequest(const RawAddress & a,tSDP_DISCOVERY_DB * b,tSDP_DISC_CMPL_CB * c)150   bool ServiceSearchAttributeRequest(const RawAddress& a, tSDP_DISCOVERY_DB* b,
151                                      tSDP_DISC_CMPL_CB* c) override {
152     return get_legacy_stack_sdp_api()
153         ->service.SDP_ServiceSearchAttributeRequest(a, b, c);
154   }
155 
FindServiceInDb(tSDP_DISCOVERY_DB * a,uint16_t b,t_sdp_disc_rec * c)156   tSDP_DISC_REC* FindServiceInDb(tSDP_DISCOVERY_DB* a, uint16_t b,
157                                  t_sdp_disc_rec* c) override {
158     return get_legacy_stack_sdp_api()->db.SDP_FindServiceInDb(a, b, c);
159   }
160 
FindAttributeInRec(t_sdp_disc_rec * a,uint16_t b)161   tSDP_DISC_ATTR* FindAttributeInRec(t_sdp_disc_rec* a, uint16_t b) override {
162     return get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(a, b);
163   }
164 
FindProfileVersionInRec(t_sdp_disc_rec * a,uint16_t b,uint16_t * c)165   bool FindProfileVersionInRec(t_sdp_disc_rec* a, uint16_t b,
166                                uint16_t* c) override {
167     return get_legacy_stack_sdp_api()->record.SDP_FindProfileVersionInRec(a, b,
168                                                                           c);
169   }
170 } sdp_interface_;
171 
172 // A wrapper class for the media callbacks that handles thread
173 // switching/synchronization so the devices don't have to worry about it.
174 class MediaInterfaceWrapper : public MediaInterface {
175  public:
MediaInterfaceWrapper(MediaInterface * cb)176   MediaInterfaceWrapper(MediaInterface* cb) : wrapped_(cb){};
177 
SendKeyEvent(uint8_t key,KeyState state)178   void SendKeyEvent(uint8_t key, KeyState state) override {
179     do_in_jni_thread(base::Bind(&MediaInterface::SendKeyEvent,
180                                 base::Unretained(wrapped_), key, state));
181   }
182 
GetSongInfo(SongInfoCallback info_cb)183   void GetSongInfo(SongInfoCallback info_cb) override {
184     auto cb_lambda = [](SongInfoCallback cb, SongInfo data) {
185       do_in_main_thread(FROM_HERE, base::BindOnce(cb, data));
186     };
187 
188     auto bound_cb = base::Bind(cb_lambda, info_cb);
189 
190     do_in_jni_thread(base::Bind(&MediaInterface::GetSongInfo,
191                                 base::Unretained(wrapped_), bound_cb));
192   }
193 
GetPlayStatus(PlayStatusCallback status_cb)194   void GetPlayStatus(PlayStatusCallback status_cb) override {
195     auto cb_lambda = [](PlayStatusCallback cb, PlayStatus status) {
196       do_in_main_thread(FROM_HERE, base::BindOnce(cb, status));
197     };
198 
199     auto bound_cb = base::Bind(cb_lambda, status_cb);
200 
201     do_in_jni_thread(base::Bind(&MediaInterface::GetPlayStatus,
202                                 base::Unretained(wrapped_), bound_cb));
203   }
204 
GetNowPlayingList(NowPlayingCallback now_playing_cb)205   void GetNowPlayingList(NowPlayingCallback now_playing_cb) override {
206     auto cb_lambda = [](NowPlayingCallback cb, std::string curr_media_id,
207                         std::vector<SongInfo> song_list) {
208       do_in_main_thread(
209           FROM_HERE, base::BindOnce(cb, curr_media_id, std::move(song_list)));
210     };
211 
212     auto bound_cb = base::Bind(cb_lambda, now_playing_cb);
213 
214     do_in_jni_thread(base::Bind(&MediaInterface::GetNowPlayingList,
215                                 base::Unretained(wrapped_), bound_cb));
216   }
217 
GetMediaPlayerList(MediaListCallback list_cb)218   void GetMediaPlayerList(MediaListCallback list_cb) override {
219     auto cb_lambda = [](MediaListCallback cb, uint16_t curr_player,
220                         std::vector<MediaPlayerInfo> player_list) {
221       do_in_main_thread(
222           FROM_HERE, base::BindOnce(cb, curr_player, std::move(player_list)));
223     };
224 
225     auto bound_cb = base::Bind(cb_lambda, list_cb);
226 
227     do_in_jni_thread(base::Bind(&MediaInterface::GetMediaPlayerList,
228                                 base::Unretained(wrapped_), bound_cb));
229   }
230 
GetFolderItems(uint16_t player_id,std::string media_id,FolderItemsCallback folder_cb)231   void GetFolderItems(uint16_t player_id, std::string media_id,
232                       FolderItemsCallback folder_cb) override {
233     auto cb_lambda = [](FolderItemsCallback cb,
234                         std::vector<ListItem> item_list) {
235       do_in_main_thread(FROM_HERE, base::BindOnce(cb, std::move(item_list)));
236     };
237 
238     auto bound_cb = base::Bind(cb_lambda, folder_cb);
239 
240     do_in_jni_thread(base::Bind(&MediaInterface::GetFolderItems,
241                                 base::Unretained(wrapped_), player_id, media_id,
242                                 bound_cb));
243   }
244 
SetBrowsedPlayer(uint16_t player_id,SetBrowsedPlayerCallback browse_cb)245   void SetBrowsedPlayer(uint16_t player_id,
246                         SetBrowsedPlayerCallback browse_cb) override {
247     auto cb_lambda = [](SetBrowsedPlayerCallback cb, bool success,
248                         std::string root_id, uint32_t num_items) {
249       do_in_main_thread(FROM_HERE,
250                         base::BindOnce(cb, success, root_id, num_items));
251     };
252 
253     auto bound_cb = base::Bind(cb_lambda, browse_cb);
254 
255     do_in_jni_thread(base::Bind(&MediaInterface::SetBrowsedPlayer,
256                                 base::Unretained(wrapped_), player_id,
257                                 bound_cb));
258   }
259 
PlayItem(uint16_t player_id,bool now_playing,std::string media_id)260   void PlayItem(uint16_t player_id, bool now_playing,
261                 std::string media_id) override {
262     do_in_jni_thread(base::Bind(&MediaInterface::PlayItem,
263                                 base::Unretained(wrapped_), player_id,
264                                 now_playing, media_id));
265   }
266 
SetActiveDevice(const RawAddress & address)267   void SetActiveDevice(const RawAddress& address) override {
268     do_in_jni_thread(base::Bind(&MediaInterface::SetActiveDevice,
269                                 base::Unretained(wrapped_), address));
270   }
271 
RegisterUpdateCallback(MediaCallbacks * callback)272   void RegisterUpdateCallback(MediaCallbacks* callback) override {
273     wrapped_->RegisterUpdateCallback(callback);
274   }
275 
UnregisterUpdateCallback(MediaCallbacks * callback)276   void UnregisterUpdateCallback(MediaCallbacks* callback) override {
277     wrapped_->UnregisterUpdateCallback(callback);
278   }
279 
280  private:
281   MediaInterface* wrapped_;
282 };
283 
284 // A wrapper class for the media callbacks that handles thread
285 // switching/synchronization so the devices don't have to worry about it.
286 class VolumeInterfaceWrapper : public VolumeInterface {
287  public:
VolumeInterfaceWrapper(VolumeInterface * interface)288   VolumeInterfaceWrapper(VolumeInterface* interface) : wrapped_(interface){};
289 
DeviceConnected(const RawAddress & bdaddr)290   void DeviceConnected(const RawAddress& bdaddr) override {
291     do_in_jni_thread(
292         base::Bind(static_cast<void (VolumeInterface::*)(const RawAddress&)>(
293                        &VolumeInterface::DeviceConnected),
294                    base::Unretained(wrapped_), bdaddr));
295   }
296 
DeviceConnected(const RawAddress & bdaddr,VolumeChangedCb cb)297   void DeviceConnected(const RawAddress& bdaddr, VolumeChangedCb cb) override {
298     auto cb_lambda = [](VolumeChangedCb cb, int8_t volume) {
299       do_in_main_thread(FROM_HERE, base::BindOnce(cb, volume));
300     };
301 
302     auto bound_cb = base::Bind(cb_lambda, cb);
303 
304     do_in_jni_thread(base::Bind(static_cast<void (VolumeInterface::*)(
305                                     const RawAddress&, VolumeChangedCb)>(
306                                     &VolumeInterface::DeviceConnected),
307                                 base::Unretained(wrapped_), bdaddr, bound_cb));
308   }
309 
DeviceDisconnected(const RawAddress & bdaddr)310   void DeviceDisconnected(const RawAddress& bdaddr) override {
311     do_in_jni_thread(base::Bind(&VolumeInterface::DeviceDisconnected,
312                                 base::Unretained(wrapped_), bdaddr));
313   }
314 
SetVolume(int8_t volume)315   void SetVolume(int8_t volume) override {
316     do_in_jni_thread(base::Bind(&VolumeInterface::SetVolume,
317                                 base::Unretained(wrapped_), volume));
318   }
319 
320  private:
321   VolumeInterface* wrapped_;
322 };
323 
324 // A wrapper class for the media callbacks that handles thread
325 // switching/synchronization so the devices don't have to worry about it.
326 class PlayerSettingsInterfaceWrapper : public PlayerSettingsInterface {
327  public:
PlayerSettingsInterfaceWrapper(PlayerSettingsInterface * interface)328   PlayerSettingsInterfaceWrapper(PlayerSettingsInterface* interface)
329       : wrapped_(interface){};
330 
ListPlayerSettings(ListPlayerSettingsCallback cb)331   void ListPlayerSettings(ListPlayerSettingsCallback cb) override {
332     auto cb_lambda = [](const ListPlayerSettingsCallback& cb,
333                         std::vector<PlayerAttribute> attributes) {
334       do_in_main_thread(FROM_HERE, base::BindOnce(cb, std::move(attributes)));
335     };
336 
337     auto bound_cb = base::Bind(cb_lambda, cb);
338 
339     do_in_jni_thread(base::Bind(&PlayerSettingsInterface::ListPlayerSettings,
340                                 base::Unretained(wrapped_), bound_cb));
341   }
342 
ListPlayerSettingValues(PlayerAttribute setting,ListPlayerSettingValuesCallback cb)343   void ListPlayerSettingValues(PlayerAttribute setting,
344                                ListPlayerSettingValuesCallback cb) override {
345     auto cb_lambda = [](const ListPlayerSettingValuesCallback& cb,
346                         PlayerAttribute setting, std::vector<uint8_t> values) {
347       do_in_main_thread(FROM_HERE,
348                         base::BindOnce(cb, setting, std::move(values)));
349     };
350 
351     auto bound_cb = base::Bind(cb_lambda, cb);
352 
353     do_in_jni_thread(
354         base::Bind(&PlayerSettingsInterface::ListPlayerSettingValues,
355                    base::Unretained(wrapped_), setting, bound_cb));
356   }
357 
GetCurrentPlayerSettingValue(std::vector<PlayerAttribute> attributes,GetCurrentPlayerSettingValueCallback cb)358   void GetCurrentPlayerSettingValue(
359       std::vector<PlayerAttribute> attributes,
360       GetCurrentPlayerSettingValueCallback cb) override {
361     auto cb_lambda = [](const GetCurrentPlayerSettingValueCallback& cb,
362                         std::vector<PlayerAttribute> attributes,
363                         std::vector<uint8_t> values) {
364       do_in_main_thread(FROM_HERE, base::BindOnce(cb, std::move(attributes),
365                                                   std::move(values)));
366     };
367 
368     auto bound_cb = base::Bind(cb_lambda, cb);
369 
370     do_in_jni_thread(base::Bind(
371         &PlayerSettingsInterface::GetCurrentPlayerSettingValue,
372         base::Unretained(wrapped_), std::move(attributes), bound_cb));
373   }
374 
SetPlayerSettings(std::vector<PlayerAttribute> attributes,std::vector<uint8_t> values,SetPlayerSettingValueCallback cb)375   void SetPlayerSettings(std::vector<PlayerAttribute> attributes,
376                          std::vector<uint8_t> values,
377                          SetPlayerSettingValueCallback cb) override {
378     auto cb_lambda = [](const SetPlayerSettingValueCallback& cb, bool success) {
379       do_in_main_thread(FROM_HERE, base::BindOnce(cb, success));
380     };
381 
382     auto bound_cb = base::Bind(cb_lambda, cb);
383 
384     do_in_jni_thread(base::Bind(
385         &PlayerSettingsInterface::SetPlayerSettings, base::Unretained(wrapped_),
386         std::move(attributes), std::move(values), bound_cb));
387   }
388 
389  private:
390   PlayerSettingsInterface* wrapped_;
391 };
392 
Init(MediaInterface * media_interface,VolumeInterface * volume_interface,PlayerSettingsInterface * player_settings_interface)393 void AvrcpService::Init(MediaInterface* media_interface,
394                         VolumeInterface* volume_interface,
395                         PlayerSettingsInterface* player_settings_interface) {
396   log::info("AVRCP Target Service started");
397 
398   profile_version = avrcp_interface_.GetAvrcpVersion();
399 
400   uint16_t supported_features = GetSupportedFeatures(profile_version);
401   sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
402 
403   avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET,
404                              "AV Remote Control Target", NULL,
405                              supported_features, sdp_record_handle, true,
406                              profile_version, 0);
407   bta_sys_add_uuid(UUID_SERVCLASS_AV_REM_CTRL_TARGET);
408 
409   ct_sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
410 
411   avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REMOTE_CONTROL,
412                              "AV Remote Control", NULL, AVRCP_SUPF_TG_CT,
413                              ct_sdp_record_handle, false,
414                              avrcp_interface_.GetAvrcpControlVersion(), 0);
415   bta_sys_add_uuid(UUID_SERVCLASS_AV_REMOTE_CONTROL);
416 
417   media_interface_ = new MediaInterfaceWrapper(media_interface);
418   media_interface->RegisterUpdateCallback(instance_);
419 
420   VolumeInterfaceWrapper* wrapped_volume_interface = nullptr;
421   if (volume_interface != nullptr) {
422     wrapped_volume_interface = new VolumeInterfaceWrapper(volume_interface);
423   }
424 
425   volume_interface_ = wrapped_volume_interface;
426 
427   PlayerSettingsInterfaceWrapper* wrapped_player_settings_interface = nullptr;
428   if (player_settings_interface != nullptr) {
429     wrapped_player_settings_interface =
430         new PlayerSettingsInterfaceWrapper(player_settings_interface);
431   }
432 
433   player_settings_interface_ = wrapped_player_settings_interface;
434 
435   ConnectionHandler::Initialize(
436       base::BindRepeating(&AvrcpService::DeviceCallback,
437                           base::Unretained(instance_)),
438       &avrcp_interface_, &sdp_interface_, wrapped_volume_interface);
439   connection_handler_ = ConnectionHandler::Get();
440 }
441 
GetSupportedFeatures(uint16_t profile_version)442 uint16_t AvrcpService::GetSupportedFeatures(uint16_t profile_version) {
443   switch (profile_version) {
444     case AVRC_REV_1_6:
445       return AVRCP_SUPF_TG_1_6;
446     case AVRC_REV_1_5:
447       return AVRCP_SUPF_TG_1_5;
448     case AVRC_REV_1_4:
449       return AVRCP_SUPF_TG_1_4;
450     case AVRC_REV_1_3:
451       return AVRCP_SUPF_TG_1_3;
452   }
453   return AVRCP_SUPF_TG_DEFAULT;
454 }
455 
Cleanup()456 void AvrcpService::Cleanup() {
457   log::info("AVRCP Target Service stopped");
458 
459   avrcp_interface_.RemoveRecord(sdp_record_handle);
460   bta_sys_remove_uuid(UUID_SERVCLASS_AV_REM_CTRL_TARGET);
461   sdp_record_handle = -1;
462   avrcp_interface_.RemoveRecord(ct_sdp_record_handle);
463   bta_sys_remove_uuid(UUID_SERVCLASS_AV_REMOTE_CONTROL);
464   ct_sdp_record_handle = -1;
465 
466   connection_handler_->CleanUp();
467   connection_handler_ = nullptr;
468   if (player_settings_interface_ != nullptr) {
469     delete player_settings_interface_;
470   }
471   if (volume_interface_ != nullptr) {
472     delete volume_interface_;
473   }
474   delete media_interface_;
475 }
476 
RegisterBipServer(int psm)477 void AvrcpService::RegisterBipServer(int psm) {
478   log::info("AVRCP Target Service has registered a BIP OBEX server, psm={}",
479             psm);
480   avrcp_interface_.RemoveRecord(sdp_record_handle);
481   uint16_t supported_features
482       = GetSupportedFeatures(profile_version) | AVRC_SUPF_TG_PLAYER_COVER_ART;
483   sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
484   avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET,
485                              "AV Remote Control Target", NULL,
486                              supported_features, sdp_record_handle, true,
487                              profile_version, psm);
488 }
489 
UnregisterBipServer()490 void AvrcpService::UnregisterBipServer() {
491   log::info("AVRCP Target Service has unregistered a BIP OBEX server");
492   avrcp_interface_.RemoveRecord(sdp_record_handle);
493   uint16_t supported_features = GetSupportedFeatures(profile_version);
494   sdp_record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord();
495   avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET,
496                              "AV Remote Control Target", NULL,
497                              supported_features, sdp_record_handle, true,
498                              profile_version, 0);
499 }
500 
Get()501 AvrcpService* AvrcpService::Get() {
502   log::assert_that(instance_ != nullptr, "assert failed: instance_ != nullptr");
503   return instance_;
504 }
505 
GetServiceInterface()506 ServiceInterface* AvrcpService::GetServiceInterface() {
507   if (service_interface_ == nullptr) {
508     service_interface_ = new ServiceInterfaceImpl();
509   }
510 
511   return service_interface_;
512 }
513 
ConnectDevice(const RawAddress & bdaddr)514 void AvrcpService::ConnectDevice(const RawAddress& bdaddr) {
515   log::info("address={}", bdaddr);
516 
517   connection_handler_->ConnectDevice(bdaddr);
518 }
519 
DisconnectDevice(const RawAddress & bdaddr)520 void AvrcpService::DisconnectDevice(const RawAddress& bdaddr) {
521   log::info("address={}", bdaddr);
522   connection_handler_->DisconnectDevice(bdaddr);
523 }
524 
SetBipClientStatus(const RawAddress & bdaddr,bool connected)525 void AvrcpService::SetBipClientStatus(const RawAddress& bdaddr,
526                                       bool connected) {
527   log::info("address={}, connected={}", bdaddr, connected);
528   connection_handler_->SetBipClientStatus(bdaddr, connected);
529 }
530 
SendMediaUpdate(bool track_changed,bool play_state,bool queue)531 void AvrcpService::SendMediaUpdate(bool track_changed, bool play_state,
532                                    bool queue) {
533   log::info("track_changed={} :  play_state={} :  queue={}", track_changed,
534             play_state, queue);
535 
536   // This function may be called on any thread, we need to make sure that the
537   // device update happens on the main thread.
538   for (const auto& device :
539        instance_->connection_handler_->GetListOfDevices()) {
540     do_in_main_thread(
541         FROM_HERE, base::BindOnce(&Device::SendMediaUpdate, device.get()->Get(),
542                                   track_changed, play_state, queue));
543   }
544 }
545 
SendFolderUpdate(bool available_players,bool addressed_players,bool uids)546 void AvrcpService::SendFolderUpdate(bool available_players,
547                                     bool addressed_players, bool uids) {
548   log::info("available_players={} :  addressed_players={} :  uids={}",
549             available_players, addressed_players, uids);
550 
551   // Ensure that the update is posted to the correct thread
552   for (const auto& device :
553        instance_->connection_handler_->GetListOfDevices()) {
554     do_in_main_thread(
555         FROM_HERE,
556         base::BindOnce(&Device::SendFolderUpdate, device.get()->Get(),
557                        available_players, addressed_players, uids));
558   }
559 }
560 
561 // Send out the track changed info to update the playback state for each device
SendActiveDeviceChanged(const RawAddress & address)562 void AvrcpService::SendActiveDeviceChanged(const RawAddress& address) {
563   SendMediaUpdate(false, true, false);
564 }
565 
SendPlayerSettingsChanged(std::vector<PlayerAttribute> attributes,std::vector<uint8_t> values)566 void AvrcpService::SendPlayerSettingsChanged(
567     std::vector<PlayerAttribute> attributes, std::vector<uint8_t> values) {
568   if (attributes.size() != values.size()) {
569     log::error("Attributes size {} doesn't match values size {}",
570                attributes.size(), values.size());
571     return;
572   }
573   std::stringstream ss;
574   for (size_t i = 0; i < attributes.size(); i++) {
575     ss << "{attribute=" << attributes.at(i) << " : ";
576     if (attributes.at(i) == PlayerAttribute::REPEAT) {
577       ss << "value=" << (PlayerRepeatValue)values.at(i);
578     } else if (attributes.at(i) == PlayerAttribute::SHUFFLE) {
579       ss << "value=" << (PlayerShuffleValue)values.at(i);
580     } else {
581       ss << "value=" << std::to_string(values.at(i));
582     }
583     ss << ((i + 1 < attributes.size()) ? "}, " : "}");
584   }
585 
586   log::info("{}", ss.str());
587 
588   // Ensure that the update is posted to the correct thread
589   for (const auto& device :
590        instance_->connection_handler_->GetListOfDevices()) {
591     do_in_main_thread(FROM_HERE,
592                       base::BindOnce(&Device::HandlePlayerSettingChanged,
593                                      device.get()->Get(), attributes, values));
594   }
595 }
596 
DeviceCallback(std::shared_ptr<Device> new_device)597 void AvrcpService::DeviceCallback(std::shared_ptr<Device> new_device) {
598   if (new_device == nullptr) return;
599 
600   // TODO (apanicke): Pass the interfaces into the connection handler
601   // so that the devices can be created with any interfaces they need.
602   new_device->RegisterInterfaces(media_interface_, &a2dp_interface_,
603                                  volume_interface_, player_settings_interface_);
604 }
605 
606 // Service Interface
Init(MediaInterface * media_interface,VolumeInterface * volume_interface,PlayerSettingsInterface * player_settings_interface)607 void AvrcpService::ServiceInterfaceImpl::Init(
608     MediaInterface* media_interface, VolumeInterface* volume_interface,
609     PlayerSettingsInterface* player_settings_interface) {
610   std::lock_guard<std::mutex> lock(service_interface_lock_);
611 
612   // TODO: This function should block until the service is completely up so
613   // that its possible to call Get() on the service immediately after calling
614   // init without issues.
615 
616   log::assert_that(instance_ == nullptr, "assert failed: instance_ == nullptr");
617   instance_ = new AvrcpService();
618 
619   do_in_main_thread(
620       FROM_HERE, base::BindOnce(&AvrcpService::Init,
621                                 base::Unretained(instance_), media_interface,
622                                 volume_interface, player_settings_interface));
623 }
624 
RegisterBipServer(int psm)625 void AvrcpService::ServiceInterfaceImpl::RegisterBipServer(int psm) {
626   std::lock_guard<std::mutex> lock(service_interface_lock_);
627   log::assert_that(instance_ != nullptr, "assert failed: instance_ != nullptr");
628   do_in_main_thread(FROM_HERE,
629                     base::BindOnce(&AvrcpService::RegisterBipServer,
630                                    base::Unretained(instance_), psm));
631 }
632 
UnregisterBipServer()633 void AvrcpService::ServiceInterfaceImpl::UnregisterBipServer() {
634   std::lock_guard<std::mutex> lock(service_interface_lock_);
635   log::assert_that(instance_ != nullptr, "assert failed: instance_ != nullptr");
636   do_in_main_thread(FROM_HERE,
637                     base::BindOnce(&AvrcpService::UnregisterBipServer,
638                                    base::Unretained(instance_)));
639 }
640 
ConnectDevice(const RawAddress & bdaddr)641 bool AvrcpService::ServiceInterfaceImpl::ConnectDevice(
642     const RawAddress& bdaddr) {
643   std::lock_guard<std::mutex> lock(service_interface_lock_);
644   log::assert_that(instance_ != nullptr, "assert failed: instance_ != nullptr");
645   do_in_main_thread(FROM_HERE,
646                     base::BindOnce(&AvrcpService::ConnectDevice,
647                                    base::Unretained(instance_), bdaddr));
648   return true;
649 }
650 
DisconnectDevice(const RawAddress & bdaddr)651 bool AvrcpService::ServiceInterfaceImpl::DisconnectDevice(
652     const RawAddress& bdaddr) {
653   std::lock_guard<std::mutex> lock(service_interface_lock_);
654   log::assert_that(instance_ != nullptr, "assert failed: instance_ != nullptr");
655   do_in_main_thread(FROM_HERE,
656                     base::BindOnce(&AvrcpService::DisconnectDevice,
657                                    base::Unretained(instance_), bdaddr));
658   return true;
659 }
660 
IsDeviceConnected(const RawAddress & bdaddr)661 bool AvrcpService::IsDeviceConnected(const RawAddress& bdaddr) {
662   if (instance_ == nullptr) {
663     log::warn("AVRCP Target Service not started");
664     return false;
665   }
666 
667   auto handler = instance_->connection_handler_;
668   if (handler == nullptr) {
669     log::warn("AVRCP connection handler is null");
670     return false;
671   }
672 
673   for (const auto& device : handler->GetListOfDevices()) {
674     if (bdaddr == device->GetAddress()) {
675       return true;
676     }
677   }
678 
679   return false;
680 }
681 
SetBipClientStatus(const RawAddress & bdaddr,bool connected)682 void AvrcpService::ServiceInterfaceImpl::SetBipClientStatus(
683     const RawAddress& bdaddr, bool connected) {
684   std::lock_guard<std::mutex> lock(service_interface_lock_);
685   log::assert_that(instance_ != nullptr, "assert failed: instance_ != nullptr");
686   do_in_main_thread(FROM_HERE, base::BindOnce(&AvrcpService::SetBipClientStatus,
687                                               base::Unretained(instance_),
688                                               bdaddr, connected));
689 }
690 
Cleanup()691 bool AvrcpService::ServiceInterfaceImpl::Cleanup() {
692   std::lock_guard<std::mutex> lock(service_interface_lock_);
693 
694   if (instance_ == nullptr) return false;
695 
696   do_in_main_thread(FROM_HERE, base::BindOnce(&AvrcpService::Cleanup,
697                                               base::Owned(instance_)));
698 
699   // Setting instance to nullptr here is fine since it will be deleted on the
700   // other thread.
701   instance_ = nullptr;
702 
703   return true;
704 }
705 
DebugDump(int fd)706 void AvrcpService::DebugDump(int fd) {
707   if (instance_ == nullptr) {
708     dprintf(fd, "\nAVRCP Target Service not started\n");
709     return;
710   }
711 
712   auto handler = instance_->connection_handler_;
713   if (handler == nullptr) {
714     dprintf(fd, "\nAVRCP connection handler is null\n");
715     return;
716   }
717 
718   auto device_list = handler->GetListOfDevices();
719   dprintf(fd, "\nAVRCP Target Native Service: %zu devices\n",
720           device_list.size());
721 
722   std::stringstream stream;
723   for (const auto& device : device_list) {
724     stream << "  " << *device << std::endl;
725   }
726 
727   dprintf(fd, "%s", stream.str().c_str());
728 }
729 
730 /** when a2dp connected, btif will start register vol changed, so we need a
731  * interface for it. */
RegisterVolChanged(const RawAddress & bdaddr)732 void AvrcpService::RegisterVolChanged(const RawAddress& bdaddr) {
733   log::info(": address={}", bdaddr);
734 
735   connection_handler_->RegisterVolChanged(bdaddr);
736 }
737 
738 }  // namespace avrcp
739 }  // namespace bluetooth
740