A2DP offload: modify the A2DP offload SCMS-T_Enable with SCMS-T header
Follow the Android HCI requirement for the 'Start A2DP Offload' cmd, it
should bring the SCMS-T header in the 'SCMS-T Enable' field as SCMS-T is
enabled. Get the SCMS-T active status of the peer devices as building
the offload start req cmd, and fill the SCMS-T header based the active
status.
Bug: 170785181
Tag: #feature
Test: connect with Sony WH-1000XM4, check the SCMS-T_Enable correctness
Test: atest --test-mapping system/bt
Change-Id: I6003b50a09f010942b37436497b06e06180b2069
diff --git a/system/bta/av/bta_av_aact.cc b/system/bta/av/bta_av_aact.cc
index 7186f04..0d0d02c 100644
--- a/system/bta/av/bta_av_aact.cc
+++ b/system/bta/av/bta_av_aact.cc
@@ -100,7 +100,7 @@
bta_av_co_audio_source_data_path,
bta_av_co_audio_delay,
bta_av_co_audio_update_mtu,
- bta_av_co_content_protect_is_active};
+ bta_av_co_get_scmst_info};
/* these tables translate AVDT events to SSM events */
static const uint16_t bta_av_stream_evt_ok[] = {
@@ -3021,7 +3021,8 @@
UINT32_TO_STREAM(p_param, offload_start->codec_type);
UINT16_TO_STREAM(p_param, offload_start->max_latency);
- UINT16_TO_STREAM(p_param, offload_start->scms_t_enable);
+ ARRAY_TO_STREAM(p_param, offload_start->scms_t_enable,
+ static_cast<int>(offload_start->scms_t_enable.size()));
UINT32_TO_STREAM(p_param, offload_start->sample_rate);
UINT8_TO_STREAM(p_param, offload_start->bits_per_sample);
UINT8_TO_STREAM(p_param, offload_start->ch_mode);
@@ -3179,10 +3180,14 @@
p_a2dp_offload->mtu = mtu;
p_a2dp_offload->acl_hdl =
BTM_GetHCIConnHandle(p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR);
- p_a2dp_offload->scms_t_enable =
- p_scb->p_cos->cp_is_active(p_scb->PeerAddress());
- APPL_TRACE_DEBUG("%s: scms_t_enable =%d", __func__,
- p_a2dp_offload->scms_t_enable);
+ btav_a2dp_scmst_info_t scmst_info =
+ p_scb->p_cos->get_scmst_info(p_scb->PeerAddress());
+ p_a2dp_offload->scms_t_enable[0] = scmst_info.enable_status;
+ p_a2dp_offload->scms_t_enable[1] = scmst_info.cp_header;
+ APPL_TRACE_DEBUG(
+ "%s: SCMS-T_enable status: %d, "
+ "SCMS-T header (if it's enabled): 0x%02x",
+ __func__, scmst_info.enable_status, scmst_info.cp_header);
switch (A2DP_GetTrackSampleRate(p_scb->cfg.codec_info)) {
case 44100:
diff --git a/system/bta/av/bta_av_int.h b/system/bta/av/bta_av_int.h
index e2dcde6..fdb1fb3 100644
--- a/system/bta/av/bta_av_int.h
+++ b/system/bta/av/bta_av_int.h
@@ -191,7 +191,7 @@
const RawAddress& peer_addr,
uint16_t mtu);
-typedef bool (*tBTA_AV_CO_CONTENT_PROTECT_IS_ACTIVE)(
+typedef btav_a2dp_scmst_info_t (*tBTA_AV_CO_GET_SCMST_INFO)(
const RawAddress& peer_addr);
/* the call-out functions for one stream */
@@ -207,7 +207,7 @@
tBTA_AV_CO_DATAPATH data;
tBTA_AV_CO_DELAY delay;
tBTA_AV_CO_UPDATE_MTU update_mtu;
- tBTA_AV_CO_CONTENT_PROTECT_IS_ACTIVE cp_is_active;
+ tBTA_AV_CO_GET_SCMST_INFO get_scmst_info;
} tBTA_AV_CO_FUNCTS;
/* data type for BTA_AV_API_ENABLE_EVT */
@@ -622,7 +622,7 @@
public:
uint32_t codec_type; /* codec types ex: SBC/AAC/LDAC/APTx */
uint16_t max_latency; /* maximum latency */
- uint16_t scms_t_enable; /* content protection enable */
+ std::array<uint8_t, 2> scms_t_enable; /* SCMS-T enable */
uint32_t sample_rate; /* Sample rates ex: 44.1/48/88.2/96 Khz */
uint8_t bits_per_sample; /* bits per sample ex: 16/24/32 */
uint8_t ch_mode; /* None:0 Left:1 Right:2 */
diff --git a/system/bta/include/bta_av_co.h b/system/bta/include/bta_av_co.h
index f83ff23..7934a6e 100644
--- a/system/bta/include/bta_av_co.h
+++ b/system/bta/include/bta_av_co.h
@@ -226,13 +226,16 @@
/*******************************************************************************
**
- ** Function bta_av_co_content_protect_is_active
+ ** Function bta_av_co_get_scmst_info
**
- ** Description Get the current configuration of content protection
+ ** Description Get the SCMS-T information for the specific peer
**
- ** Returns TRUE if the current streaming has CP, FALSE otherwise
+ ** Returns btav_a2dp_scmst_info_t.
+ ** It contains the information of SCMS-T which are the SCMS-T
+ ** enable status for the specific peer and the SCMS-T header
+ ** if SCMS-T is enabled.
**
******************************************************************************/
-bool bta_av_co_content_protect_is_active(const RawAddress& peer_address);
+btav_a2dp_scmst_info_t bta_av_co_get_scmst_info(const RawAddress& peer_address);
#endif /* BTA_AV_CO_H */
diff --git a/system/btif/co/bta_av_co.cc b/system/btif/co/bta_av_co.cc
index 708bb40..6f66be2 100644
--- a/system/btif/co/bta_av_co.cc
+++ b/system/btif/co/bta_av_co.cc
@@ -2207,10 +2207,19 @@
return bta_av_co_cb.SetCodecAudioConfig(codec_audio_config);
}
-bool bta_av_co_content_protect_is_active(const RawAddress& peer_address) {
+btav_a2dp_scmst_info_t bta_av_co_get_scmst_info(
+ const RawAddress& peer_address) {
BtaAvCoPeer* p_peer = bta_av_co_cb.FindPeer(peer_address);
CHECK(p_peer != nullptr);
- return p_peer->ContentProtectActive();
+ btav_a2dp_scmst_info_t scmst_info{};
+ scmst_info.enable_status = BTAV_A2DP_SCMST_DISABLED;
+
+ if (p_peer->ContentProtectActive()) {
+ scmst_info.enable_status = BTAV_A2DP_SCMST_ENABLED;
+ scmst_info.cp_header = bta_av_co_cb.ContentProtectFlag();
+ }
+
+ return scmst_info;
}
void btif_a2dp_codec_debug_dump(int fd) { bta_av_co_cb.DebugDump(fd); }
diff --git a/system/include/hardware/bt_av.h b/system/include/hardware/bt_av.h
index c4c0ecc..262360d 100644
--- a/system/include/hardware/bt_av.h
+++ b/system/include/hardware/bt_av.h
@@ -108,6 +108,11 @@
BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO = 0x1 << 1
} btav_a2dp_codec_channel_mode_t;
+typedef enum {
+ BTAV_A2DP_SCMST_DISABLED = 0x00,
+ BTAV_A2DP_SCMST_ENABLED = 0x01
+} btav_a2dp_scmst_enable_status_t;
+
/*
* Structure for representing codec capability or configuration.
* It is used for configuring A2DP codec preference, and for reporting back
@@ -237,6 +242,11 @@
}
} btav_a2dp_codec_config_t;
+typedef struct {
+ btav_a2dp_scmst_enable_status_t enable_status;
+ uint8_t cp_header;
+} btav_a2dp_scmst_info_t;
+
/** Callback for connection state change.
* state will have one of the values from btav_connection_state_t
*/
diff --git a/system/stack/test/fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h b/system/stack/test/fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h
index 1a11b05..5b3848a 100644
--- a/system/stack/test/fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h
+++ b/system/stack/test/fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h
@@ -150,7 +150,8 @@
retval.codec_type = fdp->ConsumeIntegral<uint32_t>();
retval.max_latency = fdp->ConsumeIntegral<uint16_t>();
- retval.scms_t_enable = fdp->ConsumeIntegral<uint16_t>();
+ std::vector<uint8_t> scms_t_enable = fdp->ConsumeBytes<uint8_t>(2);
+ memcpy(&retval.scms_t_enable[0], scms_t_enable.data(), scms_t_enable.size());
retval.sample_rate = fdp->ConsumeIntegral<uint32_t>();
retval.bits_per_sample = fdp->ConsumeIntegral<uint8_t>();
retval.ch_mode = fdp->ConsumeIntegral<uint8_t>();