Merge "Revert "Remove Vndk_use_version property from AIDL"" into main
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index 9547865..c01eb3f 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -77,7 +77,6 @@
<effect name="dynamics_processing" library="dynamics_processing" uuid="e0e6539b-1781-7261-676f-6d7573696340"/>
<effect name="haptic_generator" library="haptic_generator" uuid="97c4acd1-8b82-4f2f-832e-c2fe5d7a9931"/>
<effect name="loudness_enhancer" library="loudness_enhancer" uuid="fa415329-2034-4bea-b5dc-5b381c8d1e2c"/>
- <effect name="env_reverb" library="env_reverbsw" uuid="fa819886-588b-11ed-9b6a-0242ac120002"/>
<effect name="reverb_env_aux" library="reverb" uuid="4a387fc0-8ab3-11df-8bad-0002a5d5c51b"/>
<effect name="reverb_env_ins" library="reverb" uuid="c7a511a0-a3bb-11df-860e-0002a5d5c51b"/>
<effect name="reverb_pre_aux" library="reverb" uuid="f29a1400-a3bb-11df-8ddc-0002a5d5c51b"/>
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index b236831..cbd42c0 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -121,6 +121,9 @@
name: "VtsHalEnvironmentalReverbTargetTest",
defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalEnvironmentalReverbTargetTest.cpp"],
+ shared_libs: [
+ "libaudioutils",
+ ],
}
cc_test {
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 93a3dcd..c7c6505 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -16,28 +16,132 @@
#define LOG_TAG "VtsHalEnvironmentalReverbTest"
#include <android-base/logging.h>
+#include <audio_utils/power.h>
+#include <system/audio.h>
#include "EffectHelper.h"
using namespace android;
-
-using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::EnvironmentalReverb;
-using aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb;
-using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::Parameter;
+using namespace aidl::android::hardware::audio::effect;
+using aidl::android::hardware::audio::common::getChannelCount;
using android::hardware::audio::common::testing::detail::TestExecutionTracer;
+using TagVectorPair = std::pair<EnvironmentalReverb::Tag, std::vector<int>>;
+using TagValuePair = std::pair<EnvironmentalReverb::Tag, int>;
+static constexpr int kMaxRoomLevel = 0;
+static constexpr int kMinRoomLevel = -6000;
+static constexpr int kMinRoomHfLevel = -4000;
+static constexpr int kMinDecayTime = 0;
+static constexpr int kMinHfRatio = 100;
+static constexpr int kMinLevel = -6000;
+static constexpr int kMinDensity = 0;
+static constexpr int kMinDiffusion = 0;
+static constexpr int kMinDelay = 0;
+
+static const std::vector<TagVectorPair> kParamsIncreasingVector = {
+
+ {EnvironmentalReverb::roomLevelMb, {-3500, -2800, -2100, -1400, -700, 0}},
+ {EnvironmentalReverb::roomHfLevelMb, {-4000, -3200, -2400, -1600, -800, 0}},
+ {EnvironmentalReverb::decayTimeMs, {800, 1600, 2400, 3200, 4000}},
+ {EnvironmentalReverb::decayHfRatioPm, {100, 600, 1100, 1600, 2000}},
+ {EnvironmentalReverb::levelMb, {-3500, -2800, -2100, -1400, -700, 0}},
+};
+
+static const std::vector<TagValuePair> kParamsMinimumValue = {
+ {EnvironmentalReverb::roomLevelMb, kMinRoomLevel},
+ {EnvironmentalReverb::decayTimeMs, kMinDecayTime},
+ {EnvironmentalReverb::levelMb, kMinLevel}};
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+
+using Maker = std::set<int> (*)();
+static const std::array<Maker, static_cast<int>(EnvironmentalReverb::bypass) + 1>
+ kTestValueSetMaker = {
+ nullptr,
+ []() -> std::set<int> {
+ return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::roomLevelMb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>);
+ },
+ []() -> std::set<int> {
+ return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::roomHfLevelMb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>);
+ },
+ []() -> std::set<int> {
+ return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::decayTimeMs>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>);
+ },
+ []() -> std::set<int> {
+ return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::decayHfRatioPm>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>);
+ },
+ nullptr,
+ nullptr,
+ []() -> std::set<int> {
+ return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::levelMb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>);
+ },
+ []() -> std::set<int> {
+ return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::delayMs>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>);
+ },
+ []() -> std::set<int> {
+ return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::diffusionPm>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>);
+ },
+ []() -> std::set<int> {
+ return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::densityPm>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>);
+ },
+ []() -> std::set<int> {
+ return EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::bypass>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>);
+ },
+};
+
+static std::vector<TagValuePair> buildSetAndGetTestParams() {
+ std::vector<TagValuePair> valueTag;
+ for (EnvironmentalReverb::Tag tag : ndk::enum_range<EnvironmentalReverb::Tag>()) {
+ std::set<int> values;
+ int intTag = static_cast<int>(tag);
+ if (intTag <= static_cast<int>(EnvironmentalReverb::bypass) &&
+ kTestValueSetMaker[intTag] != nullptr) {
+ values = kTestValueSetMaker[intTag]();
+ }
+
+ for (const auto& value : values) {
+ valueTag.push_back(std::make_pair(tag, value));
+ }
+ }
+
+ return valueTag;
+}
/**
- * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
- * VtsAudioEffectTargetTest.
- * Testing parameter range, assuming the parameter supported by effect is in this range.
- * This range is verified with IEffect.getDescriptor() and range defined in the documentation, for
- * any index supported value test expects EX_NONE from IEffect.setParameter(), otherwise expects
- * EX_ILLEGAL_ARGUMENT.
+ * Tests do the following:
+ * - Testing parameter range supported by the effect. Range is verified with IEffect.getDescriptor()
+ * and range defined in the documentation.
+ * - Validating the effect by comparing the outputs of the supported parameters.
*/
+enum ParamName { DESCRIPTOR_INDEX, TAG_VALUE_PAIR };
+
class EnvironmentalReverbHelper : public EffectHelper {
public:
EnvironmentalReverbHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> pair) {
@@ -51,8 +155,7 @@
Parameter::Specific specific = getDefaultParamSpecific();
Parameter::Common common = createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
- kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
- IEffect::OpenEffectReturn ret;
+ mFrameCount /* iFrameCount */, mFrameCount /* oFrameCount */);
ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
ASSERT_NE(nullptr, mEffect);
}
@@ -63,475 +166,291 @@
}
Parameter::Specific getDefaultParamSpecific() {
- EnvironmentalReverb er = EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(-6000);
+ EnvironmentalReverb er =
+ EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(kMaxRoomLevel);
Parameter::Specific specific =
Parameter::Specific::make<Parameter::Specific::environmentalReverb>(er);
return specific;
}
- static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
- std::shared_ptr<IFactory> mFactory;
- std::shared_ptr<IEffect> mEffect;
- Descriptor mDescriptor;
- int mRoomLevel = -6000;
- int mRoomHfLevel = 0;
- int mDecayTime = 1000;
- int mDecayHfRatio = 500;
- int mLevel = -6000;
- int mDelay = 40;
- int mDiffusion = 1000;
- int mDensity = 1000;
- bool mBypass = false;
+ bool isParamValid(EnvironmentalReverb env) {
+ return isParameterValid<EnvironmentalReverb, Range::environmentalReverb>(env, mDescriptor);
+ }
- void SetAndGetReverbParameters() {
- for (auto& it : mTags) {
- auto& tag = it.first;
- auto& er = it.second;
+ Parameter createParam(EnvironmentalReverb env) {
+ return Parameter::make<Parameter::specific>(
+ Parameter::Specific::make<Parameter::Specific::environmentalReverb>(env));
+ }
- // validate parameter
- Descriptor desc;
- ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isParameterValid<EnvironmentalReverb, Range::environmentalReverb>(
- it.second, desc);
- const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+ void setAndVerifyParam(binder_exception_t expected, EnvironmentalReverb env,
+ EnvironmentalReverb::Tag tag) {
+ auto expectedParam = createParam(env);
- // set
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::environmentalReverb>(er);
- expectParam.set<Parameter::specific>(specific);
- EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+ EXPECT_STATUS(expected, mEffect->setParameter(expectedParam)) << expectedParam.toString();
- // only get if parameter in range and set success
- if (expected == EX_NONE) {
- Parameter getParam;
- Parameter::Id id;
- EnvironmentalReverb::Id erId;
- erId.set<EnvironmentalReverb::Id::commonTag>(tag);
- id.set<Parameter::Id::environmentalReverbTag>(erId);
- // if set success, then get should match
- EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
- EXPECT_EQ(expectParam, getParam);
- }
+ if (expected == EX_NONE) {
+ auto erId = EnvironmentalReverb::Id::make<EnvironmentalReverb::Id::commonTag>(
+ EnvironmentalReverb::Tag(tag));
+
+ auto id = Parameter::Id::make<Parameter::Id::environmentalReverbTag>(erId);
+
+ // get parameter
+ Parameter getParam;
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+ EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
+ << "\ngetParam:" << getParam.toString();
}
}
- void addRoomLevelParam() {
- EnvironmentalReverb er;
- er.set<EnvironmentalReverb::roomLevelMb>(mRoomLevel);
- mTags.push_back({EnvironmentalReverb::roomLevelMb, er});
+ bool isAuxiliary() {
+ return mDescriptor.common.flags.type ==
+ aidl::android::hardware::audio::effect::Flags::Type::AUXILIARY;
}
- void addRoomHfLevelParam(int roomHfLevel) {
- EnvironmentalReverb er;
- er.set<EnvironmentalReverb::roomHfLevelMb>(roomHfLevel);
- mTags.push_back({EnvironmentalReverb::roomHfLevelMb, er});
+ float computeOutputEnergy(const std::vector<float>& input, std::vector<float> output) {
+ if (!isAuxiliary()) {
+ // Extract auxiliary output
+ for (size_t i = 0; i < output.size(); i++) {
+ output[i] -= input[i];
+ }
+ }
+ return audio_utils_compute_energy_mono(output.data(), AUDIO_FORMAT_PCM_FLOAT,
+ output.size());
}
- void addDecayTimeParam(int decayTime) {
- EnvironmentalReverb er;
- er.set<EnvironmentalReverb::decayTimeMs>(decayTime);
- mTags.push_back({EnvironmentalReverb::decayTimeMs, er});
+ void generateSineWaveInput(std::vector<float>& input) {
+ int frequency = 1000;
+ size_t kSamplingFrequency = 44100;
+ for (size_t i = 0; i < input.size(); i++) {
+ input[i] = sin(2 * M_PI * frequency * i / kSamplingFrequency);
+ }
+ }
+ using Maker = EnvironmentalReverb (*)(int);
+
+ static constexpr std::array<Maker, static_cast<int>(EnvironmentalReverb::bypass) + 1>
+ kEnvironmentalReverbParamMaker = {
+ nullptr,
+ [](int value) -> EnvironmentalReverb {
+ return EnvironmentalReverb::make<EnvironmentalReverb::roomLevelMb>(value);
+ },
+ [](int value) -> EnvironmentalReverb {
+ return EnvironmentalReverb::make<EnvironmentalReverb::roomHfLevelMb>(value);
+ },
+ [](int value) -> EnvironmentalReverb {
+ return EnvironmentalReverb::make<EnvironmentalReverb::decayTimeMs>(value);
+ },
+ [](int value) -> EnvironmentalReverb {
+ return EnvironmentalReverb::make<EnvironmentalReverb::decayHfRatioPm>(
+ value);
+ },
+ nullptr,
+ nullptr,
+ [](int value) -> EnvironmentalReverb {
+ return EnvironmentalReverb::make<EnvironmentalReverb::levelMb>(value);
+ },
+ [](int value) -> EnvironmentalReverb {
+ return EnvironmentalReverb::make<EnvironmentalReverb::delayMs>(value);
+ },
+ [](int value) -> EnvironmentalReverb {
+ return EnvironmentalReverb::make<EnvironmentalReverb::diffusionPm>(value);
+ },
+ [](int value) -> EnvironmentalReverb {
+ return EnvironmentalReverb::make<EnvironmentalReverb::densityPm>(value);
+ },
+ [](int value) -> EnvironmentalReverb {
+ return EnvironmentalReverb::make<EnvironmentalReverb::bypass>(value);
+ }};
+
+ void createEnvParam(EnvironmentalReverb::Tag tag, int paramValue) {
+ int intTag = static_cast<int>(tag);
+ if (intTag <= static_cast<int>(EnvironmentalReverb::bypass) &&
+ kEnvironmentalReverbParamMaker[intTag] != NULL) {
+ mEnvParam = kEnvironmentalReverbParamMaker[intTag](paramValue);
+ } else {
+ GTEST_SKIP() << "Invalid parameter, skipping the test\n";
+ }
}
- void addDecayHfRatioParam(int decayHfRatio) {
- EnvironmentalReverb er;
- er.set<EnvironmentalReverb::decayHfRatioPm>(decayHfRatio);
- mTags.push_back({EnvironmentalReverb::decayHfRatioPm, er});
+ void setParameterAndProcess(std::vector<float>& input, std::vector<float>& output, int val,
+ EnvironmentalReverb::Tag tag) {
+ createEnvParam(tag, val);
+ if (isParamValid(mEnvParam)) {
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParam(EX_NONE, mEnvParam, tag));
+ ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput(input, output, mEffect, &ret));
+ }
}
- void addLevelParam(int level) {
- EnvironmentalReverb er;
- er.set<EnvironmentalReverb::levelMb>(level);
- mTags.push_back({EnvironmentalReverb::levelMb, er});
- }
+ static constexpr int kSamplingFrequency = 44100;
+ static constexpr int kDurationMilliSec = 500;
+ static constexpr int kBufferSize = kSamplingFrequency * kDurationMilliSec / 1000;
- void addDelayParam(int delay) {
- EnvironmentalReverb er;
- er.set<EnvironmentalReverb::delayMs>(delay);
- mTags.push_back({EnvironmentalReverb::delayMs, er});
- }
+ int mStereoChannelCount =
+ getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+ AudioChannelLayout::LAYOUT_STEREO));
+ int mFrameCount = kBufferSize / mStereoChannelCount;
- void addDiffusionParam(int diffusion) {
- EnvironmentalReverb er;
- er.set<EnvironmentalReverb::diffusionPm>(diffusion);
- mTags.push_back({EnvironmentalReverb::diffusionPm, er});
- }
-
- void addDensityParam(int density) {
- EnvironmentalReverb er;
- er.set<EnvironmentalReverb::densityPm>(density);
- mTags.push_back({EnvironmentalReverb::densityPm, er});
- }
-
- void addBypassParam(bool bypass) {
- EnvironmentalReverb er;
- er.set<EnvironmentalReverb::bypass>(bypass);
- mTags.push_back({EnvironmentalReverb::bypass, er});
- }
-
- private:
- std::vector<std::pair<EnvironmentalReverb::Tag, EnvironmentalReverb>> mTags;
- void CleanUp() { mTags.clear(); }
+ std::shared_ptr<IFactory> mFactory;
+ std::shared_ptr<IEffect> mEffect;
+ IEffect::OpenEffectReturn ret;
+ Descriptor mDescriptor;
+ EnvironmentalReverb mEnvParam;
};
-class EnvironmentalReverbRoomLevelTest
+class EnvironmentalReverbParamTest
: public ::testing::TestWithParam<
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, TagValuePair>>,
public EnvironmentalReverbHelper {
public:
- EnvironmentalReverbRoomLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
- mRoomLevel = std::get<1>(GetParam());
+ EnvironmentalReverbParamTest()
+ : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
+ std::tie(mTag, mParamValue) = std::get<TAG_VALUE_PAIR>(GetParam());
}
-
void SetUp() override { SetUpReverb(); }
-
void TearDown() override { TearDownReverb(); }
+
+ EnvironmentalReverb::Tag mTag;
+ int mParamValue;
};
-TEST_P(EnvironmentalReverbRoomLevelTest, SetAndGetRoomLevel) {
- EXPECT_NO_FATAL_FAILURE(addRoomLevelParam());
- SetAndGetReverbParameters();
+TEST_P(EnvironmentalReverbParamTest, SetAndGetParameter) {
+ createEnvParam(mTag, mParamValue);
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParam(
+ isParamValid(mEnvParam) ? EX_NONE : EX_ILLEGAL_ARGUMENT, mEnvParam, mTag));
}
-std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
-
INSTANTIATE_TEST_SUITE_P(
- EnvironmentalReverbTest, EnvironmentalReverbRoomLevelTest,
+ EnvironmentalReverbTest, EnvironmentalReverbParamTest,
::testing::Combine(
testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, getEffectTypeUuidEnvReverb())),
- testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
- Range::environmentalReverb,
- EnvironmentalReverb::roomLevelMb>(
- kDescPair, EffectHelper::expandTestValueBasic<int>))),
- [](const testing::TestParamInfo<EnvironmentalReverbRoomLevelTest::ParamType>& info) {
- auto descriptor = std::get<0>(info.param).second;
- std::string roomLevel = std::to_string(std::get<1>(info.param));
-
- std::string name = getPrefix(descriptor) + "_roomLevel" + roomLevel;
+ testing::ValuesIn(buildSetAndGetTestParams())),
+ [](const testing::TestParamInfo<EnvironmentalReverbParamTest::ParamType>& info) {
+ auto descriptor = std::get<DESCRIPTOR_INDEX>(info.param).second;
+ auto tag = std::get<TAG_VALUE_PAIR>(info.param).first;
+ auto val = std::get<TAG_VALUE_PAIR>(info.param).second;
+ std::string name =
+ getPrefix(descriptor) + "_Tag_" + toString(tag) + std::to_string(val);
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
});
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomLevelTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbParamTest);
-class EnvironmentalReverbRoomHfLevelTest
+class EnvironmentalReverbDataTest
: public ::testing::TestWithParam<
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, TagVectorPair>>,
public EnvironmentalReverbHelper {
public:
- EnvironmentalReverbRoomHfLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
- mRoomHfLevel = std::get<1>(GetParam());
+ EnvironmentalReverbDataTest()
+ : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
+ std::tie(mTag, mParamValues) = std::get<TAG_VALUE_PAIR>(GetParam());
+ mInput.resize(kBufferSize);
+ generateSineWaveInput(mInput);
+ }
+ void SetUp() override { SetUpReverb(); }
+ void TearDown() override { TearDownReverb(); }
+
+ void assertEnergyIncreasingWithParameter(bool bypass) {
+ createEnvParam(EnvironmentalReverb::bypass, bypass);
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::bypass));
+ float baseEnergy = 0;
+ for (int val : mParamValues) {
+ std::vector<float> output(kBufferSize);
+ setParameterAndProcess(mInput, output, val, mTag);
+ float energy = computeOutputEnergy(mInput, output);
+ ASSERT_GT(energy, baseEnergy);
+ baseEnergy = energy;
+ }
}
- void SetUp() override { SetUpReverb(); }
+ void assertZeroEnergyWithBypass(bool bypass) {
+ createEnvParam(EnvironmentalReverb::bypass, bypass);
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::bypass));
+ for (int val : mParamValues) {
+ std::vector<float> output(kBufferSize);
+ setParameterAndProcess(mInput, output, val, mTag);
+ float energy = computeOutputEnergy(mInput, output);
+ ASSERT_EQ(energy, 0);
+ }
+ }
- void TearDown() override { TearDownReverb(); }
+ EnvironmentalReverb::Tag mTag;
+ std::vector<int> mParamValues;
+ std::vector<float> mInput;
};
-TEST_P(EnvironmentalReverbRoomHfLevelTest, SetAndGetRoomHfLevel) {
- EXPECT_NO_FATAL_FAILURE(addRoomHfLevelParam(mRoomHfLevel));
- SetAndGetReverbParameters();
+TEST_P(EnvironmentalReverbDataTest, IncreasingParamValue) {
+ assertEnergyIncreasingWithParameter(false);
+}
+
+TEST_P(EnvironmentalReverbDataTest, WithBypassEnabled) {
+ assertZeroEnergyWithBypass(true);
}
INSTANTIATE_TEST_SUITE_P(
- EnvironmentalReverbTest, EnvironmentalReverbRoomHfLevelTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidEnvReverb())),
- testing::ValuesIn(EffectHelper::getTestValueSet<
- EnvironmentalReverb, int, Range::environmentalReverb,
- EnvironmentalReverb::roomHfLevelMb>(
- kDescPair, EffectHelper::expandTestValueBasic<int>))),
- [](const testing::TestParamInfo<EnvironmentalReverbRoomHfLevelTest::ParamType>& info) {
- auto descriptor = std::get<0>(info.param).second;
- std::string roomHfLevel = std::to_string(std::get<1>(info.param));
-
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid) + "_roomHfLevel" + roomHfLevel;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ EnvironmentalReverbTest, EnvironmentalReverbDataTest,
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+ testing::ValuesIn(kParamsIncreasingVector)),
+ [](const testing::TestParamInfo<EnvironmentalReverbDataTest::ParamType>& info) {
+ auto descriptor = std::get<DESCRIPTOR_INDEX>(info.param).second;
+ auto tag = std::get<TAG_VALUE_PAIR>(info.param).first;
+ std::string name = getPrefix(descriptor) + "_Tag_" + toString(tag);
return name;
});
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbRoomHfLevelTest);
-class EnvironmentalReverbDecayTimeTest
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDataTest);
+
+class EnvironmentalReverbMinimumParamTest
: public ::testing::TestWithParam<
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, TagValuePair>>,
public EnvironmentalReverbHelper {
public:
- EnvironmentalReverbDecayTimeTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
- mDecayTime = std::get<1>(GetParam());
+ EnvironmentalReverbMinimumParamTest()
+ : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
+ std::tie(mTag, mValue) = std::get<TAG_VALUE_PAIR>(GetParam());
}
-
- void SetUp() override { SetUpReverb(); }
-
+ void SetUp() override {
+ SetUpReverb();
+ createEnvParam(EnvironmentalReverb::roomLevelMb, kMinRoomLevel);
+ ASSERT_NO_FATAL_FAILURE(
+ setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::roomLevelMb));
+ }
void TearDown() override { TearDownReverb(); }
+
+ EnvironmentalReverb::Tag mTag;
+ int mValue;
};
-TEST_P(EnvironmentalReverbDecayTimeTest, SetAndGetDecayTime) {
- EXPECT_NO_FATAL_FAILURE(addDecayTimeParam(mDecayTime));
- SetAndGetReverbParameters();
+TEST_P(EnvironmentalReverbMinimumParamTest, MinimumValueTest) {
+ std::vector<float> input(kBufferSize);
+ generateSineWaveInput(input);
+ std::vector<float> output(kBufferSize);
+ setParameterAndProcess(input, output, mValue, mTag);
+ float energy = computeOutputEnergy(input, output);
+ // No Auxiliary output for minimum param values
+ ASSERT_EQ(energy, 0);
}
INSTANTIATE_TEST_SUITE_P(
- EnvironmentalReverbTest, EnvironmentalReverbDecayTimeTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidEnvReverb())),
- testing::ValuesIn(EffectHelper::getTestValueSet<
- EnvironmentalReverb, int, Range::environmentalReverb,
- EnvironmentalReverb::decayTimeMs>(
- kDescPair, EffectHelper::expandTestValueBasic<int>))),
- [](const testing::TestParamInfo<EnvironmentalReverbDecayTimeTest::ParamType>& info) {
- auto descriptor = std::get<0>(info.param).second;
- std::string decayTime = std::to_string(std::get<1>(info.param));
-
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid) + "_decayTime" + decayTime;
+ EnvironmentalReverbTest, EnvironmentalReverbMinimumParamTest,
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidEnvReverb())),
+ testing::ValuesIn(kParamsMinimumValue)),
+ [](const testing::TestParamInfo<EnvironmentalReverbMinimumParamTest::ParamType>& info) {
+ auto descriptor = std::get<DESCRIPTOR_INDEX>(info.param).second;
+ auto tag = std::get<TAG_VALUE_PAIR>(info.param).first;
+ auto val = std::get<TAG_VALUE_PAIR>(info.param).second;
+ std::string name =
+ getPrefix(descriptor) + "_Tag_" + toString(tag) + std::to_string(val);
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
});
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayTimeTest);
-class EnvironmentalReverbDecayHfRatioTest
- : public ::testing::TestWithParam<
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
- public EnvironmentalReverbHelper {
- public:
- EnvironmentalReverbDecayHfRatioTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
- mDecayHfRatio = std::get<1>(GetParam());
- }
-
- void SetUp() override { SetUpReverb(); }
-
- void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbDecayHfRatioTest, SetAndGetDecayHfRatio) {
- EXPECT_NO_FATAL_FAILURE(addDecayHfRatioParam(mDecayHfRatio));
- SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- EnvironmentalReverbTest, EnvironmentalReverbDecayHfRatioTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidEnvReverb())),
- testing::ValuesIn(EffectHelper::getTestValueSet<
- EnvironmentalReverb, int, Range::environmentalReverb,
- EnvironmentalReverb::decayHfRatioPm>(
- kDescPair, EffectHelper::expandTestValueBasic<int>))),
- [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
- auto descriptor = std::get<0>(info.param).second;
- std::string decayHfRatio = std::to_string(std::get<1>(info.param));
-
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid) + "_decayHfRatio" + decayHfRatio;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
- return name;
- });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDecayHfRatioTest);
-
-class EnvironmentalReverbLevelTest
- : public ::testing::TestWithParam<
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
- public EnvironmentalReverbHelper {
- public:
- EnvironmentalReverbLevelTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
- mLevel = std::get<1>(GetParam());
- }
-
- void SetUp() override { SetUpReverb(); }
-
- void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbLevelTest, SetAndGetLevel) {
- EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
- SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- EnvironmentalReverbTest, EnvironmentalReverbLevelTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidEnvReverb())),
- testing::ValuesIn(EffectHelper::getTestValueSet<
- EnvironmentalReverb, int, Range::environmentalReverb,
- EnvironmentalReverb::levelMb>(
- kDescPair, EffectHelper::expandTestValueBasic<int>))),
- [](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
- auto descriptor = std::get<0>(info.param).second;
- std::string level = std::to_string(std::get<1>(info.param));
-
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid) + "_level" + level;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
- return name;
- });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbLevelTest);
-
-class EnvironmentalReverbDelayTest
- : public ::testing::TestWithParam<
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
- public EnvironmentalReverbHelper {
- public:
- EnvironmentalReverbDelayTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
- mDelay = std::get<1>(GetParam());
- }
-
- void SetUp() override { SetUpReverb(); }
-
- void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbDelayTest, SetAndGetDelay) {
- EXPECT_NO_FATAL_FAILURE(addDelayParam(mDelay));
- SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- EnvironmentalReverbTest, EnvironmentalReverbDelayTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidEnvReverb())),
- testing::ValuesIn(EffectHelper::getTestValueSet<
- EnvironmentalReverb, int, Range::environmentalReverb,
- EnvironmentalReverb::delayMs>(
- kDescPair, EffectHelper::expandTestValueBasic<int>))),
- [](const testing::TestParamInfo<EnvironmentalReverbDelayTest::ParamType>& info) {
- auto descriptor = std::get<0>(info.param).second;
- std::string delay = std::to_string(std::get<1>(info.param));
-
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid) + "_delay" + delay;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
- return name;
- });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDelayTest);
-
-class EnvironmentalReverbDiffusionTest
- : public ::testing::TestWithParam<
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
- public EnvironmentalReverbHelper {
- public:
- EnvironmentalReverbDiffusionTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
- mDiffusion = std::get<1>(GetParam());
- }
-
- void SetUp() override { SetUpReverb(); }
-
- void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbDiffusionTest, SetAndGetDiffusion) {
- EXPECT_NO_FATAL_FAILURE(addDiffusionParam(mDiffusion));
- SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- EnvironmentalReverbTest, EnvironmentalReverbDiffusionTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidEnvReverb())),
- testing::ValuesIn(EffectHelper::getTestValueSet<
- EnvironmentalReverb, int, Range::environmentalReverb,
- EnvironmentalReverb::diffusionPm>(
- kDescPair, EffectHelper::expandTestValueBasic<int>))),
- [](const testing::TestParamInfo<EnvironmentalReverbDiffusionTest::ParamType>& info) {
- auto descriptor = std::get<0>(info.param).second;
- std::string diffusion = std::to_string(std::get<1>(info.param));
-
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid) + "_diffusion" + diffusion;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
- return name;
- });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDiffusionTest);
-
-class EnvironmentalReverbDensityTest
- : public ::testing::TestWithParam<
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>>,
- public EnvironmentalReverbHelper {
- public:
- EnvironmentalReverbDensityTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
- mDensity = std::get<1>(GetParam());
- }
-
- void SetUp() override { SetUpReverb(); }
-
- void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbDensityTest, SetAndGetDensity) {
- EXPECT_NO_FATAL_FAILURE(addDensityParam(mDensity));
- SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- EnvironmentalReverbTest, EnvironmentalReverbDensityTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidEnvReverb())),
- testing::ValuesIn(EffectHelper::getTestValueSet<
- EnvironmentalReverb, int, Range::environmentalReverb,
- EnvironmentalReverb::densityPm>(
- kDescPair, EffectHelper::expandTestValueBasic<int>))),
- [](const testing::TestParamInfo<EnvironmentalReverbDensityTest::ParamType>& info) {
- auto descriptor = std::get<0>(info.param).second;
- std::string density = std::to_string(std::get<1>(info.param));
-
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid) + "_density" + density;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
- return name;
- });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbDensityTest);
-
-class EnvironmentalReverbBypassTest
- : public ::testing::TestWithParam<
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, bool>>,
- public EnvironmentalReverbHelper {
- public:
- EnvironmentalReverbBypassTest() : EnvironmentalReverbHelper(std::get<0>(GetParam())) {
- mBypass = std::get<1>(GetParam());
- }
-
- void SetUp() override { SetUpReverb(); }
-
- void TearDown() override { TearDownReverb(); }
-};
-
-TEST_P(EnvironmentalReverbBypassTest, SetAndGetBypass) {
- EXPECT_NO_FATAL_FAILURE(addBypassParam(mBypass));
- SetAndGetReverbParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- EnvironmentalReverbTest, EnvironmentalReverbBypassTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidEnvReverb())),
- testing::Bool()),
- [](const testing::TestParamInfo<EnvironmentalReverbBypassTest::ParamType>& info) {
- auto descriptor = std::get<0>(info.param).second;
- std::string bypass = std::to_string(std::get<1>(info.param));
-
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid) + "_bypass" + bypass;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
- return name;
- });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbBypassTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EnvironmentalReverbMinimumParamTest);
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
index b0ea260..e35feee 100644
--- a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
@@ -22,6 +22,7 @@
#include <libprotocan/MessageDef.h>
#include <utils/Mutex.h>
+#include <mutex>
#include <queue>
namespace android::hardware::automotive::protocan {
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 951ca85..ad42015 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -92,3 +92,25 @@
],
}
+
+// Phony target that installs all system compatibility matrix files
+SYSTEM_MATRIX_DEPS = [
+ "framework_compatibility_matrix.5.xml",
+ "framework_compatibility_matrix.6.xml",
+ "framework_compatibility_matrix.7.xml",
+ "framework_compatibility_matrix.8.xml",
+ "framework_compatibility_matrix.202404.xml",
+ "framework_compatibility_matrix.device.xml",
+]
+
+phony {
+ name: "system_compatibility_matrix.xml",
+ required: SYSTEM_MATRIX_DEPS,
+ product_variables: {
+ release_aidl_use_unfrozen: {
+ required: [
+ "framework_compatibility_matrix.202504.xml",
+ ],
+ },
+ },
+}
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index ab57b8c..338c075 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -119,15 +119,6 @@
my_framework_matrix_deps += \
$(my_system_matrix_deps)
-# Phony target that installs all system compatibility matrix files
-include $(CLEAR_VARS)
-LOCAL_MODULE := system_compatibility_matrix.xml
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-LOCAL_REQUIRED_MODULES := $(my_system_matrix_deps)
-include $(BUILD_PHONY_PACKAGE)
-
# Phony target that installs all framework compatibility matrix files (system + product)
include $(CLEAR_VARS)
LOCAL_MODULE := framework_compatibility_matrix.xml
diff --git a/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl b/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl
index 92328a8..dcce7ef 100644
--- a/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl
+++ b/confirmationui/aidl/android/hardware/confirmationui/IConfirmationResultCallback.aidl
@@ -38,15 +38,15 @@
* prevented the TUI from being shut down gracefully.
*
* @param formattedMessage holds the prompt text and extra data.
- * The message is CBOR (RFC 7049) encoded and has the following format:
- * CBOR_MAP{ "prompt", <promptText>, "extra", <extraData> }
- * The message is a CBOR encoded map (type 5) with the keys
- * "prompt" and "extra". The keys are encoded as CBOR text string
- * (type 3). The value <promptText> is encoded as CBOR text string
- * (type 3), and the value <extraData> is encoded as CBOR byte string
- * (type 2). The map must have exactly one key value pair for each of
- * the keys "prompt" and "extra". Other keys are not allowed.
- * The value of "prompt" is given by the proptText argument to
+ * The message is CBOR (RFC 7049) encoded and has the exact format
+ * given by the following CDDL:
+ *
+ * formattedMessage = {
+ * "prompt" : tstr,
+ * "extra" : bstr,
+ * }
+ *
+ * The value of "prompt" is given by the promptText argument to
* IConfirmationUI::promptUserConfirmation and must not be modified
* by the implementation.
* The value of "extra" is given by the extraData argument to
@@ -59,8 +59,7 @@
* the "", concatenated with the formatted message as returned in the
* formattedMessage argument. The HMAC is keyed with a 256-bit secret
* which is shared with Keymaster. In test mode the test key MUST be
- * used (see TestModeCommands.aidl and
- * IConfirmationUI::TEST_KEY_BYTE).
+ * used (see TestModeCommands.aidl and IConfirmationUI::TEST_KEY_BYTE)
*/
void result(in int error, in byte[] formattedMessage, in byte[] confirmationToken);
}
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 7fbca36..5106561 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -16,7 +16,6 @@
#define LOG_TAG "keymint_1_attest_key_test"
#include <android-base/logging.h>
-#include <android-base/strings.h>
#include <cutils/log.h>
#include <cutils/properties.h>
@@ -29,66 +28,12 @@
namespace aidl::android::hardware::security::keymint::test {
namespace {
-string TELEPHONY_CMD_GET_IMEI = "cmd phone get-imei ";
bool IsSelfSigned(const vector<Certificate>& chain) {
if (chain.size() != 1) return false;
return ChainSignaturesAreValid(chain);
}
-/*
- * Run a shell command and collect the output of it. If any error, set an empty string as the
- * output.
- */
-string exec_command(string command) {
- char buffer[128];
- string result = "";
-
- FILE* pipe = popen(command.c_str(), "r");
- if (!pipe) {
- LOG(ERROR) << "popen failed.";
- return result;
- }
-
- // read till end of process:
- while (!feof(pipe)) {
- if (fgets(buffer, 128, pipe) != NULL) {
- result += buffer;
- }
- }
-
- pclose(pipe);
- return result;
-}
-
-/*
- * Get IMEI using Telephony service shell command. If any error while executing the command
- * then empty string will be returned as output.
- */
-string get_imei(int slot) {
- string cmd = TELEPHONY_CMD_GET_IMEI + std::to_string(slot);
- string output = exec_command(cmd);
-
- if (output.empty()) {
- LOG(ERROR) << "Command failed. Cmd: " << cmd;
- return "";
- }
-
- vector<string> out = ::android::base::Tokenize(::android::base::Trim(output), "Device IMEI:");
-
- if (out.size() != 1) {
- LOG(ERROR) << "Error in parsing the command output. Cmd: " << cmd;
- return "";
- }
-
- string imei = ::android::base::Trim(out[0]);
- if (imei.compare("null") == 0) {
- LOG(WARNING) << "Failed to get IMEI from Telephony service: value is null. Cmd: " << cmd;
- return "";
- }
-
- return imei;
-}
} // namespace
class AttestKeyTest : public KeyMintAidlTestBase {
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 332fcd4..cef8120 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -26,6 +26,7 @@
#include "keymint_support/keymint_tags.h"
#include <android-base/logging.h>
+#include <android-base/strings.h>
#include <android/binder_manager.h>
#include <android/content/pm/IPackageManagerNative.h>
#include <cppbor_parse.h>
@@ -1588,7 +1589,7 @@
// with any other key purpose, but the original VTS tests incorrectly did exactly that.
// This means that a device that launched prior to Android T (API level 33) may
// accept or even require KeyPurpose::SIGN too.
- if (property_get_int32("ro.board.first_api_level", 0) < __ANDROID_API_T__) {
+ if (get_vsr_api_level() < __ANDROID_API_T__) {
AuthorizationSet key_desc_plus_sign = key_desc;
key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN);
@@ -2337,6 +2338,67 @@
return result;
}
+namespace {
+
+std::string TELEPHONY_CMD_GET_IMEI = "cmd phone get-imei ";
+
+/*
+ * Run a shell command and collect the output of it. If any error, set an empty string as the
+ * output.
+ */
+std::string exec_command(const std::string& command) {
+ char buffer[128];
+ std::string result = "";
+
+ FILE* pipe = popen(command.c_str(), "r");
+ if (!pipe) {
+ LOG(ERROR) << "popen failed.";
+ return result;
+ }
+
+ // read till end of process:
+ while (!feof(pipe)) {
+ if (fgets(buffer, 128, pipe) != NULL) {
+ result += buffer;
+ }
+ }
+
+ pclose(pipe);
+ return result;
+}
+
+} // namespace
+
+/*
+ * Get IMEI using Telephony service shell command. If any error while executing the command
+ * then empty string will be returned as output.
+ */
+std::string get_imei(int slot) {
+ std::string cmd = TELEPHONY_CMD_GET_IMEI + std::to_string(slot);
+ std::string output = exec_command(cmd);
+
+ if (output.empty()) {
+ LOG(ERROR) << "Command failed. Cmd: " << cmd;
+ return "";
+ }
+
+ vector<std::string> out =
+ ::android::base::Tokenize(::android::base::Trim(output), "Device IMEI:");
+
+ if (out.size() != 1) {
+ LOG(ERROR) << "Error in parsing the command output. Cmd: " << cmd;
+ return "";
+ }
+
+ std::string imei = ::android::base::Trim(out[0]);
+ if (imei.compare("null") == 0) {
+ LOG(WARNING) << "Failed to get IMEI from Telephony service: value is null. Cmd: " << cmd;
+ return "";
+ }
+
+ return imei;
+}
+
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index b884cc7..1bf2d9d 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -430,6 +430,7 @@
void device_id_attestation_check_acceptable_error(Tag tag, const ErrorCode& result);
bool check_feature(const std::string& name);
std::optional<int32_t> keymint_feature_value(bool strongbox);
+std::string get_imei(int slot);
AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 35e5e84..3c49a82 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -2026,7 +2026,7 @@
* NewKeyGenerationTest.EcdsaAttestationIdTags
*
* Verifies that creation of an attested ECDSA key includes various ID tags in the
- * attestation extension.
+ * attestation extension one by one.
*/
TEST_P(NewKeyGenerationTest, EcdsaAttestationIdTags) {
auto challenge = "hello";
@@ -2054,6 +2054,15 @@
add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_MANUFACTURER, "manufacturer");
add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_MODEL, "model");
add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
+ string imei = get_imei(0);
+ if (!imei.empty()) {
+ extra_tags.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
+ }
+ string second_imei = get_imei(1);
+ if (!second_imei.empty()) {
+ extra_tags.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(),
+ second_imei.size());
+ }
for (const KeyParameter& tag : extra_tags) {
SCOPED_TRACE(testing::Message() << "tag-" << tag);
@@ -2091,6 +2100,83 @@
}
/*
+ * NewKeyGenerationTest.EcdsaAttestationIdAllTags
+ *
+ * Verifies that creation of an attested ECDSA key includes various ID tags in the
+ * attestation extension all together.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaAttestationIdAllTags) {
+ auto challenge = "hello";
+ auto app_id = "foo";
+ auto subject = "cert subj 2";
+ vector<uint8_t> subject_der(make_name_from_str(subject));
+ uint64_t serial_int = 0x1010;
+ vector<uint8_t> serial_blob(build_serial_blob(serial_int));
+ AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Digest(Digest::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity();
+
+ // Various ATTESTATION_ID_* tags that map to fields in the attestation extension ASN.1 schema.
+ auto extra_tags = AuthorizationSetBuilder();
+ add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_BRAND, "brand");
+ add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_DEVICE, "device");
+ add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_PRODUCT, "name");
+ add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_MANUFACTURER, "manufacturer");
+ add_attestation_id(&extra_tags, TAG_ATTESTATION_ID_MODEL, "model");
+ add_tag_from_prop(&extra_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
+ string imei = get_imei(0);
+ if (!imei.empty()) {
+ extra_tags.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
+ }
+ string second_imei = get_imei(1);
+ if (!second_imei.empty()) {
+ extra_tags.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(),
+ second_imei.size());
+ }
+ for (const KeyParameter& tag : extra_tags) {
+ builder.push_back(tag);
+ }
+
+ vector<uint8_t> key_blob;
+ vector<KeyCharacteristics> key_characteristics;
+ auto result = GenerateKey(builder, &key_blob, &key_characteristics);
+ if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
+ // ID attestation was optional till api level 32, from api level 33 it is mandatory.
+ return;
+ }
+ ASSERT_EQ(result, ErrorCode::OK);
+ KeyBlobDeleter deleter(keymint_, key_blob);
+ ASSERT_GT(key_blob.size(), 0U);
+
+ EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+ ASSERT_GT(cert_chain_.size(), 0);
+ verify_subject_and_serial(cert_chain_[0], serial_int, subject, /* self_signed = */ false);
+
+ AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
+ AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+
+ // The attested key characteristics will not contain APPLICATION_ID_* fields (their
+ // spec definitions all have "Must never appear in KeyCharacteristics"), but the
+ // attestation extension should contain them, so make sure the extra tags are added.
+ for (const KeyParameter& tag : extra_tags) {
+ hw_enforced.push_back(tag);
+ }
+
+ // Verifying the attestation record will check for the specific tag because
+ // it's included in the authorizations.
+ EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
+ hw_enforced, SecLevel(),
+ cert_chain_[0].encodedCertificate))
+ << "failed to verify " << bin2hex(cert_chain_[0].encodedCertificate);
+}
+
+/*
* NewKeyGenerationTest.EcdsaAttestationUniqueId
*
* Verifies that creation of an attested ECDSA key with a UNIQUE_ID included.
diff --git a/security/keymint/support/fuzzer/Android.bp b/security/keymint/support/fuzzer/Android.bp
new file mode 100644
index 0000000..1b1a580
--- /dev/null
+++ b/security/keymint/support/fuzzer/Android.bp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 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.
+ *
+ */
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+ default_team: "trendy_team_android_hardware_backed_security",
+}
+
+cc_defaults {
+ name: "keymint_fuzzer_defaults",
+ static_libs: [
+ "libhidlbase",
+ "libkeymint_support",
+ ],
+ shared_libs: [
+ "libbase",
+ "libcrypto",
+ "libutils",
+ "libhardware",
+ "libbinder_ndk",
+ "liblog",
+ ],
+ defaults: [
+ "keymint_use_latest_hal_aidl_ndk_shared",
+ ],
+ include_dirs: [
+ "hardware/interfaces/security/keymint/support/include",
+ "frameworks/native/libs/binder/ndk/include_platform",
+ ],
+}
+
+cc_fuzz {
+ name: "keymint_attestation_fuzzer",
+ srcs: [
+ "keymint_attestation_fuzzer.cpp",
+ ],
+ defaults: [
+ "keymint_fuzzer_defaults",
+ ],
+}
+
+cc_fuzz {
+ name: "keymint_authSet_fuzzer",
+ srcs: [
+ "keymint_authSet_fuzzer.cpp",
+ ],
+ defaults: [
+ "keymint_fuzzer_defaults",
+ ],
+}
diff --git a/security/keymint/support/fuzzer/README.md b/security/keymint/support/fuzzer/README.md
new file mode 100644
index 0000000..d41af08
--- /dev/null
+++ b/security/keymint/support/fuzzer/README.md
@@ -0,0 +1,79 @@
+# Fuzzers for libkeymint_support
+
+## Plugin Design Considerations
+The fuzzer plugins for libkeymint_support are designed based on the understanding of the source code and try to achieve the following:
+
+#### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on incoming data. This ensures more code paths are reached by the fuzzers.
+
+#### Maximize utilization of input data
+The plugins feed the entire input data to the module. This ensures that the plugins tolerate any kind of input (empty, huge, malformed, etc) and dont `exit()` on any input and thereby increasing the chance of identifying vulnerabilities.
+
+## Table of contents
++ [keymint_attestation_fuzzer](#KeyMintAttestation)
++ [keymint_authSet_fuzzer](#KeyMintAuthSet)
+
+# <a name="KeyMintAttestation"></a> Fuzzer for KeyMintAttestation
+KeyMintAttestation supports the following parameters:
+1. PaddingMode(parameter name: "padding")
+2. Digest(parameter name: "digest")
+3. Index(parameter name: "idx")
+4. Timestamp(parameter name: "timestamp")
+5. AuthSet(parameter name: "authSet")
+6. IssuerSubjectName(parameter name: "issuerSubjectName")
+7. AttestationChallenge(parameter name: "challenge")
+8. AttestationApplicationId(parameter name: "id")
+9. EcCurve(parameter name: "ecCurve")
+10. BlockMode(parameter name: "blockmode")
+11. minMacLength(parameter name: "minMacLength")
+12. macLength(parameter name: "macLength")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |--------------| -------------------- |
+|`padding`| `PaddingMode` |Value obtained from FuzzedDataProvider|
+|`digest`| `Digest` |Value obtained from FuzzedDataProvider|
+|`idx`| `size_t` |Value obtained from FuzzedDataProvider|
+|`timestamp`| `uint64_t` |Value obtained from FuzzedDataProvider|
+|`authSet`| `uint32_t` |Value obtained from FuzzedDataProvider|
+|`issuerSubjectName`| `uint8_t` |Value obtained from FuzzedDataProvider|
+|`AttestationChallenge`| `string` |Value obtained from FuzzedDataProvider|
+|`AttestationApplicationId`| `string` |Value obtained from FuzzedDataProvider|
+|`blockmode`| `BlockMode` |Value obtained from FuzzedDataProvider|
+|`minMacLength`| `uint32_t` |Value obtained from FuzzedDataProvider|
+|`macLength`| `uint32_t` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+$ mm -j$(nproc) keymint_attestation_fuzzer
+```
+2. Run on device
+```
+$ adb sync data
+$ adb shell /data/fuzz/arm64/keymint_attestation_fuzzer/keymint_attestation_fuzzer
+```
+
+# <a name="KeyMintAuthSet"></a> Fuzzer for KeyMintAuthSet
+KeyMintAuthSet supports the following parameters:
+1. AuthorizationSet(parameter name: "authSet")
+2. AuthorizationSet(parameter name: "params")
+3. KeyParameters(parameter name: "numKeyParam")
+4. Tag(parameter name: "tag")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |--------------| -------------------- |
+|`authSet`| `AuthorizationSet` |Value obtained from FuzzedDataProvider|
+|`params`| `AuthorizationSet` |Value obtained from FuzzedDataProvider|
+|`numKeyParam`| `size_t` |Value obtained from FuzzedDataProvider|
+|`tag`| `Tag` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+$ mm -j$(nproc) keymint_authSet_fuzzer
+```
+2. Run on device
+```
+$ adb sync data
+$ adb shell /data/fuzz/arm64/keymint_authSet_fuzzer/keymint_authSet_fuzzer
+```
diff --git a/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp b/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
new file mode 100644
index 0000000..bd781ac
--- /dev/null
+++ b/security/keymint/support/fuzzer/keymint_attestation_fuzzer.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2024 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 <aidl/android/hardware/security/keymint/AttestationKey.h>
+#include <aidl/android/hardware/security/keymint/KeyCreationResult.h>
+#include <android/binder_manager.h>
+#include <keymint_common.h>
+#include <keymint_support/attestation_record.h>
+#include <keymint_support/openssl_utils.h>
+#include <utils/Log.h>
+
+namespace android::hardware::security::keymint_support::fuzzer {
+using namespace android;
+using AStatus = ::ndk::ScopedAStatus;
+std::shared_ptr<IKeyMintDevice> gKeyMint = nullptr;
+
+constexpr size_t kMaxBytes = 256;
+const std::string kServiceName = "android.hardware.security.keymint.IKeyMintDevice/default";
+
+class KeyMintAttestationFuzzer {
+ public:
+ KeyMintAttestationFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+ private:
+ KeyCreationResult generateKey(const AuthorizationSet& keyDesc,
+ const std::optional<AttestationKey>& attestKey,
+ vector<uint8_t>* keyBlob,
+ vector<KeyCharacteristics>* keyCharacteristics,
+ vector<Certificate>* certChain);
+ X509_Ptr parseCertificateBlob(const vector<uint8_t>& blob);
+ ASN1_OCTET_STRING* getAttestationRecord(const X509* certificate);
+ bool verifyAttestationRecord(const vector<uint8_t>& attestationCert);
+ FuzzedDataProvider mFdp;
+};
+
+KeyCreationResult KeyMintAttestationFuzzer::generateKey(
+ const AuthorizationSet& keyDesc, const std::optional<AttestationKey>& attestKey,
+ vector<uint8_t>* keyBlob, vector<KeyCharacteristics>* keyCharacteristics,
+ vector<Certificate>* certChain) {
+ KeyCreationResult creationResult;
+ AStatus result = gKeyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
+ if (result.isOk() && creationResult.keyBlob.size() > 0) {
+ *keyBlob = std::move(creationResult.keyBlob);
+ *keyCharacteristics = std::move(creationResult.keyCharacteristics);
+ *certChain = std::move(creationResult.certificateChain);
+ }
+ return creationResult;
+}
+
+X509_Ptr KeyMintAttestationFuzzer::parseCertificateBlob(const vector<uint8_t>& blob) {
+ const uint8_t* data = blob.data();
+ return X509_Ptr(d2i_X509(nullptr, &data, blob.size()));
+}
+
+ASN1_OCTET_STRING* KeyMintAttestationFuzzer::getAttestationRecord(const X509* certificate) {
+ ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
+ if (!oid.get()) {
+ return nullptr;
+ }
+
+ int32_t location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
+ if (location == -1) {
+ return nullptr;
+ }
+
+ X509_EXTENSION* attestRecordExt = X509_get_ext(certificate, location);
+ if (!attestRecordExt) {
+ return nullptr;
+ }
+
+ ASN1_OCTET_STRING* attestRecord = X509_EXTENSION_get_data(attestRecordExt);
+ return attestRecord;
+}
+
+bool KeyMintAttestationFuzzer::verifyAttestationRecord(const vector<uint8_t>& attestationCert) {
+ X509_Ptr cert(parseCertificateBlob(attestationCert));
+ if (!cert.get()) {
+ return false;
+ }
+
+ ASN1_OCTET_STRING* attestRecord = getAttestationRecord(cert.get());
+ if (!attestRecord) {
+ return false;
+ }
+
+ AuthorizationSet attestationSwEnforced;
+ AuthorizationSet attestationHwEnforced;
+ SecurityLevel attestationSecurityLevel;
+ SecurityLevel keymintSecurityLevel;
+ vector<uint8_t> attestationChallenge;
+ vector<uint8_t> attestationUniqueId;
+ uint32_t attestationVersion;
+ uint32_t keymintVersion;
+
+ auto error = parse_attestation_record(attestRecord->data, attestRecord->length,
+ &attestationVersion, &attestationSecurityLevel,
+ &keymintVersion, &keymintSecurityLevel,
+ &attestationChallenge, &attestationSwEnforced,
+ &attestationHwEnforced, &attestationUniqueId);
+ if (error != ErrorCode::OK) {
+ return false;
+ }
+
+ VerifiedBoot verifiedBootState;
+ vector<uint8_t> verifiedBootKey;
+ vector<uint8_t> verifiedBootHash;
+ bool device_locked;
+
+ error = parse_root_of_trust(attestRecord->data, attestRecord->length, &verifiedBootKey,
+ &verifiedBootState, &device_locked, &verifiedBootHash);
+ if (error != ErrorCode::OK) {
+ return false;
+ }
+ return true;
+}
+
+void KeyMintAttestationFuzzer::process() {
+ AttestationKey attestKey;
+ vector<Certificate> attestKeyCertChain;
+ vector<KeyCharacteristics> attestKeyCharacteristics;
+ generateKey(createAuthSetForAttestKey(&mFdp), {}, &attestKey.keyBlob, &attestKeyCharacteristics,
+ &attestKeyCertChain);
+
+ vector<Certificate> attestedKeyCertChain;
+ vector<KeyCharacteristics> attestedKeyCharacteristics;
+ vector<uint8_t> attestedKeyBlob;
+ attestKey.issuerSubjectName = mFdp.ConsumeBytes<uint8_t>(kMaxBytes);
+ generateKey(createAuthorizationSet(&mFdp), attestKey, &attestedKeyBlob,
+ &attestedKeyCharacteristics, &attestedKeyCertChain);
+
+ if (attestedKeyCertChain.size() > 0) {
+ size_t leafCert = attestedKeyCertChain.size() - 1;
+ verifyAttestationRecord(attestedKeyCertChain[leafCert].encodedCertificate);
+ }
+}
+
+extern "C" int LLVMFuzzerInitialize(int /* *argc */, char /* ***argv */) {
+ ::ndk::SpAIBinder binder(AServiceManager_waitForService(kServiceName.c_str()));
+ gKeyMint = std::move(IKeyMintDevice::fromBinder(binder));
+ LOG_ALWAYS_FATAL_IF(!gKeyMint, "Failed to get IKeyMintDevice instance.");
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ KeyMintAttestationFuzzer kmAttestationFuzzer(data, size);
+ kmAttestationFuzzer.process();
+ return 0;
+}
+
+} // namespace android::hardware::security::keymint_support::fuzzer
diff --git a/security/keymint/support/fuzzer/keymint_authSet_fuzzer.cpp b/security/keymint/support/fuzzer/keymint_authSet_fuzzer.cpp
new file mode 100644
index 0000000..fcc3d91
--- /dev/null
+++ b/security/keymint/support/fuzzer/keymint_authSet_fuzzer.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2024 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 <keymint_common.h>
+#include <fstream>
+
+namespace android::hardware::security::keymint_support::fuzzer {
+
+constexpr size_t kMinAction = 0;
+constexpr size_t kMaxAction = 10;
+constexpr size_t kMinKeyParameter = 1;
+constexpr size_t kMaxKeyParameter = 10;
+
+constexpr Tag kTagArray[] = {Tag::INVALID,
+ Tag::PURPOSE,
+ Tag::ALGORITHM,
+ Tag::KEY_SIZE,
+ Tag::BLOCK_MODE,
+ Tag::DIGEST,
+ Tag::PADDING,
+ Tag::CALLER_NONCE,
+ Tag::MIN_MAC_LENGTH,
+ Tag::EC_CURVE,
+ Tag::RSA_PUBLIC_EXPONENT,
+ Tag::INCLUDE_UNIQUE_ID,
+ Tag::RSA_OAEP_MGF_DIGEST,
+ Tag::BOOTLOADER_ONLY,
+ Tag::ROLLBACK_RESISTANCE,
+ Tag::HARDWARE_TYPE,
+ Tag::EARLY_BOOT_ONLY,
+ Tag::ACTIVE_DATETIME,
+ Tag::ORIGINATION_EXPIRE_DATETIME,
+ Tag::USAGE_EXPIRE_DATETIME,
+ Tag::MIN_SECONDS_BETWEEN_OPS,
+ Tag::MAX_USES_PER_BOOT,
+ Tag::USAGE_COUNT_LIMIT,
+ Tag::USER_ID,
+ Tag::USER_SECURE_ID,
+ Tag::NO_AUTH_REQUIRED,
+ Tag::USER_AUTH_TYPE,
+ Tag::AUTH_TIMEOUT,
+ Tag::ALLOW_WHILE_ON_BODY,
+ Tag::TRUSTED_USER_PRESENCE_REQUIRED,
+ Tag::TRUSTED_CONFIRMATION_REQUIRED,
+ Tag::UNLOCKED_DEVICE_REQUIRED,
+ Tag::APPLICATION_ID,
+ Tag::APPLICATION_DATA,
+ Tag::CREATION_DATETIME,
+ Tag::ORIGIN,
+ Tag::ROOT_OF_TRUST,
+ Tag::OS_VERSION,
+ Tag::OS_PATCHLEVEL,
+ Tag::UNIQUE_ID,
+ Tag::ATTESTATION_CHALLENGE,
+ Tag::ATTESTATION_APPLICATION_ID,
+ Tag::ATTESTATION_ID_BRAND,
+ Tag::ATTESTATION_ID_DEVICE,
+ Tag::ATTESTATION_ID_PRODUCT,
+ Tag::ATTESTATION_ID_SERIAL,
+ Tag::ATTESTATION_ID_IMEI,
+ Tag::ATTESTATION_ID_MEID,
+ Tag::ATTESTATION_ID_MANUFACTURER,
+ Tag::ATTESTATION_ID_MODEL,
+ Tag::VENDOR_PATCHLEVEL,
+ Tag::BOOT_PATCHLEVEL,
+ Tag::DEVICE_UNIQUE_ATTESTATION,
+ Tag::IDENTITY_CREDENTIAL_KEY,
+ Tag::STORAGE_KEY,
+ Tag::ASSOCIATED_DATA,
+ Tag::NONCE,
+ Tag::MAC_LENGTH,
+ Tag::RESET_SINCE_ID_ROTATION,
+ Tag::CONFIRMATION_TOKEN,
+ Tag::CERTIFICATE_SERIAL,
+ Tag::CERTIFICATE_SUBJECT,
+ Tag::CERTIFICATE_NOT_BEFORE,
+ Tag::CERTIFICATE_NOT_AFTER,
+ Tag::MAX_BOOT_LEVEL};
+
+class KeyMintAuthSetFuzzer {
+ public:
+ KeyMintAuthSetFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+ private:
+ FuzzedDataProvider mFdp;
+};
+
+void KeyMintAuthSetFuzzer::process() {
+ AuthorizationSet authSet = createAuthorizationSet(&mFdp);
+ while (mFdp.remaining_bytes()) {
+ auto invokeAuthSetAPI = mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { authSet.Sort(); },
+ [&]() { authSet.Deduplicate(); },
+ [&]() { authSet.Union(createAuthorizationSet(&mFdp)); },
+ [&]() { authSet.Subtract(createAuthorizationSet(&mFdp)); },
+ [&]() { // invoke push_back()
+ AuthorizationSetBuilder builder = AuthorizationSetBuilder();
+ for (const KeyParameter& tag : authSet) {
+ builder.push_back(tag);
+ }
+ AuthorizationSet params = createAuthorizationSet(&mFdp);
+ authSet.push_back(params);
+ },
+ [&]() { // invoke copy constructor
+ auto params = AuthorizationSetBuilder().Authorizations(authSet);
+ authSet = params;
+ },
+ [&]() { // invoke move constructor
+ auto params = AuthorizationSetBuilder().Authorizations(authSet);
+ authSet = std::move(params);
+ },
+ [&]() { // invoke Constructor from vector<KeyParameter>
+ vector<KeyParameter> keyParam;
+ size_t numKeyParam =
+ mFdp.ConsumeIntegralInRange<size_t>(kMinKeyParameter, kMaxKeyParameter);
+ keyParam.resize(numKeyParam);
+ for (size_t idx = 0; idx < numKeyParam - 1; ++idx) {
+ keyParam[idx].tag = mFdp.PickValueInArray(kTagArray);
+ }
+ if (mFdp.ConsumeBool()) {
+ AuthorizationSet auths(keyParam);
+ auths.push_back(AuthorizationSet(keyParam));
+ } else { // invoke operator=
+ AuthorizationSet auths = keyParam;
+ }
+ },
+ [&]() { // invoke 'Contains()'
+ Tag tag = Tag::INVALID;
+ if (authSet.size() > 0) {
+ tag = authSet[mFdp.ConsumeIntegralInRange<size_t>(0, authSet.size() - 1)]
+ .tag;
+ }
+ authSet.Contains(mFdp.ConsumeBool() ? tag : mFdp.PickValueInArray(kTagArray));
+ },
+ [&]() { // invoke 'GetTagCount()'
+ Tag tag = Tag::INVALID;
+ if (authSet.size() > 0) {
+ tag = authSet[mFdp.ConsumeIntegralInRange<size_t>(0, authSet.size() - 1)]
+ .tag;
+ }
+ authSet.GetTagCount(mFdp.ConsumeBool() ? tag
+ : mFdp.PickValueInArray(kTagArray));
+ },
+ [&]() { // invoke 'erase()'
+ if (authSet.size() > 0) {
+ authSet.erase(mFdp.ConsumeIntegralInRange<size_t>(0, authSet.size() - 1));
+ }
+ },
+ });
+ invokeAuthSetAPI();
+ }
+ authSet.Clear();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ KeyMintAuthSetFuzzer kmAuthSetFuzzer(data, size);
+ kmAuthSetFuzzer.process();
+ return 0;
+}
+
+} // namespace android::hardware::security::keymint_support::fuzzer
diff --git a/security/keymint/support/fuzzer/keymint_common.h b/security/keymint/support/fuzzer/keymint_common.h
new file mode 100644
index 0000000..5c30e38
--- /dev/null
+++ b/security/keymint/support/fuzzer/keymint_common.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2024 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.
+ *
+ */
+#ifndef __KEYMINT_COMMON_H__
+#define __KEYMINT_COMMON_H__
+
+#include <aidl/android/hardware/security/keymint/BlockMode.h>
+#include <aidl/android/hardware/security/keymint/Digest.h>
+#include <aidl/android/hardware/security/keymint/EcCurve.h>
+#include <aidl/android/hardware/security/keymint/PaddingMode.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <keymint_support/authorization_set.h>
+
+namespace android::hardware::security::keymint_support::fuzzer {
+
+using namespace aidl::android::hardware::security::keymint;
+
+constexpr uint32_t kStringSize = 64;
+constexpr uint32_t k3DesKeySize = 168;
+constexpr uint32_t kSymmKeySize = 256;
+constexpr uint32_t kRsaKeySize = 2048;
+constexpr uint32_t kPublicExponent = 65537;
+
+constexpr EcCurve kCurve[] = {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521,
+ EcCurve::CURVE_25519};
+
+constexpr PaddingMode kPaddingMode[] = {
+ PaddingMode::NONE,
+ PaddingMode::RSA_OAEP,
+ PaddingMode::RSA_PSS,
+ PaddingMode::RSA_PKCS1_1_5_ENCRYPT,
+ PaddingMode::RSA_PKCS1_1_5_SIGN,
+ PaddingMode::PKCS7,
+};
+
+constexpr Digest kDigest[] = {
+ Digest::NONE, Digest::MD5, Digest::SHA1, Digest::SHA_2_224,
+ Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512,
+};
+
+constexpr BlockMode kBlockMode[] = {
+ BlockMode::ECB,
+ BlockMode::CBC,
+ BlockMode::CTR,
+ BlockMode::GCM,
+};
+
+enum AttestAuthSet : uint32_t {
+ RSA_ATTEST_KEY = 0u,
+ ECDSA_ATTEST_KEY,
+};
+
+enum AuthSet : uint32_t {
+ RSA_KEY = 0u,
+ RSA_SIGNING_KEY,
+ RSA_ENCRYPTION_KEY,
+ ECDSA_SIGNING_CURVE,
+ AES_ENCRYPTION_KEY,
+ TRIPLE_DES,
+ HMAC,
+ NO_DIGEST,
+ ECB_MODE,
+ GSM_MODE_MIN_MAC,
+ GSM_MODE_MAC,
+ BLOCK_MODE,
+};
+
+AuthorizationSet createAuthSetForAttestKey(FuzzedDataProvider* dataProvider) {
+ uint32_t attestAuthSet = dataProvider->ConsumeBool() ? AttestAuthSet::RSA_ATTEST_KEY
+ : AttestAuthSet::ECDSA_ATTEST_KEY;
+ uint64_t timestamp = dataProvider->ConsumeIntegral<uint64_t>();
+ Digest digest = dataProvider->PickValueInArray(kDigest);
+ PaddingMode padding = dataProvider->PickValueInArray(kPaddingMode);
+ std::string challenge = dataProvider->ConsumeRandomLengthString(kStringSize);
+ std::string id = dataProvider->ConsumeRandomLengthString(kStringSize);
+ switch (attestAuthSet) {
+ case RSA_ATTEST_KEY: {
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaKey(kRsaKeySize, kPublicExponent)
+ .Digest(digest)
+ .Padding(padding)
+ .AttestKey()
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(id)
+ .SetDefaultValidity()
+ .Authorization(TAG_CREATION_DATETIME, timestamp)
+ .Authorization(TAG_INCLUDE_UNIQUE_ID)
+ .Authorization(TAG_PURPOSE, KeyPurpose::ATTEST_KEY);
+ } break;
+ case ECDSA_ATTEST_KEY: {
+ EcCurve ecCurve = dataProvider->PickValueInArray(kCurve);
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaKey(ecCurve)
+ .AttestKey()
+ .Digest(digest)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(id)
+ .SetDefaultValidity()
+ .Authorization(TAG_CREATION_DATETIME, timestamp)
+ .Authorization(TAG_INCLUDE_UNIQUE_ID)
+ .Authorization(TAG_PURPOSE, KeyPurpose::ATTEST_KEY);
+ } break;
+ default:
+ break;
+ };
+ return AuthorizationSetBuilder();
+}
+
+AuthorizationSet createAuthorizationSet(FuzzedDataProvider* dataProvider) {
+ uint32_t authSet =
+ dataProvider->ConsumeIntegralInRange<uint32_t>(AuthSet::RSA_KEY, AuthSet::BLOCK_MODE);
+ uint64_t timestamp = dataProvider->ConsumeIntegral<uint64_t>();
+ Digest digest = dataProvider->PickValueInArray(kDigest);
+ PaddingMode padding = dataProvider->PickValueInArray(kPaddingMode);
+ std::string challenge = dataProvider->ConsumeRandomLengthString(kStringSize);
+ std::string id = dataProvider->ConsumeRandomLengthString(kStringSize);
+ switch (authSet) {
+ case RSA_KEY: {
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaKey(kRsaKeySize, kPublicExponent)
+ .Digest(digest)
+ .Padding(padding)
+ .AttestKey()
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(id)
+ .SetDefaultValidity()
+ .Authorization(TAG_CREATION_DATETIME, timestamp)
+ .Authorization(TAG_INCLUDE_UNIQUE_ID);
+ } break;
+ case RSA_SIGNING_KEY: {
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaSigningKey(kRsaKeySize, kPublicExponent)
+ .Digest(digest)
+ .Padding(padding)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(id)
+ .SetDefaultValidity()
+ .Authorization(TAG_CREATION_DATETIME, timestamp)
+ .Authorization(TAG_INCLUDE_UNIQUE_ID);
+ } break;
+ case RSA_ENCRYPTION_KEY: {
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .RsaEncryptionKey(kRsaKeySize, kPublicExponent)
+ .Digest(digest)
+ .Padding(padding)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(id)
+ .SetDefaultValidity()
+ .Authorization(TAG_CREATION_DATETIME, timestamp)
+ .Authorization(TAG_INCLUDE_UNIQUE_ID);
+ } break;
+ case ECDSA_SIGNING_CURVE: {
+ EcCurve ecCurve = dataProvider->PickValueInArray(kCurve);
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(ecCurve)
+ .Digest(digest)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(id)
+ .SetDefaultValidity()
+ .Authorization(TAG_CREATION_DATETIME, timestamp)
+ .Authorization(TAG_INCLUDE_UNIQUE_ID);
+ } break;
+ case AES_ENCRYPTION_KEY: {
+ BlockMode blockmode = dataProvider->PickValueInArray(kBlockMode);
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(kSymmKeySize)
+ .BlockMode(blockmode)
+ .Digest(digest)
+ .Padding(padding);
+ } break;
+ case TRIPLE_DES: {
+ BlockMode blockmode = dataProvider->PickValueInArray(kBlockMode);
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .TripleDesEncryptionKey(k3DesKeySize)
+ .BlockMode(blockmode)
+ .Digest(digest)
+ .Padding(padding)
+ .EcbMode()
+ .SetDefaultValidity();
+ } break;
+ case HMAC: {
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .HmacKey(kSymmKeySize)
+ .Digest(digest)
+ .Padding(padding);
+ } break;
+ case NO_DIGEST: {
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(kSymmKeySize)
+ .NoDigestOrPadding()
+ .Digest(digest)
+ .Padding(padding);
+ } break;
+ case ECB_MODE: {
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(kSymmKeySize)
+ .EcbMode()
+ .Digest(digest)
+ .Padding(padding);
+ } break;
+ case GSM_MODE_MIN_MAC: {
+ uint32_t minMacLength = dataProvider->ConsumeIntegral<uint32_t>();
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(kSymmKeySize)
+ .GcmModeMinMacLen(minMacLength)
+ .Digest(digest)
+ .Padding(padding);
+ } break;
+ case GSM_MODE_MAC: {
+ uint32_t macLength = dataProvider->ConsumeIntegral<uint32_t>();
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(kSymmKeySize)
+ .GcmModeMacLen(macLength)
+ .Digest(digest)
+ .Padding(padding);
+ } break;
+ case BLOCK_MODE: {
+ BlockMode blockmode = dataProvider->PickValueInArray(kBlockMode);
+ return AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AesEncryptionKey(kSymmKeySize)
+ .BlockMode(blockmode)
+ .Digest(digest)
+ .Padding(padding);
+ } break;
+ default:
+ break;
+ };
+ return AuthorizationSetBuilder();
+}
+
+} // namespace android::hardware::security::keymint_support::fuzzer
+
+#endif // __KEYMINT_COMMON_H__
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index d02cf4d..bb543f2 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -46,4 +46,5 @@
NB_OF_ELEVATION_MEASUREMENTS = 0xE5,
ENABLE_DIAGNOSTICS = 0xE8,
DIAGRAMS_FRAME_REPORTS_FIELDS = 0xE9,
+ ANTENNA_MODE = 0xEA,
}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index 65bb1c9..b8b4490 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -87,4 +87,12 @@
* b3 - b7: RFU
*/
DIAGRAMS_FRAME_REPORTS_FIELDS = 0xE9,
+
+ /**
+ * 1 byte data
+ * 0x0: Omni mode - the ranging antenna is used for both Tx and Rx.
+ * 0x1: Directional mode - the patch antenna is used for both Tx and Rx.
+ * 0x2 - 0xFF: RFU
+ */
+ ANTENNA_MODE = 0xEA,
}
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index 878aa64..956cf6c 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -71,7 +71,7 @@
let packet_vec: Vec<UciControlPacketHal> = packet.into();
for hal_packet in packet_vec.into_iter() {
serial
- .write(&hal_packet.to_vec())
+ .write(&hal_packet.encode_to_vec().unwrap())
.map(|written| written as i32)
.map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
}