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