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