Audio V4: Duplicate V2 tests
Because VTS must no be modified for old API version (except bug fixes),
as that could break retrocompatiblity.
As a result, a full copy is made. This commit is only:
$ cp -r core/2.0/vts/ core/4.0/vts
$ cp -r effect/2.0/vts/ effect/4.0/vts
With a V2 replaced by V4 test target name to avoid conflict.
Bug: 38184704
Test: Compile
Change-Id: Iddf9e7a9d42bfe84cf067a08d249a9cc0e6b7241
Signed-off-by: Kevin Rocard <krocard@google.com>
diff --git a/audio/effect/4.0/vts/OWNERS b/audio/effect/4.0/vts/OWNERS
new file mode 100644
index 0000000..8711a9f
--- /dev/null
+++ b/audio/effect/4.0/vts/OWNERS
@@ -0,0 +1,5 @@
+elaurent@google.com
+krocard@google.com
+mnaganov@google.com
+yim@google.com
+zhuoyao@google.com
\ No newline at end of file
diff --git a/audio/effect/4.0/vts/functional/Android.bp b/audio/effect/4.0/vts/functional/Android.bp
new file mode 100644
index 0000000..86c0afc
--- /dev/null
+++ b/audio/effect/4.0/vts/functional/Android.bp
@@ -0,0 +1,36 @@
+//
+// Copyright (C) 2016 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.
+//
+
+cc_test {
+ name: "VtsHalAudioEffectV4_0TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "VtsHalAudioEffectV4_0TargetTest.cpp",
+ "ValidateAudioEffectsConfiguration.cpp"
+ ],
+ static_libs: [
+ "android.hardware.audio.common.test.utility",
+ "android.hardware.audio.common@2.0",
+ "android.hardware.audio.effect@2.0",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "libxml2",
+ ],
+ shared_libs: [
+ "libeffectsconfig",
+ "libicuuc",
+ ],
+}
diff --git a/audio/effect/4.0/vts/functional/ValidateAudioEffectsConfiguration.cpp b/audio/effect/4.0/vts/functional/ValidateAudioEffectsConfiguration.cpp
new file mode 100644
index 0000000..d0bc690
--- /dev/null
+++ b/audio/effect/4.0/vts/functional/ValidateAudioEffectsConfiguration.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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 <unistd.h>
+#include <iterator>
+
+#include <media/EffectsConfig.h>
+
+#include "utility/ValidateXml.h"
+
+TEST(CheckConfig, audioEffectsConfigurationValidation) {
+ RecordProperty("description",
+ "Verify that the effects configuration file is valid according to the schema");
+ using namespace android::effectsConfig;
+
+ std::vector<const char*> locations(std::begin(DEFAULT_LOCATIONS), std::end(DEFAULT_LOCATIONS));
+ EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(DEFAULT_NAME, locations,
+ "/data/local/tmp/audio_effects_conf_V2_0.xsd");
+}
diff --git a/audio/effect/4.0/vts/functional/VtsHalAudioEffectV4_0TargetTest.cpp b/audio/effect/4.0/vts/functional/VtsHalAudioEffectV4_0TargetTest.cpp
new file mode 100644
index 0000000..c90c4fa
--- /dev/null
+++ b/audio/effect/4.0/vts/functional/VtsHalAudioEffectV4_0TargetTest.cpp
@@ -0,0 +1,849 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "AudioEffectHidlHalTest"
+#include <android-base/logging.h>
+#include <system/audio.h>
+
+#include <android/hardware/audio/effect/2.0/IEffect.h>
+#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
+#include <android/hardware/audio/effect/2.0/IEqualizerEffect.h>
+#include <android/hardware/audio/effect/2.0/ILoudnessEnhancerEffect.h>
+#include <android/hardware/audio/effect/2.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+
+using android::hardware::audio::common::V2_0::AudioDevice;
+using android::hardware::audio::common::V2_0::AudioHandleConsts;
+using android::hardware::audio::common::V2_0::AudioMode;
+using android::hardware::audio::common::V2_0::AudioSource;
+using android::hardware::audio::common::V2_0::Uuid;
+using android::hardware::audio::effect::V2_0::AudioBuffer;
+using android::hardware::audio::effect::V2_0::EffectAuxChannelsConfig;
+using android::hardware::audio::effect::V2_0::EffectBufferConfig;
+using android::hardware::audio::effect::V2_0::EffectConfig;
+using android::hardware::audio::effect::V2_0::EffectDescriptor;
+using android::hardware::audio::effect::V2_0::EffectOffloadParameter;
+using android::hardware::audio::effect::V2_0::IEffect;
+using android::hardware::audio::effect::V2_0::IEffectsFactory;
+using android::hardware::audio::effect::V2_0::IEqualizerEffect;
+using android::hardware::audio::effect::V2_0::ILoudnessEnhancerEffect;
+using android::hardware::audio::effect::V2_0::Result;
+using android::hardware::MQDescriptorSync;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_memory;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hidl::allocator::V1_0::IAllocator;
+using android::hidl::memory::V1_0::IMemory;
+using android::sp;
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+#endif
+
+// Test environment for Audio Effects Factory HIDL HAL.
+class AudioEffectsFactoryHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+ // get the test environment singleton
+ static AudioEffectsFactoryHidlEnvironment* Instance() {
+ static AudioEffectsFactoryHidlEnvironment* instance =
+ new AudioEffectsFactoryHidlEnvironment;
+ return instance;
+ }
+
+ virtual void registerTestServices() override { registerTestService<IEffectsFactory>(); }
+};
+
+// The main test class for Audio Effects Factory HIDL HAL.
+class AudioEffectsFactoryHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ void SetUp() override {
+ effectsFactory = ::testing::VtsHalHidlTargetTestBase::getService<IEffectsFactory>(
+ AudioEffectsFactoryHidlEnvironment::Instance()->getServiceName<IEffectsFactory>());
+ ASSERT_NE(effectsFactory, nullptr);
+ }
+
+ void TearDown() override { effectsFactory.clear(); }
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+
+ sp<IEffectsFactory> effectsFactory;
+};
+
+TEST_F(AudioEffectsFactoryHidlTest, EnumerateEffects) {
+ description("Verify that EnumerateEffects returns at least one effect");
+ Result retval = Result::NOT_INITIALIZED;
+ size_t effectCount = 0;
+ Return<void> ret = effectsFactory->getAllDescriptors(
+ [&](Result r, const hidl_vec<EffectDescriptor>& result) {
+ retval = r;
+ effectCount = result.size();
+ });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ EXPECT_GT(effectCount, 0u);
+}
+
+TEST_F(AudioEffectsFactoryHidlTest, CreateEffect) {
+ description("Verify that an effect can be created via CreateEffect");
+ bool gotEffect = false;
+ Uuid effectUuid;
+ Return<void> ret = effectsFactory->getAllDescriptors(
+ [&](Result r, const hidl_vec<EffectDescriptor>& result) {
+ if (r == Result::OK && result.size() > 0) {
+ gotEffect = true;
+ effectUuid = result[0].uuid;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_TRUE(gotEffect);
+ Result retval = Result::NOT_INITIALIZED;
+ sp<IEffect> effect;
+ ret = effectsFactory->createEffect(
+ effectUuid, 1 /*session*/, 1 /*ioHandle*/,
+ [&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
+ retval = r;
+ if (r == Result::OK) {
+ effect = result;
+ }
+ });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ EXPECT_NE(nullptr, effect.get());
+}
+
+TEST_F(AudioEffectsFactoryHidlTest, GetDescriptor) {
+ description(
+ "Verify that effects factory can provide an effect descriptor via "
+ "GetDescriptor");
+ hidl_vec<EffectDescriptor> allDescriptors;
+ Return<void> ret = effectsFactory->getAllDescriptors(
+ [&](Result r, const hidl_vec<EffectDescriptor>& result) {
+ if (r == Result::OK) {
+ allDescriptors = result;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_GT(allDescriptors.size(), 0u);
+ for (size_t i = 0; i < allDescriptors.size(); ++i) {
+ ret = effectsFactory->getDescriptor(
+ allDescriptors[i].uuid, [&](Result r, const EffectDescriptor& result) {
+ EXPECT_EQ(r, Result::OK);
+ EXPECT_EQ(result, allDescriptors[i]);
+ });
+ }
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectsFactoryHidlTest, DebugDumpInvalidArgument) {
+ description("Verify that debugDump doesn't crash on invalid arguments");
+ Return<void> ret = effectsFactory->debugDump(hidl_handle());
+ ASSERT_TRUE(ret.isOk());
+}
+
+// Equalizer effect is required by CDD, but only the type is fixed.
+// This is the same UUID as AudioEffect.EFFECT_TYPE_EQUALIZER in Java.
+static const Uuid EQUALIZER_EFFECT_TYPE = {
+ 0x0bed4300, 0xddd6, 0x11db, 0x8f34,
+ std::array<uint8_t, 6>{{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}};
+// Loudness Enhancer effect is required by CDD, but only the type is fixed.
+// This is the same UUID as AudioEffect.EFFECT_TYPE_LOUDNESS_ENHANCER in Java.
+static const Uuid LOUDNESS_ENHANCER_EFFECT_TYPE = {
+ 0xfe3199be, 0xaed0, 0x413f, 0x87bb,
+ std::array<uint8_t, 6>{{0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}}};
+
+// The main test class for Audio Effect HIDL HAL.
+class AudioEffectHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ void SetUp() override {
+ effectsFactory =
+ ::testing::VtsHalHidlTargetTestBase::getService<IEffectsFactory>();
+ ASSERT_NE(nullptr, effectsFactory.get());
+
+ findAndCreateEffect(getEffectType());
+ ASSERT_NE(nullptr, effect.get());
+
+ Return<Result> ret = effect->init();
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Result::OK, ret);
+ }
+
+ void TearDown() override {
+ effect.clear();
+ effectsFactory.clear();
+ }
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+
+ virtual Uuid getEffectType() { return EQUALIZER_EFFECT_TYPE; }
+
+ void findAndCreateEffect(const Uuid& type);
+ void findEffectInstance(const Uuid& type, Uuid* uuid);
+ void getChannelCount(uint32_t* channelCount);
+
+ sp<IEffectsFactory> effectsFactory;
+ sp<IEffect> effect;
+};
+
+void AudioEffectHidlTest::findAndCreateEffect(const Uuid& type) {
+ Uuid effectUuid;
+ findEffectInstance(type, &effectUuid);
+ Return<void> ret = effectsFactory->createEffect(
+ effectUuid, 1 /*session*/, 1 /*ioHandle*/,
+ [&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
+ if (r == Result::OK) {
+ effect = result;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+}
+
+void AudioEffectHidlTest::findEffectInstance(const Uuid& type, Uuid* uuid) {
+ bool effectFound = false;
+ Return<void> ret = effectsFactory->getAllDescriptors(
+ [&](Result r, const hidl_vec<EffectDescriptor>& result) {
+ if (r == Result::OK) {
+ for (const auto& desc : result) {
+ if (desc.type == type) {
+ effectFound = true;
+ *uuid = desc.uuid;
+ break;
+ }
+ }
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_TRUE(effectFound);
+}
+
+void AudioEffectHidlTest::getChannelCount(uint32_t* channelCount) {
+ Result retval;
+ EffectConfig currentConfig;
+ Return<void> ret = effect->getConfig([&](Result r, const EffectConfig& conf) {
+ retval = r;
+ if (r == Result::OK) {
+ currentConfig = conf;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Result::OK, retval);
+ ASSERT_TRUE(audio_channel_mask_is_valid(
+ static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels)));
+ *channelCount = audio_channel_count_from_out_mask(
+ static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels));
+}
+
+TEST_F(AudioEffectHidlTest, Close) {
+ description("Verify that an effect can be closed");
+ Return<Result> ret = effect->close();
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, GetDescriptor) {
+ description(
+ "Verify that an effect can return its own descriptor via GetDescriptor");
+ Result retval = Result::NOT_INITIALIZED;
+ Uuid actualType;
+ Return<void> ret =
+ effect->getDescriptor([&](Result r, const EffectDescriptor& desc) {
+ retval = r;
+ if (r == Result::OK) {
+ actualType = desc.type;
+ }
+ });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ EXPECT_EQ(getEffectType(), actualType);
+}
+
+TEST_F(AudioEffectHidlTest, GetSetConfig) {
+ description(
+ "Verify that it is possible to manipulate effect config via Get / "
+ "SetConfig");
+ Result retval = Result::NOT_INITIALIZED;
+ EffectConfig currentConfig;
+ Return<void> ret = effect->getConfig([&](Result r, const EffectConfig& conf) {
+ retval = r;
+ if (r == Result::OK) {
+ currentConfig = conf;
+ }
+ });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ Return<Result> ret2 = effect->setConfig(currentConfig, nullptr, nullptr);
+ EXPECT_TRUE(ret2.isOk());
+ EXPECT_EQ(Result::OK, ret2);
+}
+
+TEST_F(AudioEffectHidlTest, GetConfigReverse) {
+ description("Verify that GetConfigReverse does not crash");
+ Return<void> ret =
+ effect->getConfigReverse([&](Result, const EffectConfig&) {});
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, GetSupportedAuxChannelsConfigs) {
+ description("Verify that GetSupportedAuxChannelsConfigs does not crash");
+ Return<void> ret = effect->getSupportedAuxChannelsConfigs(
+ 0, [&](Result, const hidl_vec<EffectAuxChannelsConfig>&) {});
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, GetAuxChannelsConfig) {
+ description("Verify that GetAuxChannelsConfig does not crash");
+ Return<void> ret = effect->getAuxChannelsConfig(
+ [&](Result, const EffectAuxChannelsConfig&) {});
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, SetAuxChannelsConfig) {
+ description("Verify that SetAuxChannelsConfig does not crash");
+ Return<Result> ret = effect->setAuxChannelsConfig(EffectAuxChannelsConfig());
+ EXPECT_TRUE(ret.isOk());
+}
+
+// Not generated automatically because AudioBuffer contains
+// instances of hidl_memory which can't be compared properly
+// in general case due to presence of handles.
+//
+// However, in this particular case, handles must not present
+// thus comparison is possible.
+//
+// operator== must be defined in the same namespace as the structures.
+namespace android {
+namespace hardware {
+namespace audio {
+namespace effect {
+namespace V2_0 {
+inline bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs) {
+ return lhs.id == rhs.id && lhs.frameCount == rhs.frameCount &&
+ lhs.data.handle() == nullptr && rhs.data.handle() == nullptr;
+}
+
+inline bool operator==(const EffectBufferConfig& lhs,
+ const EffectBufferConfig& rhs) {
+ return lhs.buffer == rhs.buffer && lhs.samplingRateHz == rhs.samplingRateHz &&
+ lhs.channels == rhs.channels && lhs.format == rhs.format &&
+ lhs.accessMode == rhs.accessMode && lhs.mask == rhs.mask;
+}
+
+inline bool operator==(const EffectConfig& lhs, const EffectConfig& rhs) {
+ return lhs.inputCfg == rhs.inputCfg && lhs.outputCfg == rhs.outputCfg;
+}
+} // namespace V2_0
+} // namespace effect
+} // namespace audio
+} // namespace hardware
+} // namespace android
+
+TEST_F(AudioEffectHidlTest, Reset) {
+ description("Verify that Reset preserves effect configuration");
+ Result retval = Result::NOT_INITIALIZED;
+ EffectConfig originalConfig;
+ Return<void> ret = effect->getConfig([&](Result r, const EffectConfig& conf) {
+ retval = r;
+ if (r == Result::OK) {
+ originalConfig = conf;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Result::OK, retval);
+ Return<Result> ret2 = effect->reset();
+ EXPECT_TRUE(ret2.isOk());
+ EXPECT_EQ(Result::OK, ret2);
+ EffectConfig configAfterReset;
+ ret = effect->getConfig([&](Result r, const EffectConfig& conf) {
+ retval = r;
+ if (r == Result::OK) {
+ configAfterReset = conf;
+ }
+ });
+ EXPECT_EQ(originalConfig, configAfterReset);
+}
+
+TEST_F(AudioEffectHidlTest, DisableEnableDisable) {
+ description("Verify Disable -> Enable -> Disable sequence for an effect");
+ Return<Result> ret = effect->disable();
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, ret);
+ ret = effect->enable();
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+ ret = effect->disable();
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, SetDevice) {
+ description("Verify that SetDevice works for an output chain effect");
+ Return<Result> ret = effect->setDevice(AudioDevice::OUT_SPEAKER);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, SetAndGetVolume) {
+ description("Verify that SetAndGetVolume method works for an effect");
+ uint32_t channelCount;
+ getChannelCount(&channelCount);
+ hidl_vec<uint32_t> volumes;
+ volumes.resize(channelCount);
+ for (uint32_t i = 0; i < channelCount; ++i) {
+ volumes[i] = 0;
+ }
+ Result retval = Result::NOT_INITIALIZED;
+ Return<void> ret = effect->setAndGetVolume(
+ volumes, [&](Result r, const hidl_vec<uint32_t>&) { retval = r; });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, retval);
+}
+
+TEST_F(AudioEffectHidlTest, VolumeChangeNotification) {
+ description("Verify that effect accepts VolumeChangeNotification");
+ uint32_t channelCount;
+ getChannelCount(&channelCount);
+ hidl_vec<uint32_t> volumes;
+ volumes.resize(channelCount);
+ for (uint32_t i = 0; i < channelCount; ++i) {
+ volumes[i] = 0;
+ }
+ Return<Result> ret = effect->volumeChangeNotification(volumes);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, SetAudioMode) {
+ description("Verify that SetAudioMode works for an effect");
+ Return<Result> ret = effect->setAudioMode(AudioMode::NORMAL);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+}
+
+TEST_F(AudioEffectHidlTest, SetConfigReverse) {
+ description("Verify that SetConfigReverse does not crash");
+ Return<Result> ret =
+ effect->setConfigReverse(EffectConfig(), nullptr, nullptr);
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, SetInputDevice) {
+ description("Verify that SetInputDevice does not crash");
+ Return<Result> ret = effect->setInputDevice(AudioDevice::IN_BUILTIN_MIC);
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, SetAudioSource) {
+ description("Verify that SetAudioSource does not crash");
+ Return<Result> ret = effect->setAudioSource(AudioSource::MIC);
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, Offload) {
+ description("Verify that calling Offload method does not crash");
+ EffectOffloadParameter offloadParam;
+ offloadParam.isOffload = false;
+ offloadParam.ioHandle =
+ static_cast<int>(AudioHandleConsts::AUDIO_IO_HANDLE_NONE);
+ Return<Result> ret = effect->offload(offloadParam);
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, PrepareForProcessing) {
+ description("Verify that PrepareForProcessing method works for an effect");
+ Result retval = Result::NOT_INITIALIZED;
+ Return<void> ret = effect->prepareForProcessing(
+ [&](Result r, const MQDescriptorSync<Result>&) { retval = r; });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, retval);
+}
+
+TEST_F(AudioEffectHidlTest, SetProcessBuffers) {
+ description("Verify that SetProcessBuffers works for an effect");
+ sp<IAllocator> ashmem = IAllocator::getService("ashmem");
+ ASSERT_NE(nullptr, ashmem.get());
+ bool success = false;
+ AudioBuffer buffer;
+ Return<void> ret =
+ ashmem->allocate(1024, [&](bool s, const hidl_memory& memory) {
+ success = s;
+ if (s) {
+ buffer.data = memory;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_TRUE(success);
+ Return<Result> ret2 = effect->setProcessBuffers(buffer, buffer);
+ EXPECT_TRUE(ret2.isOk());
+ EXPECT_EQ(Result::OK, ret2);
+}
+
+TEST_F(AudioEffectHidlTest, Command) {
+ description("Verify that Command does not crash");
+ Return<void> ret = effect->command(0, hidl_vec<uint8_t>(), 0,
+ [&](int32_t, const hidl_vec<uint8_t>&) {});
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, SetParameter) {
+ description("Verify that SetParameter does not crash");
+ Return<Result> ret =
+ effect->setParameter(hidl_vec<uint8_t>(), hidl_vec<uint8_t>());
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, GetParameter) {
+ description("Verify that GetParameter does not crash");
+ Return<void> ret = effect->getParameter(
+ hidl_vec<uint8_t>(), 0, [&](Result, const hidl_vec<uint8_t>&) {});
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, GetSupportedConfigsForFeature) {
+ description("Verify that GetSupportedConfigsForFeature does not crash");
+ Return<void> ret = effect->getSupportedConfigsForFeature(
+ 0, 0, 0, [&](Result, uint32_t, const hidl_vec<uint8_t>&) {});
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, GetCurrentConfigForFeature) {
+ description("Verify that GetCurrentConfigForFeature does not crash");
+ Return<void> ret = effect->getCurrentConfigForFeature(
+ 0, 0, [&](Result, const hidl_vec<uint8_t>&) {});
+ EXPECT_TRUE(ret.isOk());
+}
+
+TEST_F(AudioEffectHidlTest, SetCurrentConfigForFeature) {
+ description("Verify that SetCurrentConfigForFeature does not crash");
+ Return<Result> ret =
+ effect->setCurrentConfigForFeature(0, hidl_vec<uint8_t>());
+ EXPECT_TRUE(ret.isOk());
+}
+
+
+// The main test class for Equalizer Audio Effect HIDL HAL.
+class EqualizerAudioEffectHidlTest : public AudioEffectHidlTest {
+ public:
+ void SetUp() override {
+ AudioEffectHidlTest::SetUp();
+ equalizer = IEqualizerEffect::castFrom(effect);
+ ASSERT_NE(nullptr, equalizer.get());
+ }
+
+ protected:
+ Uuid getEffectType() override { return EQUALIZER_EFFECT_TYPE; }
+ void getNumBands(uint16_t* numBands);
+ void getLevelRange(int16_t* minLevel, int16_t* maxLevel);
+ void getBandFrequencyRange(uint16_t band, uint32_t* minFreq,
+ uint32_t* centerFreq, uint32_t* maxFreq);
+ void getPresetCount(size_t* count);
+
+ sp<IEqualizerEffect> equalizer;
+};
+
+void EqualizerAudioEffectHidlTest::getNumBands(uint16_t* numBands) {
+ Result retval = Result::NOT_INITIALIZED;
+ Return<void> ret = equalizer->getNumBands([&](Result r, uint16_t b) {
+ retval = r;
+ if (retval == Result::OK) {
+ *numBands = b;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Result::OK, retval);
+}
+
+void EqualizerAudioEffectHidlTest::getLevelRange(int16_t* minLevel,
+ int16_t* maxLevel) {
+ Result retval = Result::NOT_INITIALIZED;
+ Return<void> ret =
+ equalizer->getLevelRange([&](Result r, int16_t min, int16_t max) {
+ retval = r;
+ if (retval == Result::OK) {
+ *minLevel = min;
+ *maxLevel = max;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Result::OK, retval);
+}
+
+void EqualizerAudioEffectHidlTest::getBandFrequencyRange(uint16_t band,
+ uint32_t* minFreq,
+ uint32_t* centerFreq,
+ uint32_t* maxFreq) {
+ Result retval = Result::NOT_INITIALIZED;
+ Return<void> ret = equalizer->getBandFrequencyRange(
+ band, [&](Result r, uint32_t min, uint32_t max) {
+ retval = r;
+ if (retval == Result::OK) {
+ *minFreq = min;
+ *maxFreq = max;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Result::OK, retval);
+ ret = equalizer->getBandCenterFrequency(band, [&](Result r, uint32_t center) {
+ retval = r;
+ if (retval == Result::OK) {
+ *centerFreq = center;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Result::OK, retval);
+}
+
+void EqualizerAudioEffectHidlTest::getPresetCount(size_t* count) {
+ Result retval = Result::NOT_INITIALIZED;
+ Return<void> ret = equalizer->getPresetNames(
+ [&](Result r, const hidl_vec<hidl_string>& names) {
+ retval = r;
+ if (retval == Result::OK) {
+ *count = names.size();
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(Result::OK, retval);
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetNumBands) {
+ description("Verify that Equalizer effect reports at least one band");
+ uint16_t numBands = 0;
+ getNumBands(&numBands);
+ EXPECT_GT(numBands, 0);
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetLevelRange) {
+ description("Verify that Equalizer effect reports adequate band level range");
+ int16_t minLevel = 0x7fff, maxLevel = 0;
+ getLevelRange(&minLevel, &maxLevel);
+ EXPECT_GT(maxLevel, minLevel);
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetSetBandLevel) {
+ description(
+ "Verify that manipulating band levels works for Equalizer effect");
+ uint16_t numBands = 0;
+ getNumBands(&numBands);
+ ASSERT_GT(numBands, 0);
+ int16_t levels[3]{0x7fff, 0, 0};
+ getLevelRange(&levels[0], &levels[2]);
+ ASSERT_GT(levels[2], levels[0]);
+ levels[1] = (levels[2] + levels[0]) / 2;
+ for (uint16_t i = 0; i < numBands; ++i) {
+ for (size_t j = 0; j < ARRAY_SIZE(levels); ++j) {
+ Return<Result> ret = equalizer->setBandLevel(i, levels[j]);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+ Result retval = Result::NOT_INITIALIZED;
+ int16_t actualLevel;
+ Return<void> ret2 = equalizer->getBandLevel(i, [&](Result r, int16_t l) {
+ retval = r;
+ if (retval == Result::OK) {
+ actualLevel = l;
+ }
+ });
+ EXPECT_TRUE(ret2.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ EXPECT_EQ(levels[j], actualLevel);
+ }
+ }
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetBandCenterFrequencyAndRange) {
+ description(
+ "Verify that Equalizer effect reports adequate band frequency range");
+ uint16_t numBands = 0;
+ getNumBands(&numBands);
+ ASSERT_GT(numBands, 0);
+ for (uint16_t i = 0; i < numBands; ++i) {
+ uint32_t minFreq = 0xffffffff, centerFreq = 0xffffffff,
+ maxFreq = 0xffffffff;
+ getBandFrequencyRange(i, &minFreq, ¢erFreq, &maxFreq);
+ // Note: NXP legacy implementation reports "1" as upper bound for last band,
+ // so this check fails.
+ EXPECT_GE(maxFreq, centerFreq);
+ EXPECT_GE(centerFreq, minFreq);
+ }
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetBandForFrequency) {
+ description(
+ "Verify that Equalizer effect supports GetBandForFrequency correctly");
+ uint16_t numBands = 0;
+ getNumBands(&numBands);
+ ASSERT_GT(numBands, 0);
+ for (uint16_t i = 0; i < numBands; ++i) {
+ uint32_t freqs[3]{0, 0, 0};
+ getBandFrequencyRange(i, &freqs[0], &freqs[1], &freqs[2]);
+ // NXP legacy implementation reports "1" as upper bound for last band, some
+ // of the checks fail.
+ for (size_t j = 0; j < ARRAY_SIZE(freqs); ++j) {
+ if (j == 0) {
+ freqs[j]++;
+ } // Min frequency is an open interval.
+ Result retval = Result::NOT_INITIALIZED;
+ uint16_t actualBand = numBands + 1;
+ Return<void> ret =
+ equalizer->getBandForFrequency(freqs[j], [&](Result r, uint16_t b) {
+ retval = r;
+ if (retval == Result::OK) {
+ actualBand = b;
+ }
+ });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ EXPECT_EQ(i, actualBand) << "Frequency: " << freqs[j];
+ }
+ }
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetPresetNames) {
+ description("Verify that Equalizer effect reports at least one preset");
+ size_t presetCount;
+ getPresetCount(&presetCount);
+ EXPECT_GT(presetCount, 0u);
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetSetCurrentPreset) {
+ description(
+ "Verify that manipulating the current preset for Equalizer effect");
+ size_t presetCount;
+ getPresetCount(&presetCount);
+ ASSERT_GT(presetCount, 0u);
+ for (uint16_t i = 0; i < presetCount; ++i) {
+ Return<Result> ret = equalizer->setCurrentPreset(i);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+ Result retval = Result::NOT_INITIALIZED;
+ uint16_t actualPreset = 0xffff;
+ Return<void> ret2 = equalizer->getCurrentPreset([&](Result r, uint16_t p) {
+ retval = r;
+ if (retval == Result::OK) {
+ actualPreset = p;
+ }
+ });
+ EXPECT_TRUE(ret2.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ EXPECT_EQ(i, actualPreset);
+ }
+}
+
+TEST_F(EqualizerAudioEffectHidlTest, GetSetAllProperties) {
+ description(
+ "Verify that setting band levels and presets works via Get / "
+ "SetAllProperties for Equalizer effect");
+ using AllProperties =
+ android::hardware::audio::effect::V2_0::IEqualizerEffect::AllProperties;
+ uint16_t numBands = 0;
+ getNumBands(&numBands);
+ ASSERT_GT(numBands, 0);
+ AllProperties props;
+ props.bandLevels.resize(numBands);
+ for (size_t i = 0; i < numBands; ++i) {
+ props.bandLevels[i] = 0;
+ }
+
+ AllProperties actualProps;
+ Result retval = Result::NOT_INITIALIZED;
+
+ // Verify setting of the band levels via properties.
+ props.curPreset = -1;
+ Return<Result> ret = equalizer->setAllProperties(props);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+ Return<void> ret2 =
+ equalizer->getAllProperties([&](Result r, AllProperties p) {
+ retval = r;
+ if (retval == Result::OK) {
+ actualProps = p;
+ }
+ });
+ EXPECT_TRUE(ret2.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ EXPECT_EQ(props.bandLevels, actualProps.bandLevels);
+
+ // Verify setting of the current preset via properties.
+ props.curPreset = 0; // Assuming there is at least one preset.
+ ret = equalizer->setAllProperties(props);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+ ret2 = equalizer->getAllProperties([&](Result r, AllProperties p) {
+ retval = r;
+ if (retval == Result::OK) {
+ actualProps = p;
+ }
+ });
+ EXPECT_TRUE(ret2.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ EXPECT_EQ(props.curPreset, actualProps.curPreset);
+}
+
+// The main test class for Equalizer Audio Effect HIDL HAL.
+class LoudnessEnhancerAudioEffectHidlTest : public AudioEffectHidlTest {
+ public:
+ void SetUp() override {
+ AudioEffectHidlTest::SetUp();
+ enhancer = ILoudnessEnhancerEffect::castFrom(effect);
+ ASSERT_NE(nullptr, enhancer.get());
+ }
+
+ protected:
+ Uuid getEffectType() override { return LOUDNESS_ENHANCER_EFFECT_TYPE; }
+
+ sp<ILoudnessEnhancerEffect> enhancer;
+};
+
+TEST_F(LoudnessEnhancerAudioEffectHidlTest, GetSetTargetGain) {
+ description(
+ "Verify that manipulating the target gain works for Loudness Enhancer "
+ "effect");
+ const int32_t gain = 100;
+ Return<Result> ret = enhancer->setTargetGain(gain);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, ret);
+ int32_t actualGain = 0;
+ Result retval;
+ Return<void> ret2 = enhancer->getTargetGain([&](Result r, int32_t g) {
+ retval = r;
+ if (retval == Result::OK) {
+ actualGain = g;
+ }
+ });
+ EXPECT_TRUE(ret2.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ EXPECT_EQ(gain, actualGain);
+}
+
+int main(int argc, char** argv) {
+ ::testing::AddGlobalTestEnvironment(AudioEffectsFactoryHidlEnvironment::Instance());
+ ::testing::InitGoogleTest(&argc, argv);
+ AudioEffectsFactoryHidlEnvironment::Instance()->init(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}