Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98684057 authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Add conditional unit testing for codecs that might not be on the device

Codecs like aptX and aptX-HD are supported on the device if the
corresponding shared library is installed.
Fix the unit tests to conditionally test for aptX/aptX-HD.

Also, update function descriptions in files a2dp_sbc.h and
a2dp_vendor_ldac.h .

Test: Running unit tests on a device that doesn't have aptX/aptX-HD
Change-Id: I44dc275ca6e0cb5438ee6ed0b6213213d56592f4
parent 167275f8
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -156,35 +156,35 @@ int A2DP_GetNumberOfSubbandsSbc(const uint8_t* p_codec_info);
int A2DP_GetNumberOfBlocksSbc(const uint8_t* p_codec_info);

// Gets the allocation method code for the A2DP SBC codec.
// The actual value is codec-specific.
// The actual value is codec-specific - see |A2DP_SBC_IE_ALLOC_MD_*|.
// |p_codec_info| is a pointer to the SBC codec_info to decode.
// Returns the allocation method code on success, or -1 if |p_codec_info|
// contains invalid codec information.
int A2DP_GetAllocationMethodCodeSbc(const uint8_t* p_codec_info);

// Gets the channel mode code for the A2DP SBC codec.
// The actual value is codec-specific.
// The actual value is codec-specific - see |A2DP_SBC_IE_CH_MD_*|.
// |p_codec_info| is a pointer to the SBC codec_info to decode.
// Returns the channel mode code on success, or -1 if |p_codec_info|
// contains invalid codec information.
int A2DP_GetChannelModeCodeSbc(const uint8_t* p_codec_info);

// Gets the sampling frequency code for the A2DP SBC codec.
// The actual value is codec-specific.
// The actual value is codec-specific - see |A2DP_SBC_IE_SAMP_FREQ_*|.
// |p_codec_info| is a pointer to the SBC codec_info to decode.
// Returns the sampling frequency code on success, or -1 if |p_codec_info|
// contains invalid codec information.
int A2DP_GetSamplingFrequencyCodeSbc(const uint8_t* p_codec_info);

// Gets the minimum bitpool for the A2DP SBC codec.
// The actual value is codec-specific.
// The actual value is codec-specific - see |A2DP_SBC_IE_MIN_BITPOOL|.
// |p_codec_info| is a pointer to the SBC codec_info to decode.
// Returns the minimum bitpool on success, or -1 if |p_codec_info|
// contains invalid codec information.
int A2DP_GetMinBitpoolSbc(const uint8_t* p_codec_info);

// Gets the maximum bitpool for the A2DP SBC codec.
// The actual value is codec-specific.
// The actual value is codec-specific - see |A2DP_SBC_IE_MAX_BITPOOL|.
// |p_codec_info| is a pointer to the SBC codec_info to decode.
// Returns the maximum bitpool on success, or -1 if |p_codec_info|
// contains invalid codec information.
+1 −1
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ int A2DP_VendorGetTrackBitsPerSampleLdac(const uint8_t* p_codec_info);
int A2DP_VendorGetTrackChannelCountLdac(const uint8_t* p_codec_info);

// Gets the channel mode code for the A2DP LDAC codec.
// The actual value is codec-specific.
// The actual value is codec-specific - see |A2DP_LDAC_CHANNEL_MODE_*|.
// |p_codec_info| is a pointer to the LDAC codec_info to decode.
// Returns the channel mode code on success, or -1 if |p_codec_info|
// contains invalid codec information.
+113 −36
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@
 *
 ******************************************************************************/

#include <dlfcn.h>

#include <set>

#include <gtest/gtest.h>

#include "stack/include/a2dp_api.h"
@@ -87,9 +91,76 @@ const uint8_t codec_info_non_a2dp_dummy[AVDT_CODEC_SIZE] = {
    10              // Dummy
};

static const char* APTX_ENCODER_LIB_NAME = "libaptX_encoder.so";
static const char* APTX_HD_ENCODER_LIB_NAME = "libaptXHD_encoder.so";
static const char* LDAC_ENCODER_LIB_NAME = "libldacBT_enc.so";

static bool has_shared_library(const char* name) {
  void* lib_handle = dlopen(name, RTLD_NOW);
  if (lib_handle != nullptr) {
    dlclose(lib_handle);
    return true;
  }
  return false;
}

}  // namespace

TEST(StackA2dpTest, test_a2dp_bits_set) {
class StackA2dpTest : public ::testing::Test {
 protected:
  StackA2dpTest() {
    // Create the set with all supported codecs
    for (int i = BTAV_A2DP_CODEC_INDEX_MIN; i < BTAV_A2DP_CODEC_INDEX_MAX;
         i++) {
      btav_a2dp_codec_index_t codec_index =
          static_cast<btav_a2dp_codec_index_t>(i);

      bool supported = false;
      switch (codec_index) {
        case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
          supported = true;
          break;
        case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
          // Codec aptX is supported only if the device has the corresponding
          // shared library installed.
          supported = has_shared_library(APTX_ENCODER_LIB_NAME);
          break;
        case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
          // Codec aptX-HD is supported only if the device has the corresponding
          // shared library installed.
          supported = has_shared_library(APTX_HD_ENCODER_LIB_NAME);
          break;
        case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
          // Codec LDAC is supported only if the device has the corresponding
          // shared library installed.
          supported = has_shared_library(LDAC_ENCODER_LIB_NAME);
          break;
        case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
          supported = true;
          break;
        case BTAV_A2DP_CODEC_INDEX_MAX:
          // Needed to avoid using "default:" case so we can capture when
          // a new codec is added, and it can be included here.
          break;
      }

      if (supported) {
        supported_codecs_.insert(codec_index);
      }
    }
  }

  bool has_codec_support(btav_a2dp_codec_index_t codec_index) {
    return supported_codecs_.find(codec_index) != supported_codecs_.end();
  }

 private:
  std::set<btav_a2dp_codec_index_t> supported_codecs_;
};

class A2dpCodecConfigTest : public StackA2dpTest {};

TEST_F(StackA2dpTest, test_a2dp_bits_set) {
  EXPECT_TRUE(A2DP_BitsSet(0x0) == A2DP_SET_ZERO_BIT);
  EXPECT_TRUE(A2DP_BitsSet(0x1) == A2DP_SET_ONE_BIT);
  EXPECT_TRUE(A2DP_BitsSet(0x2) == A2DP_SET_ONE_BIT);
@@ -100,7 +171,7 @@ TEST(StackA2dpTest, test_a2dp_bits_set) {
  EXPECT_TRUE(A2DP_BitsSet(0xff) == A2DP_SET_MULTL_BIT);
}

TEST(StackA2dpTest, test_a2dp_is_codec_valid) {
TEST_F(StackA2dpTest, test_a2dp_is_codec_valid) {
  EXPECT_TRUE(A2DP_IsSourceCodecValid(codec_info_sbc));
  EXPECT_TRUE(A2DP_IsPeerSourceCodecValid(codec_info_sbc));

@@ -135,7 +206,7 @@ TEST(StackA2dpTest, test_a2dp_is_codec_valid) {
  EXPECT_FALSE(A2DP_IsPeerSinkCodecValid(codec_info_sbc_invalid));
}

TEST(StackA2dpTest, test_a2dp_get_codec_type) {
TEST_F(StackA2dpTest, test_a2dp_get_codec_type) {
  tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(codec_info_sbc);
  EXPECT_EQ(codec_type, A2DP_MEDIA_CT_SBC);

@@ -143,19 +214,19 @@ TEST(StackA2dpTest, test_a2dp_get_codec_type) {
  EXPECT_EQ(codec_type, A2DP_MEDIA_CT_NON_A2DP);
}

TEST(StackA2dpTest, test_a2dp_is_sink_codec_supported) {
TEST_F(StackA2dpTest, test_a2dp_is_sink_codec_supported) {
  EXPECT_TRUE(A2DP_IsSinkCodecSupported(codec_info_sbc));
  EXPECT_FALSE(A2DP_IsSinkCodecSupported(codec_info_sbc_sink_capability));
  EXPECT_FALSE(A2DP_IsSinkCodecSupported(codec_info_non_a2dp));
}

TEST(StackA2dpTest, test_a2dp_is_peer_source_codec_supported) {
TEST_F(StackA2dpTest, test_a2dp_is_peer_source_codec_supported) {
  EXPECT_TRUE(A2DP_IsPeerSourceCodecSupported(codec_info_sbc));
  EXPECT_TRUE(A2DP_IsPeerSourceCodecSupported(codec_info_sbc_sink_capability));
  EXPECT_FALSE(A2DP_IsPeerSourceCodecSupported(codec_info_non_a2dp));
}

TEST(StackA2dpTest, test_init_default_codec) {
TEST_F(StackA2dpTest, test_init_default_codec) {
  uint8_t codec_info_result[AVDT_CODEC_SIZE];

  memset(codec_info_result, 0, sizeof(codec_info_result));
@@ -167,7 +238,7 @@ TEST(StackA2dpTest, test_init_default_codec) {
  }
}

TEST(StackA2dpTest, test_build_src2sink_config) {
TEST_F(StackA2dpTest, test_build_src2sink_config) {
  uint8_t codec_info_result[AVDT_CODEC_SIZE];

  memset(codec_info_result, 0, sizeof(codec_info_result));
@@ -202,14 +273,14 @@ TEST(StackA2dpTest, test_build_src2sink_config) {
            A2DP_SUCCESS);
}

TEST(StackA2dpTest, test_a2dp_uses_rtp_header) {
TEST_F(StackA2dpTest, test_a2dp_uses_rtp_header) {
  EXPECT_TRUE(A2DP_UsesRtpHeader(true, codec_info_sbc));
  EXPECT_TRUE(A2DP_UsesRtpHeader(false, codec_info_sbc));
  EXPECT_TRUE(A2DP_UsesRtpHeader(true, codec_info_non_a2dp));
  EXPECT_TRUE(A2DP_UsesRtpHeader(false, codec_info_non_a2dp));
}

TEST(StackA2dpTest, test_a2dp_get_media_type) {
TEST_F(StackA2dpTest, test_a2dp_get_media_type) {
  uint8_t codec_info_test[AVDT_CODEC_SIZE];

  EXPECT_EQ(A2DP_GetMediaType(codec_info_sbc), AVDT_MEDIA_TYPE_AUDIO);
@@ -224,7 +295,7 @@ TEST(StackA2dpTest, test_a2dp_get_media_type) {
  EXPECT_EQ(A2DP_GetMediaType(codec_info_test), AVDT_MEDIA_TYPE_MULTI);
}

TEST(StackA2dpTest, test_a2dp_codec_name) {
TEST_F(StackA2dpTest, test_a2dp_codec_name) {
  uint8_t codec_info_test[AVDT_CODEC_SIZE];

  // Explicit tests for known codecs
@@ -241,7 +312,7 @@ TEST(StackA2dpTest, test_a2dp_codec_name) {
  }
}

TEST(StackA2dpTest, test_a2dp_vendor) {
TEST_F(StackA2dpTest, test_a2dp_vendor) {
  EXPECT_EQ(A2DP_VendorCodecGetVendorId(codec_info_non_a2dp),
            (uint32_t)0x00000403);
  EXPECT_EQ(A2DP_VendorCodecGetCodecId(codec_info_non_a2dp), (uint16_t)0x0807);
@@ -249,7 +320,7 @@ TEST(StackA2dpTest, test_a2dp_vendor) {
  EXPECT_TRUE(A2DP_VendorUsesRtpHeader(false, codec_info_non_a2dp));
}

TEST(StackA2dpTest, test_a2dp_codec_type_equals) {
TEST_F(StackA2dpTest, test_a2dp_codec_type_equals) {
  EXPECT_TRUE(
      A2DP_CodecTypeEquals(codec_info_sbc, codec_info_sbc_sink_capability));
  EXPECT_TRUE(
@@ -257,7 +328,7 @@ TEST(StackA2dpTest, test_a2dp_codec_type_equals) {
  EXPECT_FALSE(A2DP_CodecTypeEquals(codec_info_sbc, codec_info_non_a2dp));
}

TEST(StackA2dpTest, test_a2dp_codec_equals) {
TEST_F(StackA2dpTest, test_a2dp_codec_equals) {
  uint8_t codec_info_sbc_test[AVDT_CODEC_SIZE];
  uint8_t codec_info_non_a2dp_test[AVDT_CODEC_SIZE];

@@ -292,69 +363,69 @@ TEST(StackA2dpTest, test_a2dp_codec_equals) {
  EXPECT_TRUE(A2DP_CodecEquals(codec_info_sbc, codec_info_sbc_test));
}

TEST(StackA2dpTest, test_a2dp_get_track_sample_rate) {
TEST_F(StackA2dpTest, test_a2dp_get_track_sample_rate) {
  EXPECT_EQ(A2DP_GetTrackSampleRate(codec_info_sbc), 44100);
  EXPECT_EQ(A2DP_GetTrackSampleRate(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_track_bits_per_sample) {
TEST_F(StackA2dpTest, test_a2dp_get_track_bits_per_sample) {
  EXPECT_EQ(A2DP_GetTrackBitsPerSample(codec_info_sbc), 16);
  EXPECT_EQ(A2DP_GetTrackBitsPerSample(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_track_channel_count) {
TEST_F(StackA2dpTest, test_a2dp_get_track_channel_count) {
  EXPECT_EQ(A2DP_GetTrackChannelCount(codec_info_sbc), 2);
  EXPECT_EQ(A2DP_GetTrackChannelCount(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_number_of_subbands_sbc) {
TEST_F(StackA2dpTest, test_a2dp_get_number_of_subbands_sbc) {
  EXPECT_EQ(A2DP_GetNumberOfSubbandsSbc(codec_info_sbc), 8);
  EXPECT_EQ(A2DP_GetNumberOfSubbandsSbc(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_number_of_blocks_sbc) {
TEST_F(StackA2dpTest, test_a2dp_get_number_of_blocks_sbc) {
  EXPECT_EQ(A2DP_GetNumberOfBlocksSbc(codec_info_sbc), 16);
  EXPECT_EQ(A2DP_GetNumberOfBlocksSbc(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_allocation_method_code_sbc) {
TEST_F(StackA2dpTest, test_a2dp_get_allocation_method_code_sbc) {
  EXPECT_EQ(A2DP_GetAllocationMethodCodeSbc(codec_info_sbc), 0);
  EXPECT_EQ(A2DP_GetAllocationMethodCodeSbc(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_channel_mode_code_sbc) {
TEST_F(StackA2dpTest, test_a2dp_get_channel_mode_code_sbc) {
  EXPECT_EQ(A2DP_GetChannelModeCodeSbc(codec_info_sbc), 3);
  EXPECT_EQ(A2DP_GetChannelModeCodeSbc(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_sampling_frequency_code_sbc) {
TEST_F(StackA2dpTest, test_a2dp_get_sampling_frequency_code_sbc) {
  EXPECT_EQ(A2DP_GetSamplingFrequencyCodeSbc(codec_info_sbc), 2);
  EXPECT_EQ(A2DP_GetSamplingFrequencyCodeSbc(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_min_bitpool_sbc) {
TEST_F(StackA2dpTest, test_a2dp_get_min_bitpool_sbc) {
  EXPECT_EQ(A2DP_GetMinBitpoolSbc(codec_info_sbc), 2);
  EXPECT_EQ(A2DP_GetMinBitpoolSbc(codec_info_sbc_sink_capability), 2);
  EXPECT_EQ(A2DP_GetMinBitpoolSbc(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_max_bitpool_sbc) {
TEST_F(StackA2dpTest, test_a2dp_get_max_bitpool_sbc) {
  EXPECT_EQ(A2DP_GetMaxBitpoolSbc(codec_info_sbc), 53);
  EXPECT_EQ(A2DP_GetMaxBitpoolSbc(codec_info_sbc_sink_capability), 53);
  EXPECT_EQ(A2DP_GetMaxBitpoolSbc(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_sink_track_channel_type) {
TEST_F(StackA2dpTest, test_a2dp_get_sink_track_channel_type) {
  EXPECT_EQ(A2DP_GetSinkTrackChannelType(codec_info_sbc), 3);
  EXPECT_EQ(A2DP_GetSinkTrackChannelType(codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_sink_frames_count_to_process) {
TEST_F(StackA2dpTest, test_a2dp_get_sink_frames_count_to_process) {
  EXPECT_EQ(A2DP_GetSinkFramesCountToProcess(20, codec_info_sbc), 7);
  EXPECT_EQ(A2DP_GetSinkFramesCountToProcess(20, codec_info_non_a2dp), -1);
}

TEST(StackA2dpTest, test_a2dp_get_packet_timestamp) {
TEST_F(StackA2dpTest, test_a2dp_get_packet_timestamp) {
  uint8_t a2dp_data[1000];
  uint32_t timestamp;
  uint32_t* p_ts = reinterpret_cast<uint32_t*>(a2dp_data);
@@ -372,7 +443,7 @@ TEST(StackA2dpTest, test_a2dp_get_packet_timestamp) {
      A2DP_GetPacketTimestamp(codec_info_non_a2dp, a2dp_data, &timestamp));
}

TEST(StackA2dpTest, test_a2dp_build_codec_header) {
TEST_F(StackA2dpTest, test_a2dp_build_codec_header) {
  uint8_t a2dp_data[1000];
  BT_HDR* p_buf = reinterpret_cast<BT_HDR*>(a2dp_data);
  const uint16_t BT_HDR_LEN = 500;
@@ -398,7 +469,7 @@ TEST(StackA2dpTest, test_a2dp_build_codec_header) {
      A2DP_BuildCodecHeader(codec_info_non_a2dp, p_buf, FRAMES_PER_PACKET));
}

TEST(StackA2dpTest, test_a2dp_adjust_codec) {
TEST_F(StackA2dpTest, test_a2dp_adjust_codec) {
  uint8_t codec_info_sbc_test[AVDT_CODEC_SIZE];
  uint8_t codec_info_non_a2dp_test[AVDT_CODEC_SIZE];

@@ -430,7 +501,7 @@ TEST(StackA2dpTest, test_a2dp_adjust_codec) {
  EXPECT_FALSE(A2DP_AdjustCodec(codec_info_non_a2dp_test));
}

TEST(StackA2dpTest, test_a2dp_source_codec_index) {
TEST_F(StackA2dpTest, test_a2dp_source_codec_index) {
  // Explicit tests for known codecs
  EXPECT_EQ(A2DP_SourceCodecIndex(codec_info_sbc),
            BTAV_A2DP_CODEC_INDEX_SOURCE_SBC);
@@ -440,7 +511,7 @@ TEST(StackA2dpTest, test_a2dp_source_codec_index) {
            BTAV_A2DP_CODEC_INDEX_MAX);
}

TEST(StackA2dpTest, test_a2dp_codec_index_str) {
TEST_F(StackA2dpTest, test_a2dp_codec_index_str) {
  // Explicit tests for known codecs
  EXPECT_STREQ(A2DP_CodecIndexStr(BTAV_A2DP_CODEC_INDEX_SOURCE_SBC), "SBC");
  EXPECT_STREQ(A2DP_CodecIndexStr(BTAV_A2DP_CODEC_INDEX_SINK_SBC), "SBC SINK");
@@ -450,14 +521,14 @@ TEST(StackA2dpTest, test_a2dp_codec_index_str) {
               "UNKNOWN CODEC INDEX");

  // Test that each codec has a known string
  for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
  for (int i = BTAV_A2DP_CODEC_INDEX_MIN; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
    btav_a2dp_codec_index_t codec_index =
        static_cast<btav_a2dp_codec_index_t>(i);
    EXPECT_STRNE(A2DP_CodecIndexStr(codec_index), "UNKNOWN CODEC INDEX");
  }
}

TEST(StackA2dpTest, test_a2dp_init_codec_config) {
TEST_F(StackA2dpTest, test_a2dp_init_codec_config) {
  tAVDT_CFG avdt_cfg;

  //
@@ -489,10 +560,16 @@ TEST(StackA2dpTest, test_a2dp_init_codec_config) {
  }
}

TEST(A2dpCodecConfig, createCodec) {
  for (int i = 0; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
TEST_F(A2dpCodecConfigTest, createCodec) {
  for (int i = BTAV_A2DP_CODEC_INDEX_MIN; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
    btav_a2dp_codec_index_t codec_index =
        static_cast<btav_a2dp_codec_index_t>(i);

    // Ignore codecs that are not supported on the device
    if (!has_codec_support(codec_index)) {
      continue;
    }

    A2dpCodecConfig* codec_config = A2dpCodecConfig::createCodec(codec_index);
    EXPECT_NE(codec_config, nullptr);
    EXPECT_EQ(codec_config->codecIndex(), codec_index);
@@ -502,7 +579,7 @@ TEST(A2dpCodecConfig, createCodec) {
  }
}

TEST(A2dpCodecConfig, setCodecConfig) {
TEST_F(A2dpCodecConfigTest, setCodecConfig) {
  uint8_t codec_info_result[AVDT_CODEC_SIZE];
  btav_a2dp_codec_index_t peer_codec_index;
  A2dpCodecs* a2dp_codecs = new A2dpCodecs();
@@ -548,7 +625,7 @@ TEST(A2dpCodecConfig, setCodecConfig) {
  delete a2dp_codecs;
}

TEST(A2dpCodecs, init) {
TEST_F(A2dpCodecConfigTest, init) {
  A2dpCodecs codecs;

  EXPECT_TRUE(codecs.init());