OSDN Git Service

Abstract the adjustment of A2DP codec parameters
authorPavlin Radoslavov <pavlin@google.com>
Wed, 19 Oct 2016 00:19:55 +0000 (17:19 -0700)
committerPavlin Radoslavov <pavlin@google.com>
Wed, 19 Oct 2016 01:03:56 +0000 (18:03 -0700)
Replaced hard-coded SBC-specific hack for updating some
of its parameters with an API abstraction: A2DP_AdjustCodec()
Also, added the corresponding unit tests.

Bug: 30958229
Test: manual A2DP testing, added new unit tests
Change-Id: I51a0a019d107362f9c24829408d426a5403b0a8e

bta/av/bta_av_aact.cc
stack/a2dp/a2dp_api.cc
stack/a2dp/a2dp_sbc.cc
stack/a2dp/a2dp_vendor.cc
stack/include/a2dp_api.h
stack/include/a2dp_sbc.h
stack/include/a2dp_vendor.h
stack/test/stack_a2dp_test.cc

index ffcefab..6041908 100644 (file)
@@ -66,9 +66,6 @@
 
 static void bta_av_st_rc_timer(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
 
-static const size_t SBC_MAX_BITPOOL_OFFSET = 6;
-static const size_t SBC_MAX_BITPOOL = 53;
-
 /* state machine states */
 enum
 {
@@ -1930,13 +1927,8 @@ void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
                         &av_sink_codec_info);
         }
 
-        if ((uuid_int == UUID_SERVCLASS_AUDIO_SOURCE) &&
-            (cfg.codec_info[SBC_MAX_BITPOOL_OFFSET] > SBC_MAX_BITPOOL))
-        {
-            APPL_TRACE_WARNING("%s: max bitpool length received for SBC is out of range."
-                    "Clamping the codec bitpool configuration from %d to %d.", __func__,
-                    cfg.codec_info[SBC_MAX_BITPOOL_OFFSET], SBC_MAX_BITPOOL);
-            cfg.codec_info[SBC_MAX_BITPOOL_OFFSET] = SBC_MAX_BITPOOL;
+        if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE) {
+            A2DP_AdjustCodec(cfg.codec_info);
         }
 
         /* open the stream */
index 71fff68..a360fd9 100644 (file)
@@ -968,3 +968,19 @@ const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterface(
   LOG_ERROR(LOG_TAG, "%s: unsupported codec type 0x%x", __func__, codec_type);
   return NULL;
 }
+
+bool A2DP_AdjustCodec(uint8_t* p_codec_info) {
+  tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
+
+  switch (codec_type) {
+    case A2DP_MEDIA_CT_SBC:
+      return A2DP_AdjustCodecSbc(p_codec_info);
+    case A2DP_MEDIA_CT_NON_A2DP:
+      return A2DP_VendorAdjustCodec(p_codec_info);
+    default:
+      break;
+  }
+
+  LOG_ERROR(LOG_TAG, "%s: unsupported codec type 0x%x", __func__, codec_type);
+  return false;
+}
index e091841..cf0c5c0 100644 (file)
@@ -1149,3 +1149,20 @@ const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterfaceSbc(
 
   return &a2dp_encoder_interface_sbc;
 }
+
+bool A2DP_AdjustCodecSbc(uint8_t* p_codec_info) {
+  tA2DP_SBC_CIE cfg_cie;
+
+  if (A2DP_ParsSbcInfo(&cfg_cie, p_codec_info, false) != A2DP_SUCCESS)
+    return false;
+
+  // Updated the max bitpool
+  if (cfg_cie.max_bitpool > A2DP_SBC_MAX_BITPOOL) {
+    LOG_WARN(LOG_TAG, "Updated the SBC codec max bitpool from %d to %d",
+             cfg_cie.max_bitpool, A2DP_SBC_MAX_BITPOOL);
+    cfg_cie.max_bitpool = A2DP_SBC_MAX_BITPOOL;
+  }
+
+  return (A2DP_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &cfg_cie,
+                          p_codec_info) == A2DP_SUCCESS);
+}
index 4ab6abc..04c6126 100644 (file)
@@ -364,3 +364,12 @@ const tA2DP_ENCODER_INTERFACE* A2DP_VendorGetEncoderInterface(
 
   return NULL;
 }
+
+bool A2DP_VendorAdjustCodec(uint8_t* p_codec_info) {
+  // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
+  // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
+
+  // Add checks based on <vendor_id, codec_id>
+
+  return false;
+}
index bb12646..e714b1a 100644 (file)
@@ -608,6 +608,11 @@ bool A2DP_BuildCodecHeader(const uint8_t* p_codec_info, BT_HDR* p_buf,
 const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterface(
     const uint8_t* p_codec_info);
 
+// Adjusts the A2DP codec, based on local support and Bluetooth specification.
+// |p_codec_info| contains the codec information to adjust.
+// Returns true if |p_codec_info| is valid and supported, otherwise false.
+bool A2DP_AdjustCodec(uint8_t* p_codec_info);
+
 #ifdef __cplusplus
 }
 #endif
index 98a3206..efb9a8a 100644 (file)
@@ -325,6 +325,12 @@ void A2DP_DumpCodecInfoSbc(const uint8_t* p_codec_info);
 const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterfaceSbc(
     const uint8_t* p_codec_info);
 
+// Adjusts the A2DP SBC codec, based on local support and Bluetooth
+// specification.
+// |p_codec_info| contains the codec information to adjust.
+// Returns true if |p_codec_info| is valid and supported, otherwise false.
+bool A2DP_AdjustCodecSbc(uint8_t* p_codec_info);
+
 #ifdef __cplusplus
 }
 #endif
index 9de2432..6693ae0 100644 (file)
@@ -255,6 +255,12 @@ bool A2DP_VendorBuildCodecHeader(const uint8_t* p_codec_info, BT_HDR* p_buf,
 const tA2DP_ENCODER_INTERFACE* A2DP_VendorGetEncoderInterface(
     const uint8_t* p_codec_info);
 
+// Adjusts the A2DP vendor-specific codec, based on local support and Bluetooth
+// specification.
+// |p_codec_info| contains the codec information to adjust.
+// Returns true if |p_codec_info| is valid and supported, otherwise false.
+bool A2DP_VendorAdjustCodec(uint8_t* p_codec_info);
+
 #ifdef __cplusplus
 }
 #endif
index ce37a54..1ce89b0 100644 (file)
@@ -33,7 +33,7 @@ const uint8_t codec_info_sbc[AVDT_CODEC_SIZE] = {
                         // Subbands: A2DP_SBC_IE_SUBBAND_8 |
                         // Allocation Method: A2DP_SBC_IE_ALLOC_MD_L
   2,                    // MinimumBitpool Value: A2DP_SBC_IE_MIN_BITPOOL
-  53,                   // Maxium Bitpool Value: A2DP_SBC_MAX_BITPOOL
+  53,                   // Maximum Bitpool Value: A2DP_SBC_MAX_BITPOOL
   7,                    // Dummy
   8,                    // Dummy
   9                     // Dummy
@@ -58,7 +58,7 @@ const uint8_t codec_info_sbc_sink[AVDT_CODEC_SIZE] = {
   0x02 | 0x01,          // Allocation Method: A2DP_SBC_IE_ALLOC_MD_S |
                         // A2DP_SBC_IE_ALLOC_MD_L
   2,                    // MinimumBitpool Value: A2DP_SBC_IE_MIN_BITPOOL
-  250,                  // Maxium Bitpool Value: A2DP_SBC_IE_MAX_BITPOOL
+  250,                  // Maximum Bitpool Value: A2DP_SBC_IE_MAX_BITPOOL
   7,                    // Dummy
   8,                    // Dummy
   9                     // Dummy
@@ -546,3 +546,35 @@ TEST(StackA2dpTest, test_a2dp_build_codec_header) {
   EXPECT_FALSE(A2DP_BuildCodecHeader(codec_info_non_a2dp, p_buf,
                                     FRAMES_PER_PACKET));
 }
+
+TEST(StackA2dpTest, test_a2dp_adjust_codec) {
+  uint8_t codec_info_sbc_test[AVDT_CODEC_SIZE];
+  uint8_t codec_info_non_a2dp_test[AVDT_CODEC_SIZE];
+
+  // Test updating a valid SBC codec that doesn't need adjustment
+  memset(codec_info_sbc_test, 0xAB, sizeof(codec_info_sbc_test));
+  memcpy(codec_info_sbc_test, codec_info_sbc, sizeof(codec_info_sbc));
+  EXPECT_TRUE(A2DP_AdjustCodec(codec_info_sbc_test));
+  EXPECT_TRUE(memcmp(codec_info_sbc_test, codec_info_sbc,
+                     sizeof(codec_info_sbc)) == 0);
+
+  // Test updating a valid SBC codec that needs adjustment
+  memset(codec_info_sbc_test, 0xAB, sizeof(codec_info_sbc_test));
+  memcpy(codec_info_sbc_test, codec_info_sbc, sizeof(codec_info_sbc));
+  codec_info_sbc_test[6] = 54;  // A2DP_SBC_MAX_BITPOOL + 1
+  EXPECT_TRUE(A2DP_AdjustCodec(codec_info_sbc_test));
+  EXPECT_TRUE(memcmp(codec_info_sbc_test, codec_info_sbc,
+                     sizeof(codec_info_sbc)) == 0);
+
+  // Test updating an invalid SBC codec
+  memset(codec_info_sbc_test, 0xAB, sizeof(codec_info_sbc_test));
+  memcpy(codec_info_sbc_test, codec_info_sbc, sizeof(codec_info_sbc));
+  codec_info_sbc_test[6] = 255; // Invalid MAX_BITPOOL
+  EXPECT_FALSE(A2DP_AdjustCodec(codec_info_sbc_test));
+
+  // Test updating a non-A2DP codec that is not recognized
+  memset(codec_info_non_a2dp_test, 0xAB, sizeof(codec_info_non_a2dp_test));
+  memcpy(codec_info_non_a2dp_test, codec_info_non_a2dp,
+         sizeof(codec_info_non_a2dp));
+  EXPECT_FALSE(A2DP_AdjustCodec(codec_info_non_a2dp_test));
+}