summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author William Escande <wescande@google.com> 2023-02-23 18:24:41 -0800
committer William Escande <wescande@google.com> 2023-02-27 09:22:21 +0000
commitf8a79afd92512519d9ed6628cdce7a17c0a43b76 (patch)
treefcea3c59a964f434a9c0e7eb8d930c62b1f93887
parent452c0114e428572ce9047e69879124c14556db5c (diff)
Add avrcp sysprop for absolute volume
The `define` cannot be override on runtime and some target need to configure the support for absolute volume to false (Eg: Wear OS) Test: manual | set the property and check avrcp absolute volume Bug: 263323082 Change-Id: I14757867def3ef3110387f92f158ec6b5708da76
-rw-r--r--sysprop/Android.bp17
-rw-r--r--sysprop/OWNERS2
-rw-r--r--sysprop/avrcp.sysprop11
-rw-r--r--system/bta/av/bta_av_cfg.cc62
-rw-r--r--system/bta/av/bta_av_int.h2
-rw-r--r--system/bta/av/bta_av_main.cc2
-rw-r--r--system/btif/src/btif_av.cc8
-rw-r--r--system/btif/src/btif_rc.cc16
-rw-r--r--system/btif/test/btif_rc_test.cc1
-rw-r--r--system/internal_include/bt_target.h4
-rw-r--r--system/stack/Android.bp1
-rw-r--r--system/stack/avrc/avrc_api.cc22
-rw-r--r--system/stack/avrc/avrc_bld_ct.cc12
-rw-r--r--system/stack/avrc/avrc_pars_ct.cc12
-rw-r--r--system/stack/include/avrc_api.h10
-rw-r--r--system/test/mock/mock_stack_avrc_api.cc4
16 files changed, 129 insertions, 57 deletions
diff --git a/sysprop/Android.bp b/sysprop/Android.bp
new file mode 100644
index 0000000000..d66d1e9cff
--- /dev/null
+++ b/sysprop/Android.bp
@@ -0,0 +1,17 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+sysprop_library {
+ name: "com.android.sysprop.bluetooth",
+ host_supported: true,
+ srcs: [
+ "avrcp.sysprop",
+ ],
+ property_owner: "Platform",
+ api_packages: ["android.sysprop"],
+ cpp: {
+ min_sdk_version: "Tiramisu",
+ },
+ apex_available: ["com.android.btservices"],
+}
diff --git a/sysprop/OWNERS b/sysprop/OWNERS
new file mode 100644
index 0000000000..263e0532b6
--- /dev/null
+++ b/sysprop/OWNERS
@@ -0,0 +1,2 @@
+licorne@google.com
+wescande@google.com
diff --git a/sysprop/avrcp.sysprop b/sysprop/avrcp.sysprop
new file mode 100644
index 0000000000..6c12087ef5
--- /dev/null
+++ b/sysprop/avrcp.sysprop
@@ -0,0 +1,11 @@
+module: "android.sysprop.bluetooth.Avrcp"
+owner: Platform
+
+prop {
+ api_name: "absolute_volume"
+ type: Boolean
+ scope: Internal
+ access: Readonly
+ prop_name: "bluetooth.avrcp.absolute_volume.enabled"
+}
+
diff --git a/system/bta/av/bta_av_cfg.cc b/system/bta/av/bta_av_cfg.cc
index d2a7d8aaaf..bebd05e412 100644
--- a/system/bta/av/bta_av_cfg.cc
+++ b/system/bta/av/bta_av_cfg.cc
@@ -92,16 +92,16 @@ const uint8_t bta_av_meta_caps_evt_ids[] = {
(sizeof(bta_av_meta_caps_evt_ids) / sizeof(bta_av_meta_caps_evt_ids[0]))
#endif /* BTA_AV_NUM_RC_EVT_IDS */
-const uint8_t bta_avk_meta_caps_evt_ids[] = {
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
- AVRC_EVT_VOLUME_CHANGE,
-#endif
-};
-
-#ifndef BTA_AVK_NUM_RC_EVT_IDS
-#define BTA_AVK_NUM_RC_EVT_IDS \
- (sizeof(bta_avk_meta_caps_evt_ids) / sizeof(bta_avk_meta_caps_evt_ids[0]))
-#endif /* BTA_AVK_NUM_RC_EVT_IDS */
+const uint8_t* get_bta_avk_meta_caps_evt_ids() {
+ if (avrcp_absolute_volume_is_enabled()) {
+ static const uint8_t bta_avk_meta_caps_evt_ids[] = {
+ AVRC_EVT_VOLUME_CHANGE,
+ };
+ return bta_avk_meta_caps_evt_ids;
+ } else {
+ return {};
+ }
+}
// These are the only events used with AVRCP1.3
const uint8_t bta_av_meta_caps_evt_ids_avrcp13[] = {
@@ -113,7 +113,7 @@ const uint8_t bta_av_meta_caps_evt_ids_avrcp13[] = {
#define BTA_AV_NUM_RC_EVT_IDS_AVRCP13 \
(sizeof(bta_av_meta_caps_evt_ids_avrcp13) / \
sizeof(bta_av_meta_caps_evt_ids_avrcp13[0]))
-#endif /* BTA_AVK_NUM_RC_EVT_IDS_AVRCP13 */
+#endif /* BTA_AV_NUM_RC_EVT_IDS_AVRCP13 */
/* This configuration to be used when we are Src + TG + CT( only for abs vol) */
extern const tBTA_AV_CFG bta_av_cfg = {
@@ -136,23 +136,29 @@ extern const tBTA_AV_CFG bta_av_cfg = {
/* This configuration to be used when we are Sink + CT + TG( only for abs vol)
*/
-extern const tBTA_AV_CFG bta_avk_cfg = {
- AVRC_CO_METADATA, /* AVRCP Company ID */
- BTA_AVK_RC_SUPF_CT, /* AVRCP controller categories */
- BTA_AVK_RC_SUPF_TG, /* AVRCP target categories */
- 6, /* AVDTP audio channel max data queue size */
- false, /* true, to accept AVRC 1.3 group nevigation command */
- 2, /* company id count in p_meta_co_ids */
- BTA_AVK_NUM_RC_EVT_IDS, /* event id count in p_meta_evt_ids */
- BTA_AV_RC_PASS_RSP_CODE, /* the default response code for pass
- through commands */
- bta_av_meta_caps_co_ids, /* the metadata Get Capabilities response
- for company id */
- bta_avk_meta_caps_evt_ids, /* the the metadata Get Capabilities
- response for event id */
- {0}, /* Default AVRCP controller name */
- {0}, /* Default AVRCP target name */
-};
+
+const tBTA_AV_CFG* get_bta_avk_cfg() {
+ static const tBTA_AV_CFG bta_avk_cfg = {
+ AVRC_CO_METADATA, /* AVRCP Company ID */
+ BTA_AVK_RC_SUPF_CT, /* AVRCP controller categories */
+ BTA_AVK_RC_SUPF_TG, /* AVRCP target categories */
+ 6, /* AVDTP audio channel max data queue size */
+ false, /* true, to accept AVRC 1.3 group nevigation command */
+ 2, /* company id count in p_meta_co_ids */
+ (uint8_t)(avrcp_absolute_volume_is_enabled()
+ ? 1
+ : 0), /* event id count in p_meta_evt_ids */
+ BTA_AV_RC_PASS_RSP_CODE, /* the default response code for pass
+ through commands */
+ bta_av_meta_caps_co_ids, /* the metadata Get Capabilities response
+ for company id */
+ get_bta_avk_meta_caps_evt_ids(), /* the metadata Get Capabilities response
+ for event id */
+ {0}, /* Default AVRCP controller name */
+ {0}, /* Default AVRCP target name */
+ };
+ return &bta_avk_cfg;
+}
/* This configuration to be used when we are using AVRCP1.3 */
extern const tBTA_AV_CFG bta_av_cfg_compatibility = {
diff --git a/system/bta/av/bta_av_int.h b/system/bta/av/bta_av_int.h
index 94e2f5ec17..f50f5bc067 100644
--- a/system/bta/av/bta_av_int.h
+++ b/system/bta/av/bta_av_int.h
@@ -690,7 +690,7 @@ extern tBTA_AV_CB bta_av_cb;
/* config struct */
extern const tBTA_AV_CFG* p_bta_av_cfg;
-extern const tBTA_AV_CFG bta_avk_cfg;
+const tBTA_AV_CFG* get_bta_avk_cfg();
extern const tBTA_AV_CFG bta_av_cfg;
extern const tBTA_AV_CFG bta_av_cfg_compatibility;
diff --git a/system/bta/av/bta_av_main.cc b/system/bta/av/bta_av_main.cc
index eceb09fc7c..f646da3161 100644
--- a/system/bta/av/bta_av_main.cc
+++ b/system/bta/av/bta_av_main.cc
@@ -432,7 +432,7 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) {
uint16_t profile_initialized = p_data->api_reg.service_uuid;
if (profile_initialized == UUID_SERVCLASS_AUDIO_SINK) {
- p_bta_av_cfg = &bta_avk_cfg;
+ p_bta_av_cfg = get_bta_avk_cfg();
} else if (profile_initialized == UUID_SERVCLASS_AUDIO_SOURCE) {
p_bta_av_cfg = &bta_av_cfg;
diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc
index 4a5065d759..f25f8b17e8 100644
--- a/system/btif/src/btif_av.cc
+++ b/system/btif/src/btif_av.cc
@@ -55,6 +55,7 @@
#include "main/shim/dumpsys.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
+#include "stack/include/avrc_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/btm_api.h"
#include "stack/include/btu.h" // do_in_main_thread
@@ -3413,9 +3414,10 @@ bt_status_t btif_av_source_execute_service(bool enable) {
features |= BTA_AV_FEAT_DELAY_RPT;
}
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
- features |= BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_BROWSE;
-#endif
+ if (avrcp_absolute_volume_is_enabled()) {
+ features |= BTA_AV_FEAT_RCCT | BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_BROWSE;
+ }
+
BTA_AvEnable(features, bta_av_source_callback);
btif_av_source.RegisterAllBtaHandles();
return BT_STATUS_SUCCESS;
diff --git a/system/btif/src/btif_rc.cc b/system/btif/src/btif_rc.cc
index 196a941701..82ce8691eb 100644
--- a/system/btif/src/btif_rc.cc
+++ b/system/btif/src/btif_rc.cc
@@ -599,22 +599,23 @@ void handle_rc_features(btif_rc_device_cb_t* p_dev) {
rc_features = (btrc_remote_features_t)(rc_features | BTRC_FEAT_BROWSE);
}
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
+ if (p_dev->rc_features & BTA_AV_FEAT_METADATA) {
+ rc_features = (btrc_remote_features_t)(rc_features | BTRC_FEAT_METADATA);
+ }
+
+ if (!avrcp_absolute_volume_is_enabled()) {
+ return;
+ }
+
if ((p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL) &&
(p_dev->rc_features & BTA_AV_FEAT_RCTG)) {
rc_features =
(btrc_remote_features_t)(rc_features | BTRC_FEAT_ABSOLUTE_VOLUME);
}
-#endif
-
- if (p_dev->rc_features & BTA_AV_FEAT_METADATA) {
- rc_features = (btrc_remote_features_t)(rc_features | BTRC_FEAT_METADATA);
- }
BTIF_TRACE_DEBUG("%s: rc_features: 0x%x", __func__, rc_features);
HAL_CBACK(bt_rc_callbacks, remote_features_cb, p_dev->rc_addr, rc_features);
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
BTIF_TRACE_DEBUG(
"%s: Checking for feature flags in btif_rc_handler with label: %d",
__func__, p_dev->rc_vol_label);
@@ -640,7 +641,6 @@ void handle_rc_features(btif_rc_device_cb_t* p_dev) {
register_volumechange(p_dev->rc_vol_label, p_dev);
}
}
-#endif
}
/***************************************************************************
diff --git a/system/btif/test/btif_rc_test.cc b/system/btif/test/btif_rc_test.cc
index a8dcca75b2..57de40badc 100644
--- a/system/btif/test/btif_rc_test.cc
+++ b/system/btif/test/btif_rc_test.cc
@@ -41,6 +41,7 @@ int AVRC_BldResponse_ = 0;
uint8_t appl_trace_level = BT_TRACE_LEVEL_WARNING;
uint8_t btif_trace_level = BT_TRACE_LEVEL_WARNING;
+bool avrcp_absolute_volume_is_enabled() { return true; }
tAVRC_STS AVRC_BldCommand(tAVRC_COMMAND* p_cmd, BT_HDR** pp_pkt) { return 0; }
tAVRC_STS AVRC_BldResponse(uint8_t handle, tAVRC_RESPONSE* p_rsp,
BT_HDR** pp_pkt) {
diff --git a/system/internal_include/bt_target.h b/system/internal_include/bt_target.h
index 1a78e06b7c..a4a966becb 100644
--- a/system/internal_include/bt_target.h
+++ b/system/internal_include/bt_target.h
@@ -975,10 +975,6 @@
*
*****************************************************************************/
-#ifndef AVRC_ADV_CTRL_INCLUDED
-#define AVRC_ADV_CTRL_INCLUDED TRUE
-#endif
-
#ifndef DUMP_PCM_DATA
#define DUMP_PCM_DATA FALSE
#endif
diff --git a/system/stack/Android.bp b/system/stack/Android.bp
index 863203f9a1..afac125d08 100644
--- a/system/stack/Android.bp
+++ b/system/stack/Android.bp
@@ -136,6 +136,7 @@ cc_library_static {
"libbt-stack-core",
],
whole_static_libs: [
+ "libcom.android.sysprop.bluetooth",
"libldacBT_abr",
"libldacBT_enc",
"libaptx_enc",
diff --git a/system/stack/avrc/avrc_api.cc b/system/stack/avrc/avrc_api.cc
index f70328e2ba..8bf95942c9 100644
--- a/system/stack/avrc/avrc_api.cc
+++ b/system/stack/avrc/avrc_api.cc
@@ -23,6 +23,9 @@
******************************************************************************/
#include "avrc_api.h"
+#ifdef OS_ANDROID
+#include <avrcp.sysprop.h>
+#endif
#include <base/logging.h>
#include <string.h>
@@ -77,6 +80,25 @@ static const uint8_t avrc_ctrl_event_map[] = {
/******************************************************************************
*
+ * Function avrcp_absolute_volume_is_enabled
+ *
+ * Description Check if config support advance control (absolute volume)
+ *
+ * Returns return true if absolute_volume is enabled
+ *
+ *****************************************************************************/
+bool avrcp_absolute_volume_is_enabled() {
+#ifdef OS_ANDROID
+ static const bool absolute_volume =
+ android::sysprop::bluetooth::Avrcp::absolute_volume().value_or(true);
+ return absolute_volume;
+#else
+ return true;
+#endif
+}
+
+/******************************************************************************
+ *
* Function avrc_ctrl_cback
*
* Description This is the callback function used by AVCTP to report
diff --git a/system/stack/avrc/avrc_bld_ct.cc b/system/stack/avrc/avrc_bld_ct.cc
index deadd29e21..5eb5d3b067 100644
--- a/system/stack/avrc/avrc_bld_ct.cc
+++ b/system/stack/avrc/avrc_bld_ct.cc
@@ -58,7 +58,6 @@ static tAVRC_STS avrc_bld_next_cmd(tAVRC_NEXT_CMD* p_cmd, BT_HDR* p_pkt) {
* the following commands are introduced in AVRCP 1.4
****************************************************************************/
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
/*******************************************************************************
*
* Function avrc_bld_set_abs_volume_cmd
@@ -110,7 +109,6 @@ static tAVRC_STS avrc_bld_register_notifn(BT_HDR* p_pkt, uint8_t event_id,
p_pkt->len = (p_data - p_start);
return AVRC_STS_NO_ERROR;
}
-#endif
/*******************************************************************************
*
@@ -607,16 +605,18 @@ tAVRC_STS AVRC_BldCommand(tAVRC_COMMAND* p_cmd, BT_HDR** pp_pkt) {
case AVRC_PDU_ABORT_CONTINUATION_RSP: /* 0x41 */
status = avrc_bld_next_cmd(&p_cmd->abort, p_pkt);
break;
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
case AVRC_PDU_SET_ABSOLUTE_VOLUME: /* 0x50 */
+ if (!avrcp_absolute_volume_is_enabled()) {
+ break;
+ }
status = avrc_bld_set_abs_volume_cmd(&p_cmd->volume, p_pkt);
break;
-#endif
case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
+ if (!avrcp_absolute_volume_is_enabled()) {
+ break;
+ }
status = avrc_bld_register_notifn(p_pkt, p_cmd->reg_notif.event_id,
p_cmd->reg_notif.param);
-#endif
break;
case AVRC_PDU_GET_CAPABILITIES:
status =
diff --git a/system/stack/avrc/avrc_pars_ct.cc b/system/stack/avrc/avrc_pars_ct.cc
index 68e6a9f01b..2c7fd76ce9 100644
--- a/system/stack/avrc/avrc_pars_ct.cc
+++ b/system/stack/avrc/avrc_pars_ct.cc
@@ -48,9 +48,7 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
tAVRC_STS status = AVRC_STS_NO_ERROR;
uint8_t* p;
uint16_t len;
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
uint8_t eventid = 0;
-#endif
/* Check the vendor data */
if (p_msg->vendor_len == 0) return AVRC_STS_NO_ERROR;
@@ -88,18 +86,21 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
/* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
/* case AVRC_PDU_ABORT_CONTINUATION_RSP: 0x41 */
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
case AVRC_PDU_SET_ABSOLUTE_VOLUME: /* 0x50 */
+ if (!avrcp_absolute_volume_is_enabled()) {
+ break;
+ }
if (len != 1)
status = AVRC_STS_INTERNAL_ERR;
else {
BE_STREAM_TO_UINT8(p_result->volume.volume, p);
}
break;
-#endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
-#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
+ if (!avrcp_absolute_volume_is_enabled()) {
+ break;
+ }
if (len < 1) {
AVRC_TRACE_WARNING(
"%s: invalid parameter length %d: must be at least 1", __func__,
@@ -124,7 +125,6 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
}
AVRC_TRACE_DEBUG("%s PDU reg notif response:event %x, volume %x",
__func__, eventid, p_result->reg_notif.param.volume);
-#endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
break;
default:
status = AVRC_STS_BAD_CMD;
diff --git a/system/stack/include/avrc_api.h b/system/stack/include/avrc_api.h
index 0f3d385cfd..8f79a84640 100644
--- a/system/stack/include/avrc_api.h
+++ b/system/stack/include/avrc_api.h
@@ -253,6 +253,16 @@ typedef struct {
/*****************************************************************************
* external function declarations
****************************************************************************/
+/******************************************************************************
+ *
+ * Function avrcp_absolute_volume_is_enabled
+ *
+ * Description Check if config support advance control (absolute volume)
+ *
+ * Returns return true if absolute_volume is enabled
+ *
+ *****************************************************************************/
+bool avrcp_absolute_volume_is_enabled();
/******************************************************************************
*
diff --git a/system/test/mock/mock_stack_avrc_api.cc b/system/test/mock/mock_stack_avrc_api.cc
index 1839327a0a..d7fb451396 100644
--- a/system/test/mock/mock_stack_avrc_api.cc
+++ b/system/test/mock/mock_stack_avrc_api.cc
@@ -39,6 +39,10 @@
#define UNUSED_ATTR
#endif
+bool avrcp_absolute_volume_is_enabled() {
+ inc_func_call_count(__func__);
+ return true;
+}
uint16_t AVRC_Close(uint8_t handle) {
inc_func_call_count(__func__);
return 0;