From aa8c8b5716cecc2e6133e484aad4d5bc41328df0 Mon Sep 17 00:00:00 2001 From: Sal Savage Date: Fri, 28 Feb 2020 11:33:06 -0800 Subject: [PATCH] Add a path to add the PSM of the BIP OBEX server to the SDP record Tag: #feature Bug: 153076316 Test: Build, flash, make sure everything still works as no one is using this code path yet Change-Id: I672be8c341c453f862a50a9b3cfb4150b9588b2e --- bta/ar/bta_ar.cc | 4 +-- btif/avrcp/avrcp_service.cc | 45 ++++++++++++++++++++++++++++++--- btif/avrcp/avrcp_service.h | 5 ++++ include/hardware/avrcp/avrcp.h | 4 ++- profile/avrcp/avrcp_internal.h | 3 ++- profile/avrcp/tests/avrcp_test_helper.h | 4 +-- stack/avrc/avrc_sdp.cc | 29 ++++++++++++++++++--- stack/include/avrc_api.h | 6 ++++- 8 files changed, 87 insertions(+), 13 deletions(-) diff --git a/bta/ar/bta_ar.cc b/bta/ar/bta_ar.cc index 4a95f3764..36b88ab8b 100644 --- a/bta/ar/bta_ar.cc +++ b/bta/ar/bta_ar.cc @@ -167,7 +167,7 @@ void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name, bta_ar_cb.sdp_tg_handle = SDP_CreateRecord(); AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_tg_handle, browse_supported, - profile_version); + profile_version, 0); bta_sys_add_uuid(service_uuid); } /* only one TG is allowed (first-come, first-served). @@ -180,7 +180,7 @@ void bta_ar_reg_avrc(uint16_t service_uuid, const char* service_name, bta_ar_cb.sdp_ct_handle = SDP_CreateRecord(); AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_ct_handle, browse_supported, - profile_version); + profile_version, 0); bta_sys_add_uuid(service_uuid); } else { /* multiple CTs are allowed. diff --git a/btif/avrcp/avrcp_service.cc b/btif/avrcp/avrcp_service.cc index 79bbec9f9..834a9739b 100644 --- a/btif/avrcp/avrcp_service.cc +++ b/btif/avrcp/avrcp_service.cc @@ -68,10 +68,11 @@ class AvrcpInterfaceImpl : public AvrcpInterface { uint16_t 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) override { + uint16_t profile_version, + uint16_t cover_art_psm) override { return AVRC_AddRecord(service_uuid, p_service_name, p_provider_name, categories, sdp_handle, browse_supported, - profile_version); + profile_version, cover_art_psm); } uint16_t RemoveRecord(uint32_t sdp_handle) { @@ -304,7 +305,7 @@ void AvrcpService::Init(MediaInterface* media_interface, avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target", NULL, supported_features, sdp_record_handle, true, - profile_version); + profile_version, 0); btif_dm_add_uuid_to_eir(UUID_SERVCLASS_AV_REM_CTRL_TARGET); media_interface_ = new MediaInterfaceWrapper(media_interface); @@ -352,6 +353,30 @@ void AvrcpService::Cleanup() { delete media_interface_; } +void AvrcpService::RegisterBipServer(int psm) { + LOG(INFO) << "AVRCP Target Service has registered a BIP OBEX server, psm=" + << psm; + avrcp_interface_.RemoveRecord(sdp_record_handle); + uint16_t supported_features + = GetSupportedFeatures(profile_version) | AVRC_SUPF_TG_PLAYER_COVER_ART; + sdp_record_handle = SDP_CreateRecord(); + avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, + "AV Remote Control Target", NULL, + supported_features, sdp_record_handle, true, + profile_version, psm); +} + +void AvrcpService::UnregisterBipServer() { + LOG(INFO) << "AVRCP Target Service has unregistered a BIP OBEX server"; + avrcp_interface_.RemoveRecord(sdp_record_handle); + uint16_t supported_features = GetSupportedFeatures(profile_version); + sdp_record_handle = SDP_CreateRecord(); + avrcp_interface_.AddRecord(UUID_SERVCLASS_AV_REM_CTRL_TARGET, + "AV Remote Control Target", NULL, + supported_features, sdp_record_handle, true, + profile_version, 0); +} + AvrcpService* AvrcpService::Get() { CHECK(instance_); return instance_; @@ -443,6 +468,20 @@ void AvrcpService::ServiceInterfaceImpl::Init( media_interface, volume_interface)); } +void AvrcpService::ServiceInterfaceImpl::RegisterBipServer(int psm) { + std::lock_guard lock(service_interface_lock_); + CHECK(instance_ != nullptr); + do_in_main_thread(FROM_HERE, base::Bind(&AvrcpService::RegisterBipServer, + base::Unretained(instance_), psm)); +} + +void AvrcpService::ServiceInterfaceImpl::UnregisterBipServer() { + std::lock_guard lock(service_interface_lock_); + CHECK(instance_ != nullptr); + do_in_main_thread(FROM_HERE, base::Bind(&AvrcpService::UnregisterBipServer, + base::Unretained(instance_))); +} + bool AvrcpService::ServiceInterfaceImpl::ConnectDevice( const RawAddress& bdaddr) { std::lock_guard lock(service_interface_lock_); diff --git a/btif/avrcp/avrcp_service.h b/btif/avrcp/avrcp_service.h index e3819c36f..72929c7db 100644 --- a/btif/avrcp/avrcp_service.h +++ b/btif/avrcp/avrcp_service.h @@ -56,6 +56,9 @@ class AvrcpService : public MediaCallbacks { void Init(MediaInterface* media_interface, VolumeInterface* volume_interface); void Cleanup(); + void RegisterBipServer(int psm); + void UnregisterBipServer(); + void ConnectDevice(const RawAddress& bdaddr); void DisconnectDevice(const RawAddress& bdaddr); @@ -70,6 +73,8 @@ class AvrcpService : public MediaCallbacks { public: void Init(MediaInterface* media_interface, VolumeInterface* volume_interface) override; + void RegisterBipServer(int psm) override; + void UnregisterBipServer() override; bool ConnectDevice(const RawAddress& bdaddr) override; bool DisconnectDevice(const RawAddress& bdaddr) override; bool Cleanup() override; diff --git a/include/hardware/avrcp/avrcp.h b/include/hardware/avrcp/avrcp.h index 577acb9f7..5612df073 100644 --- a/include/hardware/avrcp/avrcp.h +++ b/include/hardware/avrcp/avrcp.h @@ -176,6 +176,8 @@ class ServiceInterface { // Volume is disabled. virtual void Init(MediaInterface* mediaInterface, VolumeInterface* volumeInterface) = 0; + virtual void RegisterBipServer(int psm) = 0; + virtual void UnregisterBipServer() = 0; virtual bool ConnectDevice(const RawAddress& bdaddr) = 0; virtual bool DisconnectDevice(const RawAddress& bdaddr) = 0; virtual bool Cleanup() = 0; @@ -185,4 +187,4 @@ class ServiceInterface { }; } // namespace avrcp -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/profile/avrcp/avrcp_internal.h b/profile/avrcp/avrcp_internal.h index ed55d2748..ef957d8de 100644 --- a/profile/avrcp/avrcp_internal.h +++ b/profile/avrcp/avrcp_internal.h @@ -36,7 +36,8 @@ class AvrcpInterface { virtual uint16_t 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) = 0; + uint16_t profile_version, + uint16_t cover_art_psm) = 0; virtual uint16_t RemoveRecord(uint32_t sdp_handle) = 0; diff --git a/profile/avrcp/tests/avrcp_test_helper.h b/profile/avrcp/tests/avrcp_test_helper.h index 2476b07dd..a5411241a 100644 --- a/profile/avrcp/tests/avrcp_test_helper.h +++ b/profile/avrcp/tests/avrcp_test_helper.h @@ -59,8 +59,8 @@ class MockVolumeInterface : public VolumeInterface { class MockAvrcpInterface : public AvrcpInterface { public: MOCK_METHOD0(GetAvrcpVersion, uint16_t(void)); - MOCK_METHOD7(AddRecord, uint16_t(uint16_t, const char*, const char*, uint16_t, - uint32_t, bool, uint16_t)); + MOCK_METHOD8(AddRecord, uint16_t(uint16_t, const char*, const char*, uint16_t, + uint32_t, bool, uint16_t, uint16_t)); MOCK_METHOD1(RemoveRecord, uint16_t(uint32_t)); MOCK_METHOD4(FindService, uint16_t(uint16_t, const RawAddress&, tAVRC_SDP_DB_PARAMS*, tAVRC_FIND_CBACK)); diff --git a/stack/avrc/avrc_sdp.cc b/stack/avrc/avrc_sdp.cc index 3261e9dbe..42c6cbe14 100644 --- a/stack/avrc/avrc_sdp.cc +++ b/stack/avrc/avrc_sdp.cc @@ -174,6 +174,9 @@ uint16_t AVRC_FindService(uint16_t service_uuid, const RawAddress& bd_addr, * * profile_version: profile version of avrcp record. * + * cover_art_psm: The PSM of a cover art service, if + * supported. Use 0 Otherwise. Ignored on controller + * * Output Parameters: * None. * @@ -185,7 +188,7 @@ uint16_t AVRC_FindService(uint16_t service_uuid, const RawAddress& bd_addr, uint16_t AVRC_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 profile_version, uint16_t cover_art_psm) { uint16_t browse_list[1]; bool result = true; uint8_t temp[8]; @@ -195,8 +198,8 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, uint16_t class_list[2]; AVRC_TRACE_API("%s: Add AVRCP SDP record, uuid: %x, profile_version: 0x%x, " - "supported_features: 0x%x", __func__, service_uuid, - profile_version, categories); + "supported_features: 0x%x, psm: 0x%x", __func__, service_uuid, + profile_version, categories, cover_art_psm); if (service_uuid != UUID_SERVCLASS_AV_REM_CTRL_TARGET && service_uuid != UUID_SERVCLASS_AV_REMOTE_CONTROL) @@ -262,6 +265,26 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name, i++; } + /* Add the BIP PSM for cover art on 1.6+ target devices that support it */ + if (profile_version >= AVRC_REV_1_6 && + service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET && + cover_art_psm > 0) { + AVRC_TRACE_API("%s: Add AVRCP BIP PSM to additonal protocol descriptor" + " lists, psm: 0x%x", __func__, cover_art_psm); + num_additional_protocols++; + avrc_add_proto_desc_lists[i].num_elems = 2; + avrc_add_proto_desc_lists[i].list_elem[0].num_params = 1; + avrc_add_proto_desc_lists[i].list_elem[0].protocol_uuid = + UUID_PROTOCOL_L2CAP; + avrc_add_proto_desc_lists[i].list_elem[0].params[0] = cover_art_psm; + avrc_add_proto_desc_lists[i].list_elem[0].params[1] = 0; + avrc_add_proto_desc_lists[i].list_elem[1].num_params = 0; + avrc_add_proto_desc_lists[i].list_elem[1].protocol_uuid = + UUID_PROTOCOL_OBEX; + avrc_add_proto_desc_lists[i].list_elem[1].params[0] = 0; + i++; + } + /* Add the additional lists if we support any */ if (num_additional_protocols > 0) { AVRC_TRACE_API("%s: Add %d additonal protocol descriptor lists", diff --git a/stack/include/avrc_api.h b/stack/include/avrc_api.h index e6461305e..7796ae0b6 100644 --- a/stack/include/avrc_api.h +++ b/stack/include/avrc_api.h @@ -262,6 +262,9 @@ extern uint16_t AVRC_GetProfileVersion(); * * profile_version: profile version of avrcp record. * + * cover_art_psm: The PSM of a cover art service, if + * supported. Use 0 Otherwise. Ignored on controller + * * Output Parameters: * None. * @@ -274,7 +277,8 @@ extern uint16_t AVRC_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 profile_version, + uint16_t cover_art_psm); /******************************************************************************* * -- 2.11.0