Add VTS tests for audio effects
Added tests covering IEffect, IEqualizerEffect, and ILoudnessEnhancer interfaces. Minor corrections in the interface definitions and implementations: - fixed descriptions and @callflow annotations in IEffect; - fixed type used for band levels in IEqualizerEffect; - fixed specification of frequencies in IEqualizerEffect; - fixed some bugs in previously non-execrices Effects code; - warning messages changed to error messages. Test: this is a test Bug: 32022706 Change-Id: I0e0bc111b07d944ad8a0321e8b1ec703f8d1a73e
This commit is contained in:
parent
cd7bc8ff94
commit
9f2890458a
10 changed files with 757 additions and 80 deletions
|
@ -59,7 +59,7 @@ interface IEffect {
|
|||
*
|
||||
* @return retval operation completion status.
|
||||
*/
|
||||
@callflow(next={"process"})
|
||||
@callflow(next={"prepareForProcessing"})
|
||||
enable() generates (Result retval);
|
||||
|
||||
/*
|
||||
|
@ -67,7 +67,7 @@ interface IEffect {
|
|||
*
|
||||
* @return retval operation completion status.
|
||||
*/
|
||||
@exit
|
||||
@callflow(next={"close"})
|
||||
disable() generates (Result retval);
|
||||
|
||||
/*
|
||||
|
@ -75,6 +75,9 @@ interface IEffect {
|
|||
* effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its
|
||||
* descriptor to receive this command when the device changes.
|
||||
*
|
||||
* Note: this method is only supported for effects inserted into
|
||||
* the output chain.
|
||||
*
|
||||
* @param device output device specification.
|
||||
* @return retval operation completion status.
|
||||
*/
|
||||
|
@ -145,6 +148,9 @@ interface IEffect {
|
|||
* implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to
|
||||
* receive this command when the device changes.
|
||||
*
|
||||
* Note: this method is only supported for effects inserted into
|
||||
* the input chain.
|
||||
*
|
||||
* @param device input device specification.
|
||||
* @return retval operation completion status.
|
||||
*/
|
||||
|
@ -209,6 +215,9 @@ interface IEffect {
|
|||
* Set the audio source the capture path is configured for (Camcorder, voice
|
||||
* recognition...).
|
||||
*
|
||||
* Note: this method is only supported for effects inserted into
|
||||
* the input chain.
|
||||
*
|
||||
* @param source source descriptor.
|
||||
* @return retval operation completion status.
|
||||
*/
|
||||
|
@ -258,6 +267,7 @@ interface IEffect {
|
|||
* the queue.
|
||||
* @return statusMQ a message queue used for passing status from the effect.
|
||||
*/
|
||||
@callflow(next={"setProcessBuffers"})
|
||||
prepareForProcessing() generates (Result retval, fmq_sync<Result> statusMQ);
|
||||
|
||||
/*
|
||||
|
@ -275,6 +285,7 @@ interface IEffect {
|
|||
* INVALID_ARGUMENTS if there was a problem with mapping
|
||||
* any of the buffers.
|
||||
*/
|
||||
@callflow(next={"*"})
|
||||
setProcessBuffers(AudioBuffer inBuffer, AudioBuffer outBuffer) generates (
|
||||
Result retval);
|
||||
|
||||
|
@ -423,5 +434,6 @@ interface IEffect {
|
|||
* @return retval OK in case the success.
|
||||
* INVALID_STATE if the effect was already closed.
|
||||
*/
|
||||
@exit
|
||||
close() generates (Result retval);
|
||||
};
|
||||
|
|
|
@ -29,34 +29,36 @@ interface IEqualizerEffect extends IEffect {
|
|||
* Returns the minimum and maximum band levels supported.
|
||||
*/
|
||||
getLevelRange()
|
||||
generates (Result retval, uint16_t minLevel, uint16_t maxLevel);
|
||||
generates (Result retval, int16_t minLevel, int16_t maxLevel);
|
||||
|
||||
/*
|
||||
* Sets the gain for the given equalizer band.
|
||||
*/
|
||||
setBandLevel(uint16_t band, uint16_t level) generates (Result retval);
|
||||
setBandLevel(uint16_t band, int16_t level) generates (Result retval);
|
||||
|
||||
/*
|
||||
* Gets the gain for the given equalizer band.
|
||||
*/
|
||||
getBandLevel(uint16_t band) generates (Result retval, uint16_t level);
|
||||
getBandLevel(uint16_t band) generates (Result retval, int16_t level);
|
||||
|
||||
/*
|
||||
* Gets the center frequency of the given band.
|
||||
* Gets the center frequency of the given band, in milliHertz.
|
||||
*/
|
||||
getBandCenterFrequency(uint16_t band)
|
||||
generates (Result retval, uint32_t centerFreq);
|
||||
generates (Result retval, uint32_t centerFreqmHz);
|
||||
|
||||
/*
|
||||
* Gets the frequency range of the given frequency band.
|
||||
* Gets the frequency range of the given frequency band, in milliHertz.
|
||||
*/
|
||||
getBandFrequencyRange(uint16_t band)
|
||||
generates (Result retval, uint32_t minFreqHz, uint32_t maxFreqHz);
|
||||
generates (Result retval, uint32_t minFreqmHz, uint32_t maxFreqmHz);
|
||||
|
||||
/*
|
||||
* Gets the band that has the most effect on the given frequency.
|
||||
* Gets the band that has the most effect on the given frequency
|
||||
* in milliHertz.
|
||||
*/
|
||||
getBandForFrequency(uint32_t freq) generates (Result retval, uint16_t band);
|
||||
getBandForFrequency(uint32_t freqmHz)
|
||||
generates (Result retval, uint16_t band);
|
||||
|
||||
/*
|
||||
* Gets the names of all presets the equalizer supports.
|
||||
|
@ -76,7 +78,7 @@ interface IEqualizerEffect extends IEffect {
|
|||
|
||||
struct AllProperties {
|
||||
uint16_t curPreset;
|
||||
vec<uint16_t> bandLevels;
|
||||
vec<int16_t> bandLevels;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -188,6 +188,8 @@ void Effect::effectAuxChannelsConfigToHal(
|
|||
// static
|
||||
void Effect::effectBufferConfigFromHal(
|
||||
const buffer_config_t& halConfig, EffectBufferConfig* config) {
|
||||
config->buffer.id = 0;
|
||||
config->buffer.frameCount = 0;
|
||||
config->samplingRateHz = halConfig.samplingRate;
|
||||
config->channels = AudioChannelMask(halConfig.channels);
|
||||
config->format = AudioFormat(halConfig.format);
|
||||
|
@ -282,7 +284,7 @@ Result Effect::analyzeStatus(
|
|||
|
||||
void Effect::getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb) {
|
||||
uint32_t halResultSize = sizeof(effect_config_t);
|
||||
effect_config_t halConfig;
|
||||
effect_config_t halConfig{};
|
||||
status_t status = (*mHandle)->command(
|
||||
mHandle, commandCode, 0, NULL, &halResultSize, &halConfig);
|
||||
EffectConfig config;
|
||||
|
@ -309,15 +311,16 @@ Result Effect::getCurrentConfigImpl(
|
|||
Result Effect::getParameterImpl(
|
||||
uint32_t paramSize,
|
||||
const void* paramData,
|
||||
uint32_t valueSize,
|
||||
uint32_t requestValueSize,
|
||||
uint32_t replyValueSize,
|
||||
GetParameterSuccessCallback onSuccess) {
|
||||
// As it is unknown what method HAL uses for copying the provided parameter data,
|
||||
// it is safer to make sure that input and output buffers do not overlap.
|
||||
std::vector<uint8_t> halCmdBuffer =
|
||||
parameterToHal(paramSize, paramData, valueSize, nullptr);
|
||||
parameterToHal(paramSize, paramData, requestValueSize, nullptr);
|
||||
const void *valueData = nullptr;
|
||||
std::vector<uint8_t> halParamBuffer =
|
||||
parameterToHal(paramSize, paramData, valueSize, &valueData);
|
||||
parameterToHal(paramSize, paramData, replyValueSize, &valueData);
|
||||
uint32_t halParamBufferSize = halParamBuffer.size();
|
||||
|
||||
return sendCommandReturningStatusAndData(
|
||||
|
|
|
@ -60,6 +60,8 @@ using ::android::sp;
|
|||
|
||||
struct Effect : public IEffect {
|
||||
typedef MessageQueue<Result, kSynchronizedReadWrite> StatusMQ;
|
||||
using GetParameterSuccessCallback =
|
||||
std::function<void(uint32_t valueSize, const void* valueData)>;
|
||||
|
||||
explicit Effect(effect_handle_t handle);
|
||||
|
||||
|
@ -163,6 +165,22 @@ struct Effect : public IEffect {
|
|||
return setParameterImpl(sizeof(params), params, sizeof(T), ¶mValue);
|
||||
}
|
||||
|
||||
Result getParameterImpl(
|
||||
uint32_t paramSize,
|
||||
const void* paramData,
|
||||
uint32_t valueSize,
|
||||
GetParameterSuccessCallback onSuccess) {
|
||||
return getParameterImpl(paramSize, paramData, valueSize, valueSize, onSuccess);
|
||||
}
|
||||
Result getParameterImpl(
|
||||
uint32_t paramSize,
|
||||
const void* paramData,
|
||||
uint32_t requestValueSize,
|
||||
uint32_t replyValueSize,
|
||||
GetParameterSuccessCallback onSuccess);
|
||||
Result setParameterImpl(
|
||||
uint32_t paramSize, const void* paramData, uint32_t valueSize, const void* valueData);
|
||||
|
||||
private:
|
||||
friend struct VirtualizerEffect; // for getParameterImpl
|
||||
friend struct VisualizerEffect; // to allow executing commands
|
||||
|
@ -170,8 +188,6 @@ struct Effect : public IEffect {
|
|||
using CommandSuccessCallback = std::function<void()>;
|
||||
using GetConfigCallback = std::function<void(Result retval, const EffectConfig& config)>;
|
||||
using GetCurrentConfigSuccessCallback = std::function<void(void* configData)>;
|
||||
using GetParameterSuccessCallback =
|
||||
std::function<void(uint32_t valueSize, const void* valueData)>;
|
||||
using GetSupportedConfigsSuccessCallback =
|
||||
std::function<void(uint32_t supportedConfigs, void* configsData)>;
|
||||
|
||||
|
@ -220,11 +236,6 @@ struct Effect : public IEffect {
|
|||
void getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb);
|
||||
Result getCurrentConfigImpl(
|
||||
uint32_t featureId, uint32_t configSize, GetCurrentConfigSuccessCallback onSuccess);
|
||||
Result getParameterImpl(
|
||||
uint32_t paramSize,
|
||||
const void* paramData,
|
||||
uint32_t valueSize,
|
||||
GetParameterSuccessCallback onSuccess);
|
||||
Result getSupportedConfigsImpl(
|
||||
uint32_t featureId,
|
||||
uint32_t maxConfigs,
|
||||
|
@ -252,8 +263,6 @@ struct Effect : public IEffect {
|
|||
const EffectConfig& config,
|
||||
const sp<IEffectBufferProviderCallback>& inputBufferProvider,
|
||||
const sp<IEffectBufferProviderCallback>& outputBufferProvider);
|
||||
Result setParameterImpl(
|
||||
uint32_t paramSize, const void* paramData, uint32_t valueSize, const void* valueData);
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
|
|
|
@ -95,7 +95,7 @@ restart:
|
|||
status = EffectQueryNumberEffects(&numEffects);
|
||||
if (status != OK) {
|
||||
retval = Result::NOT_INITIALIZED;
|
||||
ALOGW("Error querying number of effects: %s", strerror(-status));
|
||||
ALOGE("Error querying number of effects: %s", strerror(-status));
|
||||
goto exit;
|
||||
}
|
||||
result.resize(numEffects);
|
||||
|
@ -105,7 +105,7 @@ restart:
|
|||
if (status == OK) {
|
||||
effectDescriptorFromHal(halDescriptor, &result[i]);
|
||||
} else {
|
||||
ALOGW("Error querying effect at position %d / %d: %s",
|
||||
ALOGE("Error querying effect at position %d / %d: %s",
|
||||
i, numEffects, strerror(-status));
|
||||
switch (status) {
|
||||
case -ENOSYS: {
|
||||
|
@ -139,7 +139,7 @@ Return<void> EffectsFactory::getDescriptor(const Uuid& uid, getDescriptor_cb _hi
|
|||
effectDescriptorFromHal(halDescriptor, &descriptor);
|
||||
Result retval(Result::OK);
|
||||
if (status != OK) {
|
||||
ALOGW("Error querying effect descriptor for %s: %s",
|
||||
ALOGE("Error querying effect descriptor for %s: %s",
|
||||
uuidToString(halUuid).c_str(), strerror(-status));
|
||||
if (status == -ENOENT) {
|
||||
retval = Result::INVALID_ARGUMENTS;
|
||||
|
@ -168,11 +168,13 @@ Return<void> EffectsFactory::createEffect(
|
|||
effect = dispatchEffectInstanceCreation(halDescriptor, handle);
|
||||
effectId = EffectMap::getInstance().add(handle);
|
||||
} else {
|
||||
ALOGE("Error querying effect descriptor for %s: %s",
|
||||
uuidToString(halUuid).c_str(), strerror(-status));
|
||||
EffectRelease(handle);
|
||||
}
|
||||
}
|
||||
if (status != OK) {
|
||||
ALOGW("Error creating effect %s: %s", uuidToString(halUuid).c_str(), strerror(-status));
|
||||
ALOGE("Error creating effect %s: %s", uuidToString(halUuid).c_str(), strerror(-status));
|
||||
if (status == -ENOENT) {
|
||||
retval = Result::INVALID_ARGUMENTS;
|
||||
} else {
|
||||
|
|
|
@ -35,10 +35,15 @@ EqualizerEffect::EqualizerEffect(effect_handle_t handle)
|
|||
EqualizerEffect::~EqualizerEffect() {}
|
||||
|
||||
void EqualizerEffect::propertiesFromHal(
|
||||
t_equalizer_settings& halProperties,
|
||||
const t_equalizer_settings& halProperties,
|
||||
IEqualizerEffect::AllProperties* properties) {
|
||||
properties->curPreset = halProperties.curPreset;
|
||||
properties->bandLevels.setToExternal(&halProperties.bandLevels[0], halProperties.numBands);
|
||||
// t_equalizer_settings incorrectly defines bandLevels as uint16_t,
|
||||
// whereas the actual type of values used by effects is int16_t.
|
||||
const int16_t* signedBandLevels =
|
||||
reinterpret_cast<const int16_t*>(&halProperties.bandLevels[0]);
|
||||
properties->bandLevels.setToExternal(
|
||||
const_cast<int16_t*>(signedBandLevels), halProperties.numBands);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> EqualizerEffect::propertiesToHal(
|
||||
|
@ -200,18 +205,18 @@ Return<void> EqualizerEffect::getNumBands(getNumBands_cb _hidl_cb) {
|
|||
}
|
||||
|
||||
Return<void> EqualizerEffect::getLevelRange(getLevelRange_cb _hidl_cb) {
|
||||
uint16_t halLevels[2] = { 0, 0 };
|
||||
int16_t halLevels[2] = { 0, 0 };
|
||||
Result retval = mEffect->getParam(EQ_PARAM_LEVEL_RANGE, halLevels);
|
||||
_hidl_cb(retval, halLevels[0], halLevels[1]);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> EqualizerEffect::setBandLevel(uint16_t band, uint16_t level) {
|
||||
Return<Result> EqualizerEffect::setBandLevel(uint16_t band, int16_t level) {
|
||||
return mEffect->setParam(EQ_PARAM_BAND_LEVEL, band, level);
|
||||
}
|
||||
|
||||
Return<void> EqualizerEffect::getBandLevel(uint16_t band, getBandLevel_cb _hidl_cb) {
|
||||
uint16_t halLevel = 0;
|
||||
int16_t halLevel = 0;
|
||||
Result retval = mEffect->getParam(EQ_PARAM_BAND_LEVEL, band, halLevel);
|
||||
_hidl_cb(retval, halLevel);
|
||||
return Void();
|
||||
|
@ -272,14 +277,28 @@ Return<Result> EqualizerEffect::setAllProperties(
|
|||
const IEqualizerEffect::AllProperties& properties) {
|
||||
t_equalizer_settings *halPropertiesPtr = nullptr;
|
||||
std::vector<uint8_t> halBuffer = propertiesToHal(properties, &halPropertiesPtr);
|
||||
return mEffect->setParam(EQ_PARAM_PROPERTIES, *halPropertiesPtr);
|
||||
uint32_t paramId = EQ_PARAM_PROPERTIES;
|
||||
return mEffect->setParameterImpl(
|
||||
sizeof(paramId), ¶mId, halBuffer.size(), halPropertiesPtr);
|
||||
}
|
||||
|
||||
Return<void> EqualizerEffect::getAllProperties(getAllProperties_cb _hidl_cb) {
|
||||
t_equalizer_settings halProperties;
|
||||
Result retval = mEffect->getParam(EQ_PARAM_PROPERTIES, halProperties);
|
||||
uint16_t numBands = 0;
|
||||
Result retval = mEffect->getParam(EQ_PARAM_NUM_BANDS, numBands);
|
||||
AllProperties properties;
|
||||
propertiesFromHal(halProperties, &properties);
|
||||
if (retval != Result::OK) {
|
||||
_hidl_cb(retval, properties);
|
||||
return Void();
|
||||
}
|
||||
size_t valueSize = sizeof(t_equalizer_settings) + sizeof(int16_t) * numBands;
|
||||
uint32_t paramId = EQ_PARAM_PROPERTIES;
|
||||
retval = mEffect->getParameterImpl(
|
||||
sizeof(paramId), ¶mId, valueSize,
|
||||
[&] (uint32_t, const void* valueData) {
|
||||
const t_equalizer_settings* halProperties =
|
||||
reinterpret_cast<const t_equalizer_settings*>(valueData);
|
||||
propertiesFromHal(*halProperties, &properties);
|
||||
});
|
||||
_hidl_cb(retval, properties);
|
||||
return Void();
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ struct EqualizerEffect : public IEqualizerEffect {
|
|||
// Methods from ::android::hardware::audio::effect::V2_0::IEqualizerEffect follow.
|
||||
Return<void> getNumBands(getNumBands_cb _hidl_cb) override;
|
||||
Return<void> getLevelRange(getLevelRange_cb _hidl_cb) override;
|
||||
Return<Result> setBandLevel(uint16_t band, uint16_t level) override;
|
||||
Return<Result> setBandLevel(uint16_t band, int16_t level) override;
|
||||
Return<void> getBandLevel(uint16_t band, getBandLevel_cb _hidl_cb) override;
|
||||
Return<void> getBandCenterFrequency(
|
||||
uint16_t band, getBandCenterFrequency_cb _hidl_cb) override;
|
||||
|
@ -132,7 +132,7 @@ struct EqualizerEffect : public IEqualizerEffect {
|
|||
virtual ~EqualizerEffect();
|
||||
|
||||
void propertiesFromHal(
|
||||
t_equalizer_settings& halProperties,
|
||||
const t_equalizer_settings& halProperties,
|
||||
IEqualizerEffect::AllProperties* properties);
|
||||
std::vector<uint8_t> propertiesToHal(
|
||||
const IEqualizerEffect::AllProperties& properties,
|
||||
|
|
|
@ -182,7 +182,18 @@ Return<Result> LoudnessEnhancerEffect::setTargetGain(int32_t targetGainMb) {
|
|||
}
|
||||
|
||||
Return<void> LoudnessEnhancerEffect::getTargetGain(getTargetGain_cb _hidl_cb) {
|
||||
return mEffect->getIntegerParam(LOUDNESS_ENHANCER_DEFAULT_TARGET_GAIN_MB, _hidl_cb);
|
||||
// AOSP Loudness Enhancer expects the size of the request to not include the
|
||||
// size of the parameter.
|
||||
uint32_t paramId = LOUDNESS_ENHANCER_DEFAULT_TARGET_GAIN_MB;
|
||||
uint32_t targetGainMb = 0;
|
||||
Result retval = mEffect->getParameterImpl(
|
||||
sizeof(paramId), ¶mId,
|
||||
0, sizeof(targetGainMb),
|
||||
[&] (uint32_t, const void* valueData) {
|
||||
memcpy(&targetGainMb, valueData, sizeof(targetGainMb));
|
||||
});
|
||||
_hidl_cb(retval, targetGainMb);
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
|
|
|
@ -26,7 +26,10 @@ cc_test {
|
|||
"libhidltransport",
|
||||
"libnativehelper",
|
||||
"libutils",
|
||||
"android.hardware.audio.common@2.0",
|
||||
"android.hardware.audio.effect@2.0",
|
||||
"android.hidl.allocator@1.0",
|
||||
"android.hidl.memory@1.0",
|
||||
],
|
||||
static_libs: ["VtsHalHidlTargetTestBase"],
|
||||
cflags: [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* 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.
|
||||
|
@ -16,47 +16,67 @@
|
|||
|
||||
#define LOG_TAG "AudioEffectHidlHalTest"
|
||||
#include <android-base/logging.h>
|
||||
#include <cutils/native_handle.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>
|
||||
|
||||
using ::android::hardware::audio::common::V2_0::Uuid;
|
||||
using ::android::hardware::audio::effect::V2_0::EffectDescriptor;
|
||||
using ::android::hardware::audio::effect::V2_0::IEffect;
|
||||
using ::android::hardware::audio::effect::V2_0::IEffectsFactory;
|
||||
using ::android::hardware::audio::effect::V2_0::Result;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Status;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::sp;
|
||||
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::Uuid;
|
||||
using android::hardware::audio::effect::V2_0::AudioBuffer;
|
||||
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_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;
|
||||
|
||||
// The main test class for Audio Effect HIDL HAL.
|
||||
class AudioEffectHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
|
||||
#endif
|
||||
|
||||
// The main test class for Audio Effects Factory HIDL HAL.
|
||||
class AudioEffectsFactoryHidlTest : public ::testing::VtsHalHidlTargetTestBase {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
effectsFactory = ::testing::VtsHalHidlTargetTestBase::getService<IEffectsFactory>();
|
||||
void SetUp() override {
|
||||
effectsFactory =
|
||||
::testing::VtsHalHidlTargetTestBase::getService<IEffectsFactory>();
|
||||
ASSERT_NE(effectsFactory, nullptr);
|
||||
}
|
||||
|
||||
virtual void TearDown() override {}
|
||||
void TearDown() override { effectsFactory.clear(); }
|
||||
|
||||
protected:
|
||||
static void description(const std::string& description) {
|
||||
RecordProperty("description", description);
|
||||
}
|
||||
|
||||
sp<IEffectsFactory> effectsFactory;
|
||||
};
|
||||
|
||||
// A class for test environment setup (kept since this file is a template).
|
||||
class AudioEffectHidlEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
TEST_F(AudioEffectHidlTest, EnumerateEffects) {
|
||||
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(
|
||||
|
@ -65,11 +85,12 @@ TEST_F(AudioEffectHidlTest, EnumerateEffects) {
|
|||
effectCount = result.size();
|
||||
});
|
||||
EXPECT_TRUE(ret.isOk());
|
||||
EXPECT_EQ(retval, Result::OK);
|
||||
EXPECT_EQ(Result::OK, retval);
|
||||
EXPECT_GT(effectCount, 0u);
|
||||
}
|
||||
|
||||
TEST_F(AudioEffectHidlTest, CreateEffect) {
|
||||
TEST_F(AudioEffectsFactoryHidlTest, CreateEffect) {
|
||||
description("Verify that an effect can be created via CreateEffect");
|
||||
bool gotEffect = false;
|
||||
Uuid effectUuid;
|
||||
Return<void> ret = effectsFactory->getAllDescriptors(
|
||||
|
@ -84,7 +105,7 @@ TEST_F(AudioEffectHidlTest, CreateEffect) {
|
|||
Result retval = Result::NOT_INITIALIZED;
|
||||
sp<IEffect> effect;
|
||||
ret = effectsFactory->createEffect(
|
||||
effectUuid, 1 /* session */, 1 /* ioHandle */,
|
||||
effectUuid, 1 /*session*/, 1 /*ioHandle*/,
|
||||
[&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
|
||||
retval = r;
|
||||
if (r == Result::OK) {
|
||||
|
@ -92,11 +113,14 @@ TEST_F(AudioEffectHidlTest, CreateEffect) {
|
|||
}
|
||||
});
|
||||
EXPECT_TRUE(ret.isOk());
|
||||
EXPECT_EQ(retval, Result::OK);
|
||||
EXPECT_NE(effect, nullptr);
|
||||
EXPECT_EQ(Result::OK, retval);
|
||||
EXPECT_NE(nullptr, effect.get());
|
||||
}
|
||||
|
||||
TEST_F(AudioEffectHidlTest, GetDescriptor) {
|
||||
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) {
|
||||
|
@ -116,10 +140,602 @@ TEST_F(AudioEffectHidlTest, GetDescriptor) {
|
|||
EXPECT_TRUE(ret.isOk());
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::AddGlobalTestEnvironment(new AudioEffectHidlEnvironment);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int status = RUN_ALL_TESTS();
|
||||
LOG(INFO) << "Test result = " << status;
|
||||
return status;
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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, Offload) {
|
||||
description("Verify that calling Offload methods works for an effect");
|
||||
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());
|
||||
EXPECT_EQ(Result::OK, ret);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Testing getConfigReverse, getAuxChannelsConfig,
|
||||
// getSupportedAuxChannelsConfigs, setAudioSource, setConfigReverse,
|
||||
// setInputDevice doesn't make sense, because normally they are not supported by
|
||||
// the Equalizer, but it wouldn't be a problem if some vendor implementation
|
||||
// supports them, thus we can't test these methods neither for success, nor for
|
||||
// failure.
|
||||
|
||||
// command, getParameter, getSupportedConfigsForFeature,
|
||||
// getCurrentConfigForFeature, setCurrentConfigForFeature, setParameter are
|
||||
// opaque channels between vendor apps and HALs, and can't be meaningfully
|
||||
// tested with effects that don't support them.
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue