Loading system/stack/mmc/BUILD.gn +52 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,12 @@ group("mmc") { "//bt/system/stack/mmc/codec_client:libcodec_client", "//bt/system/stack/mmc/proto:mmc_config_proto", ] if (use.test) { deps += [ ":hfp_lc3_mmc_encoder_test", ":hfp_lc3_mmc_decoder_test", ] } } pkg_config("target_defaults") { Loading Loading @@ -94,3 +100,49 @@ executable("mmc_service") { deps = [ ":libmmc" ] sources = [ "main.cc" ] } if (use.test) { executable("hfp_lc3_mmc_encoder_test") { sources = [ "codec_server/hfp_lc3_mmc_encoder.cc", "test/hfp_lc3_mmc_encoder_test.cc", "test/mock/mock_embdrv_lc3.cc", "//bt/system/test/mock/mock_osi_allocator.cc", "//bt/system/test/common/mock_functions.cc", ] include_dirs = [ "//bt/system/gd", ] configs += [ ":target_defaults", "//bt/system:external_gtest_main", ] deps = [ "//bt/system/stack/mmc/proto:mmc_config_proto", "//bt/system/common", "//bt/system/osi", ] } executable("hfp_lc3_mmc_decoder_test") { sources = [ "codec_server/hfp_lc3_mmc_decoder.cc", "test/hfp_lc3_mmc_decoder_test.cc", "test/mock/mock_embdrv_lc3.cc", "//bt/system/test/mock/mock_osi_allocator.cc", "//bt/system/test/common/mock_functions.cc", ] include_dirs = [ "//bt/system/gd", ] configs += [ ":target_defaults", "//bt/system:external_gtest_main", ] deps = [ "//bt/system/stack/mmc/proto:mmc_config_proto", "//bt/system/common", "//bt/system/osi", ] } } system/stack/mmc/codec_server/lc3_utils.h +1 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ const int HFP_LC3_PKT_FRAME_LEN = 58; const int HFP_LC3_PCM_BYTES = 480; // Helper that maps MMC pcm format to lc3 pcm format. static lc3_pcm_format MapLc3PcmFmt(Lc3Param_PcmFmt fmt) { inline lc3_pcm_format MapLc3PcmFmt(Lc3Param_PcmFmt fmt) { switch (fmt) { case Lc3Param::kLc3PcmFormatS16: return LC3_PCM_FORMAT_S16; Loading system/stack/mmc/proto/BUILD.gn +10 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,11 @@ proto_library("mmc_config_proto") { "${proto_in_dir}/mmc_config.proto", ] standalone=true if (use.test) { # Override optimize_for option in proto file. gen_cpp_mode = "speed" all_dependent_pkg_deps = [ "protobuf" ] } } proto_library("mmc_service_proto") { Loading @@ -33,4 +38,9 @@ proto_library("mmc_service_proto") { ] deps = [ ":mmc_config_proto" ] standalone=true if (use.test) { # Override optimize_for option in proto file. gen_cpp_mode = "speed" all_dependent_pkg_deps = [ "protobuf" ] } } system/stack/mmc/test/hfp_lc3_mmc_decoder_test.cc 0 → 100644 +197 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mmc/codec_server/hfp_lc3_mmc_decoder.h" #include <gmock/gmock.h> #include <google/protobuf/text_format.h> #include <gtest/gtest.h> #include <cerrno> #include <cstdint> #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "mmc/test/mock/mock_embdrv_lc3.h" #include "test/common/mock_functions.h" #include "test/mock/mock_osi_allocator.h" namespace { using ::google::protobuf::TextFormat; using ::testing::Contains; using ::testing::Each; using ::testing::Ne; using ::testing::Test; constexpr char kLc3EncoderConfig[] = R"( hfp_lc3_encoder_param: {} )"; constexpr char kLc3DecoderConfig[] = R"( hfp_lc3_decoder_param: {} )"; const int kInputLen = mmc::HFP_LC3_PKT_FRAME_LEN; const int kOutputLen = mmc::HFP_LC3_PCM_BYTES + 1; const uint8_t kInputBuf[kInputLen] = {0}; static uint8_t kOutputBuf[kOutputLen] = {0}; class HfpLc3DecoderTest : public Test { public: protected: void SetUp() override { reset_mock_function_count_map(); decoder_ = std::make_unique<mmc::HfpLc3Decoder>(); } void TearDown() override { decoder_.release(); } std::unique_ptr<mmc::HfpLc3Decoder> decoder_ = nullptr; }; class HfpLc3DecoderWithInitTest : public HfpLc3DecoderTest { public: protected: void SetUp() override { test::mock::osi_allocator::osi_malloc.body = [&](size_t size) { this->lc3_decoder_ = new struct lc3_decoder; return (void*)this->lc3_decoder_; }; test::mock::embdrv_lc3::lc3_setup_decoder.body = [this](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return this->lc3_decoder_; }; test::mock::osi_allocator::osi_free_and_reset.body = [&](void** p_ptr) { delete this->lc3_decoder_; lc3_decoder_ = nullptr; *p_ptr = nullptr; return; }; std::fill(kOutputBuf, kOutputBuf + kOutputLen, 1); HfpLc3DecoderTest::SetUp(); mmc::ConfigParam lc3_decoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); ASSERT_EQ(decoder_->init(lc3_decoder_config), mmc::HFP_LC3_PKT_FRAME_LEN); } void TearDown() override { HfpLc3DecoderTest::TearDown(); test::mock::embdrv_lc3::lc3_setup_decoder = {}; test::mock::osi_allocator::osi_malloc = {}; test::mock::osi_allocator::osi_free_and_reset = {}; std::fill(kOutputBuf, kOutputBuf + kOutputLen, 0); } struct lc3_decoder* lc3_decoder_ = nullptr; }; TEST_F(HfpLc3DecoderTest, InitWrongCodec) { mmc::ConfigParam lc3_encoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); int ret = decoder_->init(lc3_encoder_config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_decoder"), 0); } TEST_F(HfpLc3DecoderTest, InitWrongConfig) { mmc::ConfigParam lc3_decoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); // lc3_setup_decoder failed due to wrong parameters (returned nullptr). test::mock::embdrv_lc3::lc3_setup_decoder.body = [](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return nullptr; }; int ret = decoder_->init(lc3_decoder_config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_decoder"), 1); test::mock::embdrv_lc3::lc3_setup_decoder = {}; } TEST_F(HfpLc3DecoderTest, InitSuccess) { mmc::ConfigParam lc3_decoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); // lc3_setup_decoder returns decoder instance pointer. struct lc3_decoder lc3_decoder; test::mock::embdrv_lc3::lc3_setup_decoder.body = [&lc3_decoder](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return &lc3_decoder; }; int ret = decoder_->init(lc3_decoder_config); EXPECT_EQ(ret, mmc::HFP_LC3_PKT_FRAME_LEN); EXPECT_EQ(get_func_call_count("lc3_setup_decoder"), 1); test::mock::embdrv_lc3::lc3_setup_decoder = {}; } TEST_F(HfpLc3DecoderWithInitTest, CleanUp) { decoder_->cleanup(); EXPECT_EQ(get_func_call_count("osi_free_and_reset"), 1); } TEST_F(HfpLc3DecoderTest, TranscodeNullBuffer) { // Null output buffer. int ret = decoder_->transcode((uint8_t*)kInputBuf, kInputLen, nullptr, 0); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_decode"), 0); } TEST_F(HfpLc3DecoderWithInitTest, TranscodeWrongParam) { // lc3_decode failed (returned value neither zero nor one). test::mock::embdrv_lc3::lc3_decode.return_value = -1; int ret = decoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PCM_BYTES + 1); EXPECT_THAT(kOutputBuf, Each(0)); EXPECT_EQ(get_func_call_count("lc3_decode"), 1); test::mock::embdrv_lc3::lc3_decode = {}; } TEST_F(HfpLc3DecoderWithInitTest, TranscodePLC) { // lc3_decode conducted PLC (return one). test::mock::embdrv_lc3::lc3_decode.return_value = 1; int ret = decoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PCM_BYTES + 1); EXPECT_EQ(kOutputBuf[0], 1); EXPECT_EQ(get_func_call_count("lc3_decode"), 1); test::mock::embdrv_lc3::lc3_decode = {}; } TEST_F(HfpLc3DecoderWithInitTest, TranscodeSuccess) { // lc3_decode succeeded (return zero value). test::mock::embdrv_lc3::lc3_decode.return_value = 0; int ret = decoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PCM_BYTES + 1); EXPECT_EQ(kOutputBuf[0], 0); EXPECT_THAT(kOutputBuf, Contains(Ne(0))); EXPECT_EQ(get_func_call_count("lc3_decode"), 1); test::mock::embdrv_lc3::lc3_decode = {}; } } // namespace system/stack/mmc/test/hfp_lc3_mmc_encoder_test.cc 0 → 100644 +188 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mmc/codec_server/hfp_lc3_mmc_encoder.h" #include <gmock/gmock.h> #include <google/protobuf/text_format.h> #include <gtest/gtest.h> #include <cerrno> #include <cstdint> #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "mmc/test/mock/mock_embdrv_lc3.h" #include "test/common/mock_functions.h" #include "test/mock/mock_osi_allocator.h" namespace { using ::google::protobuf::TextFormat; using ::testing::Contains; using ::testing::Each; using ::testing::Ne; using ::testing::Test; constexpr char kLc3EncoderConfig[] = R"( hfp_lc3_encoder_param: {} )"; constexpr char kLc3DecoderConfig[] = R"( hfp_lc3_decoder_param: {} )"; const int kInputLen = mmc::HFP_LC3_PCM_BYTES; const int kOutputLen = mmc::HFP_LC3_PKT_FRAME_LEN; const uint8_t kInputBuf[kInputLen] = {0}; static uint8_t kOutputBuf[kOutputLen] = {0}; class HfpLc3EncoderTest : public Test { public: protected: void SetUp() override { reset_mock_function_count_map(); encoder_ = std::make_unique<mmc::HfpLc3Encoder>(); } void TearDown() override { encoder_.release(); } std::unique_ptr<mmc::HfpLc3Encoder> encoder_ = nullptr; }; class HfpLc3EncoderWithInitTest : public HfpLc3EncoderTest { public: protected: void SetUp() override { test::mock::osi_allocator::osi_malloc.body = [&](size_t size) { this->lc3_encoder_ = new struct lc3_encoder; return (void*)this->lc3_encoder_; }; test::mock::embdrv_lc3::lc3_setup_encoder.body = [this](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return this->lc3_encoder_; }; test::mock::osi_allocator::osi_free_and_reset.body = [&](void** p_ptr) { delete this->lc3_encoder_; lc3_encoder_ = nullptr; *p_ptr = nullptr; return; }; std::fill(kOutputBuf, kOutputBuf + kOutputLen, 1); HfpLc3EncoderTest::SetUp(); mmc::ConfigParam lc3_encoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); ASSERT_EQ(encoder_->init(lc3_encoder_config), mmc::HFP_LC3_PCM_BYTES); } void TearDown() override { HfpLc3EncoderTest::TearDown(); test::mock::embdrv_lc3::lc3_setup_encoder = {}; test::mock::osi_allocator::osi_malloc = {}; test::mock::osi_allocator::osi_free_and_reset = {}; std::fill(kOutputBuf, kOutputBuf + kOutputLen, 0); } struct lc3_encoder* lc3_encoder_ = nullptr; }; TEST_F(HfpLc3EncoderTest, InitWrongCodec) { mmc::ConfigParam lc3_decoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); int ret = encoder_->init(lc3_decoder_config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_encoder"), 0); } TEST_F(HfpLc3EncoderTest, InitWrongConfig) { mmc::ConfigParam lc3_encoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); // lc3_setup_encoder failed due to wrong parameters (returned nullptr). test::mock::embdrv_lc3::lc3_setup_encoder.body = [](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return nullptr; }; int ret = encoder_->init(lc3_encoder_config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_encoder"), 1); test::mock::embdrv_lc3::lc3_setup_encoder = {}; } TEST_F(HfpLc3EncoderTest, InitSuccess) { mmc::ConfigParam lc3_encoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); // lc3_setup_encoder returns encoder instance pointer. struct lc3_encoder lc3_encoder; test::mock::embdrv_lc3::lc3_setup_encoder.body = [&lc3_encoder](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return &lc3_encoder; }; int ret = encoder_->init(lc3_encoder_config); EXPECT_EQ(ret, mmc::HFP_LC3_PCM_BYTES); EXPECT_EQ(get_func_call_count("lc3_setup_encoder"), 1); test::mock::embdrv_lc3::lc3_setup_encoder = {}; } TEST_F(HfpLc3EncoderWithInitTest, CleanUp) { encoder_->cleanup(); EXPECT_EQ(get_func_call_count("osi_free_and_reset"), 1); } TEST_F(HfpLc3EncoderTest, TranscodeNullBuffer) { // Null input buffer. int ret = encoder_->transcode(nullptr, 0, kOutputBuf, kOutputLen); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_encode"), 0); // Null output buffer. ret = encoder_->transcode((uint8_t*)kInputBuf, kInputLen, nullptr, 0); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_encode"), 0); } TEST_F(HfpLc3EncoderWithInitTest, TranscodeWrongParam) { // lc3_encode failed (returned non-zero value). test::mock::embdrv_lc3::lc3_encode.return_value = 1; int ret = encoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PKT_FRAME_LEN); EXPECT_THAT(kOutputBuf, Each(0)); EXPECT_EQ(get_func_call_count("lc3_encode"), 1); test::mock::embdrv_lc3::lc3_encode = {}; } TEST_F(HfpLc3EncoderWithInitTest, TranscodeSuccess) { // lc3_encode succeeded (return zero value). test::mock::embdrv_lc3::lc3_encode.return_value = 0; int ret = encoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PKT_FRAME_LEN); EXPECT_THAT(kOutputBuf, Contains(Ne(0))); EXPECT_EQ(get_func_call_count("lc3_encode"), 1); test::mock::embdrv_lc3::lc3_encode = {}; } } // namespace Loading
system/stack/mmc/BUILD.gn +52 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,12 @@ group("mmc") { "//bt/system/stack/mmc/codec_client:libcodec_client", "//bt/system/stack/mmc/proto:mmc_config_proto", ] if (use.test) { deps += [ ":hfp_lc3_mmc_encoder_test", ":hfp_lc3_mmc_decoder_test", ] } } pkg_config("target_defaults") { Loading Loading @@ -94,3 +100,49 @@ executable("mmc_service") { deps = [ ":libmmc" ] sources = [ "main.cc" ] } if (use.test) { executable("hfp_lc3_mmc_encoder_test") { sources = [ "codec_server/hfp_lc3_mmc_encoder.cc", "test/hfp_lc3_mmc_encoder_test.cc", "test/mock/mock_embdrv_lc3.cc", "//bt/system/test/mock/mock_osi_allocator.cc", "//bt/system/test/common/mock_functions.cc", ] include_dirs = [ "//bt/system/gd", ] configs += [ ":target_defaults", "//bt/system:external_gtest_main", ] deps = [ "//bt/system/stack/mmc/proto:mmc_config_proto", "//bt/system/common", "//bt/system/osi", ] } executable("hfp_lc3_mmc_decoder_test") { sources = [ "codec_server/hfp_lc3_mmc_decoder.cc", "test/hfp_lc3_mmc_decoder_test.cc", "test/mock/mock_embdrv_lc3.cc", "//bt/system/test/mock/mock_osi_allocator.cc", "//bt/system/test/common/mock_functions.cc", ] include_dirs = [ "//bt/system/gd", ] configs += [ ":target_defaults", "//bt/system:external_gtest_main", ] deps = [ "//bt/system/stack/mmc/proto:mmc_config_proto", "//bt/system/common", "//bt/system/osi", ] } }
system/stack/mmc/codec_server/lc3_utils.h +1 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ const int HFP_LC3_PKT_FRAME_LEN = 58; const int HFP_LC3_PCM_BYTES = 480; // Helper that maps MMC pcm format to lc3 pcm format. static lc3_pcm_format MapLc3PcmFmt(Lc3Param_PcmFmt fmt) { inline lc3_pcm_format MapLc3PcmFmt(Lc3Param_PcmFmt fmt) { switch (fmt) { case Lc3Param::kLc3PcmFormatS16: return LC3_PCM_FORMAT_S16; Loading
system/stack/mmc/proto/BUILD.gn +10 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,11 @@ proto_library("mmc_config_proto") { "${proto_in_dir}/mmc_config.proto", ] standalone=true if (use.test) { # Override optimize_for option in proto file. gen_cpp_mode = "speed" all_dependent_pkg_deps = [ "protobuf" ] } } proto_library("mmc_service_proto") { Loading @@ -33,4 +38,9 @@ proto_library("mmc_service_proto") { ] deps = [ ":mmc_config_proto" ] standalone=true if (use.test) { # Override optimize_for option in proto file. gen_cpp_mode = "speed" all_dependent_pkg_deps = [ "protobuf" ] } }
system/stack/mmc/test/hfp_lc3_mmc_decoder_test.cc 0 → 100644 +197 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mmc/codec_server/hfp_lc3_mmc_decoder.h" #include <gmock/gmock.h> #include <google/protobuf/text_format.h> #include <gtest/gtest.h> #include <cerrno> #include <cstdint> #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "mmc/test/mock/mock_embdrv_lc3.h" #include "test/common/mock_functions.h" #include "test/mock/mock_osi_allocator.h" namespace { using ::google::protobuf::TextFormat; using ::testing::Contains; using ::testing::Each; using ::testing::Ne; using ::testing::Test; constexpr char kLc3EncoderConfig[] = R"( hfp_lc3_encoder_param: {} )"; constexpr char kLc3DecoderConfig[] = R"( hfp_lc3_decoder_param: {} )"; const int kInputLen = mmc::HFP_LC3_PKT_FRAME_LEN; const int kOutputLen = mmc::HFP_LC3_PCM_BYTES + 1; const uint8_t kInputBuf[kInputLen] = {0}; static uint8_t kOutputBuf[kOutputLen] = {0}; class HfpLc3DecoderTest : public Test { public: protected: void SetUp() override { reset_mock_function_count_map(); decoder_ = std::make_unique<mmc::HfpLc3Decoder>(); } void TearDown() override { decoder_.release(); } std::unique_ptr<mmc::HfpLc3Decoder> decoder_ = nullptr; }; class HfpLc3DecoderWithInitTest : public HfpLc3DecoderTest { public: protected: void SetUp() override { test::mock::osi_allocator::osi_malloc.body = [&](size_t size) { this->lc3_decoder_ = new struct lc3_decoder; return (void*)this->lc3_decoder_; }; test::mock::embdrv_lc3::lc3_setup_decoder.body = [this](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return this->lc3_decoder_; }; test::mock::osi_allocator::osi_free_and_reset.body = [&](void** p_ptr) { delete this->lc3_decoder_; lc3_decoder_ = nullptr; *p_ptr = nullptr; return; }; std::fill(kOutputBuf, kOutputBuf + kOutputLen, 1); HfpLc3DecoderTest::SetUp(); mmc::ConfigParam lc3_decoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); ASSERT_EQ(decoder_->init(lc3_decoder_config), mmc::HFP_LC3_PKT_FRAME_LEN); } void TearDown() override { HfpLc3DecoderTest::TearDown(); test::mock::embdrv_lc3::lc3_setup_decoder = {}; test::mock::osi_allocator::osi_malloc = {}; test::mock::osi_allocator::osi_free_and_reset = {}; std::fill(kOutputBuf, kOutputBuf + kOutputLen, 0); } struct lc3_decoder* lc3_decoder_ = nullptr; }; TEST_F(HfpLc3DecoderTest, InitWrongCodec) { mmc::ConfigParam lc3_encoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); int ret = decoder_->init(lc3_encoder_config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_decoder"), 0); } TEST_F(HfpLc3DecoderTest, InitWrongConfig) { mmc::ConfigParam lc3_decoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); // lc3_setup_decoder failed due to wrong parameters (returned nullptr). test::mock::embdrv_lc3::lc3_setup_decoder.body = [](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return nullptr; }; int ret = decoder_->init(lc3_decoder_config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_decoder"), 1); test::mock::embdrv_lc3::lc3_setup_decoder = {}; } TEST_F(HfpLc3DecoderTest, InitSuccess) { mmc::ConfigParam lc3_decoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); // lc3_setup_decoder returns decoder instance pointer. struct lc3_decoder lc3_decoder; test::mock::embdrv_lc3::lc3_setup_decoder.body = [&lc3_decoder](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return &lc3_decoder; }; int ret = decoder_->init(lc3_decoder_config); EXPECT_EQ(ret, mmc::HFP_LC3_PKT_FRAME_LEN); EXPECT_EQ(get_func_call_count("lc3_setup_decoder"), 1); test::mock::embdrv_lc3::lc3_setup_decoder = {}; } TEST_F(HfpLc3DecoderWithInitTest, CleanUp) { decoder_->cleanup(); EXPECT_EQ(get_func_call_count("osi_free_and_reset"), 1); } TEST_F(HfpLc3DecoderTest, TranscodeNullBuffer) { // Null output buffer. int ret = decoder_->transcode((uint8_t*)kInputBuf, kInputLen, nullptr, 0); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_decode"), 0); } TEST_F(HfpLc3DecoderWithInitTest, TranscodeWrongParam) { // lc3_decode failed (returned value neither zero nor one). test::mock::embdrv_lc3::lc3_decode.return_value = -1; int ret = decoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PCM_BYTES + 1); EXPECT_THAT(kOutputBuf, Each(0)); EXPECT_EQ(get_func_call_count("lc3_decode"), 1); test::mock::embdrv_lc3::lc3_decode = {}; } TEST_F(HfpLc3DecoderWithInitTest, TranscodePLC) { // lc3_decode conducted PLC (return one). test::mock::embdrv_lc3::lc3_decode.return_value = 1; int ret = decoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PCM_BYTES + 1); EXPECT_EQ(kOutputBuf[0], 1); EXPECT_EQ(get_func_call_count("lc3_decode"), 1); test::mock::embdrv_lc3::lc3_decode = {}; } TEST_F(HfpLc3DecoderWithInitTest, TranscodeSuccess) { // lc3_decode succeeded (return zero value). test::mock::embdrv_lc3::lc3_decode.return_value = 0; int ret = decoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PCM_BYTES + 1); EXPECT_EQ(kOutputBuf[0], 0); EXPECT_THAT(kOutputBuf, Contains(Ne(0))); EXPECT_EQ(get_func_call_count("lc3_decode"), 1); test::mock::embdrv_lc3::lc3_decode = {}; } } // namespace
system/stack/mmc/test/hfp_lc3_mmc_encoder_test.cc 0 → 100644 +188 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mmc/codec_server/hfp_lc3_mmc_encoder.h" #include <gmock/gmock.h> #include <google/protobuf/text_format.h> #include <gtest/gtest.h> #include <cerrno> #include <cstdint> #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "mmc/test/mock/mock_embdrv_lc3.h" #include "test/common/mock_functions.h" #include "test/mock/mock_osi_allocator.h" namespace { using ::google::protobuf::TextFormat; using ::testing::Contains; using ::testing::Each; using ::testing::Ne; using ::testing::Test; constexpr char kLc3EncoderConfig[] = R"( hfp_lc3_encoder_param: {} )"; constexpr char kLc3DecoderConfig[] = R"( hfp_lc3_decoder_param: {} )"; const int kInputLen = mmc::HFP_LC3_PCM_BYTES; const int kOutputLen = mmc::HFP_LC3_PKT_FRAME_LEN; const uint8_t kInputBuf[kInputLen] = {0}; static uint8_t kOutputBuf[kOutputLen] = {0}; class HfpLc3EncoderTest : public Test { public: protected: void SetUp() override { reset_mock_function_count_map(); encoder_ = std::make_unique<mmc::HfpLc3Encoder>(); } void TearDown() override { encoder_.release(); } std::unique_ptr<mmc::HfpLc3Encoder> encoder_ = nullptr; }; class HfpLc3EncoderWithInitTest : public HfpLc3EncoderTest { public: protected: void SetUp() override { test::mock::osi_allocator::osi_malloc.body = [&](size_t size) { this->lc3_encoder_ = new struct lc3_encoder; return (void*)this->lc3_encoder_; }; test::mock::embdrv_lc3::lc3_setup_encoder.body = [this](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return this->lc3_encoder_; }; test::mock::osi_allocator::osi_free_and_reset.body = [&](void** p_ptr) { delete this->lc3_encoder_; lc3_encoder_ = nullptr; *p_ptr = nullptr; return; }; std::fill(kOutputBuf, kOutputBuf + kOutputLen, 1); HfpLc3EncoderTest::SetUp(); mmc::ConfigParam lc3_encoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); ASSERT_EQ(encoder_->init(lc3_encoder_config), mmc::HFP_LC3_PCM_BYTES); } void TearDown() override { HfpLc3EncoderTest::TearDown(); test::mock::embdrv_lc3::lc3_setup_encoder = {}; test::mock::osi_allocator::osi_malloc = {}; test::mock::osi_allocator::osi_free_and_reset = {}; std::fill(kOutputBuf, kOutputBuf + kOutputLen, 0); } struct lc3_encoder* lc3_encoder_ = nullptr; }; TEST_F(HfpLc3EncoderTest, InitWrongCodec) { mmc::ConfigParam lc3_decoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3DecoderConfig, &lc3_decoder_config)); int ret = encoder_->init(lc3_decoder_config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_encoder"), 0); } TEST_F(HfpLc3EncoderTest, InitWrongConfig) { mmc::ConfigParam lc3_encoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); // lc3_setup_encoder failed due to wrong parameters (returned nullptr). test::mock::embdrv_lc3::lc3_setup_encoder.body = [](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return nullptr; }; int ret = encoder_->init(lc3_encoder_config); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_setup_encoder"), 1); test::mock::embdrv_lc3::lc3_setup_encoder = {}; } TEST_F(HfpLc3EncoderTest, InitSuccess) { mmc::ConfigParam lc3_encoder_config; ASSERT_TRUE( TextFormat::ParseFromString(kLc3EncoderConfig, &lc3_encoder_config)); // lc3_setup_encoder returns encoder instance pointer. struct lc3_encoder lc3_encoder; test::mock::embdrv_lc3::lc3_setup_encoder.body = [&lc3_encoder](int dt_us, int sr_hz, int sr_pcm_hz, void* mem) { return &lc3_encoder; }; int ret = encoder_->init(lc3_encoder_config); EXPECT_EQ(ret, mmc::HFP_LC3_PCM_BYTES); EXPECT_EQ(get_func_call_count("lc3_setup_encoder"), 1); test::mock::embdrv_lc3::lc3_setup_encoder = {}; } TEST_F(HfpLc3EncoderWithInitTest, CleanUp) { encoder_->cleanup(); EXPECT_EQ(get_func_call_count("osi_free_and_reset"), 1); } TEST_F(HfpLc3EncoderTest, TranscodeNullBuffer) { // Null input buffer. int ret = encoder_->transcode(nullptr, 0, kOutputBuf, kOutputLen); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_encode"), 0); // Null output buffer. ret = encoder_->transcode((uint8_t*)kInputBuf, kInputLen, nullptr, 0); EXPECT_EQ(ret, -EINVAL); EXPECT_EQ(get_func_call_count("lc3_encode"), 0); } TEST_F(HfpLc3EncoderWithInitTest, TranscodeWrongParam) { // lc3_encode failed (returned non-zero value). test::mock::embdrv_lc3::lc3_encode.return_value = 1; int ret = encoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PKT_FRAME_LEN); EXPECT_THAT(kOutputBuf, Each(0)); EXPECT_EQ(get_func_call_count("lc3_encode"), 1); test::mock::embdrv_lc3::lc3_encode = {}; } TEST_F(HfpLc3EncoderWithInitTest, TranscodeSuccess) { // lc3_encode succeeded (return zero value). test::mock::embdrv_lc3::lc3_encode.return_value = 0; int ret = encoder_->transcode((uint8_t*)kInputBuf, kInputLen, kOutputBuf, kOutputLen); EXPECT_EQ(ret, mmc::HFP_LC3_PKT_FRAME_LEN); EXPECT_THAT(kOutputBuf, Contains(Ne(0))); EXPECT_EQ(get_func_call_count("lc3_encode"), 1); test::mock::embdrv_lc3::lc3_encode = {}; } } // namespace