Merge "uwb: Refactor default AIDL HAL implementation" into main am: 23a520e008 am: 45df9d0ee5
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/3267754
Change-Id: I49d4c4b340e62dce66f8e99ded50c8271d793e54
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
index 8addab7..aa1a86f 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
@@ -55,6 +55,9 @@
parcelable HapticScale {
int id;
android.hardware.audio.effect.HapticGenerator.VibratorScale scale = android.hardware.audio.effect.HapticGenerator.VibratorScale.MUTE;
+ float scaleFactor = (-1.0f) /* -1.000000f */;
+ float adaptiveScaleFactor = (-1.0f) /* -1.000000f */;
+ const float UNDEFINED_SCALE_FACTOR = (-1.0f) /* -1.000000f */;
}
@VintfStability
parcelable VibratorInformation {
diff --git a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
index 3cc5acb..f882d63 100644
--- a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
@@ -56,13 +56,51 @@
@VintfStability
parcelable HapticScale {
/**
+ * Representation of undefined scale factor, applied by default for backwards compatibility.
+ */
+ const float UNDEFINED_SCALE_FACTOR = -1.0f;
+
+ /**
* Audio track ID.
*/
int id;
+
/**
* Haptic intensity.
+ *
+ * This represents haptics scale as fixed levels defined by VibrationScale. If the field
+ * scaleFactor is defined then this will be ignored in favor of scaleFactor, otherwise this
+ * will be used to define the intensity for the haptics.
*/
VibratorScale scale = VibratorScale.MUTE;
+
+ /**
+ * Haptic scale factor.
+ *
+ * This is a continuous scale representation of VibratorScale, allowing flexible number of
+ * scale levels. If this field is defined then it will be used to define the intensity of
+ * the haptics, instead of the old VibratorScale field. If this field is undefined then the
+ * old VibratorScale field will be used.
+ *
+ * The value zero represents the same as VibratorScale.MUTE and the value one represents
+ * VibratorScale.NONE. Values in (0,1) should scale down, and values > 1 should scale up
+ * within hardware bounds. Negative values will be ignored.
+ */
+ float scaleFactor = -1.0f; // UNDEFINED_SCALE_FACTOR
+
+ /**
+ * Haptic adaptive scale factor.
+ *
+ * This is an additional scale value that should be applied on top of the vibrator scale to
+ * adapt to the device current state. This should be applied to linearly scale the haptic
+ * data after scale/scaleFactor is applied.
+ *
+ * The value zero mutes the haptics, even if the scale/scaleFactor are not set to MUTE/zero.
+ * The value one will not scale the haptics, and can be used as a constant for no-op.
+ * Values in (0,1) should scale down. Values > 1 should scale up within hardware bounds.
+ * Negative values will be ignored.
+ */
+ float adaptiveScaleFactor = -1.0f; // UNDEFINED_SCALE_FACTOR
}
/**
diff --git a/audio/aidl/default/alsa/StreamAlsa.cpp b/audio/aidl/default/alsa/StreamAlsa.cpp
index f548903..372e38a 100644
--- a/audio/aidl/default/alsa/StreamAlsa.cpp
+++ b/audio/aidl/default/alsa/StreamAlsa.cpp
@@ -75,6 +75,10 @@
}
decltype(mAlsaDeviceProxies) alsaDeviceProxies;
for (const auto& device : getDeviceProfiles()) {
+ if ((device.direction == PCM_OUT && mIsInput) ||
+ (device.direction == PCM_IN && !mIsInput)) {
+ continue;
+ }
alsa::DeviceProxy proxy;
if (device.isExternal) {
// Always ask alsa configure as required since the configuration should be supported
@@ -92,6 +96,9 @@
}
alsaDeviceProxies.push_back(std::move(proxy));
}
+ if (alsaDeviceProxies.empty()) {
+ return ::android::NO_INIT;
+ }
mAlsaDeviceProxies = std::move(alsaDeviceProxies);
return ::android::OK;
}
diff --git a/audio/aidl/default/include/core-impl/StreamPrimary.h b/audio/aidl/default/include/core-impl/StreamPrimary.h
index 8d5c57d..600c377 100644
--- a/audio/aidl/default/include/core-impl/StreamPrimary.h
+++ b/audio/aidl/default/include/core-impl/StreamPrimary.h
@@ -25,7 +25,8 @@
class StreamPrimary : public StreamAlsa {
public:
- StreamPrimary(StreamContext* context, const Metadata& metadata);
+ StreamPrimary(StreamContext* context, const Metadata& metadata,
+ const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices);
::android::status_t start() override;
::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
@@ -39,6 +40,11 @@
int64_t mStartTimeNs = 0;
long mFramesSinceStart = 0;
bool mSkipNextTransfer = false;
+
+ private:
+ static std::pair<int, int> getCardAndDeviceId(
+ const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices);
+ const std::pair<int, int> mCardAndDeviceId;
};
class StreamInPrimary final : public StreamIn, public StreamSwitcher, public StreamInHwGainHelper {
diff --git a/audio/aidl/default/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp
index 7325a91..801bbb8 100644
--- a/audio/aidl/default/primary/StreamPrimary.cpp
+++ b/audio/aidl/default/primary/StreamPrimary.cpp
@@ -15,7 +15,11 @@
*/
#define LOG_TAG "AHAL_StreamPrimary"
+
+#include <cstdio>
+
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <audio_utils/clock.h>
#include <error/Result.h>
@@ -28,6 +32,7 @@
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioOffloadInfo;
@@ -36,9 +41,15 @@
namespace aidl::android::hardware::audio::core {
-StreamPrimary::StreamPrimary(StreamContext* context, const Metadata& metadata)
+const static constexpr std::pair<int, int> kDefaultCardAndDeviceId = {
+ primary::PrimaryMixer::kAlsaCard, primary::PrimaryMixer::kAlsaDevice};
+
+StreamPrimary::StreamPrimary(
+ StreamContext* context, const Metadata& metadata,
+ const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
: StreamAlsa(context, metadata, 3 /*readWriteRetries*/),
- mIsAsynchronous(!!getContext().getAsyncCallback()) {
+ mIsAsynchronous(!!getContext().getAsyncCallback()),
+ mCardAndDeviceId(getCardAndDeviceId(devices)) {
context->startStreamDataProcessor();
}
@@ -92,17 +103,27 @@
}
std::vector<alsa::DeviceProfile> StreamPrimary::getDeviceProfiles() {
- static const std::vector<alsa::DeviceProfile> kBuiltInSource{
- alsa::DeviceProfile{.card = primary::PrimaryMixer::kAlsaCard,
- .device = primary::PrimaryMixer::kAlsaDevice,
- .direction = PCM_IN,
+ return {alsa::DeviceProfile{.card = mCardAndDeviceId.first,
+ .device = mCardAndDeviceId.second,
+ .direction = mIsInput ? PCM_IN : PCM_OUT,
.isExternal = false}};
- static const std::vector<alsa::DeviceProfile> kBuiltInSink{
- alsa::DeviceProfile{.card = primary::PrimaryMixer::kAlsaCard,
- .device = primary::PrimaryMixer::kAlsaDevice,
- .direction = PCM_OUT,
- .isExternal = false}};
- return mIsInput ? kBuiltInSource : kBuiltInSink;
+}
+
+std::pair<int, int> StreamPrimary::getCardAndDeviceId(const std::vector<AudioDevice>& devices) {
+ if (devices.empty() || devices[0].address.getTag() != AudioDeviceAddress::id) {
+ return kDefaultCardAndDeviceId;
+ }
+ std::string deviceAddress = devices[0].address.get<AudioDeviceAddress::id>();
+ std::pair<int, int> cardAndDeviceId;
+ if (const size_t suffixPos = deviceAddress.rfind("CARD_");
+ suffixPos == std::string::npos ||
+ sscanf(deviceAddress.c_str() + suffixPos, "CARD_%d_DEV_%d", &cardAndDeviceId.first,
+ &cardAndDeviceId.second) != 2) {
+ return kDefaultCardAndDeviceId;
+ }
+ LOG(DEBUG) << __func__ << ": parsed with card id " << cardAndDeviceId.first << ", device id "
+ << cardAndDeviceId.second;
+ return cardAndDeviceId;
}
StreamInPrimary::StreamInPrimary(StreamContext&& context, const SinkMetadata& sinkMetadata,
@@ -116,8 +137,7 @@
GetBoolProperty("ro.boot.audio.tinyalsa.simulate_input", false);
return kSimulateInput || device.type.type == AudioDeviceType::IN_TELEPHONY_RX ||
device.type.type == AudioDeviceType::IN_FM_TUNER ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */ ||
- (device.type.type == AudioDeviceType::IN_BUS && device.type.connection.empty());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */;
}
StreamSwitcher::DeviceSwitchBehavior StreamInPrimary::switchCurrentStream(
@@ -145,7 +165,7 @@
new InnerStreamWrapper<StreamStub>(context, metadata));
}
return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamPrimary>(context, metadata));
+ new InnerStreamWrapper<StreamPrimary>(context, metadata, devices));
}
ndk::ScopedAStatus StreamInPrimary::getHwGain(std::vector<float>* _aidl_return) {
@@ -188,8 +208,7 @@
static const bool kSimulateOutput =
GetBoolProperty("ro.boot.audio.tinyalsa.ignore_output", false);
return kSimulateOutput || device.type.type == AudioDeviceType::OUT_TELEPHONY_TX ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/ ||
- (device.type.type == AudioDeviceType::OUT_BUS && device.type.connection.empty());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/;
}
StreamSwitcher::DeviceSwitchBehavior StreamOutPrimary::switchCurrentStream(
@@ -217,7 +236,7 @@
new InnerStreamWrapper<StreamStub>(context, metadata));
}
return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamPrimary>(context, metadata));
+ new InnerStreamWrapper<StreamPrimary>(context, metadata, devices));
}
ndk::ScopedAStatus StreamOutPrimary::getHwVolume(std::vector<float>* _aidl_return) {
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index cbd42c0..85d400e 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -136,6 +136,9 @@
name: "VtsHalHapticGeneratorTargetTest",
defaults: ["VtsHalAudioEffectTargetTestDefaults"],
srcs: ["VtsHalHapticGeneratorTargetTest.cpp"],
+ shared_libs: [
+ "libaudioutils",
+ ],
}
cc_test {
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 0fa170f..93589e2 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -454,6 +454,17 @@
mOutputSamples = common.output.frameCount * mOutputFrameSize / sizeof(float);
}
+ void generateInput(std::vector<float>& input, float inputFrequency, float samplingFrequency,
+ size_t inputSize = 0) {
+ if (inputSize == 0 || inputSize > input.size()) {
+ inputSize = input.size();
+ }
+
+ for (size_t i = 0; i < inputSize; i++) {
+ input[i] = sin(2 * M_PI * inputFrequency * i / samplingFrequency);
+ }
+ }
+
bool mIsSpatializer;
Descriptor mDescriptor;
size_t mInputFrameSize, mOutputFrameSize;
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index 6af326d..2802bf9 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -21,11 +21,13 @@
#define LOG_TAG "VtsHalHapticGeneratorTargetTest"
#include <android-base/logging.h>
#include <android/binder_enums.h>
+#include <audio_utils/power.h>
#include "EffectHelper.h"
using namespace android;
+using aidl::android::hardware::audio::common::getChannelCount;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::getEffectTypeUuidHapticGenerator;
using aidl::android::hardware::audio::effect::HapticGenerator;
@@ -34,400 +36,412 @@
using aidl::android::hardware::audio::effect::Parameter;
using android::hardware::audio::common::testing::detail::TestExecutionTracer;
-/**
- * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
- * VtsAudioEffectTargetTest.
- */
-enum ParamName {
- PARAM_INSTANCE_NAME,
- PARAM_HAPTIC_SCALE_ID,
- PARAM_HAPTIC_SCALE_VIBRATOR_SCALE,
- PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY,
- PARAM_VIBRATION_INFORMATION_Q_FACTOR,
- PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE,
-};
-using HapticGeneratorParamTestParam =
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
- HapticGenerator::VibratorScale, float, float, float>;
-
-/*
- * Testing parameter range, assuming the parameter supported by effect is in this range.
- * Parameter should be within the valid range defined in the documentation,
- * for any supported value test expects EX_NONE from IEffect.setParameter(),
- * otherwise expect EX_ILLEGAL_ARGUMENT.
- */
-
-// TODO : Update the test values once range/capability is updated by implementation
const int MIN_ID = std::numeric_limits<int>::min();
const int MAX_ID = std::numeric_limits<int>::max();
const float MIN_FLOAT = std::numeric_limits<float>::min();
const float MAX_FLOAT = std::numeric_limits<float>::max();
-const std::vector<int> kHapticScaleIdValues = {MIN_ID, 0, MAX_ID};
-const std::vector<HapticGenerator::VibratorScale> kVibratorScaleValues = {
+std::vector<HapticGenerator::VibratorScale> kScaleValues = {
ndk::enum_range<HapticGenerator::VibratorScale>().begin(),
ndk::enum_range<HapticGenerator::VibratorScale>().end()};
+const std::vector<float> kScaleFactorValues = {HapticGenerator::HapticScale::UNDEFINED_SCALE_FACTOR,
+ 0.0f, 0.5f, 1.0f, MAX_FLOAT};
+const std::vector<float> kAdaptiveScaleFactorValues = {
+ HapticGenerator::HapticScale::UNDEFINED_SCALE_FACTOR, 0.0f, 0.5f, 1.0f, MAX_FLOAT};
+
const std::vector<float> kResonantFrequencyValues = {MIN_FLOAT, 100, MAX_FLOAT};
const std::vector<float> kQFactorValues = {MIN_FLOAT, 100, MAX_FLOAT};
const std::vector<float> kMaxAmplitude = {MIN_FLOAT, 100, MAX_FLOAT};
-class HapticGeneratorParamTest : public ::testing::TestWithParam<HapticGeneratorParamTestParam>,
- public EffectHelper {
+constexpr int HAPTIC_SCALE_FACTORS_EFFECT_MIN_VERSION = 3;
+
+static const std::vector<int32_t> kHapticOutputLayouts = {
+ AudioChannelLayout::LAYOUT_MONO_HAPTIC_A, AudioChannelLayout::LAYOUT_MONO_HAPTIC_AB,
+ AudioChannelLayout::LAYOUT_STEREO_HAPTIC_A, AudioChannelLayout::LAYOUT_STEREO_HAPTIC_AB};
+
+class HapticGeneratorHelper : public EffectHelper {
public:
- HapticGeneratorParamTest()
- : mParamHapticScaleId(std::get<PARAM_HAPTIC_SCALE_ID>(GetParam())),
- mParamVibratorScale(std::get<PARAM_HAPTIC_SCALE_VIBRATOR_SCALE>(GetParam())),
- mParamResonantFrequency(
- std::get<PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY>(GetParam())),
- mParamQFactor(std::get<PARAM_VIBRATION_INFORMATION_Q_FACTOR>(GetParam())),
- mParamMaxAmplitude(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(GetParam())) {
- std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
- }
- void SetUp() override {
+ void SetUpHapticGenerator(int32_t chMask = AudioChannelLayout::CHANNEL_HAPTIC_A) {
ASSERT_NE(nullptr, mFactory);
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ EXPECT_STATUS(EX_NONE, mEffect->getInterfaceVersion(&mEffectInterfaceVersion));
+
+ AudioChannelLayout layout =
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(chMask);
Parameter::Common common = createParamCommon(
- 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
- kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
- IEffect::OpenEffectReturn ret;
+ 0 /* session */, 1 /* ioHandle */, kSamplingFrequency /* iSampleRate */,
+ kSamplingFrequency /* oSampleRate */, kFrameCount /* iFrameCount */,
+ kFrameCount /* oFrameCount */, layout, layout);
ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
ASSERT_NE(nullptr, mEffect);
}
- void TearDown() override {
+ void TearDownHapticGenerator() {
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ ret = IEffect::OpenEffectReturn{};
}
- static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
- std::shared_ptr<IFactory> mFactory;
- std::shared_ptr<IEffect> mEffect;
- Descriptor mDescriptor;
- int mParamHapticScaleId = 0;
- HapticGenerator::VibratorScale mParamVibratorScale = HapticGenerator::VibratorScale::MUTE;
- float mParamResonantFrequency = 0;
- float mParamQFactor = 0;
- float mParamMaxAmplitude = 0;
+ Parameter createScaleParam(const std::vector<HapticGenerator::HapticScale>& hapticScales) {
+ return Parameter::make<Parameter::specific>(
+ Parameter::Specific::make<Parameter::Specific::hapticGenerator>(
+ HapticGenerator::make<HapticGenerator::hapticScales>(hapticScales)));
+ }
- void SetAndGetHapticGeneratorParameters() {
- for (auto& it : mTags) {
- auto& tag = std::get<ParamTestEnum::PARAM_TEST_TAG>(it);
- auto& setHg = std::get<ParamTestEnum::PARAM_TEST_TARGET>(it);
+ Parameter createVibratorParam(HapticGenerator::VibratorInformation vibrationInfo) {
+ return Parameter::make<Parameter::specific>(
+ Parameter::Specific::make<Parameter::Specific::hapticGenerator>(
+ HapticGenerator::make<HapticGenerator::vibratorInfo>(vibrationInfo)));
+ }
- // set parameter
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::hapticGenerator>(setHg);
- expectParam.set<Parameter::specific>(specific);
- EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
-
+ void setAndVerifyParameter(Parameter hapticParameter, HapticGenerator::Tag tag,
+ binder_exception_t expected = EX_NONE) {
+ EXPECT_STATUS(expected, mEffect->setParameter(hapticParameter))
+ << hapticParameter.toString();
+ if (expected == EX_NONE) {
// get parameter
Parameter getParam;
- Parameter::Id id;
- HapticGenerator::Id hgId;
- hgId.set<HapticGenerator::Id::commonTag>(tag);
- id.set<Parameter::Id::hapticGeneratorTag>(hgId);
- EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
- EXPECT_EQ(expectParam, getParam) << expectParam.toString() << "\n"
- << getParam.toString();
+ auto second = Parameter::Id::make<Parameter::Id::hapticGeneratorTag>(
+ HapticGenerator::Id::make<HapticGenerator::Id::commonTag>(
+ HapticGenerator::Tag(tag)));
+ // If the set is successful, get param should match
+ EXPECT_STATUS(expected, mEffect->getParameter(second, &getParam));
+ EXPECT_EQ(hapticParameter, getParam) << "\nexpectedParam:" << hapticParameter.toString()
+ << "\ngetParam:" << getParam.toString();
}
}
- void addHapticScaleParam(int id, HapticGenerator::VibratorScale scale) {
- HapticGenerator setHg;
- std::vector<HapticGenerator::HapticScale> hapticScales = {{.id = id, .scale = scale}};
- setHg.set<HapticGenerator::hapticScales>(hapticScales);
- mTags.push_back({HapticGenerator::hapticScales, setHg});
+ HapticGenerator::VibratorInformation createVibratorInfo(float resonantFrequency, float qFactor,
+ float amplitude) {
+ return HapticGenerator::VibratorInformation(resonantFrequency, qFactor, amplitude);
}
- void addVibratorInformationParam(float resonantFrequencyHz, float qFactor, float maxAmplitude) {
- HapticGenerator hg;
- HapticGenerator::VibratorInformation vibrationInfo = {
- .resonantFrequencyHz = resonantFrequencyHz,
- .qFactor = qFactor,
- .maxAmplitude = maxAmplitude};
- hg.set<HapticGenerator::vibratorInfo>(vibrationInfo);
- mTags.push_back({HapticGenerator::vibratorInfo, hg});
- }
-
- private:
- enum ParamTestEnum { PARAM_TEST_TAG, PARAM_TEST_TARGET };
- std::vector<std::tuple<HapticGenerator::Tag, HapticGenerator>> mTags;
-
- void CleanUp() { mTags.clear(); }
-};
-
-TEST_P(HapticGeneratorParamTest, SetAndGetHapticScale) {
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
- SetAndGetHapticGeneratorParameters();
-}
-
-TEST_P(HapticGeneratorParamTest, SetAndGetMultipleHapticScales) {
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
- SetAndGetHapticGeneratorParameters();
-}
-
-TEST_P(HapticGeneratorParamTest, SetAndGetVibratorInformation) {
- EXPECT_NO_FATAL_FAILURE(addVibratorInformationParam(mParamResonantFrequency, mParamQFactor,
- mParamMaxAmplitude));
- SetAndGetHapticGeneratorParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- HapticGeneratorValidTest, HapticGeneratorParamTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
- testing::ValuesIn(kHapticScaleIdValues),
- testing::ValuesIn(kVibratorScaleValues),
- testing::ValuesIn(kResonantFrequencyValues),
- testing::ValuesIn(kQFactorValues), testing::ValuesIn(kMaxAmplitude)),
- [](const testing::TestParamInfo<HapticGeneratorParamTest::ParamType>& info) {
- auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
- std::string hapticScaleID = std::to_string(std::get<PARAM_HAPTIC_SCALE_ID>(info.param));
- std::string hapticScaleVibScale = std::to_string(
- static_cast<int>(std::get<PARAM_HAPTIC_SCALE_VIBRATOR_SCALE>(info.param)));
- std::string resonantFrequency = std::to_string(
- std::get<PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY>(info.param));
- std::string qFactor =
- std::to_string(std::get<PARAM_VIBRATION_INFORMATION_Q_FACTOR>(info.param));
- std::string maxAmplitude =
- std::to_string(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(info.param));
- std::string name = getPrefix(descriptor) + "_hapticScaleId" + hapticScaleID +
- "_hapticScaleVibScale" + hapticScaleVibScale + "_resonantFrequency" +
- resonantFrequency + "_qFactor" + qFactor + "_maxAmplitude" +
- maxAmplitude;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
- return name;
- });
-
-INSTANTIATE_TEST_SUITE_P(
- HapticGeneratorInvalidTest, HapticGeneratorParamTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
- testing::Values(MIN_ID),
- testing::Values(HapticGenerator::VibratorScale::NONE),
- testing::Values(MIN_FLOAT), testing::Values(MIN_FLOAT),
- testing::Values(MIN_FLOAT)),
- [](const testing::TestParamInfo<HapticGeneratorParamTest::ParamType>& info) {
- auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
- std::string hapticScaleID = std::to_string(std::get<PARAM_HAPTIC_SCALE_ID>(info.param));
- std::string hapticScaleVibScale = std::to_string(
- static_cast<int>(std::get<PARAM_HAPTIC_SCALE_VIBRATOR_SCALE>(info.param)));
- std::string resonantFrequency = std::to_string(
- std::get<PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY>(info.param));
- std::string qFactor =
- std::to_string(std::get<PARAM_VIBRATION_INFORMATION_Q_FACTOR>(info.param));
- std::string maxAmplitude =
- std::to_string(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(info.param));
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid) + "_hapticScaleId" +
- hapticScaleID + "_hapticScaleVibScale" + hapticScaleVibScale +
- "_resonantFrequency" + resonantFrequency + "_qFactor" + qFactor +
- "_maxAmplitude" + maxAmplitude;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
- return name;
- });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorParamTest);
-
-// Test HapticScale[] hapticScales parameter
-using HapticGeneratorScalesTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>>;
-class HapticGeneratorScalesTest : public ::testing::TestWithParam<HapticGeneratorScalesTestParam>,
- public EffectHelper {
- public:
- HapticGeneratorScalesTest() {
- std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
- }
-
- void SetUp() override {
- ASSERT_NE(nullptr, mFactory);
- ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
-
- Parameter::Common common = createParamCommon(
- 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
- kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
- IEffect::OpenEffectReturn ret;
- ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
- ASSERT_NE(nullptr, mEffect);
- }
-
- void TearDown() override {
- ASSERT_NO_FATAL_FAILURE(close(mEffect));
- ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
- CleanUp();
- }
-
- static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ static const long kFrameCount = 10000;
+ static constexpr int kSamplingFrequency = 44100;
+ static constexpr int kDefaultScaleID = 0;
+ static constexpr float kDefaultMaxAmp = 1;
+ static constexpr float kDefaultResonantFrequency = 150;
+ static constexpr float kDefaultQfactor = 8;
+ static constexpr HapticGenerator::VibratorScale kDefaultScale =
+ HapticGenerator::VibratorScale::NONE;
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
- Descriptor mDescriptor;
-
- void addHapticScaleParam(std::vector<HapticGenerator::HapticScale> scales) {
- mHapticScales.push_back(HapticGenerator::make<HapticGenerator::hapticScales>(scales));
- for (const auto& scale : scales) {
- expectMap.insert_or_assign(scale.id, scale.scale);
- }
- }
-
- void SetHapticScaleParameters() {
- // std::unordered_set<HapticGenerator::HapticScale> target;
- for (auto& it : mHapticScales) {
- Parameter::Specific specific =
- Parameter::Specific::make<Parameter::Specific::hapticGenerator>(it);
- Parameter param = Parameter::make<Parameter::specific>(specific);
- EXPECT_STATUS(EX_NONE, mEffect->setParameter(param)) << param.toString();
- }
- }
-
- void checkHapticScaleParameter() {
- // get parameter
- Parameter targetParam;
- HapticGenerator::Id hgId = HapticGenerator::Id::make<HapticGenerator::Id::commonTag>(
- HapticGenerator::hapticScales);
- Parameter::Id id = Parameter::Id::make<Parameter::Id::hapticGeneratorTag>(hgId);
- EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &targetParam));
- ASSERT_EQ(Parameter::specific, targetParam.getTag());
- Parameter::Specific specific = targetParam.get<Parameter::specific>();
- ASSERT_EQ(Parameter::Specific::hapticGenerator, specific.getTag());
- HapticGenerator hg = specific.get<Parameter::Specific::hapticGenerator>();
- ASSERT_EQ(HapticGenerator::hapticScales, hg.getTag());
- std::vector<HapticGenerator::HapticScale> scales = hg.get<HapticGenerator::hapticScales>();
- ASSERT_EQ(scales.size(), expectMap.size());
- for (const auto& scale : scales) {
- auto itor = expectMap.find(scale.id);
- ASSERT_NE(expectMap.end(), itor);
- ASSERT_EQ(scale.scale, itor->second);
- expectMap.erase(scale.id);
- }
- ASSERT_EQ(0ul, expectMap.size());
- }
-
- const static HapticGenerator::HapticScale kHapticScaleWithMinId;
- const static HapticGenerator::HapticScale kHapticScaleWithMinIdNew;
- const static HapticGenerator::HapticScale kHapticScale;
- const static HapticGenerator::HapticScale kHapticScaleNew;
- const static HapticGenerator::HapticScale kHapticScaleWithMaxId;
- const static HapticGenerator::HapticScale kHapticScaleWithMaxIdNew;
-
- std::vector<HapticGenerator> mHapticScales;
-
- void CleanUp() {
- mHapticScales.clear();
- expectMap.clear();
- }
-
- private:
- std::map<int /* trackID */, HapticGenerator::VibratorScale> expectMap;
+ IEffect::OpenEffectReturn ret;
+ Parameter mHapticSpecificParameter;
+ Parameter::Id mHapticIdParameter;
+ int mEffectInterfaceVersion;
};
-const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinId = {
- .id = MIN_ID, .scale = HapticGenerator::VibratorScale::MUTE};
-const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinIdNew = {
- .id = MIN_ID, .scale = HapticGenerator::VibratorScale::VERY_LOW};
-const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScale = {
- .id = 1, .scale = HapticGenerator::VibratorScale::LOW};
-const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleNew = {
- .id = 1, .scale = HapticGenerator::VibratorScale::NONE};
-const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxId = {
- .id = MAX_ID, .scale = HapticGenerator::VibratorScale::VERY_HIGH};
-const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxIdNew = {
- .id = MAX_ID, .scale = HapticGenerator::VibratorScale::MUTE};
+/**
+ *Tests do the following:
+ * -Testing parameter range supported by the effect.
+ * -For any supported value test expects EX_NONE from IEffect.setParameter(),
+ * otherwise expect EX_ILLEGAL_ARGUMENT.
+ * -Validating the effect by comparing the output energies of the supported parameters.
+ **/
-TEST_P(HapticGeneratorScalesTest, SetAndUpdateOne) {
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleNew}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+using EffectInstance = std::pair<std::shared_ptr<IFactory>, Descriptor>;
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinIdNew}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+class HapticGeneratorScaleParamTest : public ::testing::TestWithParam<EffectInstance>,
+ public HapticGeneratorHelper {
+ public:
+ HapticGeneratorScaleParamTest() { std::tie(mFactory, mDescriptor) = GetParam(); }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpHapticGenerator()); }
+ void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownHapticGenerator()); }
+};
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxIdNew}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
-
- EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+TEST_P(HapticGeneratorScaleParamTest, SetAndGetScales) {
+ std::vector<HapticGenerator::HapticScale> hapticScales;
+ for (int i = 0; i < static_cast<int>(kScaleValues.size()); i++) {
+ hapticScales.push_back({.id = i, .scale = kScaleValues[i]});
+ }
+ ASSERT_NO_FATAL_FAILURE(
+ setAndVerifyParameter(createScaleParam(hapticScales), HapticGenerator::hapticScales));
}
-TEST_P(HapticGeneratorScalesTest, SetAndUpdateVector) {
- EXPECT_NO_FATAL_FAILURE(
- addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(
- {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+TEST_P(HapticGeneratorScaleParamTest, SetAndGetScaleFactors) {
+ if (mEffectInterfaceVersion < HAPTIC_SCALE_FACTORS_EFFECT_MIN_VERSION) {
+ GTEST_SKIP() << "Skipping HapticGenerator ScaleFactors test for effect version "
+ << std::to_string(mEffectInterfaceVersion);
+ }
- EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+ std::vector<HapticGenerator::HapticScale> hapticScales;
+ for (int i = 0; i < static_cast<int>(kScaleFactorValues.size()); i++) {
+ hapticScales.push_back(
+ {.id = i, .scale = kScaleValues[0], .scaleFactor = kScaleFactorValues[i]});
+ }
+ ASSERT_NO_FATAL_FAILURE(
+ setAndVerifyParameter(createScaleParam(hapticScales), HapticGenerator::hapticScales));
}
-TEST_P(HapticGeneratorScalesTest, SetAndUpdateMultipleVector) {
- EXPECT_NO_FATAL_FAILURE(
- addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(
- {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(
- addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+TEST_P(HapticGeneratorScaleParamTest, SetAndGetAdaptiveScaleFactors) {
+ if (mEffectInterfaceVersion < HAPTIC_SCALE_FACTORS_EFFECT_MIN_VERSION) {
+ GTEST_SKIP() << "Skipping HapticGenerator AdaptiveScaleFactors test for effect version "
+ << std::to_string(mEffectInterfaceVersion);
+ }
- EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
-}
-
-TEST_P(HapticGeneratorScalesTest, SetOneAndAddMoreVector) {
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
-
- EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
-}
-
-TEST_P(HapticGeneratorScalesTest, SetMultipleAndAddOneVector) {
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
-
- EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
-}
-
-TEST_P(HapticGeneratorScalesTest, SetMultipleVectorRepeat) {
- EXPECT_NO_FATAL_FAILURE(
- addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(
- addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
- EXPECT_NO_FATAL_FAILURE(
- addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
- EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
-
- EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+ std::vector<HapticGenerator::HapticScale> hapticScales;
+ for (int i = 0; i < static_cast<int>(kAdaptiveScaleFactorValues.size()); i++) {
+ hapticScales.push_back({.id = i,
+ .scale = kScaleValues[0],
+ .scaleFactor = kScaleFactorValues[3],
+ .adaptiveScaleFactor = kAdaptiveScaleFactorValues[i]});
+ }
+ ASSERT_NO_FATAL_FAILURE(
+ setAndVerifyParameter(createScaleParam(hapticScales), HapticGenerator::hapticScales));
}
INSTANTIATE_TEST_SUITE_P(
- HapticGeneratorScalesTest, HapticGeneratorScalesTest,
+ HapticGeneratorValidTest, HapticGeneratorScaleParamTest,
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
+ [](const testing::TestParamInfo<HapticGeneratorScaleParamTest::ParamType>& info) {
+ auto descriptor = info.param;
+ return getPrefix(descriptor.second);
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorScaleParamTest);
+
+enum VibratorParamName {
+ VIBRATOR_PARAM_INSTANCE,
+ VIBRATOR_PARAM_RESONANT_FREQUENCY,
+ VIBRATOR_PARAM_Q_FACTOR,
+ VIBRATOR_PARAM_MAX_AMPLITUDE,
+};
+
+using HapticGeneratorVibratorInfoTestParam = std::tuple<EffectInstance, float, float, float>;
+
+class HapticGeneratorVibratorInfoParamTest
+ : public ::testing::TestWithParam<HapticGeneratorVibratorInfoTestParam>,
+ public HapticGeneratorHelper {
+ public:
+ HapticGeneratorVibratorInfoParamTest()
+ : mParamResonantFrequency(std::get<VIBRATOR_PARAM_RESONANT_FREQUENCY>(GetParam())),
+ mParamQFactor(std::get<VIBRATOR_PARAM_Q_FACTOR>(GetParam())),
+ mParamMaxAmplitude(std::get<VIBRATOR_PARAM_MAX_AMPLITUDE>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<VIBRATOR_PARAM_INSTANCE>(GetParam());
+ }
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpHapticGenerator()); }
+ void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownHapticGenerator()); }
+
+ float mParamResonantFrequency = kDefaultResonantFrequency;
+ float mParamQFactor = kDefaultQfactor;
+ float mParamMaxAmplitude = kDefaultMaxAmp;
+};
+
+TEST_P(HapticGeneratorVibratorInfoParamTest, SetAndGetVibratorInformation) {
+ auto vibratorInfo =
+ createVibratorInfo(mParamResonantFrequency, mParamQFactor, mParamMaxAmplitude);
+ if (isParameterValid<HapticGenerator, Range::hapticGenerator>(vibratorInfo, mDescriptor)) {
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameter(createVibratorParam(vibratorInfo),
+ HapticGenerator::vibratorInfo));
+ } else {
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameter(createVibratorParam(vibratorInfo),
+ HapticGenerator::vibratorInfo,
+ EX_ILLEGAL_ARGUMENT));
+ }
+}
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorVibratorInfoParamTest);
+
+INSTANTIATE_TEST_SUITE_P(
+ HapticGeneratorValidTest, HapticGeneratorVibratorInfoParamTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidHapticGenerator()))),
- [](const testing::TestParamInfo<HapticGeneratorScalesTest::ParamType>& info) {
- auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- toString(descriptor.common.id.uuid);
+ IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
+ testing::ValuesIn(kResonantFrequencyValues),
+ testing::ValuesIn(kQFactorValues), testing::ValuesIn(kMaxAmplitude)),
+ [](const testing::TestParamInfo<HapticGeneratorVibratorInfoParamTest::ParamType>& info) {
+ auto descriptor = std::get<VIBRATOR_PARAM_INSTANCE>(info.param).second;
+ std::string resonantFrequency =
+ std::to_string(std::get<VIBRATOR_PARAM_RESONANT_FREQUENCY>(info.param));
+ std::string qFactor = std::to_string(std::get<VIBRATOR_PARAM_Q_FACTOR>(info.param));
+ std::string maxAmplitude =
+ std::to_string(std::get<VIBRATOR_PARAM_MAX_AMPLITUDE>(info.param));
+ std::string name = getPrefix(descriptor) + "_resonantFrequency" + resonantFrequency +
+ "_qFactor" + qFactor + "_maxAmplitude" + maxAmplitude;
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
});
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorScalesTest);
+
+/**
+ * The data tests do the following
+ * -Generate test input.
+ * -Check if the parameters are supported. Skip the unsupported parameter values.
+ * -Validate increase in haptic output energy energy.
+ **/
+
+enum DataTestParam { EFFECT_INSTANCE, LAYOUT };
+using HapticGeneratorDataTestParam = std::tuple<EffectInstance, int32_t>;
+
+class HapticGeneratorDataTest : public ::testing::TestWithParam<HapticGeneratorDataTestParam>,
+ public HapticGeneratorHelper {
+ public:
+ HapticGeneratorDataTest() : mChMask(std::get<LAYOUT>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<EFFECT_INSTANCE>(GetParam());
+ mAudioChannelCount =
+ getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChMask),
+ ~AudioChannelLayout::LAYOUT_HAPTIC_AB);
+ mHapticChannelCount =
+ getChannelCount(AudioChannelLayout::make<AudioChannelLayout::layoutMask>(mChMask),
+ AudioChannelLayout::LAYOUT_HAPTIC_AB);
+
+ mAudioSamples = kFrameCount * mAudioChannelCount;
+ mHapticSamples = kFrameCount * mHapticChannelCount;
+ mInput.resize(mHapticSamples + mAudioSamples, 0);
+ mOutput.resize(mHapticSamples + mAudioSamples, 0);
+ }
+
+ void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpHapticGenerator(mChMask)); }
+ void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownHapticGenerator()); }
+
+ void generateSinePeriod() {
+ size_t cycleSize = kSamplingFrequency / kInputFrequency;
+ size_t startSize = 0;
+ while (startSize < mAudioSamples) {
+ for (size_t i = 0; i < cycleSize; i++) {
+ mInput[i + startSize] = sin(2 * M_PI * kInputFrequency * i / kSamplingFrequency);
+ }
+ startSize += mAudioSamples / 4;
+ }
+ }
+
+ void setBaseVibratorParam() {
+ auto vibratorInfo =
+ createVibratorInfo(kDefaultResonantFrequency, kDefaultQfactor, kDefaultMaxAmp);
+ if (isParameterValid<HapticGenerator, Range::hapticGenerator>(vibratorInfo, mDescriptor)) {
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameter(createVibratorParam(vibratorInfo),
+ HapticGenerator::vibratorInfo));
+ } else {
+ GTEST_SKIP() << "Invalid base vibrator values, skipping the test\n";
+ }
+ }
+
+ void setBaseScaleParam() {
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameter(
+ createScaleParam({HapticGenerator::HapticScale(kDefaultScaleID, kDefaultScale)}),
+ HapticGenerator::hapticScales));
+ }
+
+ void validateIncreasingEnergy(HapticGenerator::Tag tag) {
+ float baseEnergy = -1;
+ for (auto param : mHapticParam) {
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameter(param, tag));
+ SCOPED_TRACE("Param: " + param.toString());
+ ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput(mInput, mOutput, mEffect, &ret));
+ float hapticOutputEnergy = audio_utils_compute_energy_mono(
+ mOutput.data() + mAudioSamples, AUDIO_FORMAT_PCM_FLOAT, mHapticSamples);
+ EXPECT_GT(hapticOutputEnergy, baseEnergy);
+ baseEnergy = hapticOutputEnergy;
+ }
+ }
+
+ float findAbsMax(auto begin, auto end) {
+ return *std::max_element(begin, end,
+ [](float a, float b) { return std::abs(a) < std::abs(b); });
+ }
+
+ void findMaxAmplitude() {
+ for (float amp = 0.1; amp <= 1; amp += 0.1) {
+ auto vibratorInfo = createVibratorInfo(kDefaultResonantFrequency, kDefaultQfactor, amp);
+ if (!isParameterValid<HapticGenerator, Range::hapticGenerator>(vibratorInfo,
+ mDescriptor)) {
+ continue;
+ }
+ ASSERT_NO_FATAL_FAILURE(setAndVerifyParameter(createVibratorParam(vibratorInfo),
+ HapticGenerator::vibratorInfo));
+ ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput(mInput, mOutput, mEffect, &ret));
+ float outAmplitude = findAbsMax(mOutput.begin() + mAudioSamples, mOutput.end());
+ if (outAmplitude > mMaxAmplitude) {
+ mMaxAmplitude = outAmplitude;
+ } else {
+ break;
+ }
+ }
+ }
+
+ const int kInputFrequency = 1000;
+ float mMaxAmplitude = 0;
+ size_t mHapticSamples;
+ int32_t mChMask;
+ int32_t mAudioChannelCount;
+ int32_t mHapticChannelCount;
+ size_t mAudioSamples;
+ float mBaseHapticOutputEnergy;
+ std::vector<Parameter> mHapticParam;
+ // both input and output buffer includes audio and haptic samples
+ std::vector<float> mInput;
+ std::vector<float> mOutput;
+};
+
+TEST_P(HapticGeneratorDataTest, IncreasingVibratorScaleTest) {
+ generateInput(mInput, kInputFrequency, kSamplingFrequency, mAudioSamples);
+ ASSERT_NO_FATAL_FAILURE(setBaseVibratorParam());
+ for (HapticGenerator::VibratorScale scale : kScaleValues) {
+ mHapticParam.push_back(
+ createScaleParam({HapticGenerator::HapticScale(kDefaultScaleID, scale)}));
+ }
+ ASSERT_NO_FATAL_FAILURE(validateIncreasingEnergy(HapticGenerator::hapticScales));
+}
+
+TEST_P(HapticGeneratorDataTest, IncreasingMaxAmplitudeTest) {
+ generateInput(mInput, kInputFrequency, kSamplingFrequency, mAudioSamples);
+ ASSERT_NO_FATAL_FAILURE(setBaseScaleParam());
+ findMaxAmplitude();
+ std::vector<float> increasingAmplitudeValues = {0.25f * mMaxAmplitude, 0.5f * mMaxAmplitude,
+ 0.75f * mMaxAmplitude, mMaxAmplitude};
+ for (float amplitude : increasingAmplitudeValues) {
+ auto vibratorInfo =
+ createVibratorInfo(kDefaultResonantFrequency, kDefaultQfactor, amplitude);
+ if (!isParameterValid<HapticGenerator, Range::hapticGenerator>(vibratorInfo, mDescriptor)) {
+ continue;
+ }
+ mHapticParam.push_back(createVibratorParam(vibratorInfo));
+ }
+ ASSERT_NO_FATAL_FAILURE(validateIncreasingEnergy(HapticGenerator::vibratorInfo));
+}
+
+TEST_P(HapticGeneratorDataTest, DescreasingResonantFrequencyTest) {
+ std::vector<float> descreasingResonantFrequency = {800, 600, 400, 200};
+ generateInput(mInput, kInputFrequency, kSamplingFrequency, mAudioSamples);
+ ASSERT_NO_FATAL_FAILURE(setBaseScaleParam());
+ for (float resonantFrequency : descreasingResonantFrequency) {
+ auto vibratorInfo = createVibratorInfo(resonantFrequency, kDefaultQfactor, kDefaultMaxAmp);
+ if (!isParameterValid<HapticGenerator, Range::hapticGenerator>(vibratorInfo, mDescriptor)) {
+ continue;
+ }
+ mHapticParam.push_back(createVibratorParam(vibratorInfo));
+ }
+ ASSERT_NO_FATAL_FAILURE(validateIncreasingEnergy(HapticGenerator::vibratorInfo));
+}
+
+TEST_P(HapticGeneratorDataTest, IncreasingQfactorTest) {
+ std::vector<float> increasingQfactor = {16, 24, 32, 40};
+ generateSinePeriod();
+ ASSERT_NO_FATAL_FAILURE(setBaseScaleParam());
+ for (float qFactor : increasingQfactor) {
+ auto vibratorInfo = createVibratorInfo(kDefaultResonantFrequency, qFactor, kDefaultMaxAmp);
+ if (!isParameterValid<HapticGenerator, Range::hapticGenerator>(vibratorInfo, mDescriptor)) {
+ continue;
+ }
+ mHapticParam.push_back(createVibratorParam(vibratorInfo));
+ }
+ ASSERT_NO_FATAL_FAILURE(validateIncreasingEnergy(HapticGenerator::vibratorInfo));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ DataTest, HapticGeneratorDataTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
+ testing::ValuesIn(kHapticOutputLayouts)),
+ [](const testing::TestParamInfo<HapticGeneratorDataTest::ParamType>& info) {
+ auto descriptor = std::get<EFFECT_INSTANCE>(info.param).second;
+ std::string layout = "0x" + std::format("{:x}", std::get<LAYOUT>(info.param));
+ std::string name = getPrefix(descriptor) + "_layout_" + layout;
+ return name;
+ });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorDataTest);
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
diff --git a/automotive/TEST_MAPPING b/automotive/TEST_MAPPING
index c64c880..483a85f 100644
--- a/automotive/TEST_MAPPING
+++ b/automotive/TEST_MAPPING
@@ -19,10 +19,58 @@
"name": "CtsCarBuiltinApiHostTestCases"
},
{
- "name": "CarServiceTest"
+ "name": "CarServiceAudioTest"
+ },
+ {
+ "name": "CarServiceCarTest"
+ },
+ {
+ "name": "CarServiceClusterTest"
+ },
+ {
+ "name": "CarServiceDiagnosticTest"
+ },
+ {
+ "name": "CarServiceDrivingStateTest"
+ },
+ {
+ "name": "CarServiceEvsTest"
+ },
+ {
+ "name": "CarServiceGarageModeTest"
+ },
+ {
+ "name": "CarServiceInputTest"
+ },
+ {
+ "name": "CarServiceOsTest"
+ },
+ {
+ "name": "CarServicePmTest"
+ },
+ {
+ "name": "CarServicePowerTest"
+ },
+ {
+ "name": "CarServicePropertyTest"
+ },
+ {
+ "name": "CarServiceRemoteAccessTest"
+ },
+ {
+ "name": "CarServiceStorageMonitoringTest"
+ },
+ {
+ "name": "CarServiceTelemetryTest"
},
{
"name": "CarServiceUnitTest"
+ },
+ {
+ "name": "CarServiceVmsTest"
+ },
+ {
+ "name": "CarServiceWatchdogTest"
}
]
}
\ No newline at end of file
diff --git a/automotive/evs/aidl/Android.bp b/automotive/evs/aidl/Android.bp
index dfb15c6..5b2f82f 100644
--- a/automotive/evs/aidl/Android.bp
+++ b/automotive/evs/aidl/Android.bp
@@ -44,6 +44,9 @@
ndk: {
min_sdk_version: "29",
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
diff --git a/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml b/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml
index 50692f7..9ddc6ad 100644
--- a/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml
+++ b/automotive/evs/aidl/impl/default/manifest_evs-default-service.xml
@@ -2,6 +2,6 @@
<hal format="aidl">
<name>android.hardware.automotive.evs</name>
<fqname>IEvsEnumerator/hw/0</fqname>
- <version>1</version>
+ <version>2</version>
</hal>
</manifest>
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl b/automotive/evs/aidl/rust_impl/Android.bp
similarity index 60%
copy from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
copy to automotive/evs/aidl/rust_impl/Android.bp
index c7be950..ac8b90f 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
+++ b/automotive/evs/aidl/rust_impl/Android.bp
@@ -14,22 +14,17 @@
* limitations under the License.
*/
-package android.hardware.biometrics.fingerprint;
-
-import android.hardware.biometrics.fingerprint.AcquiredInfo;
-
-/**
- * @hide
- */
-@VintfStability
-union AcquiredInfoAndVendorCode {
- /**
- * Acquired info as specified in AcqauiredInfo.aidl
- */
- AcquiredInfo acquiredInfo = AcquiredInfo.UNKNOWN;
-
- /**
- * Vendor specific code
- */
- int vendorCode;
+rust_binary {
+ name: "android.hardware.automotive.evs-aidl-rust-service",
+ relative_install_path: "hw",
+ vendor: true,
+ srcs: ["src/*.rs"],
+ crate_root: "src/main.rs",
+ vintf_fragments: ["manifest_evs-rust-service.xml"],
+ init_rc: ["evs-rust-service.rc"],
+ rustlibs: [
+ "android.hardware.automotive.evs-V2-rust",
+ "libbinder_rs",
+ "liblog_rust",
+ ],
}
diff --git a/automotive/evs/aidl/rust_impl/README.md b/automotive/evs/aidl/rust_impl/README.md
new file mode 100644
index 0000000..bf00aed
--- /dev/null
+++ b/automotive/evs/aidl/rust_impl/README.md
@@ -0,0 +1,21 @@
+# Rust Skeleton EVS HAL implementation.
+
+WARNING: This is not a reference EVS HAL implementation and therefore does not
+provide any actual functionality.
+
+This folder contains a skeleton EVS HAL implementation in Rust to demonstrate
+how vendors could implement their EVS HAL in Rust. To compile and run this
+implementation, please include below package to the device build script:
+
+* `android.hardware.automotive.evs-aidl-rust-service`
+
+Please note that this service will attempt to register the service as
+`IEvsEnumerator/rust/0` and therefore is also required to be declared in the
+service context by adding below line to a proper `service_contexts` file:
+
+> android.hardware.automotive.evs.IEvsEnumerator/rust/0 u:object_r:hal_evs_service:s0
+
+This implementation intentionally returns `binder::StatusCode::UNKNOWN_ERROR`
+for any API call except deprecated API for ultrasonics; the process will be
+panicked on these methods instead. Hence, this implementation does not comply
+with VTS tests and vendors must replace each method with actual implementation.
diff --git a/automotive/evs/aidl/rust_impl/evs-rust-service.rc b/automotive/evs/aidl/rust_impl/evs-rust-service.rc
new file mode 100644
index 0000000..3741b21
--- /dev/null
+++ b/automotive/evs/aidl/rust_impl/evs-rust-service.rc
@@ -0,0 +1,8 @@
+service vendor.evs-hal-rust-default /vendor/bin/hw/android.hardware.automotive.evs-aidl-rust-service
+ class early_hal
+ priority -20
+ user graphics
+ group automotive_evs camera
+ onrestart restart cardisplayproxyd
+ onrestart restart evsmanagerd
+ disabled
diff --git a/automotive/evs/aidl/rust_impl/manifest_evs-rust-service.xml b/automotive/evs/aidl/rust_impl/manifest_evs-rust-service.xml
new file mode 100644
index 0000000..813cbb2
--- /dev/null
+++ b/automotive/evs/aidl/rust_impl/manifest_evs-rust-service.xml
@@ -0,0 +1,7 @@
+<manifest version="2.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.automotive.evs</name>
+ <version>2</version>
+ <fqname>IEvsEnumerator/rust/0</fqname>
+ </hal>
+</manifest>
diff --git a/automotive/evs/aidl/rust_impl/src/default_evs_hal.rs b/automotive/evs/aidl/rust_impl/src/default_evs_hal.rs
new file mode 100644
index 0000000..72b2d53
--- /dev/null
+++ b/automotive/evs/aidl/rust_impl/src/default_evs_hal.rs
@@ -0,0 +1,113 @@
+//
+// 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.
+//
+
+use android_hardware_automotive_evs::aidl::android::hardware::automotive::evs::{
+ CameraDesc::CameraDesc, DisplayState::DisplayState, IEvsCamera::IEvsCamera,
+ IEvsDisplay::IEvsDisplay, IEvsEnumerator::IEvsEnumerator,
+ IEvsEnumeratorStatusCallback::IEvsEnumeratorStatusCallback,
+ IEvsUltrasonicsArray::IEvsUltrasonicsArray, Stream::Stream,
+ UltrasonicsArrayDesc::UltrasonicsArrayDesc,
+};
+
+pub struct DefaultEvsHal {}
+
+impl binder::Interface for DefaultEvsHal {}
+
+impl IEvsEnumerator for DefaultEvsHal {
+ fn closeCamera(
+ &self,
+ _: &binder::Strong<(dyn IEvsCamera + 'static)>,
+ ) -> std::result::Result<(), binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn closeDisplay(
+ &self,
+ _: &binder::Strong<(dyn IEvsDisplay + 'static)>,
+ ) -> std::result::Result<(), binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn closeUltrasonicsArray(
+ &self,
+ _: &binder::Strong<(dyn IEvsUltrasonicsArray + 'static)>,
+ ) -> std::result::Result<(), binder::Status> {
+ unimplemented!()
+ }
+
+ fn getCameraList(&self) -> std::result::Result<std::vec::Vec<CameraDesc>, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn getDisplayIdList(&self) -> std::result::Result<std::vec::Vec<u8>, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn getDisplayState(&self) -> std::result::Result<DisplayState, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn getStreamList(
+ &self,
+ _: &CameraDesc,
+ ) -> std::result::Result<std::vec::Vec<Stream>, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn getUltrasonicsArrayList(
+ &self,
+ ) -> std::result::Result<std::vec::Vec<UltrasonicsArrayDesc>, binder::Status> {
+ unimplemented!()
+ }
+
+ fn isHardware(&self) -> std::result::Result<bool, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn openCamera(
+ &self,
+ _: &str,
+ _: &Stream,
+ ) -> std::result::Result<binder::Strong<(dyn IEvsCamera + 'static)>, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn openDisplay(
+ &self,
+ _: i32,
+ ) -> std::result::Result<binder::Strong<(dyn IEvsDisplay + 'static)>, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn openUltrasonicsArray(
+ &self,
+ _: &str,
+ ) -> std::result::Result<binder::Strong<(dyn IEvsUltrasonicsArray + 'static)>, binder::Status>
+ {
+ unimplemented!()
+ }
+
+ fn registerStatusCallback(
+ &self,
+ _: &binder::Strong<(dyn IEvsEnumeratorStatusCallback + 'static)>,
+ ) -> std::result::Result<(), binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn getDisplayStateById(&self, _: i32) -> std::result::Result<DisplayState, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+}
diff --git a/automotive/evs/aidl/rust_impl/src/main.rs b/automotive/evs/aidl/rust_impl/src/main.rs
new file mode 100644
index 0000000..df312c0
--- /dev/null
+++ b/automotive/evs/aidl/rust_impl/src/main.rs
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+mod default_evs_hal;
+
+use crate::default_evs_hal::DefaultEvsHal;
+
+use android_hardware_automotive_evs::aidl::android::hardware::automotive::evs::IEvsEnumerator::BnEvsEnumerator;
+
+use log::info;
+
+fn main() {
+ binder::ProcessState::start_thread_pool();
+
+ let service = DefaultEvsHal {};
+
+ // Register HAL implementation as rust/0 instance.
+ let service_name = "android.hardware.automotive.evs.IEvsEnumerator/rust/0";
+ let service_binder = BnEvsEnumerator::new_binder(service, binder::BinderFeatures::default());
+
+ binder::add_service(service_name, service_binder.as_binder())
+ .expect(format!("Failed to register {}.", service_name).as_str());
+ info!("EVS Hardware Enumerator is ready");
+
+ binder::ProcessState::join_thread_pool();
+
+ // In normal operation, we don't expect the thread pool to exit.
+ info!("EVS Hardware Enumerator is shutting down");
+}
diff --git a/automotive/vehicle/Android.bp b/automotive/vehicle/Android.bp
index e614937..606e108 100644
--- a/automotive/vehicle/Android.bp
+++ b/automotive/vehicle/Android.bp
@@ -22,7 +22,7 @@
name: "VehicleHalInterfaceDefaults",
static_libs: [
"android.hardware.automotive.vehicle-V3-ndk",
- "android.hardware.automotive.vehicle.property-V3-ndk",
+ "android.hardware.automotive.vehicle.property-V4-ndk",
],
}
@@ -30,6 +30,14 @@
name: "VehicleHalInterfaceRustDefaults",
rustlibs: [
"android.hardware.automotive.vehicle-V3-rust",
- "android.hardware.automotive.vehicle.property-V3-rust",
+ "android.hardware.automotive.vehicle.property-V4-rust",
+ ],
+}
+
+aidl_interface_defaults {
+ name: "android.hardware.automotive.vehicle-latest-defaults",
+ imports: [
+ "android.hardware.automotive.vehicle-V3",
+ "android.hardware.automotive.vehicle.property-V4",
],
}
diff --git a/automotive/vehicle/aidl/aidl_test/Android.bp b/automotive/vehicle/aidl/aidl_test/Android.bp
index f517df8..1e43070 100644
--- a/automotive/vehicle/aidl/aidl_test/Android.bp
+++ b/automotive/vehicle/aidl/aidl_test/Android.bp
@@ -40,7 +40,7 @@
cc_test {
name: "VehiclePropertyAnnotationCppTest",
srcs: ["VehiclePropertyAnnotationCppTest.cpp"],
- header_libs: ["IVehicleGeneratedHeaders-V3"],
+ header_libs: ["IVehicleGeneratedHeaders-V4"],
defaults: ["VehicleHalInterfaceDefaults"],
test_suites: ["general-tests"],
}
@@ -49,11 +49,11 @@
name: "VehiclePropertyAnnotationJavaTest",
srcs: [
"VehiclePropertyAnnotationJavaTest.java",
- ":IVehicleGeneratedJavaFiles-V3",
+ ":IVehicleGeneratedJavaFiles-V4",
],
static_libs: [
"android.hardware.automotive.vehicle-V3-java",
- "android.hardware.automotive.vehicle.property-V3-java",
+ "android.hardware.automotive.vehicle.property-V4-java",
"androidx.test.runner",
"truth",
],
diff --git a/automotive/vehicle/aidl/generated_lib/3/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/3/cpp/AccessForVehicleProperty.h
index 51a3025..6f6c91c 100644
--- a/automotive/vehicle/aidl/generated_lib/3/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/3/cpp/AccessForVehicleProperty.h
@@ -27,6 +27,10 @@
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
+// Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+#include <PerDisplayMaxBrightness.h>
+// End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+
#include <unordered_map>
namespace aidl {
@@ -302,6 +306,9 @@
{VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
+ // Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+ {PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyAccess::READ},
+ // End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/3/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/3/cpp/ChangeModeForVehicleProperty.h
index 60e9a72..88f2f88 100644
--- a/automotive/vehicle/aidl/generated_lib/3/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/3/cpp/ChangeModeForVehicleProperty.h
@@ -27,6 +27,10 @@
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
+// Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+#include <PerDisplayMaxBrightness.h>
+// End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+
#include <unordered_map>
namespace aidl {
@@ -302,6 +306,9 @@
{VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ // Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+ {PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyChangeMode::STATIC},
+ // End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
};
} // namespace vehicle
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl b/automotive/vehicle/aidl/generated_lib/3/cpp/PerDisplayMaxBrightness.h
similarity index 62%
copy from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
copy to automotive/vehicle/aidl/generated_lib/3/cpp/PerDisplayMaxBrightness.h
index c7be950..2b50db3 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
+++ b/automotive/vehicle/aidl/generated_lib/3/cpp/PerDisplayMaxBrightness.h
@@ -14,22 +14,13 @@
* limitations under the License.
*/
-package android.hardware.biometrics.fingerprint;
+#pragma once
-import android.hardware.biometrics.fingerprint.AcquiredInfo;
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
-/**
- * @hide
- */
-@VintfStability
-union AcquiredInfoAndVendorCode {
- /**
- * Acquired info as specified in AcqauiredInfo.aidl
- */
- AcquiredInfo acquiredInfo = AcquiredInfo.UNKNOWN;
+namespace aidl::android::hardware::automotive::vehicle {
- /**
- * Vendor specific code
- */
- int vendorCode;
-}
+// Same as VehicleProperty::PER_DISPLAY_MAX_BRIGHTNESS as defined in v4.
+static constexpr VehicleProperty PER_DISPLAY_MAX_BRIGHTNESS = (VehicleProperty)0x11410F4E;
+
+} // namespace aidl::android::hardware::automotive::vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/3/cpp/VersionForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/3/cpp/VersionForVehicleProperty.h
index 0e80bd8..0d24273 100644
--- a/automotive/vehicle/aidl/generated_lib/3/cpp/VersionForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/3/cpp/VersionForVehicleProperty.h
@@ -26,6 +26,10 @@
#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+// Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+#include <PerDisplayMaxBrightness.h>
+// End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+
#include <unordered_map>
namespace aidl {
@@ -301,6 +305,9 @@
{VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, 3},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, 3},
{VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, 3},
+ // Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+ {PER_DISPLAY_MAX_BRIGHTNESS, 2},
+ // End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/3/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/AccessForVehicleProperty.java
index afb6cab..f899df8 100644
--- a/automotive/vehicle/aidl/generated_lib/3/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/3/java/AccessForVehicleProperty.java
@@ -28,6 +28,10 @@
public final class AccessForVehicleProperty {
+ // Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+ private static final int PER_DISPLAY_MAX_BRIGHTNESS = 0x11410F4E;
+ // End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+
public static final Map<Integer, Integer> values = Map.ofEntries(
Map.entry(VehicleProperty.INFO_VIN, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.INFO_MAKE, VehiclePropertyAccess.READ),
@@ -294,7 +298,10 @@
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
- Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ)
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ),
+ // Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+ Map.entry(PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyAccess.READ)
+ // End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
);
}
diff --git a/automotive/vehicle/aidl/generated_lib/3/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/ChangeModeForVehicleProperty.java
index 12aff40..09989bf 100644
--- a/automotive/vehicle/aidl/generated_lib/3/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/3/java/ChangeModeForVehicleProperty.java
@@ -28,6 +28,10 @@
public final class ChangeModeForVehicleProperty {
+ // Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+ private static final int PER_DISPLAY_MAX_BRIGHTNESS = 0x11410F4E;
+ // End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+
public static final Map<Integer, Integer> values = Map.ofEntries(
Map.entry(VehicleProperty.INFO_VIN, VehiclePropertyChangeMode.STATIC),
Map.entry(VehicleProperty.INFO_MAKE, VehiclePropertyChangeMode.STATIC),
@@ -294,7 +298,10 @@
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
- Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE)
+ Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ // Start manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
+ Map.entry(PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyChangeMode.STATIC)
+ // End manual edit: backport PER_DISPLAY_MAX_BRIGHTNESS.
);
}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
index 28c95ce..aef2909 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
@@ -27,7 +27,7 @@
defaults: ["VehicleHalDefaults"],
static_libs: ["VehicleHalUtils"],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: ["libjsoncpp"],
}
@@ -44,7 +44,7 @@
defaults: ["VehicleHalDefaults"],
static_libs: ["VehicleHalUtils"],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
"libbinder_headers",
],
cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
@@ -60,7 +60,7 @@
defaults: ["VehicleHalDefaults"],
static_libs: ["VehicleHalUtils"],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: ["libjsoncpp"],
}
diff --git a/automotive/vehicle/aidl/impl/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
index 70933be..52014fb 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
@@ -31,7 +31,7 @@
"libgtest",
],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: [
"libjsoncpp",
@@ -57,7 +57,7 @@
"-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: [
"libjsoncpp",
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
index 73bb521..8750375 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
@@ -83,6 +83,17 @@
return configs;
}
+std::optional<aidlvhal::VehiclePropConfig> GRPCVehicleHardware::getPropertyConfig(
+ int32_t propId) const {
+ // TODO(b/354055835): Use GRPC call to get one config instead of getting all the configs.
+ for (const auto& config : getAllPropertyConfigs()) {
+ if (config.prop == propId) {
+ return config;
+ }
+ }
+ return std::nullopt;
+}
+
aidlvhal::StatusCode GRPCVehicleHardware::setValues(
std::shared_ptr<const SetValuesCallback> callback,
const std::vector<aidlvhal::SetValueRequest>& requests) {
@@ -265,6 +276,7 @@
return {
.callerShouldDumpState = protoDumpResult.caller_should_dump_state(),
.buffer = protoDumpResult.buffer(),
+ .refreshPropertyConfigs = protoDumpResult.refresh_property_configs(),
};
}
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
index 1edf658..15f473c 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
@@ -50,6 +50,10 @@
// Get all the property configs.
std::vector<aidlvhal::VehiclePropConfig> getAllPropertyConfigs() const override;
+ // Get the config for the specified propId.
+ std::optional<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
+ getPropertyConfig(int32_t propId) const override;
+
// Set property values asynchronously. Server could return before the property set requests
// are sent to vehicle bus or before property set confirmation is received. The callback is
// safe to be called after the function returns and is safe to be called in a different thread.
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
index d7cbe1b..7697c03 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
@@ -226,6 +226,7 @@
auto dumpResult = mHardware->dump(dumpOptionStrings);
result->set_caller_should_dump_state(dumpResult.callerShouldDumpState);
result->set_buffer(dumpResult.buffer);
+ result->set_refresh_property_configs(dumpResult.refreshPropertyConfigs);
return ::grpc::Status::OK;
}
diff --git a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
index f49d91b..0684655 100644
--- a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
@@ -20,6 +20,7 @@
#include <VehicleHalTypes.h>
#include <memory>
+#include <optional>
#include <vector>
namespace android {
@@ -46,33 +47,53 @@
int32_t areaId;
};
+namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
+
// An abstract interface to access vehicle hardware.
// For virtualized VHAL, GrpcVehicleHardware would communicate with a VehicleHardware
// implementation in another VM through GRPC. For non-virtualzied VHAL, VHAL directly communicates
// with a VehicleHardware through this interface.
class IVehicleHardware {
public:
- using SetValuesCallback = std::function<void(
- std::vector<aidl::android::hardware::automotive::vehicle::SetValueResult>)>;
- using GetValuesCallback = std::function<void(
- std::vector<aidl::android::hardware::automotive::vehicle::GetValueResult>)>;
- using PropertyChangeCallback = std::function<void(
- std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>)>;
+ using SetValuesCallback = std::function<void(std::vector<aidlvhal::SetValueResult>)>;
+ using GetValuesCallback = std::function<void(std::vector<aidlvhal::GetValueResult>)>;
+ using PropertyChangeCallback = std::function<void(std::vector<aidlvhal::VehiclePropValue>)>;
using PropertySetErrorCallback = std::function<void(std::vector<SetValueErrorEvent>)>;
virtual ~IVehicleHardware() = default;
// Get all the property configs.
- virtual std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
- getAllPropertyConfigs() const = 0;
+ virtual std::vector<aidlvhal::VehiclePropConfig> getAllPropertyConfigs() const = 0;
+
+ // Get the property configs for the specified propId. This is used for early-boot
+ // native VHAL clients to access certain property configs when not all property configs are
+ // available. For example, a config discovery process might be required to determine the
+ // property config for HVAC. However, for early boot properties, e.g. VHAL_HEARTBEAT, it
+ // could return before the config discovery process.
+ //
+ // Currently Android system may try to access the following properties during early boot:
+ // STORAGE_ENCRYPTION_BINDING_SEED, WATCHDOG_ALIVE, WATCHDOG_TERMINATE_PROCESS, VHAL_HEARTBEAT,
+ // CURRENT_POWER_POLICY, POWER_POLICY_REQ, POWER_POLICY_GROUP_REQ. They should return
+ // quickly otherwise the whole bootup process might be blocked.
+ virtual std::optional<aidlvhal::VehiclePropConfig> getPropertyConfig(int32_t propId) const {
+ // The default implementation is to use getAllPropertyConfigs(). This should be
+ // overridden if getAllPropertyConfigs() takes a while to return for initial boot or
+ // relies on ethernet or other communication channel that is not available during early
+ // boot.
+ for (const auto& config : getAllPropertyConfigs()) {
+ if (config.prop == propId) {
+ return config;
+ }
+ }
+ return std::nullopt;
+ }
// Set property values asynchronously. Server could return before the property set requests
// are sent to vehicle bus or before property set confirmation is received. The callback is
// safe to be called after the function returns and is safe to be called in a different thread.
- virtual aidl::android::hardware::automotive::vehicle::StatusCode setValues(
+ virtual aidlvhal::StatusCode setValues(
std::shared_ptr<const SetValuesCallback> callback,
- const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
- requests) = 0;
+ const std::vector<aidlvhal::SetValueRequest>& requests) = 0;
// Get property values asynchronously. Server could return before the property values are ready.
// The callback is safe to be called after the function returns and is safe to be called in a
@@ -86,7 +107,7 @@
virtual DumpResult dump(const std::vector<std::string>& options) = 0;
// Check whether the system is healthy, return {@code StatusCode::OK} for healthy.
- virtual aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() = 0;
+ virtual aidlvhal::StatusCode checkHealth() = 0;
// Register a callback that would be called when there is a property change event from vehicle.
// This function must only be called once during initialization.
@@ -179,16 +200,14 @@
// 5. The second subscriber is removed, 'unsubscribe' is called.
// The impl can optionally disable the polling for vehicle speed.
//
- virtual aidl::android::hardware::automotive::vehicle::StatusCode subscribe(
- [[maybe_unused]] aidl::android::hardware::automotive::vehicle::SubscribeOptions
- options) {
- return aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+ virtual aidlvhal::StatusCode subscribe([[maybe_unused]] aidlvhal::SubscribeOptions options) {
+ return aidlvhal::StatusCode::OK;
}
// A [propId, areaId] is unsubscribed. This applies for both continuous or on-change property.
- virtual aidl::android::hardware::automotive::vehicle::StatusCode unsubscribe(
- [[maybe_unused]] int32_t propId, [[maybe_unused]] int32_t areaId) {
- return aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+ virtual aidlvhal::StatusCode unsubscribe([[maybe_unused]] int32_t propId,
+ [[maybe_unused]] int32_t areaId) {
+ return aidlvhal::StatusCode::OK;
}
// This function is deprecated, subscribe/unsubscribe should be used instead.
@@ -216,10 +235,10 @@
//
// If the impl is always polling at {@code maxSampleRate} as specified in config, then this
// function can be a no-op.
- virtual aidl::android::hardware::automotive::vehicle::StatusCode updateSampleRate(
- [[maybe_unused]] int32_t propId, [[maybe_unused]] int32_t areaId,
- [[maybe_unused]] float sampleRate) {
- return aidl::android::hardware::automotive::vehicle::StatusCode::OK;
+ virtual aidlvhal::StatusCode updateSampleRate([[maybe_unused]] int32_t propId,
+ [[maybe_unused]] int32_t areaId,
+ [[maybe_unused]] float sampleRate) {
+ return aidlvhal::StatusCode::OK;
}
};
diff --git a/automotive/vehicle/aidl/impl/proto/Android.bp b/automotive/vehicle/aidl/impl/proto/Android.bp
index b2edf75..1d35e0c 100644
--- a/automotive/vehicle/aidl/impl/proto/Android.bp
+++ b/automotive/vehicle/aidl/impl/proto/Android.bp
@@ -106,3 +106,17 @@
"-Wno-unused-parameter",
],
}
+
+rust_protobuf {
+ name: "libvehicle_hal_property_protos",
+ crate_name: "vehicle_hal_property_protos",
+ protos: [":VehicleHalProtoFiles"],
+ source_stem: "vehicle_hal_property_protos",
+ host_supported: true,
+ vendor_available: true,
+ product_available: true,
+ exported_include_dirs: ["."],
+ proto_flags: [
+ "-I external/protobuf/src",
+ ],
+}
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpResult.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpResult.proto
index 25bb7d4..fbfb505 100644
--- a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpResult.proto
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpResult.proto
@@ -25,4 +25,6 @@
bool caller_should_dump_state = 1;
/* The dumped information for the caller to print. */
string buffer = 2;
+ /* To pass if DefaultVehicleHal should refresh the property configs. */
+ bool refresh_property_configs = 3;
}
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index 5cc071d..54d148e 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -66,7 +66,7 @@
],
header_libs: [
"IVehicleHardware",
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
shared_libs: [
"libbinder_ndk",
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index fa2a310..932a2e2 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -31,6 +31,7 @@
#include <android-base/thread_annotations.h>
#include <android/binder_auto_utils.h>
+#include <functional>
#include <memory>
#include <mutex>
#include <shared_mutex>
@@ -138,12 +139,11 @@
// Only used for testing.
int32_t mTestInterfaceVersion = 0;
- // mConfigsByPropId and mConfigFile is lazy initialized.
- mutable std::mutex mConfigInitLock;
- mutable bool mConfigInit GUARDED_BY(mConfigInitLock) = false;
+ mutable std::atomic<bool> mConfigInit = false;
+ mutable std::shared_timed_mutex mConfigLock;
mutable std::unordered_map<int32_t, aidlvhal::VehiclePropConfig> mConfigsByPropId
- GUARDED_BY(mConfigInitLock);
- mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigInitLock);
+ GUARDED_BY(mConfigLock);
+ mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigLock);
std::mutex mLock;
std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
@@ -175,7 +175,10 @@
android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
const std::vector<aidlvhal::SetValueRequest>& requests);
- VhalResult<void> checkSubscribeOptions(const std::vector<aidlvhal::SubscribeOptions>& options);
+ VhalResult<void> checkSubscribeOptions(
+ const std::vector<aidlvhal::SubscribeOptions>& options,
+ const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId)
+ REQUIRES_SHARED(mConfigLock);
VhalResult<void> checkPermissionHelper(const aidlvhal::VehiclePropValue& value,
aidlvhal::VehiclePropertyAccess accessToTest) const;
@@ -184,7 +187,7 @@
VhalResult<void> checkWritePermission(const aidlvhal::VehiclePropValue& value) const;
- android::base::Result<const aidlvhal::VehiclePropConfig*> getConfig(int32_t propId) const;
+ android::base::Result<aidlvhal::VehiclePropConfig> getConfig(int32_t propId) const;
void onBinderDiedWithContext(const AIBinder* clientId);
@@ -196,7 +199,9 @@
bool checkDumpPermission();
- bool getAllPropConfigsFromHardwareLocked() const REQUIRES(mConfigInitLock);
+ bool isConfigSupportedForCurrentVhalVersion(const aidlvhal::VehiclePropConfig& config) const;
+
+ bool getAllPropConfigsFromHardwareLocked() const EXCLUDES(mConfigLock);
// The looping handler function to process all onBinderDied or onBinderUnlinked events in
// mBinderEvents.
@@ -209,10 +214,12 @@
int32_t getVhalInterfaceVersion() const;
- // Gets mConfigsByPropId, lazy init it if necessary.
- const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& getConfigsByPropId() const;
- // Gets mConfigFile, lazy init it if necessary.
- const ndk::ScopedFileDescriptor* getConfigFile() const;
+ // Gets mConfigsByPropId, lazy init it if necessary. Note that the reference is only valid in
+ // the scope of the callback and it is guaranteed that read lock is obtained during the
+ // callback.
+ void getConfigsByPropId(
+ std::function<void(const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>&)>
+ callback) const EXCLUDES(mConfigLock);
// Puts the property change events into a queue so that they can handled in batch.
static void batchPropertyChangeEvent(
@@ -239,6 +246,12 @@
static void onBinderUnlinked(void* cookie);
+ static void parseSubscribeOptions(
+ const std::vector<aidlvhal::SubscribeOptions>& options,
+ const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId,
+ std::vector<aidlvhal::SubscribeOptions>& onChangeSubscriptions,
+ std::vector<aidlvhal::SubscribeOptions>& continuousSubscriptions);
+
// Test-only
// Set the default timeout for pending requests.
void setTimeout(int64_t timeoutInNano);
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index 9dc039d..0ead819 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -95,6 +95,18 @@
return sampleRateHz;
}
+class SCOPED_CAPABILITY SharedScopedLockAssertion {
+ public:
+ SharedScopedLockAssertion(std::shared_timed_mutex& mutex) ACQUIRE_SHARED(mutex) {}
+ ~SharedScopedLockAssertion() RELEASE() {}
+};
+
+class SCOPED_CAPABILITY UniqueScopedLockAssertion {
+ public:
+ UniqueScopedLockAssertion(std::shared_timed_mutex& mutex) ACQUIRE(mutex) {}
+ ~UniqueScopedLockAssertion() RELEASE() {}
+};
+
} // namespace
DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
@@ -328,95 +340,127 @@
return myVersion;
}
-bool DefaultVehicleHal::getAllPropConfigsFromHardwareLocked() const {
- ALOGD("Get all property configs from hardware");
- auto configs = mVehicleHardware->getAllPropertyConfigs();
- std::vector<VehiclePropConfig> filteredConfigs;
+bool DefaultVehicleHal::isConfigSupportedForCurrentVhalVersion(
+ const VehiclePropConfig& config) const {
int32_t myVersion = getVhalInterfaceVersion();
- for (auto& config : configs) {
- if (!isSystemProp(config.prop)) {
- filteredConfigs.push_back(std::move(config));
- continue;
- }
- VehicleProperty property = static_cast<VehicleProperty>(config.prop);
- std::string propertyName = aidl::android::hardware::automotive::vehicle::toString(property);
- auto it = VersionForVehicleProperty.find(property);
- if (it == VersionForVehicleProperty.end()) {
- ALOGE("The property: %s is not a supported system property, ignore",
- propertyName.c_str());
- continue;
- }
- int requiredVersion = it->second;
- if (myVersion < requiredVersion) {
- ALOGE("The property: %s is not supported for current client VHAL version, "
- "require %d, current version: %d, ignore",
- propertyName.c_str(), requiredVersion, myVersion);
- continue;
- }
- filteredConfigs.push_back(std::move(config));
+ if (!isSystemProp(config.prop)) {
+ return true;
}
- for (auto& config : filteredConfigs) {
- mConfigsByPropId[config.prop] = config;
- }
- VehiclePropConfigs vehiclePropConfigs;
- vehiclePropConfigs.payloads = std::move(filteredConfigs);
- auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
- if (!result.ok()) {
- ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
- result.error().message().c_str(), static_cast<int>(result.error().code()));
- mConfigFile = nullptr;
+ VehicleProperty property = static_cast<VehicleProperty>(config.prop);
+ std::string propertyName = aidl::android::hardware::automotive::vehicle::toString(property);
+ auto it = VersionForVehicleProperty.find(property);
+ if (it == VersionForVehicleProperty.end()) {
+ ALOGE("The property: %s is not a supported system property, ignore", propertyName.c_str());
return false;
}
-
- if (result.value() != nullptr) {
- mConfigFile = std::move(result.value());
+ int requiredVersion = it->second;
+ if (myVersion < requiredVersion) {
+ ALOGE("The property: %s is not supported for current client VHAL version, "
+ "require %d, current version: %d, ignore",
+ propertyName.c_str(), requiredVersion, myVersion);
+ return false;
}
return true;
}
-const ScopedFileDescriptor* DefaultVehicleHal::getConfigFile() const {
- std::scoped_lock lockGuard(mConfigInitLock);
- if (!mConfigInit) {
- CHECK(getAllPropConfigsFromHardwareLocked())
- << "Failed to get property configs from hardware";
- mConfigInit = true;
+bool DefaultVehicleHal::getAllPropConfigsFromHardwareLocked() const {
+ ALOGD("Get all property configs from hardware");
+ auto configs = mVehicleHardware->getAllPropertyConfigs();
+ std::vector<VehiclePropConfig> filteredConfigs;
+ for (const auto& config : configs) {
+ if (isConfigSupportedForCurrentVhalVersion(config)) {
+ filteredConfigs.push_back(std::move(config));
+ }
}
- return mConfigFile.get();
+
+ {
+ std::unique_lock<std::shared_timed_mutex> configWriteLock(mConfigLock);
+ UniqueScopedLockAssertion lockAssertion(mConfigLock);
+
+ for (auto& config : filteredConfigs) {
+ mConfigsByPropId[config.prop] = config;
+ }
+ VehiclePropConfigs vehiclePropConfigs;
+ vehiclePropConfigs.payloads = std::move(filteredConfigs);
+ auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
+ if (!result.ok()) {
+ ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
+ result.error().message().c_str(), static_cast<int>(result.error().code()));
+ mConfigFile = nullptr;
+ return false;
+ }
+
+ if (result.value() != nullptr) {
+ mConfigFile = std::move(result.value());
+ }
+ }
+
+ mConfigInit = true;
+ return true;
}
-const std::unordered_map<int32_t, VehiclePropConfig>& DefaultVehicleHal::getConfigsByPropId()
- const {
- std::scoped_lock lockGuard(mConfigInitLock);
+void DefaultVehicleHal::getConfigsByPropId(
+ std::function<void(const std::unordered_map<int32_t, VehiclePropConfig>&)> callback) const {
if (!mConfigInit) {
CHECK(getAllPropConfigsFromHardwareLocked())
<< "Failed to get property configs from hardware";
- mConfigInit = true;
}
- return mConfigsByPropId;
+
+ std::shared_lock<std::shared_timed_mutex> configReadLock(mConfigLock);
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ callback(mConfigsByPropId);
}
ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
- const ScopedFileDescriptor* configFile = getConfigFile();
- const auto& configsByPropId = getConfigsByPropId();
- if (configFile != nullptr) {
+ if (!mConfigInit) {
+ CHECK(getAllPropConfigsFromHardwareLocked())
+ << "Failed to get property configs from hardware";
+ }
+
+ std::shared_lock<std::shared_timed_mutex> configReadLock(mConfigLock);
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ if (mConfigFile != nullptr) {
output->payloads.clear();
- output->sharedMemoryFd.set(dup(configFile->get()));
+ output->sharedMemoryFd.set(dup(mConfigFile->get()));
return ScopedAStatus::ok();
}
- output->payloads.reserve(configsByPropId.size());
- for (const auto& [_, config] : configsByPropId) {
+
+ output->payloads.reserve(mConfigsByPropId.size());
+ for (const auto& [_, config] : mConfigsByPropId) {
output->payloads.push_back(config);
}
return ScopedAStatus::ok();
}
-Result<const VehiclePropConfig*> DefaultVehicleHal::getConfig(int32_t propId) const {
- const auto& configsByPropId = getConfigsByPropId();
- auto it = configsByPropId.find(propId);
- if (it == configsByPropId.end()) {
- return Error() << "no config for property, ID: " << propId;
+Result<VehiclePropConfig> DefaultVehicleHal::getConfig(int32_t propId) const {
+ Result<VehiclePropConfig> result;
+
+ if (!mConfigInit) {
+ std::optional<VehiclePropConfig> config = mVehicleHardware->getPropertyConfig(propId);
+ if (!config.has_value()) {
+ return Error() << "no config for property, ID: " << propId;
+ }
+ if (!isConfigSupportedForCurrentVhalVersion(config.value())) {
+ return Error() << "property not supported for current VHAL interface, ID: " << propId;
+ }
+
+ return config.value();
}
- return &(it->second);
+
+ getConfigsByPropId([this, &result, propId](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ auto it = configsByPropId.find(propId);
+ if (it == configsByPropId.end()) {
+ result = Error() << "no config for property, ID: " << propId;
+ return;
+ }
+ // Copy the VehiclePropConfig
+ result = it->second;
+ });
+ return result;
}
Result<void> DefaultVehicleHal::checkProperty(const VehiclePropValue& propValue) {
@@ -425,15 +469,15 @@
if (!result.ok()) {
return result.error();
}
- const VehiclePropConfig* config = result.value();
- const VehicleAreaConfig* areaConfig = getAreaConfig(propValue, *config);
+ const VehiclePropConfig& config = result.value();
+ const VehicleAreaConfig* areaConfig = getAreaConfig(propValue, config);
if (!isGlobalProp(propId) && areaConfig == nullptr) {
// Ignore areaId for global property. For non global property, check whether areaId is
// allowed. areaId must appear in areaConfig.
return Error() << "invalid area ID: " << propValue.areaId << " for prop ID: " << propId
<< ", not listed in config";
}
- if (auto result = checkPropValue(propValue, config); !result.ok()) {
+ if (auto result = checkPropValue(propValue, &config); !result.ok()) {
return Error() << "invalid property value: " << propValue.toString()
<< ", error: " << getErrorMsg(result);
}
@@ -659,17 +703,43 @@
ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>& props,
VehiclePropConfigs* output) {
std::vector<VehiclePropConfig> configs;
- const auto& configsByPropId = getConfigsByPropId();
- for (int32_t prop : props) {
- auto it = configsByPropId.find(prop);
- if (it != configsByPropId.end()) {
- configs.push_back(it->second);
- } else {
- return ScopedAStatus::fromServiceSpecificErrorWithMessage(
- toInt(StatusCode::INVALID_ARG),
- StringPrintf("no config for property, ID: %" PRId32, prop).c_str());
+
+ if (!mConfigInit) {
+ for (int32_t prop : props) {
+ auto maybeConfig = mVehicleHardware->getPropertyConfig(prop);
+ if (!maybeConfig.has_value() ||
+ !isConfigSupportedForCurrentVhalVersion(maybeConfig.value())) {
+ return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ toInt(StatusCode::INVALID_ARG),
+ StringPrintf("no config for property, ID: %" PRId32, prop).c_str());
+ }
+ configs.push_back(maybeConfig.value());
}
+
+ return vectorToStableLargeParcelable(std::move(configs), output);
}
+
+ ScopedAStatus status = ScopedAStatus::ok();
+ getConfigsByPropId([this, &configs, &status, &props](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ for (int32_t prop : props) {
+ auto it = configsByPropId.find(prop);
+ if (it != configsByPropId.end()) {
+ configs.push_back(it->second);
+ } else {
+ status = ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ toInt(StatusCode::INVALID_ARG),
+ StringPrintf("no config for property, ID: %" PRId32, prop).c_str());
+ return;
+ }
+ }
+ });
+
+ if (!status.isOk()) {
+ return status;
+ }
+
return vectorToStableLargeParcelable(std::move(configs), output);
}
@@ -691,8 +761,8 @@
}
VhalResult<void> DefaultVehicleHal::checkSubscribeOptions(
- const std::vector<SubscribeOptions>& options) {
- const auto& configsByPropId = getConfigsByPropId();
+ const std::vector<SubscribeOptions>& options,
+ const std::unordered_map<int32_t, VehiclePropConfig>& configsByPropId) {
for (const auto& option : options) {
int32_t propId = option.propId;
auto it = configsByPropId.find(propId);
@@ -757,23 +827,15 @@
}
}
}
+
return {};
}
-ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
- const std::vector<SubscribeOptions>& options,
- [[maybe_unused]] int32_t maxSharedMemoryFileCount) {
- // TODO(b/205189110): Use shared memory file count.
- if (callback == nullptr) {
- return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
- }
- if (auto result = checkSubscribeOptions(options); !result.ok()) {
- ALOGE("subscribe: invalid subscribe options: %s", getErrorMsg(result).c_str());
- return toScopedAStatus(result);
- }
- std::vector<SubscribeOptions> onChangeSubscriptions;
- std::vector<SubscribeOptions> continuousSubscriptions;
- const auto& configsByPropId = getConfigsByPropId();
+void DefaultVehicleHal::parseSubscribeOptions(
+ const std::vector<SubscribeOptions>& options,
+ const std::unordered_map<int32_t, VehiclePropConfig>& configsByPropId,
+ std::vector<SubscribeOptions>& onChangeSubscriptions,
+ std::vector<SubscribeOptions>& continuousSubscriptions) {
for (const auto& option : options) {
int32_t propId = option.propId;
// We have already validate config exists.
@@ -831,6 +893,34 @@
onChangeSubscriptions.push_back(std::move(optionCopy));
}
}
+}
+
+ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback,
+ const std::vector<SubscribeOptions>& options,
+ [[maybe_unused]] int32_t maxSharedMemoryFileCount) {
+ // TODO(b/205189110): Use shared memory file count.
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+ }
+ std::vector<SubscribeOptions> onChangeSubscriptions;
+ std::vector<SubscribeOptions> continuousSubscriptions;
+ ScopedAStatus returnStatus = ScopedAStatus::ok();
+ getConfigsByPropId([this, &returnStatus, &options, &onChangeSubscriptions,
+ &continuousSubscriptions](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ if (auto result = checkSubscribeOptions(options, configsByPropId); !result.ok()) {
+ ALOGE("subscribe: invalid subscribe options: %s", getErrorMsg(result).c_str());
+ returnStatus = toScopedAStatus(result);
+ return;
+ }
+ parseSubscribeOptions(options, configsByPropId, onChangeSubscriptions,
+ continuousSubscriptions);
+ });
+
+ if (!returnStatus.isOk()) {
+ return returnStatus;
+ }
{
// Lock to make sure onBinderDied would not be called concurrently.
@@ -891,13 +981,13 @@
return StatusError(StatusCode::INVALID_ARG) << getErrorMsg(result);
}
- const VehiclePropConfig* config = result.value();
- const VehicleAreaConfig* areaConfig = getAreaConfig(value, *config);
+ const VehiclePropConfig& config = result.value();
+ const VehicleAreaConfig* areaConfig = getAreaConfig(value, config);
if (areaConfig == nullptr && !isGlobalProp(propId)) {
return StatusError(StatusCode::INVALID_ARG) << "no config for area ID: " << value.areaId;
}
- if (!hasRequiredAccess(config->access, accessToTest) &&
+ if (!hasRequiredAccess(config.access, accessToTest) &&
(areaConfig == nullptr || !hasRequiredAccess(areaConfig->access, accessToTest))) {
return StatusError(StatusCode::ACCESS_DENIED)
<< StringPrintf("Property %" PRId32 " does not have the following access: %" PRId32,
@@ -966,7 +1056,6 @@
}
DumpResult result = mVehicleHardware->dump(options);
if (result.refreshPropertyConfigs) {
- std::scoped_lock lockGuard(mConfigInitLock);
getAllPropConfigsFromHardwareLocked();
}
dprintf(fd, "%s", (result.buffer + "\n").c_str());
@@ -974,11 +1063,16 @@
return STATUS_OK;
}
dprintf(fd, "Vehicle HAL State: \n");
- const auto& configsByPropId = getConfigsByPropId();
+ std::unordered_map<int32_t, VehiclePropConfig> configsByPropIdCopy;
+ getConfigsByPropId([this, &configsByPropIdCopy](const auto& configsByPropId) {
+ SharedScopedLockAssertion lockAssertion(mConfigLock);
+
+ configsByPropIdCopy = configsByPropId;
+ });
{
std::scoped_lock<std::mutex> lockGuard(mLock);
dprintf(fd, "Interface version: %" PRId32 "\n", getVhalInterfaceVersion());
- dprintf(fd, "Containing %zu property configs\n", configsByPropId.size());
+ dprintf(fd, "Containing %zu property configs\n", configsByPropIdCopy.size());
dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size());
dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size());
dprintf(fd, "Currently have %zu subscribe clients\n", countSubscribeClients());
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index 11a8fc7..4891bf5 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -650,6 +650,8 @@
auto hardware = std::make_unique<MockVehicleHardware>();
hardware->setPropertyConfigs(testConfigs);
+ // Store the pointer for testing. We are sure it is valid.
+ MockVehicleHardware* hardwarePtr = hardware.get();
auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
@@ -658,6 +660,7 @@
ASSERT_TRUE(status.isOk()) << "getPropConfigs failed: " << status.getMessage();
ASSERT_EQ(output.payloads, testConfigs);
+ ASSERT_FALSE(hardwarePtr->getAllPropertyConfigsCalled());
}
TEST_F(DefaultVehicleHalTest, testGetPropConfigsInvalidArg) {
@@ -704,6 +707,34 @@
ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
EXPECT_EQ(maybeGetValueResults.value().payloads, expectedResults) << "results mismatch";
EXPECT_EQ(countClients(), static_cast<size_t>(1));
+ ASSERT_FALSE(getHardware()->getAllPropertyConfigsCalled());
+}
+
+TEST_F(DefaultVehicleHalTest, testGetValuesSmall_AfterGetAllPropConfigs) {
+ GetValueRequests requests;
+ std::vector<GetValueResult> expectedResults;
+ std::vector<GetValueRequest> expectedHardwareRequests;
+
+ // If we already called getAllPropConfigs, the configs will be cached.
+ VehiclePropConfigs output;
+ getClient()->getAllPropConfigs(&output);
+
+ ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+ getHardware()->addGetValueResponses(expectedResults);
+
+ auto status = getClient()->getValues(getCallbackClient(), requests);
+
+ ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
+
+ EXPECT_EQ(getHardware()->nextGetValueRequests(), expectedHardwareRequests)
+ << "requests to hardware mismatch";
+
+ auto maybeGetValueResults = getCallback()->nextGetValueResults();
+ ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
+ EXPECT_EQ(maybeGetValueResults.value().payloads, expectedResults) << "results mismatch";
+ EXPECT_EQ(countClients(), static_cast<size_t>(1));
+ ASSERT_TRUE(getHardware()->getAllPropertyConfigsCalled());
}
TEST_F(DefaultVehicleHalTest, testGetValuesLarge) {
@@ -1016,6 +1047,34 @@
ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
ASSERT_EQ(maybeSetValueResults.value().payloads, expectedResults) << "results mismatch";
EXPECT_EQ(countClients(), static_cast<size_t>(1));
+ ASSERT_FALSE(getHardware()->getAllPropertyConfigsCalled());
+}
+
+TEST_F(DefaultVehicleHalTest, testSetValuesSmall_AfterGetAllPropConfigs) {
+ SetValueRequests requests;
+ std::vector<SetValueResult> expectedResults;
+ std::vector<SetValueRequest> expectedHardwareRequests;
+
+ // If we already called getAllPropConfigs, the configs will be cached.
+ VehiclePropConfigs output;
+ getClient()->getAllPropConfigs(&output);
+
+ ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+ getHardware()->addSetValueResponses(expectedResults);
+
+ auto status = getClient()->setValues(getCallbackClient(), requests);
+
+ ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
+
+ EXPECT_EQ(getHardware()->nextSetValueRequests(), expectedHardwareRequests)
+ << "requests to hardware mismatch";
+
+ auto maybeSetValueResults = getCallback()->nextSetValueResults();
+ ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
+ ASSERT_EQ(maybeSetValueResults.value().payloads, expectedResults) << "results mismatch";
+ EXPECT_EQ(countClients(), static_cast<size_t>(1));
+ ASSERT_TRUE(getHardware()->getAllPropertyConfigsCalled());
}
TEST_F(DefaultVehicleHalTest, testSetValuesLarge) {
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
index db15c89..e796ce5 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
@@ -45,9 +45,20 @@
std::vector<VehiclePropConfig> MockVehicleHardware::getAllPropertyConfigs() const {
std::scoped_lock<std::mutex> lockGuard(mLock);
+ mGetAllPropertyConfigsCalled = true;
return mPropertyConfigs;
}
+std::optional<VehiclePropConfig> MockVehicleHardware::getPropertyConfig(int32_t propId) const {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ for (const auto& config : mPropertyConfigs) {
+ if (config.prop == propId) {
+ return config;
+ }
+ }
+ return std::nullopt;
+}
+
StatusCode MockVehicleHardware::setValues(std::shared_ptr<const SetValuesCallback> callback,
const std::vector<SetValueRequest>& requests) {
std::scoped_lock<std::mutex> lockGuard(mLock);
@@ -336,6 +347,11 @@
(*mPropertySetErrorCallback)(errorEvents);
}
+bool MockVehicleHardware::getAllPropertyConfigsCalled() {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+ return mGetAllPropertyConfigsCalled;
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
index eeca582..06e01a8 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
@@ -47,6 +47,8 @@
std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
getAllPropertyConfigs() const override;
+ std::optional<aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
+ getPropertyConfig(int32_t propId) const override;
aidl::android::hardware::automotive::vehicle::StatusCode setValues(
std::shared_ptr<const SetValuesCallback> callback,
const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
@@ -98,6 +100,9 @@
std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>
getSubscribeOptions();
void clearSubscribeOptions();
+ // Whether getAllPropertyConfigs() has been called, which blocks all all property configs
+ // being ready.
+ bool getAllPropertyConfigsCalled();
private:
mutable std::mutex mLock;
@@ -143,6 +148,8 @@
DumpResult mDumpResult;
+ mutable bool mGetAllPropertyConfigsCalled GUARDED_BY(mLock) = false;
+
// RecurrentTimer is thread-safe.
std::shared_ptr<RecurrentTimer> mRecurrentTimer;
std::unordered_map<int32_t, std::unordered_map<int32_t, std::shared_ptr<std::function<void()>>>>
diff --git a/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java b/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
index bea5951..7f4ceb8 100644
--- a/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
+++ b/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
@@ -79,17 +79,18 @@
+ "either this or input_files must be specified\n" + INPUT_FILES_OPTION
+ ": one or more Java files, this is used to decide the input "
+ "directory\n" + PACKAGE_NAME_OPTION
- + ": the optional package name for the interface, by default is " + DEFAULT_PACKAGE_NAME
- + "\n" + OUTPUT_JSON_OPTION + ": The output JSON file\n" + OUTPUT_EMPTY_FILE_OPTION
- + ": Only used for check_mode, this file will be created if "
+ + ": the optional package name for the interface, by default is "
+ + DEFAULT_PACKAGE_NAME + "\n" + OUTPUT_JSON_OPTION + ": The output JSON file\n"
+ + OUTPUT_EMPTY_FILE_OPTION + ": Only used for check_mode, this file will be created if "
+ "check passed\n" + CHECK_AGAINST_OPTION
+ ": An optional JSON file to check against. If specified, the "
- + "generated output file will be checked against this file, if they are not the same, "
+ + ("generated output file will be checked against this file, if they are not the "
+ + "same, ")
+ "the script will fail, otherwise, the output_empty_file will be created\n"
+ "For example: \n"
+ "EnumMetadataGenerator --input_dir out/soong/.intermediates/hardware/"
+ "interfaces/automotive/vehicle/aidl_property/android.hardware.automotive.vehicle."
- + "property-V3-java-source/gen/ --package_name android.hardware.automotive.vehicle "
+ + "property-V4-java-source/gen/ --package_name android.hardware.automotive.vehicle "
+ "--output_json /tmp/android.hardware.automotive.vehicle-types-meta.json";
private static final String VEHICLE_PROPERTY_FILE = "VehicleProperty.java";
private static final String CHECK_FILE_PATH =
diff --git a/automotive/vehicle/vhal_static_cpp_lib.mk b/automotive/vehicle/vhal_static_cpp_lib.mk
index 6b3d486..9371453 100644
--- a/automotive/vehicle/vhal_static_cpp_lib.mk
+++ b/automotive/vehicle/vhal_static_cpp_lib.mk
@@ -17,4 +17,4 @@
LOCAL_STATIC_LIBRARIES += \
android.hardware.automotive.vehicle-V3-ndk \
- android.hardware.automotive.vehicle.property-V3-ndk
+ android.hardware.automotive.vehicle.property-V4-ndk
diff --git a/automotive/vehicle/vts/Android.bp b/automotive/vehicle/vts/Android.bp
index 40aec59..433ac41 100644
--- a/automotive/vehicle/vts/Android.bp
+++ b/automotive/vehicle/vts/Android.bp
@@ -43,7 +43,7 @@
"vhalclient_defaults",
],
header_libs: [
- "IVehicleGeneratedHeaders-V3",
+ "IVehicleGeneratedHeaders-V4",
],
test_suites: [
"general-tests",
diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp
index 246bcf2..854bd4a 100644
--- a/biometrics/common/aidl/Android.bp
+++ b/biometrics/common/aidl/Android.bp
@@ -22,6 +22,12 @@
cpp: {
enabled: false,
},
+ ndk: {
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
+ },
},
versions_with_info: [
{
diff --git a/biometrics/common/config/Android.bp b/biometrics/common/config/Android.bp
index d38ffe8..b86aafa 100644
--- a/biometrics/common/config/Android.bp
+++ b/biometrics/common/config/Android.bp
@@ -22,7 +22,7 @@
// SPDX-license-identifier-Apache-2.0
name: "android.hardware.biometrics.common.config",
export_include_dirs: ["include"],
- vendor: true,
+ vendor_available: true,
srcs: [
"Config.cpp",
],
@@ -30,6 +30,10 @@
"libbase",
"libbinder_ndk",
],
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
cc_test_host {
diff --git a/biometrics/common/thread/Android.bp b/biometrics/common/thread/Android.bp
index e7a7e4c..c1ebe3b 100644
--- a/biometrics/common/thread/Android.bp
+++ b/biometrics/common/thread/Android.bp
@@ -10,10 +10,14 @@
// SPDX-license-identifier-Apache-2.0
name: "android.hardware.biometrics.common.thread",
export_include_dirs: ["include"],
- vendor: true,
+ vendor_available: true,
srcs: [
"WorkerThread.cpp",
],
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
cc_test_host {
diff --git a/biometrics/common/util/Android.bp b/biometrics/common/util/Android.bp
index 599c491..a0bd211 100644
--- a/biometrics/common/util/Android.bp
+++ b/biometrics/common/util/Android.bp
@@ -6,7 +6,7 @@
// SPDX-license-identifier-Apache-2.0
name: "android.hardware.biometrics.common.util",
export_include_dirs: ["include"],
- vendor: true,
+ vendor_available: true,
srcs: [
"CancellationSignal.cpp",
],
@@ -15,4 +15,8 @@
"libbinder_ndk",
"android.hardware.biometrics.common-V4-ndk",
],
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index a395c01..c5b9937 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -11,7 +11,7 @@
name: "android.hardware.biometrics.fingerprint",
vendor_available: true,
srcs: [
- "android/hardware/biometrics/fingerprint/**/*.aidl",
+ "android/hardware/biometrics/fingerprint/*.aidl",
],
imports: [
"android.hardware.biometrics.common-V4",
@@ -25,6 +25,12 @@
cpp: {
enabled: false,
},
+ ndk: {
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
+ },
},
versions_with_info: [
{
@@ -57,5 +63,34 @@
},
],
+ frozen: true,
+}
+
+aidl_interface {
+ name: "android.hardware.biometrics.fingerprint.virtualhal",
+ srcs: [
+ "android/hardware/biometrics/fingerprint/virtualhal/*.aidl",
+ ],
+ imports: [
+ "android.hardware.biometrics.common-V4",
+ "android.hardware.keymaster-V4",
+ "android.hardware.biometrics.fingerprint-V4",
+ ],
+ vendor_available: true,
+ unstable: true,
+ backend: {
+ java: {
+ platform_apis: true,
+ },
+ cpp: {
+ enabled: false,
+ },
+ ndk: {
+ apex_available: [
+ "com.android.hardware.biometrics.fingerprint.virtual",
+ "//apex_available:platform",
+ ],
+ },
+ },
frozen: false,
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
deleted file mode 100644
index c1dc51c..0000000
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.biometrics.fingerprint;
-/* @hide */
-@VintfStability
-union AcquiredInfoAndVendorCode {
- android.hardware.biometrics.fingerprint.AcquiredInfo acquiredInfo = android.hardware.biometrics.fingerprint.AcquiredInfo.UNKNOWN;
- int vendorCode;
-}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
deleted file mode 100644
index 33ae83c..0000000
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.biometrics.fingerprint;
-/* @hide */
-@VintfStability
-interface IVirtualHal {
- oneway void setEnrollments(in int[] id);
- oneway void setEnrollmentHit(in int hit_id);
- oneway void setNextEnrollment(in android.hardware.biometrics.fingerprint.NextEnrollment next_enrollment);
- oneway void setAuthenticatorId(in long id);
- oneway void setChallenge(in long challenge);
- oneway void setOperationAuthenticateFails(in boolean fail);
- oneway void setOperationAuthenticateLatency(in int[] latencyMs);
- oneway void setOperationAuthenticateDuration(in int durationMs);
- oneway void setOperationAuthenticateError(in int error);
- oneway void setOperationAuthenticateAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquired);
- oneway void setOperationEnrollError(in int error);
- oneway void setOperationEnrollLatency(in int[] latencyMs);
- oneway void setOperationDetectInteractionLatency(in int[] latencyMs);
- oneway void setOperationDetectInteractionError(in int error);
- oneway void setOperationDetectInteractionDuration(in int durationMs);
- oneway void setOperationDetectInteractionAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquired);
- oneway void setLockout(in boolean lockout);
- oneway void setLockoutEnable(in boolean enable);
- oneway void setLockoutTimedThreshold(in int threshold);
- oneway void setLockoutTimedDuration(in int durationMs);
- oneway void setLockoutPermanentThreshold(in int threshold);
- oneway void resetConfigurations();
- oneway void setType(in android.hardware.biometrics.fingerprint.FingerprintSensorType type);
- oneway void setSensorId(in int id);
- oneway void setSensorStrength(in android.hardware.biometrics.common.SensorStrength strength);
- oneway void setMaxEnrollmentPerUser(in int max);
- oneway void setSensorLocation(in android.hardware.biometrics.fingerprint.SensorLocation loc);
- oneway void setNavigationGuesture(in boolean v);
- oneway void setDetectInteraction(in boolean v);
- oneway void setDisplayTouch(in boolean v);
- oneway void setControlIllumination(in boolean v);
- const int STATUS_INVALID_PARAMETER = 1;
-}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/AcquiredInfoAndVendorCode.aidl
similarity index 93%
rename from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
rename to biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/AcquiredInfoAndVendorCode.aidl
index c7be950..1fc7221 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/AcquiredInfoAndVendorCode.aidl
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-package android.hardware.biometrics.fingerprint;
+package android.hardware.biometrics.fingerprint.virtualhal;
import android.hardware.biometrics.fingerprint.AcquiredInfo;
/**
* @hide
*/
-@VintfStability
union AcquiredInfoAndVendorCode {
/**
* Acquired info as specified in AcqauiredInfo.aidl
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/EnrollmentProgressStep.aidl
similarity index 87%
rename from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
rename to biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/EnrollmentProgressStep.aidl
index bf038f6..b0b2926 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/EnrollmentProgressStep.aidl
@@ -14,14 +14,13 @@
* limitations under the License.
*/
-package android.hardware.biometrics.fingerprint;
+package android.hardware.biometrics.fingerprint.virtualhal;
-import android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode;
+import android.hardware.biometrics.fingerprint.virtualhal.AcquiredInfoAndVendorCode;
/**
* @hide
*/
-@VintfStability
parcelable EnrollmentProgressStep {
/**
* The duration of the enrollment step in milli-seconds
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/IVirtualHal.aidl
similarity index 96%
rename from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
rename to biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/IVirtualHal.aidl
index cb9135e..5af84ed 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/IVirtualHal.aidl
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-package android.hardware.biometrics.fingerprint;
+package android.hardware.biometrics.fingerprint.virtualhal;
import android.hardware.biometrics.common.SensorStrength;
-import android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode;
import android.hardware.biometrics.fingerprint.FingerprintSensorType;
-import android.hardware.biometrics.fingerprint.NextEnrollment;
+import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.SensorLocation;
+import android.hardware.biometrics.fingerprint.virtualhal.AcquiredInfoAndVendorCode;
+import android.hardware.biometrics.fingerprint.virtualhal.NextEnrollment;
/**
* @hide
*/
-@VintfStability
-oneway interface IVirtualHal {
+interface IVirtualHal {
/**
* The operation failed due to invalid input parameters, the error messages should
* gives more details
@@ -315,4 +315,5 @@
void setDetectInteraction(in boolean v);
void setDisplayTouch(in boolean v);
void setControlIllumination(in boolean v);
+ IFingerprint getFingerprintHal();
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/NextEnrollment.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/NextEnrollment.aidl
similarity index 85%
rename from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
rename to biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/NextEnrollment.aidl
index 4b50850..2d704f1 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/NextEnrollment.aidl
@@ -14,12 +14,13 @@
* limitations under the License.
*/
-package android.hardware.biometrics.fingerprint;
+package android.hardware.biometrics.fingerprint.virtualhal;
+
+import android.hardware.biometrics.fingerprint.virtualhal.EnrollmentProgressStep;
/**
* @hide
*/
-@VintfStability
parcelable NextEnrollment {
/**
* Identifier of the next enrollment if successful
@@ -31,7 +32,7 @@
* and sequence of acquired info codes to be generated by HAL.
* See EnrollmentProgressStep.aidl for more details
*/
- android.hardware.biometrics.fingerprint.EnrollmentProgressStep[] progressSteps;
+ EnrollmentProgressStep[] progressSteps;
/**
* Success or failure of the next enrollment
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/README.md b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/README.md
new file mode 100644
index 0000000..eaf2336
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/virtualhal/README.md
@@ -0,0 +1,2 @@
+The aidl files in this directory are used only by fingerprint virtual hal
+which is controlled/configured via IVirtualHal interface
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index 9b72c87..faaa9c6 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -8,10 +8,9 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-cc_binary {
- name: "android.hardware.biometrics.fingerprint-service.example",
- vendor: true,
- relative_install_path: "hw",
+cc_library_static {
+ name: "android.hardware.biometrics.fingerprint-service.lib",
+ vendor_available: true,
local_include_dirs: ["include"],
srcs: [
"FakeLockoutTracker.cpp",
@@ -30,22 +29,80 @@
"libbinder_ndk",
"liblog",
],
- static_libs: [
+ whole_static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
"libbase",
- "android.hardware.biometrics.fingerprint-V5-ndk",
+ "android.hardware.biometrics.fingerprint.virtualhal-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
"android.hardware.biometrics.common-V4-ndk",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
"android.hardware.biometrics.common.config",
"android.hardware.keymaster-V4-ndk",
],
+ product_variables: {
+ debuggable: {
+ cflags: ["-DFPS_DEBUGGABLE"],
+ },
+ },
+ apex_available: [
+ "com.android.hardware.biometrics.fingerprint.virtual",
+ "//apex_available:platform",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.biometrics.fingerprint-service.example",
+ system_ext_specific: true,
+ relative_install_path: "hw",
+ local_include_dirs: ["include"],
+ srcs: [
+ ],
+ stl: "c++_static",
+ shared_libs: [
+ "libbinder_ndk",
+ "liblog",
+ ],
+ whole_static_libs: [
+ "android.hardware.biometrics.fingerprint-service.lib",
+ ],
installable: false, // install APEX instead
product_variables: {
debuggable: {
cflags: ["-DFPS_DEBUGGABLE"],
},
},
+ apex_available: [
+ "com.android.hardware.biometrics.fingerprint.virtual",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.biometrics.fingerprint-service.default",
+ //system_ext_specific: true,
+ vendor: true,
+ relative_install_path: "hw",
+ init_rc: ["fingerprint-default.rc"],
+ vintf_fragments: ["fingerprint-default.xml"],
+ local_include_dirs: ["include"],
+ srcs: [
+ ],
+ stl: "c++_static",
+ shared_libs: [
+ "libbinder_ndk",
+ "liblog",
+ ],
+ whole_static_libs: [
+ "android.hardware.biometrics.fingerprint-service.lib",
+ ],
+ product_variables: {
+ debuggable: {
+ cflags: ["-DFPS_DEBUGGABLE"],
+ },
+ },
+ apex_available: [
+ "//apex_available:platform",
+ ],
}
cc_test {
@@ -63,14 +120,13 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V5-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
"android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
"android.hardware.biometrics.common.config",
"android.hardware.biometrics.common.thread",
],
- vendor: true,
test_suites: ["general-tests"],
require_root: true,
}
@@ -91,14 +147,13 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V5-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
"android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
"android.hardware.biometrics.common.config",
"android.hardware.biometrics.common.thread",
],
- vendor: true,
test_suites: ["general-tests"],
require_root: true,
}
@@ -117,14 +172,13 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V5-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
"android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.config",
],
- vendor: true,
test_suites: ["general-tests"],
require_root: true,
}
@@ -145,14 +199,13 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V5-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
"android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.config",
],
- vendor: true,
test_suites: ["general-tests"],
require_root: true,
}
@@ -178,7 +231,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V5-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.fingerprint.virtualhal-ndk",
"android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
@@ -190,7 +244,6 @@
cflags: ["-DFPS_DEBUGGABLE"],
},
},
- vendor: true,
test_suites: ["general-tests"],
require_root: true,
}
@@ -198,39 +251,34 @@
sysprop_library {
name: "android.hardware.biometrics.fingerprint.VirtualProps",
srcs: ["fingerprint.sysprop"],
- property_owner: "Vendor",
- vendor: true,
+ property_owner: "Platform",
+ vendor_available: true,
+ apex_available: [
+ "com.android.hardware.biometrics.fingerprint.virtual",
+ "//apex_available:platform",
+ ],
}
prebuilt_etc {
- name: "fingerprint-example.rc",
- src: "fingerprint-example.rc",
- installable: false,
-}
-
-prebuilt_etc {
- name: "fingerprint-example.xml",
- src: "fingerprint-example.xml",
- sub_dir: "vintf",
+ name: "fingerprint-virtual.rc",
+ src: "fingerprint-virtual.rc",
installable: false,
}
apex {
name: "com.android.hardware.biometrics.fingerprint.virtual",
manifest: "apex_manifest.json",
- file_contexts: "apex_file_contexts",
+ file_contexts: ":com.android.biometrics.virtual.fingerprint-file_contexts",
key: "com.android.hardware.key",
certificate: ":com.android.hardware.certificate",
updatable: false,
- vendor: true,
+ system_ext_specific: true,
binaries: [
"android.hardware.biometrics.fingerprint-service.example",
],
prebuilts: [
// init_rc
- "fingerprint-example.rc",
- // vintf_fragment
- "fingerprint-example.xml",
+ "fingerprint-virtual.rc",
],
}
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
index 67eb837..7a43d7b 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -389,10 +389,10 @@
if (isLockoutTimerStarted) isLockoutTimerAborted = true;
}
-void FakeFingerprintEngine::clearLockout(ISessionCallback* cb) {
+void FakeFingerprintEngine::clearLockout(ISessionCallback* cb, bool dueToTimeout) {
Fingerprint::cfg().set<bool>("lockout", false);
cb->onLockoutCleared();
- mLockoutTracker.reset();
+ mLockoutTracker.reset(dueToTimeout);
}
ndk::ScopedAStatus FakeFingerprintEngine::onPointerDownImpl(int32_t /*pointerId*/, int32_t /*x*/,
@@ -536,7 +536,7 @@
void FakeFingerprintEngine::lockoutTimerExpired(ISessionCallback* cb) {
BEGIN_OP(0);
if (!isLockoutTimerAborted) {
- clearLockout(cb);
+ clearLockout(cb, true);
}
isLockoutTimerStarted = false;
isLockoutTimerAborted = false;
diff --git a/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
index a056db5..7d46845 100644
--- a/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
@@ -23,8 +23,11 @@
namespace aidl::android::hardware::biometrics::fingerprint {
-void FakeLockoutTracker::reset() {
- mFailedCount = 0;
+void FakeLockoutTracker::reset(bool dueToTimeout) {
+ if (!dueToTimeout) {
+ mFailedCount = 0;
+ }
+ mFailedCountTimed = 0;
mLockoutTimedStart = 0;
mCurrentMode = LockoutMode::kNone;
}
@@ -33,6 +36,7 @@
bool enabled = Fingerprint::cfg().get<bool>("lockout_enable");
if (enabled) {
mFailedCount++;
+ mFailedCountTimed++;
int32_t lockoutTimedThreshold =
Fingerprint::cfg().get<std::int32_t>("lockout_timed_threshold");
int32_t lockoutPermanetThreshold =
@@ -40,7 +44,7 @@
if (mFailedCount >= lockoutPermanetThreshold) {
mCurrentMode = LockoutMode::kPermanent;
Fingerprint::cfg().set<bool>("lockout", true);
- } else if (mFailedCount >= lockoutTimedThreshold) {
+ } else if (mFailedCountTimed >= lockoutTimedThreshold) {
if (mCurrentMode == LockoutMode::kNone) {
mCurrentMode = LockoutMode::kTimed;
mLockoutTimedStart = Util::getSystemNanoTime();
diff --git a/biometrics/fingerprint/aidl/default/VirtualHal.cpp b/biometrics/fingerprint/aidl/default/VirtualHal.cpp
index e107d2f..d161765 100644
--- a/biometrics/fingerprint/aidl/default/VirtualHal.cpp
+++ b/biometrics/fingerprint/aidl/default/VirtualHal.cpp
@@ -26,7 +26,7 @@
#define LOG_TAG "FingerprintVirtualHalAidl"
namespace aidl::android::hardware::biometrics::fingerprint {
-
+using AcquiredInfoAndVendorCode = virtualhal::AcquiredInfoAndVendorCode;
using Tag = AcquiredInfoAndVendorCode::Tag;
::ndk::ScopedAStatus VirtualHal::setEnrollments(const std::vector<int32_t>& enrollments) {
@@ -41,8 +41,7 @@
return ndk::ScopedAStatus::ok();
}
-::ndk::ScopedAStatus VirtualHal::setNextEnrollment(
- const ::aidl::android::hardware::biometrics::fingerprint::NextEnrollment& next_enrollment) {
+::ndk::ScopedAStatus VirtualHal::setNextEnrollment(const NextEnrollment& next_enrollment) {
Fingerprint::cfg().sourcedFromAidl();
std::ostringstream os;
os << next_enrollment.id << ":";
@@ -333,4 +332,10 @@
return ndk::ScopedAStatus::ok();
}
+::ndk::ScopedAStatus VirtualHal::getFingerprintHal(
+ std::shared_ptr<::aidl::android::hardware::biometrics::fingerprint::IFingerprint>* pFp) {
+ LOG(INFO) << " calling getFingerprintHal in VirtualHal.cpp";
+ *pFp = mFp;
+ return ndk::ScopedAStatus::ok();
+}
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
index e69de29..8c02a68 100644
--- a/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
+++ b/biometrics/fingerprint/aidl/default/api/android.hardware.biometrics.fingerprint.VirtualProps-current.txt
@@ -0,0 +1,178 @@
+props {
+ owner: Vendor
+ module: "android.fingerprint.virt.FingerprintHalProperties"
+ prop {
+ api_name: "authenticator_id"
+ type: Long
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
+ }
+ prop {
+ api_name: "challenge"
+ type: Long
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.challenge"
+ }
+ prop {
+ api_name: "control_illumination"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
+ }
+ prop {
+ api_name: "detect_interaction"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
+ }
+ prop {
+ api_name: "display_touch"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
+ }
+ prop {
+ api_name: "enrollment_hit"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.enrollment_hit"
+ }
+ prop {
+ api_name: "enrollments"
+ type: IntegerList
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.enrollments"
+ }
+ prop {
+ api_name: "lockout"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.lockout"
+ }
+ prop {
+ api_name: "lockout_enable"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.lockout_enable"
+ }
+ prop {
+ api_name: "lockout_permanent_threshold"
+ type: Integer
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.lockout_permanent_threshold"
+ }
+ prop {
+ api_name: "lockout_timed_duration"
+ type: Integer
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.lockout_timed_duration"
+ }
+ prop {
+ api_name: "lockout_timed_threshold"
+ type: Integer
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.lockout_timed_threshold"
+ }
+ prop {
+ api_name: "max_enrollments"
+ type: Integer
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
+ }
+ prop {
+ api_name: "navigation_guesture"
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
+ }
+ prop {
+ api_name: "next_enrollment"
+ type: String
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.next_enrollment"
+ }
+ prop {
+ api_name: "operation_authenticate_acquired"
+ type: String
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
+ }
+ prop {
+ api_name: "operation_authenticate_duration"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_duration"
+ }
+ prop {
+ api_name: "operation_authenticate_error"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
+ }
+ prop {
+ api_name: "operation_authenticate_fails"
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_fails"
+ }
+ prop {
+ api_name: "operation_authenticate_latency"
+ type: IntegerList
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_authenticate_latency"
+ }
+ prop {
+ api_name: "operation_detect_interaction_acquired"
+ type: String
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
+ }
+ prop {
+ api_name: "operation_detect_interaction_duration"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
+ }
+ prop {
+ api_name: "operation_detect_interaction_error"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
+ }
+ prop {
+ api_name: "operation_detect_interaction_latency"
+ type: IntegerList
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_latency"
+ }
+ prop {
+ api_name: "operation_enroll_error"
+ type: Integer
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
+ }
+ prop {
+ api_name: "operation_enroll_latency"
+ type: IntegerList
+ access: ReadWrite
+ prop_name: "vendor.fingerprint.virtual.operation_enroll_latency"
+ }
+ prop {
+ api_name: "sensor_id"
+ type: Integer
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
+ }
+ prop {
+ api_name: "sensor_location"
+ type: String
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_location"
+ }
+ prop {
+ api_name: "sensor_strength"
+ type: Integer
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
+ }
+ prop {
+ api_name: "type"
+ type: String
+ access: ReadWrite
+ prop_name: "persist.vendor.fingerprint.virtual.type"
+ enum_values: "default|rear|udfps|side"
+ }
+}
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-default.rc b/biometrics/fingerprint/aidl/default/fingerprint-default.rc
new file mode 100644
index 0000000..7e46bc1
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/fingerprint-default.rc
@@ -0,0 +1,7 @@
+service vendor.fingerprint-default /vendor/bin/hw/android.hardware.biometrics.fingerprint-service.default default
+ class hal
+ user nobody
+ group nobody
+ interface aidl android.hardware.biometrics.fingerprint.IFingerprint/default
+ oneshot
+ disabled
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-default.xml b/biometrics/fingerprint/aidl/default/fingerprint-default.xml
new file mode 100644
index 0000000..d140459
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/fingerprint-default.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.biometrics.fingerprint</name>
+ <version>4</version>
+ <interface>
+ <name>IFingerprint</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.rc b/biometrics/fingerprint/aidl/default/fingerprint-example.rc
deleted file mode 100644
index da4ea45..0000000
--- a/biometrics/fingerprint/aidl/default/fingerprint-example.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-service vendor.fingerprint-example /apex/com.android.hardware.biometrics.fingerprint.virtual/bin/hw/android.hardware.biometrics.fingerprint-service.example
- class hal
- user nobody
- group nobody
- interface aidl android.hardware.biometrics.fingerprint.IFingerprint/virtual
- oneshot
- disabled
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.xml b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
deleted file mode 100644
index ee529e9..0000000
--- a/biometrics/fingerprint/aidl/default/fingerprint-example.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<manifest version="1.0" type="device">
- <hal format="aidl">
- <name>android.hardware.biometrics.fingerprint</name>
- <version>5</version>
- <fqname>IFingerprint/virtual</fqname>
- </hal>
-</manifest>
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-virtual.rc b/biometrics/fingerprint/aidl/default/fingerprint-virtual.rc
new file mode 100644
index 0000000..5d1506c
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/fingerprint-virtual.rc
@@ -0,0 +1,7 @@
+service fingerprint-virtual /apex/com.android.hardware.biometrics.fingerprint.virtual/bin/hw/android.hardware.biometrics.fingerprint-service.example virtual
+ class hal
+ user nobody
+ group nobody
+ interface aidl android.hardware.biometrics.fingerprint.virtualhal.IVirtualHal/virtual
+ oneshot
+ disabled
diff --git a/biometrics/fingerprint/aidl/default/fingerprint.sysprop b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
index 6a6c297..eb33432 100644
--- a/biometrics/fingerprint/aidl/default/fingerprint.sysprop
+++ b/biometrics/fingerprint/aidl/default/fingerprint.sysprop
@@ -7,7 +7,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.type"
type: String
- scope: Internal
+ scope: Public
access: ReadWrite
enum_values: "default|rear|udfps|side"
api_name: "type"
@@ -17,7 +17,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.enrollments"
type: IntegerList
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "enrollments"
}
@@ -27,7 +27,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.enrollment_hit"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "enrollment_hit"
}
@@ -42,7 +42,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.next_enrollment"
type: String
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "next_enrollment"
}
@@ -51,7 +51,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.authenticator_id"
type: Long
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "authenticator_id"
}
@@ -60,7 +60,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.challenge"
type: Long
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "challenge"
}
@@ -69,7 +69,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_authenticate_fails"
type: Boolean
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_authenticate_fails"
}
@@ -82,7 +82,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_error"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_detect_interaction_error"
}
@@ -91,7 +91,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_enroll_error"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_enroll_error"
}
@@ -104,7 +104,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_authenticate_latency"
type: IntegerList
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_authenticate_latency"
}
@@ -114,7 +114,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_latency"
type: IntegerList
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_detect_interaction_latency"
}
@@ -124,7 +124,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_enroll_latency"
type: IntegerList
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_enroll_latency"
}
@@ -134,7 +134,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_authenticate_duration"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_authenticate_duration"
}
@@ -143,7 +143,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_authenticate_error"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_authenticate_error"
}
@@ -153,7 +153,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.sensor_location"
type: String
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "sensor_location"
}
@@ -162,7 +162,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_authenticate_acquired"
type: String
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_authenticate_acquired"
}
@@ -172,7 +172,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_duration"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_detect_interaction_duration"
}
@@ -184,7 +184,7 @@
prop {
prop_name: "vendor.fingerprint.virtual.operation_detect_interaction_acquired"
type: String
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "operation_detect_interaction_acquired"
}
@@ -193,7 +193,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.sensor_id"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "sensor_id"
}
@@ -203,7 +203,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.sensor_strength"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "sensor_strength"
}
@@ -213,7 +213,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.max_enrollments"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "max_enrollments"
}
@@ -222,7 +222,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.navigation_guesture"
type: Boolean
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "navigation_guesture"
}
@@ -231,7 +231,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.detect_interaction"
type: Boolean
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "detect_interaction"
}
@@ -240,7 +240,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.udfps.display_touch"
type: Boolean
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "display_touch"
}
@@ -249,7 +249,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.udfps.control_illumination"
type: Boolean
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "control_illumination"
}
@@ -258,7 +258,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.lockout"
type: Boolean
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "lockout"
}
@@ -267,7 +267,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.lockout_enable"
type: Boolean
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "lockout_enable"
}
@@ -276,7 +276,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.lockout_timed_threshold"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "lockout_timed_threshold"
}
@@ -285,7 +285,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.lockout_timed_duration"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "lockout_timed_duration"
}
@@ -294,7 +294,7 @@
prop {
prop_name: "persist.vendor.fingerprint.virtual.lockout_permanent_threshold"
type: Integer
- scope: Internal
+ scope: Public
access: ReadWrite
api_name: "lockout_permanent_threshold"
}
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 0d53575..362d0df 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -110,7 +110,7 @@
std::pair<Error, int32_t> convertError(int32_t code);
int32_t getRandomInRange(int32_t bound1, int32_t bound2);
bool checkSensorLockout(ISessionCallback*);
- void clearLockout(ISessionCallback* cb);
+ void clearLockout(ISessionCallback* cb, bool dueToTimeout = false);
void waitForFingerDown(ISessionCallback* cb, const std::future<void>& cancel);
FakeLockoutTracker mLockoutTracker;
diff --git a/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h b/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
index a1b6128..a7f2f8e 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
@@ -24,12 +24,12 @@
class FakeLockoutTracker {
public:
- FakeLockoutTracker() : mFailedCount(0) {}
+ FakeLockoutTracker() : mFailedCount(0), mFailedCountTimed(0) {}
~FakeLockoutTracker() {}
enum class LockoutMode : int8_t { kNone = 0, kTimed, kPermanent };
- void reset();
+ void reset(bool dueToTimeout = false);
LockoutMode getMode();
void addFailedAttempt();
int64_t getLockoutTimeLeft();
@@ -44,6 +44,7 @@
private:
int32_t mFailedCount;
+ int32_t mFailedCountTimed;
int64_t mLockoutTimedStart;
LockoutMode mCurrentMode;
};
diff --git a/biometrics/fingerprint/aidl/default/include/VirtualHal.h b/biometrics/fingerprint/aidl/default/include/VirtualHal.h
index e5f62fc..5488383 100644
--- a/biometrics/fingerprint/aidl/default/include/VirtualHal.h
+++ b/biometrics/fingerprint/aidl/default/include/VirtualHal.h
@@ -16,21 +16,21 @@
#pragma once
-#include <aidl/android/hardware/biometrics/fingerprint/BnVirtualHal.h>
+#include <aidl/android/hardware/biometrics/fingerprint/virtualhal/BnVirtualHal.h>
#include "Fingerprint.h"
namespace aidl::android::hardware::biometrics::fingerprint {
+using namespace virtualhal;
+
class VirtualHal : public BnVirtualHal {
public:
- VirtualHal(Fingerprint* fp) : mFp(fp) {}
+ VirtualHal(std::shared_ptr<Fingerprint> fp) : mFp(fp) {}
::ndk::ScopedAStatus setEnrollments(const std::vector<int32_t>& in_id) override;
::ndk::ScopedAStatus setEnrollmentHit(int32_t in_hit_id) override;
- ::ndk::ScopedAStatus setNextEnrollment(
- const ::aidl::android::hardware::biometrics::fingerprint::NextEnrollment&
- in_next_enrollment) override;
+ ::ndk::ScopedAStatus setNextEnrollment(const NextEnrollment& in_next_enrollment) override;
::ndk::ScopedAStatus setAuthenticatorId(int64_t in_id) override;
::ndk::ScopedAStatus setChallenge(int64_t in_challenge) override;
::ndk::ScopedAStatus setOperationAuthenticateFails(bool in_fail) override;
@@ -67,12 +67,15 @@
::ndk::ScopedAStatus setDetectInteraction(bool in_v) override;
::ndk::ScopedAStatus setDisplayTouch(bool in_v) override;
::ndk::ScopedAStatus setControlIllumination(bool in_v) override;
+ ::ndk::ScopedAStatus getFingerprintHal(
+ std::shared_ptr<::aidl::android::hardware::biometrics::fingerprint::IFingerprint>*
+ _aidl_return);
private:
OptIntVec intVec2OptIntVec(const std::vector<int32_t>& intVec);
OptIntVec acquiredInfoVec2OptIntVec(const std::vector<AcquiredInfoAndVendorCode>& intVec);
::ndk::ScopedAStatus sanityCheckLatency(const std::vector<int32_t>& in_latency);
- Fingerprint* mFp;
+ std::shared_ptr<Fingerprint> mFp;
};
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/main.cpp b/biometrics/fingerprint/aidl/default/main.cpp
index ba0c8ec..8ca44d6 100644
--- a/biometrics/fingerprint/aidl/default/main.cpp
+++ b/biometrics/fingerprint/aidl/default/main.cpp
@@ -24,21 +24,38 @@
using aidl::android::hardware::biometrics::fingerprint::Fingerprint;
using aidl::android::hardware::biometrics::fingerprint::VirtualHal;
-int main() {
- LOG(INFO) << "Fingerprint HAL started";
+int main(int argc, char** argv) {
+ if (argc < 2) {
+ LOG(ERROR) << "Missing argument -> exiting";
+ return EXIT_FAILURE;
+ }
+
+ LOG(INFO) << "Fingerprint HAL started: " << argv[1];
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<Fingerprint> hal = ndk::SharedRefBase::make<Fingerprint>();
- auto binder = hal->asBinder();
-
- std::shared_ptr<VirtualHal> hal_ext = ndk::SharedRefBase::make<VirtualHal>(hal.get());
- auto binder_ext = hal_ext->asBinder();
+ std::shared_ptr<VirtualHal> hal_vhal = ndk::SharedRefBase::make<VirtualHal>(hal);
if (hal->connected()) {
- CHECK(STATUS_OK == AIBinder_setExtension(binder.get(), binder_ext.get()));
- const std::string instance = std::string(Fingerprint::descriptor) + "/virtual";
- binder_status_t status =
- AServiceManager_registerLazyService(binder.get(), instance.c_str());
- CHECK_EQ(status, STATUS_OK);
+ if (strcmp(argv[1], "default") == 0) {
+ const std::string instance = std::string(Fingerprint::descriptor) + "/default";
+ auto binder = hal->asBinder();
+ auto binder_ext = hal_vhal->asBinder();
+ CHECK(STATUS_OK == AIBinder_setExtension(binder.get(), binder_ext.get()));
+ binder_status_t status =
+ AServiceManager_registerLazyService(binder.get(), instance.c_str());
+ CHECK_EQ(status, STATUS_OK);
+ LOG(INFO) << "started IFingerprint/default";
+ } else if (strcmp(argv[1], "virtual") == 0) {
+ const std::string instance = std::string(VirtualHal::descriptor) + "/virtual";
+ auto binder = hal_vhal->asBinder();
+ binder_status_t status =
+ AServiceManager_registerLazyService(binder.get(), instance.c_str());
+ CHECK_EQ(status, STATUS_OK);
+ LOG(INFO) << "started IVirtualHal/virtual";
+ } else {
+ LOG(ERROR) << "Unexpected argument: " << argv[1];
+ return EXIT_FAILURE;
+ }
AServiceManager_forceLazyServicesPersist(true);
} else {
LOG(ERROR) << "Fingerprint HAL is not connected";
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
index 3c12b6d..4c1277b 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
@@ -75,7 +75,7 @@
prevTimeLeft = currTimeLeft;
}
ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
- mLockoutTracker.reset();
+ mLockoutTracker.reset(true);
}
TEST_F(FakeLockoutTrackerTest, addFailedAttemptPermanent) {
diff --git a/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp b/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
index 3fe0b2a..8ffc96b 100644
--- a/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
@@ -35,7 +35,7 @@
protected:
void SetUp() override {
mHal = ndk::SharedRefBase::make<Fingerprint>();
- mVhal = ndk::SharedRefBase::make<VirtualHal>(mHal.get());
+ mVhal = ndk::SharedRefBase::make<VirtualHal>(mHal);
ASSERT_TRUE(mVhal != nullptr);
mHal->resetConfigToDefault();
}
diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp
index fc32fe6..628f03f 100644
--- a/biometrics/fingerprint/aidl/vts/Android.bp
+++ b/biometrics/fingerprint/aidl/vts/Android.bp
@@ -16,8 +16,8 @@
],
srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"],
static_libs: [
- "android.hardware.biometrics.common-V3-ndk",
- "android.hardware.biometrics.fingerprint-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
"android.hardware.keymaster-V4-ndk",
],
shared_libs: [
diff --git a/camera/common/aidl/Android.bp b/camera/common/aidl/Android.bp
index 8f7d19d..b59c92e 100644
--- a/camera/common/aidl/Android.bp
+++ b/camera/common/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.camera.common",
+ host_supported: true,
vendor_available: true,
srcs: ["android/hardware/camera/common/*.aidl"],
frozen: true,
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index 78aefac..125f14c 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.camera.device",
+ host_supported: true,
vendor_available: true,
srcs: ["android/hardware/camera/device/*.aidl"],
frozen: true,
@@ -29,6 +30,9 @@
sdk_version: "module_current",
enabled: false,
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl
index 62a19cf..63ae320 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl
@@ -575,6 +575,11 @@
* This can be called at any point after 'processCaptureRequest' in response
* to camera clients disabling an active repeating request.
*
+ * Note: The frame number parameter is the latest possible frame number at which the
+ * ongoing repeating request will end. It is possible that the repeating request may end
+ * before the specified frame number due to reasons such as the camera client abandoning
+ * buffers, which is timing dependent.
+ *
* Performance requirements:
* The call must not be blocked for extensive periods and should be extremely lightweight. There
* must be no frame rate degradation or frame jitter introduced.
diff --git a/camera/metadata/aidl/Android.bp b/camera/metadata/aidl/Android.bp
index ae8ba14..a9c1a1a 100644
--- a/camera/metadata/aidl/Android.bp
+++ b/camera/metadata/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.camera.metadata",
+ host_supported: true,
vendor_available: true,
srcs: ["android/hardware/camera/metadata/*.aidl"],
frozen: true,
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 82666ae..49c8410 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -52,6 +52,7 @@
#include <android/hardware/camera/provider/2.7/ICameraProvider.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
+#include <com_android_graphics_libgui_flags.h>
#include <cutils/properties.h>
#include <fmq/MessageQueue.h>
#include <grallocusage/GrallocUsageConversion.h>
@@ -8714,16 +8715,25 @@
ASSERT_NE(nullptr, bufferItemConsumer);
ASSERT_NE(nullptr, bufferHandler);
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
+ *bufferItemConsumer = new BufferItemConsumer(
+ GraphicBuffer::USAGE_HW_TEXTURE); // Use GLConsumer default usage flags
+#else
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
*bufferItemConsumer = new BufferItemConsumer(consumer,
GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
ASSERT_NE(nullptr, (*bufferItemConsumer).get());
*bufferHandler = new BufferItemHander(*bufferItemConsumer);
ASSERT_NE(nullptr, (*bufferHandler).get());
(*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
+ sp<Surface> surface = (*bufferItemConsumer)->getSurface();
+#else
sp<Surface> surface = new Surface(producer);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
auto rc = device->setPreviewWindow(previewCb);
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index 38a8936..faad35a 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.camera.provider",
+ host_supported: true,
vendor_available: true,
srcs: [
"android/hardware/camera/provider/*.aidl",
@@ -27,6 +28,9 @@
cpp: {
enabled: false,
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index ad8d4c8..e0e3a0e 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -288,77 +288,70 @@
}
TEST_P(CameraAidlTest, getSessionCharacteristics) {
- if (flags::feature_combination_query()) {
- std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+ std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
- for (const auto& name : cameraDeviceNames) {
- std::shared_ptr<ICameraDevice> device;
- ALOGI("getSessionCharacteristics: Testing camera device %s", name.c_str());
- ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
- ALOGI("getCameraDeviceInterface returns: %d:%d", ret.getExceptionCode(),
- ret.getServiceSpecificError());
- ASSERT_TRUE(ret.isOk());
- ASSERT_NE(device, nullptr);
+ for (const auto& name : cameraDeviceNames) {
+ std::shared_ptr<ICameraDevice> device;
+ ALOGI("getSessionCharacteristics: Testing camera device %s", name.c_str());
+ ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
+ ALOGI("getCameraDeviceInterface returns: %d:%d", ret.getExceptionCode(),
+ ret.getServiceSpecificError());
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_NE(device, nullptr);
- int32_t interfaceVersion = -1;
- ret = device->getInterfaceVersion(&interfaceVersion);
- ASSERT_TRUE(ret.isOk());
- bool supportSessionCharacteristics =
- (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
- if (!supportSessionCharacteristics) {
- continue;
- }
-
- CameraMetadata meta;
- openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
- &device /*out*/);
-
- std::vector<AvailableStream> outputStreams;
- camera_metadata_t* staticMeta =
- reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
- outputStreams.clear();
- ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
- ASSERT_NE(0u, outputStreams.size());
-
- AvailableStream sampleStream = outputStreams[0];
-
- int32_t streamId = 0;
- Stream stream = {streamId,
- StreamType::OUTPUT,
- sampleStream.width,
- sampleStream.height,
- static_cast<PixelFormat>(sampleStream.format),
- static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
- GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
- Dataspace::UNKNOWN,
- StreamRotation::ROTATION_0,
- std::string(),
- /*bufferSize*/ 0,
- /*groupId*/ -1,
- {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
- RequestAvailableDynamicRangeProfilesMap::
- ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
-
- std::vector<Stream> streams = {stream};
- StreamConfiguration config;
- createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config);
-
- CameraMetadata camera_chars;
- ret = device->getCameraCharacteristics(&camera_chars);
- ASSERT_TRUE(ret.isOk());
-
- CameraMetadata session_chars;
- ret = device->getSessionCharacteristics(config, &session_chars);
- ASSERT_TRUE(ret.isOk());
- verifySessionCharacteristics(session_chars, camera_chars);
-
- ret = mSession->close();
- mSession = nullptr;
- ASSERT_TRUE(ret.isOk());
+ int32_t interfaceVersion = -1;
+ ret = device->getInterfaceVersion(&interfaceVersion);
+ ASSERT_TRUE(ret.isOk());
+ bool supportSessionCharacteristics =
+ (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
+ if (!supportSessionCharacteristics) {
+ continue;
}
- } else {
- ALOGI("getSessionCharacteristics: Test skipped.\n");
- GTEST_SKIP();
+
+ CameraMetadata meta;
+ openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/, &device /*out*/);
+
+ std::vector<AvailableStream> outputStreams;
+ camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
+ outputStreams.clear();
+ ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
+ ASSERT_NE(0u, outputStreams.size());
+
+ AvailableStream sampleStream = outputStreams[0];
+
+ int32_t streamId = 0;
+ Stream stream = {streamId,
+ StreamType::OUTPUT,
+ sampleStream.width,
+ sampleStream.height,
+ static_cast<PixelFormat>(sampleStream.format),
+ static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
+ Dataspace::UNKNOWN,
+ StreamRotation::ROTATION_0,
+ std::string(),
+ /*bufferSize*/ 0,
+ /*groupId*/ -1,
+ {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+ RequestAvailableDynamicRangeProfilesMap::
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+
+ std::vector<Stream> streams = {stream};
+ StreamConfiguration config;
+ createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config);
+
+ CameraMetadata camera_chars;
+ ret = device->getCameraCharacteristics(&camera_chars);
+ ASSERT_TRUE(ret.isOk());
+
+ CameraMetadata session_chars;
+ ret = device->getSessionCharacteristics(config, &session_chars);
+ ASSERT_TRUE(ret.isOk());
+ verifySessionCharacteristics(session_chars, camera_chars);
+
+ ret = mSession->close();
+ mSession = nullptr;
+ ASSERT_TRUE(ret.isOk());
}
}
@@ -615,19 +608,17 @@
ASSERT_EQ(0u, rawMetadata.metadata.size());
}
- if (flags::feature_combination_query()) {
- if (supportFeatureCombinationQuery) {
- CameraMetadata rawMetadata2;
- ndk::ScopedAStatus ret2 =
- device->constructDefaultRequestSettings(reqTemplate, &rawMetadata2);
+ if (supportFeatureCombinationQuery) {
+ CameraMetadata rawMetadata2;
+ ndk::ScopedAStatus ret2 =
+ device->constructDefaultRequestSettings(reqTemplate, &rawMetadata2);
- ASSERT_EQ(ret.isOk(), ret2.isOk());
- ASSERT_EQ(ret.getStatus(), ret2.getStatus());
+ ASSERT_EQ(ret.isOk(), ret2.isOk());
+ ASSERT_EQ(ret.getStatus(), ret2.getStatus());
- ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
- if (ret2.isOk()) {
- validateDefaultRequestMetadata(reqTemplate, rawMetadata2);
- }
+ ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
+ if (ret2.isOk()) {
+ validateDefaultRequestMetadata(reqTemplate, rawMetadata2);
}
}
}
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index f905011..6ecd451 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -1920,28 +1920,22 @@
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(expectedStatus, streamCombinationSupported);
- if (flags::feature_combination_query()) {
- int32_t interfaceVersion;
- ret = device->getInterfaceVersion(&interfaceVersion);
+ int32_t interfaceVersion;
+ ret = device->getInterfaceVersion(&interfaceVersion);
+ ASSERT_TRUE(ret.isOk());
+ bool supportFeatureCombinationQuery =
+ (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
+ if (supportFeatureCombinationQuery) {
+ ret = device->isStreamCombinationWithSettingsSupported(config,
+ &streamCombinationSupported);
ASSERT_TRUE(ret.isOk());
- bool supportFeatureCombinationQuery =
- (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
- if (supportFeatureCombinationQuery) {
- ret = device->isStreamCombinationWithSettingsSupported(config,
- &streamCombinationSupported);
- ASSERT_TRUE(ret.isOk());
- ASSERT_EQ(expectedStatus, streamCombinationSupported);
- }
+ ASSERT_EQ(expectedStatus, streamCombinationSupported);
}
}
}
void CameraAidlTest::verifySessionCharacteristics(const CameraMetadata& session_chars,
const CameraMetadata& camera_chars) {
- if (!flags::feature_combination_query()) {
- return;
- }
-
const camera_metadata_t* session_metadata =
reinterpret_cast<const camera_metadata_t*>(session_chars.metadata.data());
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 7e19852..ed45c1b 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -241,7 +241,7 @@
</hal>
<hal format="aidl">
<name>android.hardware.graphics.composer3</name>
- <version>3</version>
+ <version>4</version>
<interface>
<name>IComposer</name>
<instance>default</instance>
@@ -622,7 +622,7 @@
</hal>
<hal format="aidl">
<name>android.hardware.vibrator</name>
- <version>1-2</version>
+ <version>1-3</version>
<interface>
<name>IVibrator</name>
<instance>default</instance>
@@ -630,7 +630,7 @@
</hal>
<hal format="aidl">
<name>android.hardware.vibrator</name>
- <version>1-2</version>
+ <version>1-3</version>
<interface>
<name>IVibratorManager</name>
<instance>default</instance>
@@ -662,7 +662,7 @@
</hal>
<hal format="aidl">
<name>android.hardware.wifi.hostapd</name>
- <version>1-2</version>
+ <version>2-3</version>
<interface>
<name>IHostapd</name>
<instance>default</instance>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index b86f399..e7a31e6 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -149,6 +149,7 @@
"android.hardware.radio@",
"android.hardware.uwb.fira_android@",
"android.hardware.wifi.common@",
+ "android.hardware.biometrics.fingerprint.virtualhal@",
// Test packages are exempted.
"android.hardware.tests.",
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
index afcb603..99780dc 100644
--- a/drm/aidl/Android.bp
+++ b/drm/aidl/Android.bp
@@ -14,6 +14,7 @@
stability: "vintf",
imports: [
"android.hardware.common-V2",
+ "android.hardware.drm.common-V1",
],
backend: {
cpp: {
@@ -30,7 +31,10 @@
versions_with_info: [
{
version: "1",
- imports: ["android.hardware.common-V2"],
+ imports: [
+ "android.hardware.common-V2",
+ "android.hardware.drm.common-V1",
+ ],
},
],
diff --git a/drm/aidl/aidl_api/android.hardware.drm/1/.hash b/drm/aidl/aidl_api/android.hardware.drm/1/.hash
index 886e28c..9a735e9 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/1/.hash
+++ b/drm/aidl/aidl_api/android.hardware.drm/1/.hash
@@ -1 +1,2 @@
7b4b0a0f36a7a6bb22d2016375e4a9d4a033592f
+3a0197fb44863256da9034c26e721b1eee12d1be
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl
index 80ebb28..f09eadd 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl
@@ -34,9 +34,9 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum EventType {
- PROVISION_REQUIRED = 0,
- KEY_NEEDED = 1,
- KEY_EXPIRED = 2,
- VENDOR_DEFINED = 3,
- SESSION_RECLAIMED = 4,
+ PROVISION_REQUIRED,
+ KEY_NEEDED,
+ KEY_EXPIRED,
+ VENDOR_DEFINED,
+ SESSION_RECLAIMED,
}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl
deleted file mode 100644
index 5704fb0..0000000
--- a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.drm;
-@Backing(type="int") @VintfStability
-enum HdcpLevel {
- HDCP_UNKNOWN = 0,
- HDCP_NONE = 1,
- HDCP_V1 = 2,
- HDCP_V2 = 3,
- HDCP_V2_1 = 4,
- HDCP_V2_2 = 5,
- HDCP_NO_OUTPUT = 6,
- HDCP_V2_3 = 7,
-}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl
index 34b9615..556ee38 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl
@@ -34,10 +34,10 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum KeyRequestType {
- INITIAL = 0,
- RENEWAL = 1,
- RELEASE = 2,
- UNKNOWN = 3,
- NONE = 4,
- UPDATE = 5,
+ INITIAL,
+ RENEWAL,
+ RELEASE,
+ UNKNOWN,
+ NONE,
+ UPDATE,
}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl
index 261516f..5a46552 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl
@@ -34,10 +34,10 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum KeyStatusType {
- USABLE = 0,
- EXPIRED = 1,
- OUTPUT_NOT_ALLOWED = 2,
- STATUS_PENDING = 3,
- INTERNAL_ERROR = 4,
- USABLE_IN_FUTURE = 5,
+ USABLE,
+ EXPIRED,
+ OUTPUT_NOT_ALLOWED,
+ STATUS_PENDING,
+ INTERNAL_ERROR,
+ USABLE_IN_FUTURE,
}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl
index 7a9d633..e677c86 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl
@@ -34,7 +34,7 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum KeyType {
- OFFLINE = 0,
- STREAMING = 1,
- RELEASE = 2,
+ OFFLINE,
+ STREAMING,
+ RELEASE,
}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl
index 83362c3..b77ddf6 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl
@@ -34,12 +34,12 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum LogPriority {
- UNKNOWN = 0,
- DEFAULT = 1,
- VERBOSE = 2,
- DEBUG = 3,
- INFO = 4,
- WARN = 5,
- ERROR = 6,
- FATAL = 7,
+ UNKNOWN,
+ DEFAULT,
+ VERBOSE,
+ DEBUG,
+ INFO,
+ WARN,
+ ERROR,
+ FATAL,
}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl
index 629564d..be0e822 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl
@@ -34,7 +34,7 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum OfflineLicenseState {
- UNKNOWN = 0,
- USABLE = 1,
- INACTIVE = 2,
+ UNKNOWN,
+ USABLE,
+ INACTIVE,
}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl
index 65b2b9d..87b3641 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl
@@ -34,11 +34,11 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum SecurityLevel {
- UNKNOWN = 0,
- SW_SECURE_CRYPTO = 1,
- SW_SECURE_DECODE = 2,
- HW_SECURE_CRYPTO = 3,
- HW_SECURE_DECODE = 4,
- HW_SECURE_ALL = 5,
- DEFAULT = 6,
+ UNKNOWN,
+ SW_SECURE_CRYPTO,
+ SW_SECURE_DECODE,
+ HW_SECURE_CRYPTO,
+ HW_SECURE_DECODE,
+ HW_SECURE_ALL,
+ DEFAULT,
}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl
index c640689..a3ba6c3 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl
@@ -34,44 +34,44 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum Status {
- OK = 0,
- ERROR_DRM_NO_LICENSE = 1,
- ERROR_DRM_LICENSE_EXPIRED = 2,
- ERROR_DRM_SESSION_NOT_OPENED = 3,
- ERROR_DRM_CANNOT_HANDLE = 4,
- ERROR_DRM_INVALID_STATE = 5,
- BAD_VALUE = 6,
- ERROR_DRM_NOT_PROVISIONED = 7,
- ERROR_DRM_RESOURCE_BUSY = 8,
- ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = 9,
- ERROR_DRM_DEVICE_REVOKED = 10,
- ERROR_DRM_DECRYPT = 11,
- ERROR_DRM_UNKNOWN = 12,
- ERROR_DRM_INSUFFICIENT_SECURITY = 13,
- ERROR_DRM_FRAME_TOO_LARGE = 14,
- ERROR_DRM_SESSION_LOST_STATE = 15,
- ERROR_DRM_RESOURCE_CONTENTION = 16,
- CANNOT_DECRYPT_ZERO_SUBSAMPLES = 17,
- CRYPTO_LIBRARY_ERROR = 18,
- GENERAL_OEM_ERROR = 19,
- GENERAL_PLUGIN_ERROR = 20,
- INIT_DATA_INVALID = 21,
- KEY_NOT_LOADED = 22,
- LICENSE_PARSE_ERROR = 23,
- LICENSE_POLICY_ERROR = 24,
- LICENSE_RELEASE_ERROR = 25,
- LICENSE_REQUEST_REJECTED = 26,
- LICENSE_RESTORE_ERROR = 27,
- LICENSE_STATE_ERROR = 28,
- MALFORMED_CERTIFICATE = 29,
- MEDIA_FRAMEWORK_ERROR = 30,
- MISSING_CERTIFICATE = 31,
- PROVISIONING_CERTIFICATE_ERROR = 32,
- PROVISIONING_CONFIGURATION_ERROR = 33,
- PROVISIONING_PARSE_ERROR = 34,
- PROVISIONING_REQUEST_REJECTED = 35,
- RETRYABLE_PROVISIONING_ERROR = 36,
- SECURE_STOP_RELEASE_ERROR = 37,
- STORAGE_READ_FAILURE = 38,
- STORAGE_WRITE_FAILURE = 39,
+ OK,
+ ERROR_DRM_NO_LICENSE,
+ ERROR_DRM_LICENSE_EXPIRED,
+ ERROR_DRM_SESSION_NOT_OPENED,
+ ERROR_DRM_CANNOT_HANDLE,
+ ERROR_DRM_INVALID_STATE,
+ BAD_VALUE,
+ ERROR_DRM_NOT_PROVISIONED,
+ ERROR_DRM_RESOURCE_BUSY,
+ ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION,
+ ERROR_DRM_DEVICE_REVOKED,
+ ERROR_DRM_DECRYPT,
+ ERROR_DRM_UNKNOWN,
+ ERROR_DRM_INSUFFICIENT_SECURITY,
+ ERROR_DRM_FRAME_TOO_LARGE,
+ ERROR_DRM_SESSION_LOST_STATE,
+ ERROR_DRM_RESOURCE_CONTENTION,
+ CANNOT_DECRYPT_ZERO_SUBSAMPLES,
+ CRYPTO_LIBRARY_ERROR,
+ GENERAL_OEM_ERROR,
+ GENERAL_PLUGIN_ERROR,
+ INIT_DATA_INVALID,
+ KEY_NOT_LOADED,
+ LICENSE_PARSE_ERROR,
+ LICENSE_POLICY_ERROR,
+ LICENSE_RELEASE_ERROR,
+ LICENSE_REQUEST_REJECTED,
+ LICENSE_RESTORE_ERROR,
+ LICENSE_STATE_ERROR,
+ MALFORMED_CERTIFICATE,
+ MEDIA_FRAMEWORK_ERROR,
+ MISSING_CERTIFICATE,
+ PROVISIONING_CERTIFICATE_ERROR,
+ PROVISIONING_CONFIGURATION_ERROR,
+ PROVISIONING_PARSE_ERROR,
+ PROVISIONING_REQUEST_REJECTED,
+ RETRYABLE_PROVISIONING_ERROR,
+ SECURE_STOP_RELEASE_ERROR,
+ STORAGE_READ_FAILURE,
+ STORAGE_WRITE_FAILURE,
}
diff --git a/drm/aidl/vts/Android.bp b/drm/aidl/vts/Android.bp
index 5139036..27ce0d7 100644
--- a/drm/aidl/vts/Android.bp
+++ b/drm/aidl/vts/Android.bp
@@ -47,6 +47,7 @@
],
static_libs: [
"android.hardware.drm@1.0-helper",
+ "android.hardware.drm.common-V1-ndk",
"android.hardware.drm-V1-ndk",
"android.hardware.common-V2-ndk",
"libaidlcommonsupport",
@@ -59,13 +60,19 @@
data: [":libvtswidevine-arm-prebuilts"],
},
arm64: {
- data: [":libvtswidevine-arm64-prebuilts", ":libvtswidevine-arm-prebuilts"],
+ data: [
+ ":libvtswidevine-arm64-prebuilts",
+ ":libvtswidevine-arm-prebuilts",
+ ],
},
x86: {
data: [":libvtswidevine-x86-prebuilts"],
},
x86_64: {
- data: [":libvtswidevine-x86_64-prebuilts", ":libvtswidevine-x86-prebuilts"],
+ data: [
+ ":libvtswidevine-x86_64-prebuilts",
+ ":libvtswidevine-x86-prebuilts",
+ ],
},
},
test_suites: [
diff --git a/drm/common/aidl/Android.bp b/drm/common/aidl/Android.bp
new file mode 100644
index 0000000..c5cb441
--- /dev/null
+++ b/drm/common/aidl/Android.bp
@@ -0,0 +1,39 @@
+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"],
+}
+
+aidl_interface {
+ name: "android.hardware.drm.common",
+ host_supported: true,
+ vendor_available: true,
+ srcs: ["android/hardware/drm/*.aidl"],
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ },
+ ndk: {
+ min_sdk_version: "34",
+ },
+ rust: {
+ enabled: true,
+ },
+ },
+ double_loadable: true,
+ versions_with_info: [
+ {
+ version: "1",
+ imports: [],
+ },
+ ],
+ frozen: true,
+
+}
diff --git a/drm/common/aidl/aidl_api/android.hardware.drm.common/1/.hash b/drm/common/aidl/aidl_api/android.hardware.drm.common/1/.hash
new file mode 100644
index 0000000..66690e1
--- /dev/null
+++ b/drm/common/aidl/aidl_api/android.hardware.drm.common/1/.hash
@@ -0,0 +1 @@
+1b5e9159609b3aa05e2c7158f3a1488fda2250d1
diff --git a/drm/aidl/aidl_api/android.hardware.drm/1/android/hardware/drm/HdcpLevel.aidl b/drm/common/aidl/aidl_api/android.hardware.drm.common/1/android/hardware/drm/HdcpLevel.aidl
similarity index 92%
rename from drm/aidl/aidl_api/android.hardware.drm/1/android/hardware/drm/HdcpLevel.aidl
rename to drm/common/aidl/aidl_api/android.hardware.drm.common/1/android/hardware/drm/HdcpLevel.aidl
index 5704fb0..118bef6 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/1/android/hardware/drm/HdcpLevel.aidl
+++ b/drm/common/aidl/aidl_api/android.hardware.drm.common/1/android/hardware/drm/HdcpLevel.aidl
@@ -34,12 +34,12 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum HdcpLevel {
- HDCP_UNKNOWN = 0,
- HDCP_NONE = 1,
- HDCP_V1 = 2,
- HDCP_V2 = 3,
- HDCP_V2_1 = 4,
- HDCP_V2_2 = 5,
- HDCP_NO_OUTPUT = 6,
- HDCP_V2_3 = 7,
+ HDCP_UNKNOWN,
+ HDCP_NONE,
+ HDCP_V1,
+ HDCP_V2,
+ HDCP_V2_1,
+ HDCP_V2_2,
+ HDCP_NO_OUTPUT,
+ HDCP_V2_3,
}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/1/android/hardware/drm/HdcpLevels.aidl b/drm/common/aidl/aidl_api/android.hardware.drm.common/1/android/hardware/drm/HdcpLevels.aidl
similarity index 100%
rename from drm/aidl/aidl_api/android.hardware.drm/1/android/hardware/drm/HdcpLevels.aidl
rename to drm/common/aidl/aidl_api/android.hardware.drm.common/1/android/hardware/drm/HdcpLevels.aidl
diff --git a/drm/aidl/aidl_api/android.hardware.drm/1/android/hardware/drm/HdcpLevel.aidl b/drm/common/aidl/aidl_api/android.hardware.drm.common/current/android/hardware/drm/HdcpLevel.aidl
similarity index 92%
copy from drm/aidl/aidl_api/android.hardware.drm/1/android/hardware/drm/HdcpLevel.aidl
copy to drm/common/aidl/aidl_api/android.hardware.drm.common/current/android/hardware/drm/HdcpLevel.aidl
index 5704fb0..118bef6 100644
--- a/drm/aidl/aidl_api/android.hardware.drm/1/android/hardware/drm/HdcpLevel.aidl
+++ b/drm/common/aidl/aidl_api/android.hardware.drm.common/current/android/hardware/drm/HdcpLevel.aidl
@@ -34,12 +34,12 @@
package android.hardware.drm;
@Backing(type="int") @VintfStability
enum HdcpLevel {
- HDCP_UNKNOWN = 0,
- HDCP_NONE = 1,
- HDCP_V1 = 2,
- HDCP_V2 = 3,
- HDCP_V2_1 = 4,
- HDCP_V2_2 = 5,
- HDCP_NO_OUTPUT = 6,
- HDCP_V2_3 = 7,
+ HDCP_UNKNOWN,
+ HDCP_NONE,
+ HDCP_V1,
+ HDCP_V2,
+ HDCP_V2_1,
+ HDCP_V2_2,
+ HDCP_NO_OUTPUT,
+ HDCP_V2_3,
}
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl b/drm/common/aidl/aidl_api/android.hardware.drm.common/current/android/hardware/drm/HdcpLevels.aidl
similarity index 100%
rename from drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl
rename to drm/common/aidl/aidl_api/android.hardware.drm.common/current/android/hardware/drm/HdcpLevels.aidl
diff --git a/drm/aidl/android/hardware/drm/HdcpLevel.aidl b/drm/common/aidl/android/hardware/drm/HdcpLevel.aidl
similarity index 100%
rename from drm/aidl/android/hardware/drm/HdcpLevel.aidl
rename to drm/common/aidl/android/hardware/drm/HdcpLevel.aidl
diff --git a/drm/aidl/android/hardware/drm/HdcpLevels.aidl b/drm/common/aidl/android/hardware/drm/HdcpLevels.aidl
similarity index 100%
rename from drm/aidl/android/hardware/drm/HdcpLevels.aidl
rename to drm/common/aidl/android/hardware/drm/HdcpLevels.aidl
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 8a22d6e..aaafe7f 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -217,10 +217,6 @@
* Starts a location output stream using the IGnssCallback gnssLocationCb(), following the
* settings from the most recent call to setPositionMode().
*
- * When a location output stream is in progress, calling setPositionMode() does not change the
- * settings of the current location output stream. stop() and start() must be called to make the
- * new settings effective.
- *
* This output must operate independently of any GNSS location batching operations,
* see the IGnssBatching for details.
*/
@@ -310,10 +306,6 @@
/**
* Sets the GnssPositionMode parameter, its associated recurrence value, the time between fixes,
* requested fix accuracy, time to first fix.
- *
- * If a location output stream is in progress, calling this method does not affect the settings
- * of current location output stream. stop() and start() must be called to make the new settings
- * effective.
*/
void setPositionMode(in PositionModeOptions options);
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 5e2cbe3..6d5a9a2 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -276,29 +276,35 @@
}
/*
- * FindStrongFrequentNonGpsSource:
+ * FindStrongFrequentBlockableSource:
*
- * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
+ * Search through a GnssSvStatus list for the strongest blockable satellite observed enough times
*
* returns the strongest source,
* or a source with constellation == UNKNOWN if none are found sufficient times
*/
-BlocklistedSource GnssHalTest::FindStrongFrequentNonGpsSource(
+BlocklistedSource GnssHalTest::FindStrongFrequentBlockableSource(
const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
const int min_observations) {
- return FindStrongFrequentNonGpsSource(convertToAidl(sv_info_list), min_observations);
+ return FindStrongFrequentBlockableSource(convertToAidl(sv_info_list), min_observations);
}
-BlocklistedSource GnssHalTest::FindStrongFrequentNonGpsSource(
+BlocklistedSource GnssHalTest::FindStrongFrequentBlockableSource(
const std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_list,
const int min_observations) {
std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
+ bool isCnBuild = Utils::isCnBuild();
+ ALOGD("isCnBuild: %s", isCnBuild ? "true" : "false");
for (const auto& sv_info_vec : sv_info_list) {
for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
const auto& gnss_sv = sv_info_vec[iSv];
if ((gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
(gnss_sv.constellation != GnssConstellationType::GPS)) {
+ if (isCnBuild && (gnss_sv.constellation == GnssConstellationType::BEIDOU)) {
+ // Do not blocklist BDS on CN builds
+ continue;
+ }
ComparableBlocklistedSource source;
source.id.svid = gnss_sv.svid;
source.id.constellation = gnss_sv.constellation;
@@ -343,7 +349,7 @@
return source_to_blocklist.id;
}
-GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation(
+GnssConstellationType GnssHalTest::startLocationAndGetBlockableConstellation(
const int locations_to_await, const int gnss_sv_info_list_timeout) {
if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
return static_cast<GnssConstellationType>(
@@ -360,7 +366,9 @@
ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
sv_info_list_cbq_size, locations_to_await, location_called_count);
- // Find first non-GPS constellation to blocklist
+ bool isCnBuild = Utils::isCnBuild();
+ ALOGD("isCnBuild: %s", isCnBuild ? "true" : "false");
+ // Find first blockable constellation to blocklist
GnssConstellationType constellation_to_blocklist = GnssConstellationType::UNKNOWN;
for (int i = 0; i < sv_info_list_cbq_size; ++i) {
std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
@@ -370,7 +378,11 @@
if ((gnss_sv.svFlag & (uint32_t)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
(gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
(gnss_sv.constellation != GnssConstellationType::GPS)) {
- // found a non-GPS constellation
+ if (isCnBuild && (gnss_sv.constellation == GnssConstellationType::BEIDOU)) {
+ // Do not blocklist BDS on CN builds
+ continue;
+ }
+ // found a blockable constellation
constellation_to_blocklist = gnss_sv.constellation;
break;
}
@@ -381,11 +393,11 @@
}
if (constellation_to_blocklist == GnssConstellationType::UNKNOWN) {
- ALOGI("No non-GPS constellations found, constellation blocklist test less effective.");
+ ALOGI("No blockable constellations found, constellation blocklist test less effective.");
// Proceed functionally to blocklist something.
constellation_to_blocklist = GnssConstellationType::GLONASS;
}
-
+ ALOGD("Constellation to blocklist: %d", constellation_to_blocklist);
return constellation_to_blocklist;
}
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index 88d01c1..dec5856 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -76,16 +76,16 @@
void StartAndCheckLocations(const int count);
void StartAndCheckLocations(const int count, const bool start_sv_status, const bool start_nmea);
- android::hardware::gnss::GnssConstellationType startLocationAndGetNonGpsConstellation(
+ android::hardware::gnss::GnssConstellationType startLocationAndGetBlockableConstellation(
const int locations_to_await, const int gnss_sv_info_list_timeout);
std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>> convertToAidl(
const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>&
sv_info_list);
- android::hardware::gnss::BlocklistedSource FindStrongFrequentNonGpsSource(
+ android::hardware::gnss::BlocklistedSource FindStrongFrequentBlockableSource(
const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>
sv_info_list,
const int min_observations);
- android::hardware::gnss::BlocklistedSource FindStrongFrequentNonGpsSource(
+ android::hardware::gnss::BlocklistedSource FindStrongFrequentBlockableSource(
const std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
sv_info_list,
const int min_observations);
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index f7408d8..091b523 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -657,19 +657,19 @@
kGnssSvInfoListTimeout);
ASSERT_EQ(count, sv_info_list_cbq_size);
source_to_blocklist =
- FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+ FindStrongFrequentBlockableSource(sv_info_vec_list, kLocationsToAwait - 1);
} else {
std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_vec_list;
int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
sv_info_vec_list, sv_info_list_cbq_size, kGnssSvInfoListTimeout);
ASSERT_EQ(count, sv_info_list_cbq_size);
source_to_blocklist =
- FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+ FindStrongFrequentBlockableSource(sv_info_vec_list, kLocationsToAwait - 1);
}
if (source_to_blocklist.constellation == GnssConstellationType::UNKNOWN) {
- // Cannot find a non-GPS satellite. Let the test pass.
- ALOGD("Cannot find a non-GPS satellite. Letting the test pass.");
+ // Cannot find a blockable satellite. Let the test pass.
+ ALOGD("Cannot find a blockable satellite. Letting the test pass.");
return;
}
@@ -816,8 +816,8 @@
* BlocklistConstellationLocationOff:
*
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
- * GnssStatus for any non-GPS constellations.
- * 2a & b) Turns off location, and blocklist first non-GPS constellations.
+ * GnssStatus for any blockable constellations.
+ * 2a & b) Turns off location, and blocklist first blockable constellations.
* 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus does not use any constellation but GPS.
* 4a & b) Clean up by turning off location, and send in empty blocklist.
@@ -833,9 +833,9 @@
const int kLocationsToAwait = 3;
const int kGnssSvInfoListTimeout = 2;
- // Find first non-GPS constellation to blocklist
+ // Find first blockable constellation to blocklist
GnssConstellationType constellation_to_blocklist = static_cast<GnssConstellationType>(
- startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
+ startLocationAndGetBlockableConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
// Turns off location
StopAndClearLocations();
@@ -919,8 +919,8 @@
* BlocklistConstellationLocationOn:
*
* 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
- * GnssStatus for any non-GPS constellations.
- * 2a & b) Blocklist first non-GPS constellation, and turn off location.
+ * GnssStatus for any blockable constellations.
+ * 2a & b) Blocklist first blockable constellation, and turn off location.
* 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
* GnssStatus does not use any constellation but GPS.
* 4a & b) Clean up by turning off location, and send in empty blocklist.
@@ -936,9 +936,9 @@
const int kLocationsToAwait = 3;
const int kGnssSvInfoListTimeout = 2;
- // Find first non-GPS constellation to blocklist
+ // Find first blockable constellation to blocklist
GnssConstellationType constellation_to_blocklist = static_cast<GnssConstellationType>(
- startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
+ startLocationAndGetBlockableConstellation(kLocationsToAwait, kGnssSvInfoListTimeout));
BlocklistedSource source_to_blocklist_1;
source_to_blocklist_1.constellation = constellation_to_blocklist;
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index e3ff0f3..38afaf3 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -319,6 +319,24 @@
return d * 1000; // meters
}
+// Returns true iff the device has the specified feature.
+bool Utils::deviceSupportsFeature(const char* feature) {
+ bool device_supports_feature = false;
+ FILE* p = popen("/system/bin/pm list features", "re");
+ if (p) {
+ char* line = NULL;
+ size_t len = 0;
+ while (getline(&line, &len, p) > 0) {
+ if (strstr(line, feature)) {
+ device_supports_feature = true;
+ break;
+ }
+ }
+ pclose(p);
+ }
+ return device_supports_feature;
+}
+
} // namespace common
} // namespace gnss
} // namespace hardware
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index 62d409a..09b99c4 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -60,6 +60,11 @@
static bool isAutomotiveDevice();
static double distanceMeters(double lat1, double lon1, double lat2, double lon2);
+ // Returns true iff the device has the specified feature.
+ static bool deviceSupportsFeature(const char* feature);
+
+ static bool isCnBuild() { return deviceSupportsFeature("cn.google.services"); }
+
private:
template <class T>
static int64_t getLocationTimestampMillis(const T&);
diff --git a/graphics/Android.bp b/graphics/Android.bp
index cae5292..c33f7ff 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -53,13 +53,15 @@
cc_defaults {
name: "android.hardware.graphics.composer3-ndk_static",
static_libs: [
- "android.hardware.graphics.composer3-V3-ndk",
+ "android.hardware.drm.common-V1-ndk",
+ "android.hardware.graphics.composer3-V4-ndk",
],
}
cc_defaults {
name: "android.hardware.graphics.composer3-ndk_shared",
shared_libs: [
- "android.hardware.graphics.composer3-V3-ndk",
+ "android.hardware.drm.common-V1-ndk",
+ "android.hardware.graphics.composer3-V4-ndk",
],
}
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 7157862..3b0a597 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -39,6 +39,7 @@
shared_libs: [
"libui",
"server_configurable_flags",
+ "libtracing_perfetto",
],
static_libs: [
"android.hardware.graphics.composer@2.1-vts",
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index bda4198..431b1b6 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -55,6 +55,7 @@
"libui",
"android.hardware.common-V2-ndk",
"server_configurable_flags",
+ "libtracing_perfetto",
],
static_libs: [
"android.hardware.graphics.common@1.1",
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index c4e6878..1728f78 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -29,7 +29,7 @@
host_supported: true,
vendor_available: true,
double_loadable: true,
- frozen: true,
+ frozen: false,
srcs: [
"android/hardware/graphics/composer3/*.aidl",
],
@@ -37,6 +37,7 @@
imports: [
"android.hardware.graphics.common-V5",
"android.hardware.common-V2",
+ "android.hardware.drm.common-V1",
],
backend: {
cpp: {
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandResultPayload.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandResultPayload.aidl
index 6892f06..0fff523 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandResultPayload.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandResultPayload.aidl
@@ -41,4 +41,5 @@
android.hardware.graphics.composer3.ReleaseFences releaseFences;
android.hardware.graphics.composer3.PresentOrValidate presentOrValidateResult;
android.hardware.graphics.composer3.ClientTargetPropertyWithBrightness clientTargetProperty;
+ android.hardware.graphics.composer3.DisplayLuts displayLuts;
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl
similarity index 84%
rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl
index 75ed070..327e84c 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl
@@ -5,7 +5,7 @@
* 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
+ * 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,
@@ -31,11 +31,13 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.biometrics.fingerprint;
-/* @hide */
+package android.hardware.graphics.composer3;
@VintfStability
-parcelable NextEnrollment {
- int id;
- android.hardware.biometrics.fingerprint.EnrollmentProgressStep[] progressSteps;
- boolean result = true;
+parcelable DisplayLuts {
+ long display;
+ android.hardware.graphics.composer3.DisplayLuts.LayerLut[] layerLuts;
+ parcelable LayerLut {
+ long layer;
+ android.hardware.graphics.composer3.Lut lut;
+ }
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
index e64bd52..cd27360 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -45,4 +45,5 @@
oneway void onVsyncIdle(long display);
oneway void onRefreshRateChangedDebug(in android.hardware.graphics.composer3.RefreshRateChangedDebugData data);
void onHotplugEvent(long display, android.hardware.graphics.common.DisplayHotplugEvent event);
+ oneway void onHdcpLevelsChanged(long display, in android.hardware.drm.HdcpLevels levels);
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
index 87c8c18..8b2b13c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -57,4 +57,5 @@
@nullable int[] bufferSlotsToClear;
android.hardware.graphics.composer3.LayerLifecycleBatchCommandType layerLifecycleBatchCommandType;
int newBufferSlotCount;
+ @nullable android.hardware.graphics.composer3.Lut[] luts;
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
similarity index 85%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
index 173ac17..5fae35b 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
@@ -5,7 +5,7 @@
* 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
+ * 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,
@@ -31,10 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.biometrics.fingerprint;
-/* @hide */
+package android.hardware.graphics.composer3;
@VintfStability
-parcelable EnrollmentProgressStep {
- int durationMs;
- android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquiredInfoAndVendorCodes;
+parcelable Lut {
+ @nullable ParcelFileDescriptor pfd;
+ android.hardware.graphics.composer3.LutProperties lutProperties;
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LutProperties.aidl
similarity index 79%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LutProperties.aidl
index 75ed070..5edceb5 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LutProperties.aidl
@@ -5,7 +5,7 @@
* 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
+ * 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,
@@ -31,11 +31,20 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.biometrics.fingerprint;
-/* @hide */
+package android.hardware.graphics.composer3;
@VintfStability
-parcelable NextEnrollment {
- int id;
- android.hardware.biometrics.fingerprint.EnrollmentProgressStep[] progressSteps;
- boolean result = true;
+parcelable LutProperties {
+ android.hardware.graphics.composer3.LutProperties.Dimension dimension;
+ long size;
+ android.hardware.graphics.composer3.LutProperties.SamplingKey[] samplingKeys;
+ @VintfStability
+ enum Dimension {
+ ONE_D = 1,
+ THREE_D = 3,
+ }
+ @VintfStability
+ enum SamplingKey {
+ RGB,
+ MAX_RGB,
+ }
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl
index 7d31ea3..dae78fd 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OverlayProperties.aidl
@@ -36,6 +36,7 @@
parcelable OverlayProperties {
android.hardware.graphics.composer3.OverlayProperties.SupportedBufferCombinations[] combinations;
boolean supportMixedColorSpaces;
+ @nullable android.hardware.graphics.composer3.LutProperties[] lutProperties;
parcelable SupportedBufferCombinations {
android.hardware.graphics.common.PixelFormat[] pixelFormats;
android.hardware.graphics.common.Dataspace[] standards;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl
index 99c91aa..94fc3d0 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl
@@ -19,6 +19,7 @@
import android.hardware.graphics.composer3.ChangedCompositionTypes;
import android.hardware.graphics.composer3.ClientTargetPropertyWithBrightness;
import android.hardware.graphics.composer3.CommandError;
+import android.hardware.graphics.composer3.DisplayLuts;
import android.hardware.graphics.composer3.DisplayRequest;
import android.hardware.graphics.composer3.PresentFence;
import android.hardware.graphics.composer3.PresentOrValidate;
@@ -96,4 +97,13 @@
* the SDR buffers when an HDR layer is simultaneously device-composited.
*/
ClientTargetPropertyWithBrightness clientTargetProperty;
+
+ /**
+ * Sets the Lut(s) for the layers.
+ *
+ * HWC should only request Lut(s) if SurfaceFlinger does not send the Lut(s) to the HWC.
+ * The main use-case is like HDR10+ or Dolby Vision where there is no Lut to send from
+ * SurfaceFlinger.
+ */
+ DisplayLuts displayLuts;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl
new file mode 100644
index 0000000..ac0a606
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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 android.hardware.graphics.composer3;
+
+import android.hardware.graphics.composer3.Lut;
+
+/**
+ * LUT (Look-Up Table) Interface for Color Transformation.
+ *
+ * This interface allows the HWC (Hardware Composer) to define and communicate Luts
+ * to SurfaceFlinger.
+ */
+@VintfStability
+parcelable DisplayLuts {
+ /**
+ * The display which the layerLuts list is for.
+ */
+ long display;
+
+ parcelable LayerLut {
+ /**
+ * The layer that the HWC is requesting a LUT to be applied during GPU composition.
+ */
+ long layer;
+ /**
+ * A Lut specified by the HWC for given HDR layers that don't have Luts provided.
+ */
+ Lut lut;
+ }
+
+ LayerLut[] layerLuts;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
index 96eccd7..a1d61fd 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -16,6 +16,7 @@
package android.hardware.graphics.composer3;
+import android.hardware.drm.HdcpLevels;
import android.hardware.graphics.common.DisplayHotplugEvent;
import android.hardware.graphics.composer3.RefreshRateChangedDebugData;
import android.hardware.graphics.composer3.VsyncPeriodChangeTimeline;
@@ -139,4 +140,12 @@
* @param event is the type of event that occurred.
*/
void onHotplugEvent(long display, DisplayHotplugEvent event);
+
+ /**
+ * Notify the client the HDCP levels of the display changed.
+ *
+ * @param display is the display whose HDCP levels have changed.
+ * @param levels is the new HDCP levels.
+ */
+ oneway void onHdcpLevelsChanged(long display, in HdcpLevels levels);
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index e961c48..bf4f504 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -24,6 +24,7 @@
import android.hardware.graphics.composer3.Color;
import android.hardware.graphics.composer3.LayerBrightness;
import android.hardware.graphics.composer3.LayerLifecycleBatchCommandType;
+import android.hardware.graphics.composer3.Lut;
import android.hardware.graphics.composer3.ParcelableBlendMode;
import android.hardware.graphics.composer3.ParcelableComposition;
import android.hardware.graphics.composer3.ParcelableDataspace;
@@ -279,4 +280,9 @@
* Specifies the number of buffer slot to be reserved.
*/
int newBufferSlotCount;
+
+ /**
+ * Sets the lut(s) for the layer.
+ */
+ @nullable Lut[] luts;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl
new file mode 100644
index 0000000..abfeb14
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl
@@ -0,0 +1,56 @@
+/*
+ * 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 android.hardware.graphics.composer3;
+
+import android.hardware.graphics.composer3.LutProperties;
+
+/**
+ * LUT (Look-Up Table) Interface for Color Transformation.
+ *
+ * This interface allows the HWC (Hardware Composer) to define and communicate LUTs
+ * with SurfaceFlinger.
+ */
+
+@VintfStability
+parcelable Lut {
+ /**
+ * A handle to a memory region.
+ * If the file descriptor is not set, this means that the HWC doesn't specify a Lut.
+ *
+ * When specifying a Lut, the HWC is required to follow the instructions as below:
+ * 1. use `memfd_create` to create a shared memory segment
+ * with the size specified in lutProperties.
+ * 2. use `mmap` to map the shared memory segment into its own virtual address space.
+ * PROT_READ/PROT_WRITE recommended for prot argument.
+ *
+ * For data precision, 32-bit float is used to specify a Lut by both the HWC and
+ * the platform.
+ *
+ * For unflattening/flattening 3D Lut(s), the algorithm below should be observed
+ * by both the HWC and the platform.
+ * Assuming that we have a 3D array `ORIGINAL[WIDTH, HEIGHT, DEPTH]`, we would turn it into
+ * `FLAT[WIDTH * HEIGHT * DEPTH]` by
+ *
+ * `FLAT[z + DEPTH * (y + HEIGHT * x)] = ORIGINAL[x, y, z]`
+ */
+ @nullable ParcelFileDescriptor pfd;
+
+ /**
+ * The properties of the Lut.
+ */
+ LutProperties lutProperties;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl
new file mode 100644
index 0000000..47ec390
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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 android.hardware.graphics.composer3;
+
+/**
+ * The properties of the LUT (Look-Up Table).
+ */
+@VintfStability
+parcelable LutProperties {
+ /**
+ * The dimension of the Lut.
+ * Either 1d or 3d.
+ */
+ @VintfStability enum Dimension { ONE_D = 1, THREE_D = 3 }
+ Dimension dimension;
+
+ /**
+ * The size of the Lut.
+ * This refers to the length of a 1D Lut, or the grid size of a 3D one.
+ */
+ long size;
+
+ /**
+ * SamplingKey is about how a Lut can be sampled.
+ * A Lut can be sampled in more than one way,
+ * but only one sampling method is used at one time.
+ *
+ * The implementations should use a sampling strategy
+ * at least as good as linear sampling.
+ */
+ // TODO(b/358422255): add sampling ways
+ @VintfStability enum SamplingKey { RGB, MAX_RGB }
+ SamplingKey[] samplingKeys;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl
index c25eea4..b97cdcc 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/OverlayProperties.aidl
@@ -16,6 +16,8 @@
package android.hardware.graphics.composer3;
+import android.hardware.graphics.composer3.LutProperties;
+
@VintfStability
parcelable OverlayProperties {
parcelable SupportedBufferCombinations {
@@ -42,4 +44,8 @@
// True if the DPU is able to color manage at least two overlays
// with different input colorspaces, false otherwise.
boolean supportMixedColorSpaces;
+
+ // Array of lut properties in order that the HWC supports.
+ // The list accepts 1D lut(s) and 3D lut(s).
+ @nullable LutProperties[] lutProperties;
}
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
index 76ba24b..331d717 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
@@ -27,9 +27,8 @@
#include <string.h>
#include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h>
-#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/CommandResultPayload.h>
-
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <log/log.h>
#include <sync/sync.h>
@@ -84,6 +83,10 @@
parseSetClientTargetProperty(std::move(
result.get<CommandResultPayload::Tag::clientTargetProperty>()));
break;
+ case CommandResultPayload::Tag::displayLuts:
+ parseSetDisplayLuts(
+ std::move(result.get<CommandResultPayload::Tag::displayLuts>()));
+ break;
}
}
}
@@ -182,6 +185,20 @@
return std::move(data.clientTargetProperty);
}
+ // Get the lut(s) requested by hardware composer.
+ std::vector<DisplayLuts::LayerLut> takeDisplayLuts(int64_t display) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
+ auto found = mReturnData.find(display);
+
+ // If not found, return the empty vector
+ if (found == mReturnData.end()) {
+ return {};
+ }
+
+ ReturnData& data = found->second;
+ return std::move(data.layerLuts);
+ }
+
private:
void resetData() {
mErrors.clear();
@@ -227,6 +244,18 @@
data.clientTargetProperty = std::move(clientTargetProperty);
}
+ void parseSetDisplayLuts(DisplayLuts&& displayLuts) {
+ LOG_ALWAYS_FATAL_IF(mDisplay && displayLuts.display != *mDisplay);
+ auto& data = mReturnData[displayLuts.display];
+ for (auto& layerLut : displayLuts.layerLuts) {
+ if (layerLut.lut.pfd.get() >= 0) {
+ data.layerLuts.push_back(
+ {layerLut.layer, Lut{ndk::ScopedFileDescriptor(layerLut.lut.pfd.release()),
+ layerLut.lut.lutProperties}});
+ }
+ }
+ }
+
struct ReturnData {
DisplayRequest displayRequests;
std::vector<ChangedCompositionLayer> changedLayers;
@@ -238,6 +267,7 @@
.clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
.brightness = 1.f,
};
+ std::vector<DisplayLuts::LayerLut> layerLuts;
};
std::vector<CommandError> mErrors;
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
index a1ccbfe..02fb3aa 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -30,6 +30,7 @@
#include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h>
#include <aidl/android/hardware/graphics/composer3/LayerBrightness.h>
#include <aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.h>
+#include <aidl/android/hardware/graphics/composer3/Lut.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
@@ -245,6 +246,15 @@
getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end());
}
+ void setLayerLuts(int64_t display, int64_t layer, std::vector<Lut>& luts) {
+ std::vector<std::optional<Lut>> currentLuts;
+ for (auto& lut : luts) {
+ currentLuts.push_back(std::make_optional<Lut>(
+ {ndk::ScopedFileDescriptor(lut.pfd.release()), lut.lutProperties}));
+ }
+ getLayerCommand(display, layer).luts.emplace(std::move(currentLuts));
+ }
+
std::vector<DisplayCommand> takePendingCommands() {
flushLayerCommand();
flushDisplayCommand();
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index 3464fe9..894ca52 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -57,6 +57,7 @@
"libprocessgroup",
"libvndksupport",
"server_configurable_flags",
+ "libtracing_perfetto",
],
header_libs: [
"android.hardware.graphics.composer3-command-buffer",
@@ -65,6 +66,7 @@
"android.hardware.graphics.common@1.2",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
+ "android.hardware.drm.common-V1-ndk",
"libaidlcommonsupport",
"libarect",
"libbase",
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
index 544f692..1f7972c 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.cpp
@@ -208,4 +208,15 @@
}
}
+::ndk::ScopedAStatus GraphicsComposerCallback::onHdcpLevelsChanged(
+ int64_t in_display, const ::aidl::android::hardware::drm::HdcpLevels&) {
+ std::scoped_lock lock(mMutex);
+
+ const auto it = std::find(mDisplays.begin(), mDisplays.end(), in_display);
+ if (it != mDisplays.end()) {
+ mHdcpLevelChangedCount++;
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/GraphicsComposerCallback.h b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
index 7a8d4a3..97f8e2b 100644
--- a/graphics/composer/aidl/vts/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/vts/GraphicsComposerCallback.h
@@ -65,6 +65,8 @@
const RefreshRateChangedDebugData&) override;
virtual ::ndk::ScopedAStatus onHotplugEvent(int64_t in_display,
common::DisplayHotplugEvent) override;
+ virtual ::ndk::ScopedAStatus onHdcpLevelsChanged(
+ int64_t in_display, const ::aidl::android::hardware::drm::HdcpLevels&) override;
mutable std::mutex mMutex;
// the set of all currently connected displays
@@ -88,6 +90,7 @@
int32_t mInvalidVsyncPeriodChangeCount GUARDED_BY(mMutex) = 0;
int32_t mInvalidSeamlessPossibleCount GUARDED_BY(mMutex) = 0;
int32_t mInvalidRefreshRateDebugEnabledCallbackCount GUARDED_BY(mMutex) = 0;
+ int32_t mHdcpLevelChangedCount GUARDED_BY(mMutex) = 0;
};
} // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/ReadbackVts.cpp b/graphics/composer/aidl/vts/ReadbackVts.cpp
index 283b8ce..9d5928d 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/vts/ReadbackVts.cpp
@@ -16,6 +16,7 @@
#include "ReadbackVts.h"
#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <cmath>
#include "RenderEngineVts.h"
#include "renderengine/ExternalTexture.h"
#include "renderengine/impl/ExternalTexture.h"
@@ -106,37 +107,72 @@
return layerSettings;
}
-int32_t ReadbackHelper::GetBytesPerPixel(common::PixelFormat pixelFormat) {
+int32_t ReadbackHelper::GetBitsPerChannel(common::PixelFormat pixelFormat) {
switch (pixelFormat) {
+ case common::PixelFormat::RGBA_1010102:
+ return 10;
case common::PixelFormat::RGBA_8888:
- return 4;
case common::PixelFormat::RGB_888:
- return 3;
+ return 8;
default:
return -1;
}
}
-void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
+int32_t ReadbackHelper::GetAlphaBits(common::PixelFormat pixelFormat) {
+ switch (pixelFormat) {
+ case common::PixelFormat::RGBA_8888:
+ return 8;
+ case common::PixelFormat::RGBA_1010102:
+ return 2;
+ case common::PixelFormat::RGB_888:
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride,
+ int32_t bytesPerPixel, void* bufferData,
common::PixelFormat pixelFormat,
std::vector<Color> desiredPixelColors) {
ASSERT_TRUE(pixelFormat == common::PixelFormat::RGB_888 ||
- pixelFormat == common::PixelFormat::RGBA_8888);
- int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
+ pixelFormat == common::PixelFormat::RGBA_8888 ||
+ pixelFormat == common::PixelFormat::RGBA_1010102);
+ int32_t bitsPerChannel = GetBitsPerChannel(pixelFormat);
+ int32_t alphaBits = GetAlphaBits(pixelFormat);
+ ASSERT_NE(-1, alphaBits);
+ ASSERT_NE(-1, bitsPerChannel);
ASSERT_NE(-1, bytesPerPixel);
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- auto pixel = row * static_cast<int32_t>(width) + col;
+
+ uint32_t maxValue = (1 << bitsPerChannel) - 1;
+ uint32_t maxAlphaValue = (1 << alphaBits) - 1;
+ for (uint32_t row = 0; row < height; row++) {
+ for (uint32_t col = 0; col < width; col++) {
+ auto pixel = row * width + col;
Color srcColor = desiredPixelColors[static_cast<size_t>(pixel)];
- int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
- uint8_t* pixelColor = (uint8_t*)bufferData + offset;
- pixelColor[0] = static_cast<uint8_t>(std::round(255.0f * srcColor.r));
- pixelColor[1] = static_cast<uint8_t>(std::round(255.0f * srcColor.g));
- pixelColor[2] = static_cast<uint8_t>(std::round(255.0f * srcColor.b));
+ uint32_t offset = (row * stride + col) * static_cast<uint32_t>(bytesPerPixel);
- if (bytesPerPixel == 4) {
- pixelColor[3] = static_cast<uint8_t>(std::round(255.0f * srcColor.a));
+ uint32_t* pixelStart = (uint32_t*)((uint8_t*)bufferData + offset);
+
+ uint32_t red = static_cast<uint32_t>(std::round(maxValue * srcColor.r));
+ uint32_t green = static_cast<uint32_t>(std::round(maxValue * srcColor.g));
+ uint32_t blue = static_cast<uint32_t>(std::round(maxValue * srcColor.b));
+
+ // Boo we're not word aligned so special case this.
+ if (pixelFormat == common::PixelFormat::RGB_888) {
+ uint8_t* pixelColor = (uint8_t*)pixelStart;
+ pixelColor[0] = static_cast<uint8_t>(red);
+ pixelColor[1] = static_cast<uint8_t>(green);
+ pixelColor[2] = static_cast<uint8_t>(blue);
+ } else {
+ uint32_t alpha = static_cast<uint32_t>(std::round(maxAlphaValue * srcColor.a));
+ uint32_t color = (alpha << (32 - alphaBits)) |
+ (blue << (32 - alphaBits - bitsPerChannel)) |
+ (green << (32 - alphaBits - bitsPerChannel * 2)) |
+ (red << (32 - alphaBits - bitsPerChannel * 3));
+ *pixelStart = color;
}
}
}
@@ -165,7 +201,8 @@
bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
const common::Dataspace& dataspace) {
if (pixelFormat != common::PixelFormat::RGB_888 &&
- pixelFormat != common::PixelFormat::RGBA_8888) {
+ pixelFormat != common::PixelFormat::RGBA_8888 &&
+ pixelFormat != common::PixelFormat::RGBA_1010102) {
return false;
}
if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
@@ -175,36 +212,110 @@
}
void ReadbackHelper::compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData,
- const uint32_t stride, const uint32_t width,
- const uint32_t height, common::PixelFormat pixelFormat) {
- const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
- ASSERT_NE(-1, bytesPerPixel);
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- auto pixel = row * static_cast<int32_t>(width) + col;
- int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
- uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+ const uint32_t stride, int32_t bytesPerPixel,
+ const uint32_t width, const uint32_t height,
+ common::PixelFormat pixelFormat) {
+ int32_t bitsPerChannel = GetBitsPerChannel(pixelFormat);
+ int32_t alphaBits = GetAlphaBits(pixelFormat);
+ ASSERT_GT(bytesPerPixel, 0);
+ ASSERT_NE(-1, alphaBits);
+ ASSERT_NE(-1, bitsPerChannel);
+ uint32_t maxValue = (1 << bitsPerChannel) - 1;
+ uint32_t maxAlphaValue = (1 << alphaBits) - 1;
+ for (uint32_t row = 0; row < height; row++) {
+ for (uint32_t col = 0; col < width; col++) {
+ auto pixel = row * width + col;
const Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
- ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]);
- ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]);
- ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]);
+
+ uint32_t offset = (row * stride + col) * static_cast<uint32_t>(bytesPerPixel);
+ uint32_t* pixelStart = (uint32_t*)((uint8_t*)bufferData + offset);
+
+ uint32_t expectedRed = static_cast<uint32_t>(std::round(maxValue * expectedColor.r));
+ uint32_t expectedGreen = static_cast<uint32_t>(std::round(maxValue * expectedColor.g));
+ uint32_t expectedBlue = static_cast<uint32_t>(std::round(maxValue * expectedColor.b));
+
+ // Boo we're not word aligned so special case this.
+ if (pixelFormat == common::PixelFormat::RGB_888) {
+ uint8_t* pixelColor = (uint8_t*)pixelStart;
+ ASSERT_EQ(pixelColor[0], static_cast<uint8_t>(expectedRed))
+ << "Red channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(pixelColor[1], static_cast<uint8_t>(expectedGreen))
+ << "Green channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(pixelColor[2], static_cast<uint8_t>(expectedBlue))
+ << "Blue channel mismatch at (" << row << ", " << col << ")";
+ } else {
+ uint32_t expectedAlpha =
+ static_cast<uint32_t>(std::round(maxAlphaValue * expectedColor.a));
+
+ uint32_t actualRed =
+ (*pixelStart >> (32 - alphaBits - bitsPerChannel * 3)) & maxValue;
+ uint32_t actualGreen =
+ (*pixelStart >> (32 - alphaBits - bitsPerChannel * 2)) & maxValue;
+ uint32_t actualBlue = (*pixelStart >> (32 - alphaBits - bitsPerChannel)) & maxValue;
+ uint32_t actualAlpha = (*pixelStart >> (32 - alphaBits)) & maxAlphaValue;
+
+ ASSERT_EQ(expectedRed, actualRed)
+ << "Red channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(expectedGreen, actualGreen)
+ << "Green channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(expectedBlue, actualBlue)
+ << "Blue channel mismatch at (" << row << ", " << col << ")";
+ }
}
}
}
void ReadbackHelper::compareColorBuffers(void* expectedBuffer, void* actualBuffer,
- const uint32_t stride, const uint32_t width,
- const uint32_t height, common::PixelFormat pixelFormat) {
- const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
- ASSERT_NE(-1, bytesPerPixel);
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
- uint8_t* expectedColor = (uint8_t*)expectedBuffer + offset;
- uint8_t* actualColor = (uint8_t*)actualBuffer + offset;
- ASSERT_EQ(expectedColor[0], actualColor[0]);
- ASSERT_EQ(expectedColor[1], actualColor[1]);
- ASSERT_EQ(expectedColor[2], actualColor[2]);
+ const uint32_t stride, int32_t bytesPerPixel,
+ const uint32_t width, const uint32_t height,
+ common::PixelFormat pixelFormat) {
+ int32_t bitsPerChannel = GetBitsPerChannel(pixelFormat);
+ int32_t alphaBits = GetAlphaBits(pixelFormat);
+ ASSERT_GT(bytesPerPixel, 0);
+ ASSERT_NE(-1, alphaBits);
+ ASSERT_NE(-1, bitsPerChannel);
+ uint32_t maxValue = (1 << bitsPerChannel) - 1;
+ uint32_t maxAlphaValue = (1 << alphaBits) - 1;
+ for (uint32_t row = 0; row < height; row++) {
+ for (uint32_t col = 0; col < width; col++) {
+ uint32_t offset = (row * stride + col) * static_cast<uint32_t>(bytesPerPixel);
+ uint32_t* expectedStart = (uint32_t*)((uint8_t*)expectedBuffer + offset);
+ uint32_t* actualStart = (uint32_t*)((uint8_t*)actualBuffer + offset);
+
+ // Boo we're not word aligned so special case this.
+ if (pixelFormat == common::PixelFormat::RGB_888) {
+ uint8_t* expectedPixel = (uint8_t*)expectedStart;
+ uint8_t* actualPixel = (uint8_t*)actualStart;
+ ASSERT_EQ(actualPixel[0], expectedPixel[0])
+ << "Red channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(actualPixel[1], expectedPixel[1])
+ << "Green channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(actualPixel[2], expectedPixel[2])
+ << "Blue channel mismatch at (" << row << ", " << col << ")";
+ } else {
+ uint32_t expectedRed =
+ (*expectedStart >> (32 - alphaBits - bitsPerChannel * 3)) & maxValue;
+ uint32_t expectedGreen =
+ (*expectedStart >> (32 - alphaBits - bitsPerChannel * 2)) & maxValue;
+ uint32_t expectedBlue =
+ (*expectedStart >> (32 - alphaBits - bitsPerChannel)) & maxValue;
+ uint32_t expectedAlpha = (*expectedStart >> (32 - alphaBits)) & maxAlphaValue;
+
+ uint32_t actualRed =
+ (*actualStart >> (32 - alphaBits - bitsPerChannel * 3)) & maxValue;
+ uint32_t actualGreen =
+ (*actualStart >> (32 - alphaBits - bitsPerChannel * 2)) & maxValue;
+ uint32_t actualBlue =
+ (*actualStart >> (32 - alphaBits - bitsPerChannel)) & maxValue;
+ uint32_t actualAlpha = (*actualStart >> (32 - alphaBits)) & maxAlphaValue;
+
+ ASSERT_EQ(expectedRed, actualRed)
+ << "Red channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(expectedGreen, actualGreen)
+ << "Green channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(expectedBlue, actualBlue)
+ << "Blue channel mismatch at (" << row << ", " << col << ")";
+ }
}
}
}
@@ -258,12 +369,13 @@
auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, &bufData, dup(bufferFence.get()),
&bytesPerPixel, &bytesPerStride);
EXPECT_EQ(::android::OK, status);
- ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
+ ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888 ||
+ mPixelFormat == PixelFormat::RGBA_1010102);
const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
: mGraphicBuffer->getStride();
- ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, mWidth, mHeight,
- mPixelFormat);
+ ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, bytesPerPixel, mWidth,
+ mHeight, mPixelFormat);
status = mGraphicBuffer->unlock();
EXPECT_EQ(::android::OK, status);
}
@@ -353,8 +465,8 @@
? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
: mGraphicBuffer->getStride();
EXPECT_EQ(::android::OK, status);
- ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bufData,
- mPixelFormat, expectedColors));
+ ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bytesPerPixel,
+ bufData, mPixelFormat, expectedColors));
const auto unlockStatus = mGraphicBuffer->unlockAsync(&mFillFence);
ASSERT_EQ(::android::OK, unlockStatus);
diff --git a/graphics/composer/aidl/vts/ReadbackVts.h b/graphics/composer/aidl/vts/ReadbackVts.h
index 8ac0f4b..e3b2384 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.h
+++ b/graphics/composer/aidl/vts/ReadbackVts.h
@@ -172,10 +172,12 @@
static Dataspace getDataspaceForColorMode(ColorMode mode);
- static int32_t GetBytesPerPixel(PixelFormat pixelFormat);
+ static int32_t GetBitsPerChannel(PixelFormat pixelFormat);
+ static int32_t GetAlphaBits(PixelFormat pixelFormat);
- static void fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
- PixelFormat pixelFormat, std::vector<Color> desiredPixelColors);
+ static void fillBuffer(uint32_t width, uint32_t height, uint32_t stride, int32_t bytesPerPixel,
+ void* bufferData, PixelFormat pixelFormat,
+ std::vector<Color> desiredPixelColors);
static void clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
int32_t displayWidth);
@@ -189,11 +191,12 @@
static const std::vector<Dataspace> dataspaces;
static void compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData,
- const uint32_t stride, const uint32_t width,
- const uint32_t height, PixelFormat pixelFormat);
- static void compareColorBuffers(void* expectedBuffer, void* actualBuffer, const uint32_t stride,
+ const uint32_t stride, int32_t bytesPerPixel,
const uint32_t width, const uint32_t height,
PixelFormat pixelFormat);
+ static void compareColorBuffers(void* expectedBuffer, void* actualBuffer, const uint32_t stride,
+ int32_t bytesPerPixel, const uint32_t width,
+ const uint32_t height, PixelFormat pixelFormat);
};
class ReadbackBuffer {
diff --git a/graphics/composer/aidl/vts/RenderEngineVts.cpp b/graphics/composer/aidl/vts/RenderEngineVts.cpp
index 4e7f773..48cb8ae 100644
--- a/graphics/composer/aidl/vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/vts/RenderEngineVts.cpp
@@ -83,7 +83,7 @@
const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
: mGraphicBuffer->getStride();
- ReadbackHelper::compareColorBuffers(expectedColors, bufferData, stride,
+ ReadbackHelper::compareColorBuffers(expectedColors, bufferData, stride, bytesPerPixel,
mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
mFormat);
ASSERT_EQ(::android::OK, mGraphicBuffer->unlock());
@@ -110,7 +110,7 @@
ASSERT_EQ(renderedStride, bufferStride);
- ReadbackHelper::compareColorBuffers(renderedBufferData, bufferData, bufferStride,
+ ReadbackHelper::compareColorBuffers(renderedBufferData, bufferData, bufferStride, bytesPerPixel,
mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
mFormat);
ASSERT_EQ(::android::OK, buffer->unlock());
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 3d9253f..9db8794 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -496,11 +496,14 @@
const auto& buffer = graphicBuffer->handle;
void* clientBufData;
const auto stride = static_cast<uint32_t>(graphicBuffer->stride);
- graphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData);
+ int bytesPerPixel = -1;
+ int bytesPerStride = -1;
+ graphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData,
+ &bytesPerPixel, &bytesPerStride);
- ASSERT_NO_FATAL_FAILURE(
- ReadbackHelper::fillBuffer(layer->getWidth(), layer->getHeight(), stride,
- clientBufData, clientFormat, expectedColors));
+ ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
+ layer->getWidth(), layer->getHeight(), stride, bytesPerPixel, clientBufData,
+ clientFormat, expectedColors));
int32_t clientFence;
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
@@ -677,15 +680,18 @@
const auto& buffer = graphicBuffer->handle;
void* clientBufData;
+ int bytesPerPixel = -1;
+ int bytesPerStride = -1;
graphicBuffer->lock(clientUsage, {0, 0, getDisplayWidth(), getDisplayHeight()},
- &clientBufData);
+ &clientBufData, &bytesPerPixel, &bytesPerStride);
std::vector<Color> clientColors(
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
ReadbackHelper::fillColorsArea(clientColors, getDisplayWidth(), clientFrame, RED);
ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
static_cast<uint32_t>(getDisplayWidth()), static_cast<uint32_t>(getDisplayHeight()),
- graphicBuffer->getStride(), clientBufData, clientFormat, clientColors));
+ graphicBuffer->getStride(), bytesPerPixel, clientBufData, clientFormat,
+ clientColors));
int32_t clientFence;
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index bae362f..f398c53 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -719,6 +719,38 @@
}
/**
+ * Test IMapper::lock and IMapper::unlock with no CPU usage requested.
+ */
+TEST_P(GraphicsMapperHidlTest, LockUnlockNoCPUUsage) {
+ const auto& info = mDummyDescriptorInfo;
+
+ const native_handle_t* bufferHandle;
+ uint32_t stride;
+ ASSERT_NO_FATAL_FAILURE(
+ bufferHandle = mGralloc->allocate(info, true, Tolerance::kToleranceStrict, &stride));
+
+ // lock buffer with 0 usage
+ const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+ static_cast<int32_t>(info.height)};
+
+ hidl_handle acquireFenceHandle;
+
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ mGralloc->getMapper()->lock(buffer, 0, region, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& /*tmpData*/) {
+ EXPECT_EQ(Error::BAD_VALUE, tmpError)
+ << "Locking with 0 access succeeded";
+ });
+
+ mGralloc->getMapper()->unlock(buffer, [&](const auto& tmpError, const auto&) {
+ EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+ << "Unlocking not locked buffer succeeded";
+ });
+
+ mGralloc->freeBuffer(bufferHandle);
+}
+
+/**
* Test multiple operations associated with different color formats
*/
TEST_P(GraphicsMapperHidlTest, Lock_YCRCB_420_SP) {
diff --git a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
index 1e0c427..bdbe4d0 100644
--- a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
+++ b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
@@ -750,6 +750,42 @@
}
/**
+ * Test IMapper::lock and IMapper::unlock with no CPU usage requested.
+ */
+TEST_P(GraphicsMapperStableCTests, LockUnlockNoCPUUsage) {
+ constexpr auto usage = BufferUsage::CPU_READ_NEVER | BufferUsage::CPU_WRITE_NEVER;
+ auto buffer = allocate({
+ .name = {"VTS_TEMP"},
+ .width = 64,
+ .height = 64,
+ .layerCount = 1,
+ .format = PixelFormat::RGBA_8888,
+ .usage = usage,
+ .reservedSize = 0,
+ });
+ ASSERT_NE(nullptr, buffer.get());
+
+ // lock buffer for writing
+ const auto& info = buffer->info();
+ const ARect region{0, 0, info.width, info.height};
+ auto handle = buffer->import();
+ uint8_t* data = nullptr;
+
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_VALUE,
+ mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
+ region, -1,(void**)&data))
+ << "Locking with 0 access succeeded";
+
+ int releaseFence = -1;
+ EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER,
+ mapper()->v5.unlock(*handle, &releaseFence))
+ << "Unlocking not locked buffer succeeded";
+ if (releaseFence != -1) {
+ close(releaseFence);
+ }
+}
+
+/**
* Test multiple operations associated with different color formats
*/
TEST_P(GraphicsMapperStableCTests, Lock_YCRCB_420_SP) {
diff --git a/keymaster/aidl/Android.bp b/keymaster/aidl/Android.bp
index 0f2debd..9f4e5cb 100644
--- a/keymaster/aidl/Android.bp
+++ b/keymaster/aidl/Android.bp
@@ -18,6 +18,12 @@
java: {
platform_apis: true,
},
+ ndk: {
+ apex_available: [
+ "com.android.hardware.biometrics.fingerprint.virtual",
+ "//apex_available:platform",
+ ],
+ },
},
versions_with_info: [
{
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.cpp b/radio/aidl/compat/libradiocompat/sim/structs.cpp
index 00db2b8..27aca60 100644
--- a/radio/aidl/compat/libradiocompat/sim/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/structs.cpp
@@ -70,26 +70,60 @@
};
}
-aidl::CarrierRestrictions toAidl(const V1_0::CarrierRestrictions& cr) {
+static aidl::CarrierInfo toCarrierInfo(const aidl::Carrier& carrier) {
return {
- .allowedCarriers = toAidl(cr.allowedCarriers),
- .excludedCarriers = toAidl(cr.excludedCarriers),
+ .mcc = carrier.mcc,
+ .mnc = carrier.mnc,
+ };
+}
+
+static std::vector<aidl::CarrierInfo> toCarrierInfos(const std::vector<aidl::Carrier>& carriers) {
+ std::vector<aidl::CarrierInfo> infos(carriers.size());
+ for (size_t i = 0; i < carriers.size(); i++) {
+ infos[i] = toCarrierInfo(carriers[i]);
+ }
+ return infos;
+}
+
+V1_0::Carrier toHidl(const aidl::CarrierInfo& carrierInfo) {
+ return {
+ .mcc = carrierInfo.mcc,
+ .mnc = carrierInfo.mnc,
+ };
+}
+
+aidl::CarrierRestrictions toAidl(const V1_0::CarrierRestrictions& cr) {
+ auto allowedCarriers = toAidl(cr.allowedCarriers);
+ auto excludedCarriers = toAidl(cr.excludedCarriers);
+ return {
+ .allowedCarriers = allowedCarriers,
+ .excludedCarriers = excludedCarriers,
.allowedCarriersPrioritized = true,
+ .allowedCarrierInfoList = toCarrierInfos(allowedCarriers),
+ .excludedCarrierInfoList = toCarrierInfos(excludedCarriers),
};
}
aidl::CarrierRestrictions toAidl(const V1_4::CarrierRestrictionsWithPriority& cr) {
+ auto allowedCarriers = toAidl(cr.allowedCarriers);
+ auto excludedCarriers = toAidl(cr.excludedCarriers);
return {
- .allowedCarriers = toAidl(cr.allowedCarriers),
- .excludedCarriers = toAidl(cr.excludedCarriers),
+ .allowedCarriers = allowedCarriers,
+ .excludedCarriers = excludedCarriers,
.allowedCarriersPrioritized = cr.allowedCarriersPrioritized,
+ .allowedCarrierInfoList = toCarrierInfos(allowedCarriers),
+ .excludedCarrierInfoList = toCarrierInfos(excludedCarriers),
};
}
V1_4::CarrierRestrictionsWithPriority toHidl(const aidl::CarrierRestrictions& cr) {
return {
- .allowedCarriers = toHidl(cr.allowedCarriers),
- .excludedCarriers = toHidl(cr.excludedCarriers),
+ .allowedCarriers = (cr.allowedCarriers.size() > cr.allowedCarrierInfoList.size())
+ ? toHidl(cr.allowedCarriers)
+ : toHidl(cr.allowedCarrierInfoList),
+ .excludedCarriers = (cr.excludedCarriers.size() > cr.excludedCarrierInfoList.size())
+ ? toHidl(cr.excludedCarriers)
+ : toHidl(cr.excludedCarrierInfoList),
.allowedCarriersPrioritized = cr.allowedCarriersPrioritized,
};
}
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.h b/radio/aidl/compat/libradiocompat/sim/structs.h
index 54099b7..7774bee 100644
--- a/radio/aidl/compat/libradiocompat/sim/structs.h
+++ b/radio/aidl/compat/libradiocompat/sim/structs.h
@@ -37,6 +37,7 @@
::aidl::android::hardware::radio::sim::Carrier toAidl(const V1_0::Carrier& carrier);
V1_0::Carrier toHidl(const ::aidl::android::hardware::radio::sim::Carrier& carrier);
+V1_0::Carrier toHidl(const ::aidl::android::hardware::radio::sim::CarrierInfo& carrierInfo);
::aidl::android::hardware::radio::sim::CarrierRestrictions //
toAidl(const V1_0::CarrierRestrictions& cr);
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index e9b68cc..2823977 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -460,14 +460,43 @@
serial = GetRandomSerialNumber();
CarrierRestrictions carrierRestrictions;
memset(&carrierRestrictions, 0, sizeof(carrierRestrictions));
- carrierRestrictions.allowedCarriers.resize(1);
- carrierRestrictions.excludedCarriers.resize(0);
- carrierRestrictions.allowedCarriers[0].mcc = std::string("123");
- carrierRestrictions.allowedCarriers[0].mnc = std::string("456");
- carrierRestrictions.allowedCarriers[0].matchType = Carrier::MATCH_TYPE_ALL;
- carrierRestrictions.allowedCarriers[0].matchData = std::string();
- carrierRestrictions.allowedCarriersPrioritized = true;
+ int32_t aidl_version;
+ ndk::ScopedAStatus aidl_status = radio_sim->getInterfaceVersion(&aidl_version);
+ ASSERT_OK(aidl_status);
+
+ // Changes start
+
SimLockMultiSimPolicy multisimPolicy = SimLockMultiSimPolicy::NO_MULTISIM_POLICY;
+ ALOGI("VTSAllowedCarriers Current AIDL version is %d ", aidl_version);
+ if (aidl_version <= 2) {
+ ALOGI("VTSAllowedCarriers If aidl_version is below 3 then , it will consider old AIDLs");
+ carrierRestrictions.allowedCarrierInfoList.resize(1);
+ if ((carrierRestrictions.allowedCarrierInfoList.size() > 0)) {
+ ALOGI("VTSAllowedCarriers If size of allowedCarrierInfoList is greater than 0");
+ }
+ carrierRestrictions.allowedCarriers.resize(1);
+ carrierRestrictions.excludedCarriers.resize(0);
+ carrierRestrictions.allowedCarriers[0].mcc = std::string("123");
+ carrierRestrictions.allowedCarriers[0].mnc = std::string("456");
+ carrierRestrictions.allowedCarriers[0].matchType = Carrier::MATCH_TYPE_ALL;
+ carrierRestrictions.allowedCarriers[0].matchData = std::string();
+ carrierRestrictions.allowedCarriersPrioritized = true;
+ multisimPolicy = SimLockMultiSimPolicy::NO_MULTISIM_POLICY;
+ } else {
+ carrierRestrictions.allowedCarrierInfoList.resize(1);
+ carrierRestrictions.excludedCarrierInfoList.resize(0);
+ // TODO(b/365568518): change mcc/mnc to something else once CF fully supports
+ // setAllowedCarriers
+ carrierRestrictions.allowedCarrierInfoList[0].mcc = std::string("123");
+ carrierRestrictions.allowedCarrierInfoList[0].mnc = std::string("456");
+ carrierRestrictions.allowedCarrierInfoList[0].spn = std::string("TestNetwork");
+ carrierRestrictions.allowedCarrierInfoList[0].gid1 = std::string("BAE000000000000");
+ carrierRestrictions.allowedCarrierInfoList[0].gid2 = std::string("AE0000000000000");
+ carrierRestrictions.allowedCarrierInfoList[0].imsiPrefix = std::string("9987");
+ carrierRestrictions.allowedCarriersPrioritized = true;
+ carrierRestrictions.status = CarrierRestrictions::CarrierRestrictionStatus::RESTRICTED;
+ multisimPolicy = SimLockMultiSimPolicy::NO_MULTISIM_POLICY;
+ }
radio_sim->setAllowedCarriers(serial, carrierRestrictions, multisimPolicy);
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -490,7 +519,7 @@
sleep(2);
updateSimCardStatus();
}
- // TODO: uncomment once CF fully supports setAllowedCarriers
+ // TODO(b/365568518): uncomment once CF fully supports setAllowedCarriers
// EXPECT_EQ(CardStatus::STATE_RESTRICTED, cardStatus.cardState);
}
@@ -503,17 +532,38 @@
EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
- EXPECT_EQ(1, radioRsp_sim->carrierRestrictionsResp.allowedCarriers.size());
- EXPECT_EQ(0, radioRsp_sim->carrierRestrictionsResp.excludedCarriers.size());
- ASSERT_TRUE(std::string("123") ==
- radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].mcc);
- ASSERT_TRUE(std::string("456") ==
- radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].mnc);
- EXPECT_EQ(Carrier::MATCH_TYPE_ALL,
- radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].matchType);
- ASSERT_TRUE(radioRsp_sim->carrierRestrictionsResp.allowedCarriersPrioritized);
- EXPECT_EQ(SimLockMultiSimPolicy::NO_MULTISIM_POLICY, radioRsp_sim->multiSimPolicyResp);
+ if (aidl_version <= 2) {
+ ASSERT_EQ(1, radioRsp_sim->carrierRestrictionsResp.allowedCarriers.size());
+ EXPECT_EQ(0, radioRsp_sim->carrierRestrictionsResp.excludedCarriers.size());
+ ASSERT_TRUE(std::string("123") ==
+ radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].mcc);
+ ASSERT_TRUE(std::string("456") ==
+ radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].mnc);
+ EXPECT_EQ(Carrier::MATCH_TYPE_ALL,
+ radioRsp_sim->carrierRestrictionsResp.allowedCarriers[0].matchType);
+ ASSERT_TRUE(radioRsp_sim->carrierRestrictionsResp.allowedCarriersPrioritized);
+ EXPECT_EQ(SimLockMultiSimPolicy::NO_MULTISIM_POLICY, radioRsp_sim->multiSimPolicyResp);
+ } else {
+ ASSERT_EQ(1, radioRsp_sim->carrierRestrictionsResp.allowedCarrierInfoList.size());
+ EXPECT_EQ(0, radioRsp_sim->carrierRestrictionsResp.excludedCarrierInfoList.size());
+ ASSERT_EQ(std::string("123"),
+ radioRsp_sim->carrierRestrictionsResp.allowedCarrierInfoList[0].mcc);
+ ASSERT_EQ(std::string("456"),
+ radioRsp_sim->carrierRestrictionsResp.allowedCarrierInfoList[0].mnc);
+#if 0 // TODO(b/365568518): enable once CF fully supports setAllowedCarriers
+ ASSERT_EQ(std::string("BAE000000000000"),
+ radioRsp_sim->carrierRestrictionsResp.allowedCarrierInfoList[0].gid1);
+ ASSERT_EQ(std::string("AE0000000000000"),
+ radioRsp_sim->carrierRestrictionsResp.allowedCarrierInfoList[0].gid2);
+ ASSERT_EQ(std::string("9987"),
+ radioRsp_sim->carrierRestrictionsResp.allowedCarrierInfoList[0].imsiPrefix);
+ EXPECT_EQ(CarrierRestrictions::CarrierRestrictionStatus::RESTRICTED,
+ radioRsp_sim->carrierRestrictionsResp.status);
+#endif
+ ASSERT_TRUE(radioRsp_sim->carrierRestrictionsResp.allowedCarriersPrioritized);
+ EXPECT_EQ(SimLockMultiSimPolicy::NO_MULTISIM_POLICY, radioRsp_sim->multiSimPolicyResp);
+ }
sleep(10);
/**
@@ -522,9 +572,15 @@
* status for cardStatus.
*/
memset(&carrierRestrictions, 0, sizeof(carrierRestrictions));
- carrierRestrictions.allowedCarriers.resize(0);
- carrierRestrictions.excludedCarriers.resize(0);
- carrierRestrictions.allowedCarriersPrioritized = false;
+ if (aidl_version <= 2) {
+ carrierRestrictions.allowedCarriers.resize(0);
+ carrierRestrictions.excludedCarriers.resize(0);
+ carrierRestrictions.allowedCarriersPrioritized = false;
+ } else {
+ carrierRestrictions.allowedCarrierInfoList.resize(0);
+ carrierRestrictions.excludedCarrierInfoList.resize(0);
+ carrierRestrictions.allowedCarriersPrioritized = false;
+ }
serial = GetRandomSerialNumber();
radio_sim->setAllowedCarriers(serial, carrierRestrictions, multisimPolicy);
diff --git a/sensors/aidl/android/hardware/sensors/SensorType.aidl b/sensors/aidl/android/hardware/sensors/SensorType.aidl
index 9098894..4904c3f 100644
--- a/sensors/aidl/android/hardware/sensors/SensorType.aidl
+++ b/sensors/aidl/android/hardware/sensors/SensorType.aidl
@@ -718,8 +718,8 @@
HEADING = 42,
/**
- * Base for device manufacturers private sensor types.
- * These sensor types can't be exposed in the SDK.
+ * Base of the range reserved for device manufacturers' private sensor
+ * types. These sensor types aren't documented in the SDK.
*/
DEVICE_PRIVATE_BASE = 0x10000,
}
diff --git a/sensors/aidl/default/include/sensors-impl/Sensors.h b/sensors/aidl/default/include/sensors-impl/Sensors.h
index 2adbc9d..c90db69 100644
--- a/sensors/aidl/default/include/sensors-impl/Sensors.h
+++ b/sensors/aidl/default/include/sensors-impl/Sensors.h
@@ -97,9 +97,13 @@
return;
}
if (mEventQueue->write(&events.front(), events.size())) {
+ if (mEventQueueFlag == nullptr) {
+ // Don't take the wake lock if we can't wake the receiver to avoid holding it
+ // indefinitely.
+ return;
+ }
mEventQueueFlag->wake(
static_cast<uint32_t>(BnSensors::EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS));
-
if (wakeup) {
// Keep track of the number of outstanding WAKE_UP events in order to properly hold
// a wake lock until the framework has secured a wake lock
diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp
index 0306dca..3ef8749 100644
--- a/tests/extension/vibrator/aidl/Android.bp
+++ b/tests/extension/vibrator/aidl/Android.bp
@@ -37,6 +37,15 @@
java: {
enabled: false,
},
+ ndk: {
+ enabled: true,
+ },
+ cpp: {
+ enabled: false,
+ },
+ rust: {
+ enabled: false,
+ },
},
frozen: true,
versions_with_info: [
diff --git a/tests/extension/vibrator/aidl/client/Android.bp b/tests/extension/vibrator/aidl/client/Android.bp
index 284ac74..00510b7 100644
--- a/tests/extension/vibrator/aidl/client/Android.bp
+++ b/tests/extension/vibrator/aidl/client/Android.bp
@@ -16,16 +16,10 @@
srcs: [
// system code has the option to use the unstable C++ libbinder API
// or the NDK one. For maximum code portability, using the ndk client
- // makes the most sense, but both are provided here as an example.
- "test-cpp-client.cpp",
+ // makes the most sense.
"test-ndk-client.cpp",
],
shared_libs: [
- "libbinder",
- "libutils",
- "android.hardware.vibrator-V2-cpp",
- "android.hardware.tests.extension.vibrator-V1-cpp",
-
"libbinder_ndk",
"android.hardware.vibrator-V2-ndk",
"android.hardware.tests.extension.vibrator-V1-ndk",
diff --git a/tests/extension/vibrator/aidl/client/test-cpp-client.cpp b/tests/extension/vibrator/aidl/client/test-cpp-client.cpp
deleted file mode 100644
index 015a345..0000000
--- a/tests/extension/vibrator/aidl/client/test-cpp-client.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2019 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 <android/hardware/tests/extension/vibrator/ICustomVibrator.h>
-#include <android/hardware/vibrator/IVibrator.h>
-#include <binder/IInterface.h>
-#include <binder/IServiceManager.h>
-#include <gtest/gtest.h>
-
-using android::checked_interface_cast;
-using android::IBinder;
-using android::IInterface;
-using android::OK;
-using android::sp;
-using android::waitForVintfService;
-using android::hardware::tests::extension::vibrator::Directionality;
-using android::hardware::tests::extension::vibrator::ICustomVibrator;
-using android::hardware::vibrator::IVibrator;
-
-TEST(Cpp, CallRootMethod) {
- sp<IVibrator> vib = waitForVintfService<IVibrator>();
- ASSERT_NE(nullptr, vib.get());
- ASSERT_TRUE(vib->off().isOk());
-}
-
-TEST(Cpp, CallExtMethod) {
- // normally you would want to cache this
- sp<IVibrator> vib = waitForVintfService<IVibrator>();
- ASSERT_NE(nullptr, vib.get());
-
- // getting the extension
- sp<IBinder> ext;
- ASSERT_EQ(OK, IInterface::asBinder(vib)->getExtension(&ext));
- sp<ICustomVibrator> cvib = checked_interface_cast<ICustomVibrator>(ext);
- ASSERT_NE(nullptr, cvib.get());
-
- // calling extension method
- ASSERT_TRUE(cvib->setDirectionality(Directionality::TRANSVERSE).isOk());
-}
diff --git a/tests/extension/vibrator/aidl/client/test-ndk-client.cpp b/tests/extension/vibrator/aidl/client/test-ndk-client.cpp
index c846495..4dd86e8 100644
--- a/tests/extension/vibrator/aidl/client/test-ndk-client.cpp
+++ b/tests/extension/vibrator/aidl/client/test-ndk-client.cpp
@@ -28,7 +28,7 @@
static const std::string kInstance = std::string() + IVibrator::descriptor + "/default";
TEST(Ndk, CallRootMethod) {
- SpAIBinder vibBinder = SpAIBinder(AServiceManager_getService(kInstance.c_str()));
+ SpAIBinder vibBinder = SpAIBinder(AServiceManager_waitForService(kInstance.c_str()));
ASSERT_NE(nullptr, vibBinder.get());
std::shared_ptr<IVibrator> vib = IVibrator::fromBinder(vibBinder);
ASSERT_NE(nullptr, vib.get());
@@ -38,7 +38,7 @@
TEST(Ndk, CallExtMethod) {
// normally you would want to cache this
//
- SpAIBinder vibBinder = SpAIBinder(AServiceManager_getService(kInstance.c_str()));
+ SpAIBinder vibBinder = SpAIBinder(AServiceManager_waitForService(kInstance.c_str()));
ASSERT_NE(nullptr, vibBinder.get());
std::shared_ptr<IVibrator> vib = IVibrator::fromBinder(vibBinder);
ASSERT_NE(nullptr, vib.get());
diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp
index 5e156af..479b4fd 100644
--- a/tests/extension/vibrator/aidl/default/Android.bp
+++ b/tests/extension/vibrator/aidl/default/Android.bp
@@ -10,11 +10,6 @@
cc_binary {
name: "android.hardware.tests.extension.vibrator-service.example",
relative_install_path: "hw",
- // normally you implement a service directly, but we are using an implementation
- // from a library to attach our extension to.
- static_libs: [
- "libvibratorexampleimpl",
- ],
// need to add this in the manifest and to init as well to use, see
// android.hardware.vibrator-service.example. This binary is being tested
@@ -23,6 +18,7 @@
vendor: true,
srcs: [
"service.cpp",
+ "Vibrator.cpp",
"CustomVibrator.cpp",
],
shared_libs: [
diff --git a/tests/extension/vibrator/aidl/default/Vibrator.cpp b/tests/extension/vibrator/aidl/default/Vibrator.cpp
new file mode 100644
index 0000000..5084096
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/Vibrator.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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 "Vibrator.h"
+
+#include <android-base/logging.h>
+
+namespace aidl::android::hardware::vibrator {
+
+ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
+ // basic example with only amplitude control capability
+ *_aidl_return = IVibrator::CAP_AMPLITUDE_CONTROL;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::off() {
+ LOG(INFO) << "Vibrator off";
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs, const std::shared_ptr<IVibratorCallback>&) {
+ LOG(INFO) << "Vibrator on for timeoutMs: " << timeoutMs;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
+ LOG(INFO) << "Vibrator set amplitude: " << amplitude;
+ if (amplitude <= 0.0f || amplitude > 1.0f) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::perform(Effect, EffectStrength,
+ const std::shared_ptr<IVibratorCallback>&, int32_t*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect>* _aidl_return) {
+ *_aidl_return = {};
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::setExternalControl(bool) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector<CompositePrimitive>*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive, int32_t*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>&,
+ const std::shared_ptr<IVibratorCallback>&) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect>*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t, Effect, EffectStrength) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getResonantFrequency(float*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getQFactor(float*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getFrequencyResolution(float*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector<float>*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector<Braking>*) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle>&,
+ const std::shared_ptr<IVibratorCallback>&) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+}
+
+} // namespace aidl::android::hardware::vibrator
diff --git a/tests/extension/vibrator/aidl/default/Vibrator.h b/tests/extension/vibrator/aidl/default/Vibrator.h
new file mode 100644
index 0000000..80916ae
--- /dev/null
+++ b/tests/extension/vibrator/aidl/default/Vibrator.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/vibrator/BnVibrator.h>
+
+namespace aidl::android::hardware::vibrator {
+
+class Vibrator : public BnVibrator {
+ ndk::ScopedAStatus getCapabilities(int32_t* _aidl_return) override;
+ ndk::ScopedAStatus off() override;
+ ndk::ScopedAStatus on(int32_t timeoutMs,
+ const std::shared_ptr<IVibratorCallback>& callback) override;
+ ndk::ScopedAStatus perform(Effect effect, EffectStrength strength,
+ const std::shared_ptr<IVibratorCallback>& callback,
+ int32_t* _aidl_return) override;
+ ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _aidl_return) override;
+ ndk::ScopedAStatus setAmplitude(float amplitude) override;
+ ndk::ScopedAStatus setExternalControl(bool enabled) override;
+ ndk::ScopedAStatus getCompositionDelayMax(int32_t* maxDelayMs);
+ ndk::ScopedAStatus getCompositionSizeMax(int32_t* maxSize);
+ ndk::ScopedAStatus getSupportedPrimitives(std::vector<CompositePrimitive>* supported) override;
+ ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive,
+ int32_t* durationMs) override;
+ ndk::ScopedAStatus compose(const std::vector<CompositeEffect>& composite,
+ const std::shared_ptr<IVibratorCallback>& callback) override;
+ ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect>* _aidl_return) override;
+ ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override;
+ ndk::ScopedAStatus alwaysOnDisable(int32_t id) override;
+ ndk::ScopedAStatus getResonantFrequency(float* resonantFreqHz) override;
+ ndk::ScopedAStatus getQFactor(float* qFactor) override;
+ ndk::ScopedAStatus getFrequencyResolution(float* freqResolutionHz) override;
+ ndk::ScopedAStatus getFrequencyMinimum(float* freqMinimumHz) override;
+ ndk::ScopedAStatus getBandwidthAmplitudeMap(std::vector<float>* _aidl_return) override;
+ ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t* durationMs) override;
+ ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t* maxSize) override;
+ ndk::ScopedAStatus getSupportedBraking(std::vector<Braking>* supported) override;
+ ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle>& composite,
+ const std::shared_ptr<IVibratorCallback>& callback) override;
+};
+
+} // namespace aidl::android::hardware::vibrator
diff --git a/tests/extension/vibrator/aidl/default/service.cpp b/tests/extension/vibrator/aidl/default/service.cpp
index 16290df..5917d0f 100644
--- a/tests/extension/vibrator/aidl/default/service.cpp
+++ b/tests/extension/vibrator/aidl/default/service.cpp
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#include <vibrator-impl/Vibrator.h>
#include "CustomVibrator.h"
+#include "Vibrator.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
diff --git a/tv/tuner/aidl/Android.bp b/tv/tuner/aidl/Android.bp
index 6cbf362..efcc327 100644
--- a/tv/tuner/aidl/Android.bp
+++ b/tv/tuner/aidl/Android.bp
@@ -41,6 +41,5 @@
},
],
- frozen: true,
}
diff --git a/tv/tuner/aidl/default/Android.bp b/tv/tuner/aidl/default/Android.bp
index 4f0d04b..a76a653 100644
--- a/tv/tuner/aidl/default/Android.bp
+++ b/tv/tuner/aidl/default/Android.bp
@@ -29,7 +29,7 @@
],
shared_libs: [
"android.hardware.common.fmq-V1-ndk",
- "android.hardware.tv.tuner-V2-ndk",
+ "android.hardware.tv.tuner-V3-ndk",
"libbase",
"libbinder_ndk",
"libcutils",
diff --git a/tv/tuner/aidl/vts/functional/Android.bp b/tv/tuner/aidl/vts/functional/Android.bp
index 09e63fc..0057b6f 100644
--- a/tv/tuner/aidl/vts/functional/Android.bp
+++ b/tv/tuner/aidl/vts/functional/Android.bp
@@ -55,7 +55,7 @@
"android.hardware.cas-V1-ndk",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
- "android.hardware.tv.tuner-V2-ndk",
+ "android.hardware.tv.tuner-V3-ndk",
"libaidlcommonsupport",
"libfmq",
"libcutils",
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index b5199e2..b2d98f5 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -15,14 +15,33 @@
srcs: [
"android/hardware/vibrator/*.aidl",
],
+ headers: [
+ "PersistableBundle_aidl",
+ ],
stability: "vintf",
backend: {
java: {
sdk_version: "system_current",
},
+ ndk: {
+ enabled: true,
+ },
+ cpp: {
+ enabled: false,
+ },
+ rust: {
+ enabled: false,
+ },
},
- versions: [
- "1",
- "2",
+ versions_with_info: [
+ {
+ version: "1",
+ imports: [],
+ },
+ {
+ version: "2",
+ imports: [],
+ },
],
+ frozen: false,
}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl
index b7afb66..0dcc657 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl
@@ -58,15 +58,23 @@
int getPwleCompositionSizeMax();
android.hardware.vibrator.Braking[] getSupportedBraking();
void composePwle(in android.hardware.vibrator.PrimitivePwle[] composite, in android.hardware.vibrator.IVibratorCallback callback);
- const int CAP_ON_CALLBACK = 1;
- const int CAP_PERFORM_CALLBACK = 2;
- const int CAP_AMPLITUDE_CONTROL = 4;
- const int CAP_EXTERNAL_CONTROL = 8;
- const int CAP_EXTERNAL_AMPLITUDE_CONTROL = 16;
- const int CAP_COMPOSE_EFFECTS = 32;
- const int CAP_ALWAYS_ON_CONTROL = 64;
- const int CAP_GET_RESONANT_FREQUENCY = 128;
- const int CAP_GET_Q_FACTOR = 256;
- const int CAP_FREQUENCY_CONTROL = 512;
- const int CAP_COMPOSE_PWLE_EFFECTS = 1024;
+ void performVendorEffect(in android.hardware.vibrator.VendorEffect vendorEffect, in android.hardware.vibrator.IVibratorCallback callback);
+ List<android.hardware.vibrator.PwleV2OutputMapEntry> getPwleV2FrequencyToOutputAccelerationMap();
+ int getPwleV2PrimitiveDurationMaxMillis();
+ int getPwleV2CompositionSizeMax();
+ int getPwleV2PrimitiveDurationMinMillis();
+ void composePwleV2(in android.hardware.vibrator.PwleV2Primitive[] composite, in android.hardware.vibrator.IVibratorCallback callback);
+ const int CAP_ON_CALLBACK = (1 << 0) /* 1 */;
+ const int CAP_PERFORM_CALLBACK = (1 << 1) /* 2 */;
+ const int CAP_AMPLITUDE_CONTROL = (1 << 2) /* 4 */;
+ const int CAP_EXTERNAL_CONTROL = (1 << 3) /* 8 */;
+ const int CAP_EXTERNAL_AMPLITUDE_CONTROL = (1 << 4) /* 16 */;
+ const int CAP_COMPOSE_EFFECTS = (1 << 5) /* 32 */;
+ const int CAP_ALWAYS_ON_CONTROL = (1 << 6) /* 64 */;
+ const int CAP_GET_RESONANT_FREQUENCY = (1 << 7) /* 128 */;
+ const int CAP_GET_Q_FACTOR = (1 << 8) /* 256 */;
+ const int CAP_FREQUENCY_CONTROL = (1 << 9) /* 512 */;
+ const int CAP_COMPOSE_PWLE_EFFECTS = (1 << 10) /* 1024 */;
+ const int CAP_PERFORM_VENDOR_EFFECTS = (1 << 11) /* 2048 */;
+ const int CAP_COMPOSE_PWLE_EFFECTS_V2 = (1 << 12) /* 4096 */;
}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
index 290c68d..ef5794c 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
@@ -40,12 +40,12 @@
void prepareSynced(in int[] vibratorIds);
void triggerSynced(in android.hardware.vibrator.IVibratorCallback callback);
void cancelSynced();
- const int CAP_SYNC = 1;
- const int CAP_PREPARE_ON = 2;
- const int CAP_PREPARE_PERFORM = 4;
- const int CAP_PREPARE_COMPOSE = 8;
- const int CAP_MIXED_TRIGGER_ON = 16;
- const int CAP_MIXED_TRIGGER_PERFORM = 32;
- const int CAP_MIXED_TRIGGER_COMPOSE = 64;
- const int CAP_TRIGGER_CALLBACK = 128;
+ const int CAP_SYNC = (1 << 0) /* 1 */;
+ const int CAP_PREPARE_ON = (1 << 1) /* 2 */;
+ const int CAP_PREPARE_PERFORM = (1 << 2) /* 4 */;
+ const int CAP_PREPARE_COMPOSE = (1 << 3) /* 8 */;
+ const int CAP_MIXED_TRIGGER_ON = (1 << 4) /* 16 */;
+ const int CAP_MIXED_TRIGGER_PERFORM = (1 << 5) /* 32 */;
+ const int CAP_MIXED_TRIGGER_COMPOSE = (1 << 6) /* 64 */;
+ const int CAP_TRIGGER_CALLBACK = (1 << 7) /* 128 */;
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
similarity index 88%
rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
rename to vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
index 173ac17..a5eda52 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
@@ -31,10 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.biometrics.fingerprint;
-/* @hide */
+package android.hardware.vibrator;
@VintfStability
-parcelable EnrollmentProgressStep {
- int durationMs;
- android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquiredInfoAndVendorCodes;
+parcelable PwleV2OutputMapEntry {
+ float frequencyHz;
+ float maxOutputAccelerationGs;
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2Primitive.aidl
similarity index 88%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
copy to vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2Primitive.aidl
index 173ac17..c4f3ea9 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2Primitive.aidl
@@ -31,10 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.biometrics.fingerprint;
-/* @hide */
+package android.hardware.vibrator;
@VintfStability
-parcelable EnrollmentProgressStep {
- int durationMs;
- android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquiredInfoAndVendorCodes;
+parcelable PwleV2Primitive {
+ float amplitude;
+ float frequencyHz;
+ int timeMillis;
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
copy to vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl
index 173ac17..62a7380 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl
@@ -31,10 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.biometrics.fingerprint;
-/* @hide */
+package android.hardware.vibrator;
@VintfStability
-parcelable EnrollmentProgressStep {
- int durationMs;
- android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquiredInfoAndVendorCodes;
+parcelable VendorEffect {
+ android.os.PersistableBundle vendorData;
+ android.hardware.vibrator.EffectStrength strength = android.hardware.vibrator.EffectStrength.MEDIUM;
+ float scale;
+ float vendorScale;
}
diff --git a/vibrator/aidl/android/hardware/vibrator/Braking.aidl b/vibrator/aidl/android/hardware/vibrator/Braking.aidl
index 2bc51db..f934ff2 100644
--- a/vibrator/aidl/android/hardware/vibrator/Braking.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/Braking.aidl
@@ -23,12 +23,12 @@
* No braking mechanism used.
* This is the default if the hardware does not support any braking mechanism.
*/
- NONE,
+ NONE = 0,
/**
* Closed-loop active braking.
*
* This effect should produce a sharp, crisp end to the waveform
* Support is optional.
*/
- CLAB,
+ CLAB = 1,
}
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
index 5314898..5f8ee8d 100644
--- a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
@@ -24,13 +24,13 @@
*
* Support is required.
*/
- NOOP,
+ NOOP = 0,
/**
* This effect should produce a sharp, crisp click sensation.
*
* Support is required.
*/
- CLICK,
+ CLICK = 1,
/**
* A haptic effect that simulates downwards movement with gravity. Often
* followed by extra energy of hitting and reverberation to augment
@@ -38,43 +38,43 @@
*
* Support is optional.
*/
- THUD,
+ THUD = 2,
/**
* A haptic effect that simulates spinning momentum.
*
* Support is optional.
*/
- SPIN,
+ SPIN = 3,
/**
* A haptic effect that simulates quick upward movement against gravity.
*
* Support is required.
*/
- QUICK_RISE,
+ QUICK_RISE = 4,
/**
* A haptic effect that simulates slow upward movement against gravity.
*
* Support is required.
*/
- SLOW_RISE,
+ SLOW_RISE = 5,
/**
* A haptic effect that simulates quick downwards movement with gravity.
*
* Support is required.
*/
- QUICK_FALL,
+ QUICK_FALL = 6,
/**
* This very short effect should produce a light crisp sensation intended
* to be used repetitively for dynamic feedback.
*
* Support is required.
*/
- LIGHT_TICK,
+ LIGHT_TICK = 7,
/**
* This very short low frequency effect should produce a light crisp sensation intended
* to be used repetitively for dynamic feedback.
*
* Support is required.
*/
- LOW_TICK,
+ LOW_TICK = 8,
}
diff --git a/vibrator/aidl/android/hardware/vibrator/Effect.aidl b/vibrator/aidl/android/hardware/vibrator/Effect.aidl
index c60bfe9..f5cf9e3 100644
--- a/vibrator/aidl/android/hardware/vibrator/Effect.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/Effect.aidl
@@ -24,57 +24,57 @@
*
* This effect should produce a sharp, crisp click sensation.
*/
- CLICK,
+ CLICK = 0,
/**
* A double click effect.
*
* This effect should produce two sequential sharp, crisp click sensations with a minimal
* amount of time between them.
*/
- DOUBLE_CLICK,
+ DOUBLE_CLICK = 1,
/**
* A tick effect.
*
* This effect should produce a soft, short sensation, like the tick of a clock.
*/
- TICK,
+ TICK = 2,
/**
* A thud effect.
*
* This effect should solid feeling bump, like the depression of a heavy mechanical button.
*/
- THUD,
+ THUD = 3,
/**
* A pop effect.
*
* A short, quick burst effect.
*/
- POP,
+ POP = 4,
/**
* A heavy click effect.
*
* This should produce a sharp striking sensation, like a click but stronger.
*/
- HEAVY_CLICK,
+ HEAVY_CLICK = 5,
/**
* Ringtone patterns. They may correspond with the device's ringtone audio, or may just be a
* pattern that can be played as a ringtone with any audio, depending on the device.
*/
- RINGTONE_1,
- RINGTONE_2,
- RINGTONE_3,
- RINGTONE_4,
- RINGTONE_5,
- RINGTONE_6,
- RINGTONE_7,
- RINGTONE_8,
- RINGTONE_9,
- RINGTONE_10,
- RINGTONE_11,
- RINGTONE_12,
- RINGTONE_13,
- RINGTONE_14,
- RINGTONE_15,
+ RINGTONE_1 = 6,
+ RINGTONE_2 = 7,
+ RINGTONE_3 = 8,
+ RINGTONE_4 = 9,
+ RINGTONE_5 = 10,
+ RINGTONE_6 = 11,
+ RINGTONE_7 = 12,
+ RINGTONE_8 = 13,
+ RINGTONE_9 = 14,
+ RINGTONE_10 = 15,
+ RINGTONE_11 = 16,
+ RINGTONE_12 = 17,
+ RINGTONE_13 = 18,
+ RINGTONE_14 = 19,
+ RINGTONE_15 = 20,
/**
* A soft tick effect meant to be played as a texture.
*
@@ -82,5 +82,5 @@
* are expected to be played multiple times in quick succession, replicating a specific
* texture to the user as a form of haptic feedback.
*/
- TEXTURE_TICK,
+ TEXTURE_TICK = 21,
}
diff --git a/vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl b/vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl
index 66f70e5..c6a78d4 100644
--- a/vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl
@@ -19,7 +19,7 @@
@VintfStability
@Backing(type="byte")
enum EffectStrength {
- LIGHT,
- MEDIUM,
- STRONG,
+ LIGHT = 0,
+ MEDIUM = 1,
+ STRONG = 2,
}
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
index b4e7e44..11f36ba 100644
--- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
@@ -16,13 +16,16 @@
package android.hardware.vibrator;
-import android.hardware.vibrator.IVibratorCallback;
import android.hardware.vibrator.Braking;
-import android.hardware.vibrator.Effect;
-import android.hardware.vibrator.EffectStrength;
import android.hardware.vibrator.CompositeEffect;
import android.hardware.vibrator.CompositePrimitive;
+import android.hardware.vibrator.Effect;
+import android.hardware.vibrator.EffectStrength;
+import android.hardware.vibrator.IVibratorCallback;
import android.hardware.vibrator.PrimitivePwle;
+import android.hardware.vibrator.PwleV2OutputMapEntry;
+import android.hardware.vibrator.PwleV2Primitive;
+import android.hardware.vibrator.VendorEffect;
@VintfStability
interface IVibrator {
@@ -70,6 +73,14 @@
* Whether composePwle is supported.
*/
const int CAP_COMPOSE_PWLE_EFFECTS = 1 << 10;
+ /**
+ * Whether perform w/ vendor effect is supported.
+ */
+ const int CAP_PERFORM_VENDOR_EFFECTS = 1 << 11;
+ /**
+ * Whether composePwleV2 for PwlePrimitives is supported.
+ */
+ const int CAP_COMPOSE_PWLE_EFFECTS_V2 = 1 << 12;
/**
* Determine capabilities of the vibrator HAL (CAP_* mask)
@@ -359,4 +370,103 @@
* @param composite Array of PWLEs.
*/
void composePwle(in PrimitivePwle[] composite, in IVibratorCallback callback);
+
+ /**
+ * Fire off a vendor-defined haptic event.
+ *
+ * This may not be supported and this support is reflected in
+ * getCapabilities (CAP_PERFORM_VENDOR_EFFECTS).
+ *
+ * The duration of the effect is unknown and can be undefined for looping effects.
+ * IVibratorCallback.onComplete() support is required for this API.
+ *
+ * Doing this operation while the vibrator is already on is undefined behavior. Clients should
+ * explicitly call off.
+ *
+ * @param effect The vendor data representing the effect to be performed.
+ * @param callback A callback used to inform Frameworks of state change.
+ * @throws :
+ * - EX_UNSUPPORTED_OPERATION if unsupported, as reflected by getCapabilities.
+ * - EX_ILLEGAL_ARGUMENT for bad framework parameters, e.g. scale or effect strength.
+ * - EX_SERVICE_SPECIFIC for bad vendor data, vibration is not triggered.
+ */
+ void performVendorEffect(in VendorEffect vendorEffect, in IVibratorCallback callback);
+
+ /**
+ * Retrieves a mapping of vibration frequency (Hz) to the maximum achievable output
+ * acceleration (Gs) the device can reach at that frequency.
+ *
+ * The map, represented as a list of `PwleV2OutputMapEntry` (frequency, output acceleration)
+ * pairs, defines the device's frequency response. The platform uses the minimum and maximum
+ * frequency values to determine the supported input range for `IVibrator.composePwleV2`.
+ * Output acceleration values are used to identify a frequency range suitable to safely play
+ * perceivable vibrations with a simple API. The map is also exposed for developers using an
+ * advanced API.
+ *
+ * The platform does not impose specific requirements on map resolution which can vary
+ * depending on the shape of device output curve. The values will be linearly interpolated
+ * during lookups. The platform will provide a simple API, defined by the first frequency range
+ * where output acceleration consistently exceeds a minimum threshold of 10 db SL.
+ *
+ *
+ * This may not be supported and this support is reflected in getCapabilities
+ * (CAP_COMPOSE_PWLE_EFFECTS_V2). If this is supported, it's expected to be non-empty and
+ * describe a valid non-empty frequency range where the simple API can be defined
+ * (i.e. a range where the output acceleration is always above 10 db SL).
+ *
+ * @return A list of map entries representing the frequency to max acceleration
+ * mapping.
+ * @throws EX_UNSUPPORTED_OPERATION if unsupported, as reflected by getCapabilities.
+ */
+ List<PwleV2OutputMapEntry> getPwleV2FrequencyToOutputAccelerationMap();
+
+ /**
+ * Retrieve the maximum duration allowed for any primitive PWLE in units of
+ * milliseconds.
+ *
+ * This may not be supported and this support is reflected in
+ * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS_V2).
+ *
+ * @return The maximum duration allowed for a single PrimitivePwle. Non-zero value if supported.
+ * @throws EX_UNSUPPORTED_OPERATION if unsupported, as reflected by getCapabilities.
+ */
+ int getPwleV2PrimitiveDurationMaxMillis();
+
+ /**
+ * Retrieve the maximum number of PWLE primitives input supported by IVibrator.composePwleV2.
+ *
+ * This may not be supported and this support is reflected in
+ * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS_V2). Devices supporting PWLE effects must
+ * support effects with at least 16 PwleV2Primitive.
+ *
+ * @return The maximum count allowed. Non-zero value if supported.
+ * @throws EX_UNSUPPORTED_OPERATION if unsupported, as reflected by getCapabilities.
+ */
+ int getPwleV2CompositionSizeMax();
+
+ /**
+ * Retrieves the minimum duration (in milliseconds) of any segment within a
+ * PWLE effect. Devices supporting PWLE effects must support a minimum ramp
+ * time of 20 milliseconds.
+ *
+ * This may not be supported and this support is reflected in
+ * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS_V2).
+ *
+ * @return The minimum duration allowed for a single PrimitivePwle. Non-zero value if supported.
+ * @throws EX_UNSUPPORTED_OPERATION if unsupported, as reflected by getCapabilities.
+ */
+ int getPwleV2PrimitiveDurationMinMillis();
+
+ /**
+ * Play composed sequence of chirps with optional callback upon completion.
+ *
+ * This may not be supported and this support is reflected in
+ * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS_V2).
+ *
+ * Doing this operation while the vibrator is already on is undefined behavior. Clients should
+ * explicitly call off. IVibratorCallback.onComplete() support is required for this API.
+ *
+ * @param composite An array of primitives that represents a PWLE (Piecewise-Linear Envelope).
+ */
+ void composePwleV2(in PwleV2Primitive[] composite, in IVibratorCallback callback);
}
diff --git a/vibrator/aidl/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/vibrator/aidl/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
new file mode 100644
index 0000000..a8db87c
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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 android.hardware.vibrator;
+
+@VintfStability
+parcelable PwleV2OutputMapEntry {
+ /**
+ * Absolute frequency point in the units of hertz
+ *
+ */
+ float frequencyHz;
+
+ /**
+ * Max output acceleration for the specified frequency in units of Gs.
+ *
+ * This value represents the maximum safe output acceleration (in Gs) achievable at the
+ * specified frequency, typically determined during calibration. The actual output acceleration
+ * is assumed to scale linearly with the input amplitude within the range of [0, 1].
+ */
+ float maxOutputAccelerationGs;
+}
diff --git a/vibrator/aidl/android/hardware/vibrator/PwleV2Primitive.aidl b/vibrator/aidl/android/hardware/vibrator/PwleV2Primitive.aidl
new file mode 100644
index 0000000..bd7bec6
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/PwleV2Primitive.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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 android.hardware.vibrator;
+
+@VintfStability
+parcelable PwleV2Primitive {
+ /**
+ * Input amplitude ranges from 0.0 (inclusive) to 1.0 (inclusive), representing the relative
+ * input value. Actual output acceleration depends on frequency and device response curve
+ * (see IVibrator.getPwleV2FrequencyToOutputAccelerationMap for max values).
+ *
+ * Input amplitude linearly maps to output acceleration (e.g., 0.5 amplitude yields half the
+ * max acceleration for that frequency).
+ *
+ * 0.0 represents no output acceleration amplitude
+ * 1.0 represents the maximum achievable strength for each frequency, as determined by the
+ * actuator response curve
+ */
+ float amplitude;
+
+ /**
+ * Absolute frequency point in the units of hertz
+ *
+ * Values are within the continuous inclusive frequency range defined by
+ * IVibrator#getPwleV2FrequencyToOutputAccelerationMap.
+ */
+ float frequencyHz;
+
+ /* Total time from the previous PWLE point to the current one in units of milliseconds. */
+ int timeMillis;
+}
diff --git a/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl b/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl
new file mode 100644
index 0000000..6b1af53
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl
@@ -0,0 +1,70 @@
+/*
+ * 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 android.hardware.vibrator;
+
+import android.hardware.vibrator.EffectStrength;
+import android.os.PersistableBundle;
+
+@VintfStability
+parcelable VendorEffect {
+ /**
+ * Vendor data describing the haptic effect. Expected fields should be defined by the vendor.
+ *
+ * Vendors can use this as a platform extension point for experimental hardware capabilities,
+ * but they are strongly discouraged from using it as an alternative to the AOSP support for
+ * stable vibrator APIs. Implemenitng vendor-specific custom effects outside the platform APIs
+ * will hinder portability for the code and overall user experience.
+ *
+ * Vendors are encouraged to upstream new capabilities to the IVibrator surface once it has
+ * matured into a stable interface.
+ */
+ PersistableBundle vendorData;
+
+ /**
+ * The intensity of the haptic effect.
+ *
+ * This value is defined by discrete scale levels that represents the intensity of this haptic
+ * effect. This is a discrete representation of the scale parameter below.
+ */
+ EffectStrength strength = EffectStrength.MEDIUM;
+
+ /**
+ * The intensity of the haptic effect.
+ *
+ * This value is defined by continuous scale that represents the intensity of this haptic
+ * effect. The vendor implementation can follow the platform scaling function or customize the
+ * implementation to their needs. This is a continuous representation of the strength parameter
+ * above.
+ *
+ * Values in [0,1) should scale down. Values > 1 should scale up within hardware bounds.
+ */
+ float scale;
+
+ /**
+ * The dynamic scale parameter provided by the vendor vibrator controller.
+ *
+ * This value is the same provided by the vendor to the platform IVibratorControlService and
+ * should be applied on top of the effect intensity provided by the strength/scale fields.
+ * The vendor can use this to dynamically adapt the haptic effect intensity to the device state.
+ *
+ * See frameworks/hardware/interfaces/vibrator for more documentation on vendor vibrator
+ * controller, and ScaleParam for more about this scale parameter.
+ *
+ * Values in [0,1) should scale down. Values > 1 should scale up within hardware bounds.
+ */
+ float vendorScale;
+}
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index 0f342db..4b26640 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -15,7 +15,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.vibrator-V2-ndk",
+ "android.hardware.vibrator-V3-ndk",
],
export_include_dirs: ["include"],
srcs: [
@@ -49,7 +49,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.vibrator-V2-ndk",
+ "android.hardware.vibrator-V3-ndk",
],
static_libs: [
"libvibratorexampleimpl",
@@ -62,7 +62,7 @@
host_supported: true,
defaults: ["service_fuzzer_defaults"],
static_libs: [
- "android.hardware.vibrator-V2-ndk",
+ "android.hardware.vibrator-V3-ndk",
"liblog",
"libvibratorexampleimpl",
],
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index 01602ab..4f8c2b8 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -27,9 +27,12 @@
static constexpr int32_t COMPOSE_DELAY_MAX_MS = 1000;
static constexpr int32_t COMPOSE_SIZE_MAX = 256;
static constexpr int32_t COMPOSE_PWLE_SIZE_MAX = 127;
+static constexpr int32_t COMPOSE_PWLE_V2_SIZE_MAX = 16;
static constexpr float Q_FACTOR = 11.0;
static constexpr int32_t COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS = 16383;
+static constexpr int32_t COMPOSE_PWLE_V2_PRIMITIVE_DURATION_MAX_MS = 1000;
+static constexpr int32_t COMPOSE_PWLE_V2_PRIMITIVE_DURATION_MIN_MS = 20;
static constexpr float PWLE_LEVEL_MIN = 0.0;
static constexpr float PWLE_LEVEL_MAX = 1.0;
static constexpr float PWLE_FREQUENCY_RESOLUTION_HZ = 1.0;
@@ -39,14 +42,30 @@
static constexpr float PWLE_BW_MAP_SIZE =
1 + ((PWLE_FREQUENCY_MAX_HZ - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ);
+// Service specific error code used for vendor vibration effects.
+static constexpr int32_t ERROR_CODE_INVALID_DURATION = 1;
+
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
LOG(VERBOSE) << "Vibrator reporting capabilities";
- *_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
- IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL |
- IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL | IVibrator::CAP_COMPOSE_EFFECTS |
- IVibrator::CAP_ALWAYS_ON_CONTROL | IVibrator::CAP_GET_RESONANT_FREQUENCY |
- IVibrator::CAP_GET_Q_FACTOR | IVibrator::CAP_FREQUENCY_CONTROL |
- IVibrator::CAP_COMPOSE_PWLE_EFFECTS;
+ std::lock_guard lock(mMutex);
+ if (mCapabilities == 0) {
+ if (!getInterfaceVersion(&mVersion).isOk()) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_STATE));
+ }
+ mCapabilities = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
+ IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL |
+ IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL | IVibrator::CAP_COMPOSE_EFFECTS |
+ IVibrator::CAP_ALWAYS_ON_CONTROL | IVibrator::CAP_GET_RESONANT_FREQUENCY |
+ IVibrator::CAP_GET_Q_FACTOR | IVibrator::CAP_FREQUENCY_CONTROL |
+ IVibrator::CAP_COMPOSE_PWLE_EFFECTS;
+
+ if (mVersion >= 3) {
+ mCapabilities |= (IVibrator::CAP_PERFORM_VENDOR_EFFECTS |
+ IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2);
+ }
+ }
+
+ *_aidl_return = mCapabilities;
return ndk::ScopedAStatus::ok();
}
@@ -102,6 +121,47 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Vibrator::performVendorEffect(
+ const VendorEffect& effect, const std::shared_ptr<IVibratorCallback>& callback) {
+ LOG(VERBOSE) << "Vibrator perform vendor effect";
+ int32_t capabilities = 0;
+ if (!getCapabilities(&capabilities).isOk()) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+ }
+ EffectStrength strength = effect.strength;
+ if (strength != EffectStrength::LIGHT && strength != EffectStrength::MEDIUM &&
+ strength != EffectStrength::STRONG) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
+ }
+ float scale = effect.scale;
+ if (scale <= 0) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ float vendorScale = effect.vendorScale;
+ if (vendorScale <= 0) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ int32_t durationMs = 0;
+ if (!effect.vendorData.getInt("DURATION_MS", &durationMs) || durationMs <= 0) {
+ return ndk::ScopedAStatus::fromServiceSpecificError(ERROR_CODE_INVALID_DURATION);
+ }
+
+ if (callback != nullptr) {
+ std::thread([callback, durationMs] {
+ LOG(VERBOSE) << "Starting perform on another thread for durationMs:" << durationMs;
+ usleep(durationMs * 1000);
+ LOG(VERBOSE) << "Notifying perform vendor effect complete";
+ callback->onComplete();
+ }).detach();
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect>* _aidl_return) {
*_aidl_return = {Effect::CLICK, Effect::TICK};
return ndk::ScopedAStatus::ok();
@@ -412,6 +472,122 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Vibrator::getPwleV2FrequencyToOutputAccelerationMap(
+ std::vector<PwleV2OutputMapEntry>* _aidl_return) {
+ std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
+
+ std::vector<std::pair<float, float>> frequencyToOutputAccelerationData = {
+ {30.0f, 0.01f}, {46.0f, 0.09f}, {50.0f, 0.1f}, {55.0f, 0.12f}, {62.0f, 0.66f},
+ {83.0f, 0.82f}, {85.0f, 0.85f}, {92.0f, 1.05f}, {107.0f, 1.63f}, {115.0f, 1.72f},
+ {123.0f, 1.81f}, {135.0f, 2.23f}, {144.0f, 2.47f}, {145.0f, 2.5f}, {150.0f, 3.0f},
+ {175.0f, 2.51f}, {181.0f, 2.41f}, {190.0f, 2.28f}, {200.0f, 2.08f}, {204.0f, 1.96f},
+ {205.0f, 1.9f}, {224.0f, 1.7f}, {235.0f, 1.5f}, {242.0f, 1.46f}, {253.0f, 1.41f},
+ {263.0f, 1.39f}, {65.0f, 1.38f}, {278.0f, 1.37f}, {294.0f, 1.35f}, {300.0f, 1.34f}};
+ for (const auto& entry : frequencyToOutputAccelerationData) {
+ frequencyToOutputAccelerationMap.push_back(
+ PwleV2OutputMapEntry(/*frequency=*/entry.first,
+ /*maxOutputAcceleration=*/entry.second));
+ }
+
+ *_aidl_return = frequencyToOutputAccelerationMap;
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::getPwleV2PrimitiveDurationMaxMillis(int32_t* maxDurationMs) {
+ *maxDurationMs = COMPOSE_PWLE_V2_PRIMITIVE_DURATION_MAX_MS;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::getPwleV2CompositionSizeMax(int32_t* maxSize) {
+ *maxSize = COMPOSE_PWLE_V2_SIZE_MAX;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Vibrator::getPwleV2PrimitiveDurationMinMillis(int32_t* minDurationMs) {
+ *minDurationMs = COMPOSE_PWLE_V2_PRIMITIVE_DURATION_MIN_MS;
+ return ndk::ScopedAStatus::ok();
+}
+
+float getPwleV2FrequencyMinHz(std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap) {
+ if (frequencyToOutputAccelerationMap.empty()) {
+ return 0.0f;
+ }
+
+ float minFrequency = frequencyToOutputAccelerationMap[0].frequencyHz;
+
+ for (const auto& entry : frequencyToOutputAccelerationMap) {
+ if (entry.frequencyHz < minFrequency) {
+ minFrequency = entry.frequencyHz;
+ }
+ }
+
+ return minFrequency;
+}
+
+float getPwleV2FrequencyMaxHz(std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap) {
+ if (frequencyToOutputAccelerationMap.empty()) {
+ return 0.0f;
+ }
+
+ float maxFrequency = frequencyToOutputAccelerationMap[0].frequencyHz;
+
+ for (const auto& entry : frequencyToOutputAccelerationMap) {
+ if (entry.frequencyHz > maxFrequency) {
+ maxFrequency = entry.frequencyHz;
+ }
+ }
+
+ return maxFrequency;
+}
+
+ndk::ScopedAStatus Vibrator::composePwleV2(const std::vector<PwleV2Primitive>& composite,
+ const std::shared_ptr<IVibratorCallback>& callback) {
+ int32_t capabilities = 0;
+ if (!getCapabilities(&capabilities).isOk()) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ if ((capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) == 0) {
+ return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+ }
+
+ int compositionSizeMax;
+ getPwleV2CompositionSizeMax(&compositionSizeMax);
+ if (composite.size() <= 0 || composite.size() > compositionSizeMax) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ int32_t totalEffectDuration = 0;
+ std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
+ getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
+ float minFrequency = getPwleV2FrequencyMinHz(frequencyToOutputAccelerationMap);
+ float maxFrequency = getPwleV2FrequencyMaxHz(frequencyToOutputAccelerationMap);
+
+ for (auto& e : composite) {
+ if (e.timeMillis < 0.0f || e.timeMillis > COMPOSE_PWLE_V2_PRIMITIVE_DURATION_MAX_MS) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (e.amplitude < 0.0f || e.amplitude > 1.0f) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (e.frequencyHz < minFrequency || e.frequencyHz > maxFrequency) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ totalEffectDuration += e.timeMillis;
+ }
+
+ std::thread([totalEffectDuration, callback] {
+ LOG(VERBOSE) << "Starting composePwleV2 on another thread";
+ usleep(totalEffectDuration * 1000);
+ if (callback != nullptr) {
+ LOG(VERBOSE) << "Notifying compose PWLE V2 complete";
+ callback->onComplete();
+ }
+ }).detach();
+
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace vibrator
} // namespace hardware
} // namespace android
diff --git a/vibrator/aidl/default/android.hardware.vibrator.xml b/vibrator/aidl/default/android.hardware.vibrator.xml
index b5bd3dd..b730046 100644
--- a/vibrator/aidl/default/android.hardware.vibrator.xml
+++ b/vibrator/aidl/default/android.hardware.vibrator.xml
@@ -1,12 +1,12 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.vibrator</name>
- <version>2</version>
+ <version>3</version>
<fqname>IVibrator/default</fqname>
</hal>
<hal format="aidl">
<name>android.hardware.vibrator</name>
- <version>2</version>
+ <version>3</version>
<fqname>IVibratorManager/default</fqname>
</hal>
</manifest>
diff --git a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
index 4203bf2..28bc763 100644
--- a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
+++ b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/vibrator/BnVibrator.h>
+#include <android-base/thread_annotations.h>
namespace aidl {
namespace android {
@@ -31,6 +32,9 @@
ndk::ScopedAStatus perform(Effect effect, EffectStrength strength,
const std::shared_ptr<IVibratorCallback>& callback,
int32_t* _aidl_return) override;
+ ndk::ScopedAStatus performVendorEffect(
+ const VendorEffect& effect,
+ const std::shared_ptr<IVibratorCallback>& callback) override;
ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _aidl_return) override;
ndk::ScopedAStatus setAmplitude(float amplitude) override;
ndk::ScopedAStatus setExternalControl(bool enabled) override;
@@ -54,7 +58,18 @@
ndk::ScopedAStatus getSupportedBraking(std::vector<Braking>* supported) override;
ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle> &composite,
const std::shared_ptr<IVibratorCallback> &callback) override;
+ ndk::ScopedAStatus getPwleV2FrequencyToOutputAccelerationMap(
+ std::vector<PwleV2OutputMapEntry>* _aidl_return) override;
+ ndk::ScopedAStatus getPwleV2PrimitiveDurationMaxMillis(int32_t* maxDurationMs) override;
+ ndk::ScopedAStatus getPwleV2PrimitiveDurationMinMillis(int32_t* minDurationMs) override;
+ ndk::ScopedAStatus getPwleV2CompositionSizeMax(int32_t* maxSize) override;
+ ndk::ScopedAStatus composePwleV2(const std::vector<PwleV2Primitive>& composite,
+ const std::shared_ptr<IVibratorCallback>& callback) override;
+ private:
+ mutable std::mutex mMutex;
+ int32_t mVersion GUARDED_BY(mMutex) = 0; // current Hal version
+ int32_t mCapabilities GUARDED_BY(mMutex) = 0;
};
} // namespace vibrator
diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp
index b6d2fb2..a48bb2e 100644
--- a/vibrator/aidl/vts/Android.bp
+++ b/vibrator/aidl/vts/Android.bp
@@ -17,10 +17,10 @@
tidy_timeout_srcs: ["VtsHalVibratorTargetTest.cpp"],
srcs: ["VtsHalVibratorTargetTest.cpp"],
shared_libs: [
- "libbinder",
+ "libbinder_ndk",
],
static_libs: [
- "android.hardware.vibrator-V2-cpp",
+ "android.hardware.vibrator-V3-ndk",
],
test_suites: [
"general-tests",
@@ -36,10 +36,10 @@
],
srcs: ["VtsHalVibratorManagerTargetTest.cpp"],
shared_libs: [
- "libbinder",
+ "libbinder_ndk",
],
static_libs: [
- "android.hardware.vibrator-V2-cpp",
+ "android.hardware.vibrator-V3-ndk",
],
test_suites: [
"general-tests",
diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
index e8ed26a..3c2a360 100644
--- a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
@@ -15,42 +15,40 @@
*/
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
+#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibratorManager.h>
-#include <android/hardware/vibrator/BnVibratorCallback.h>
-#include <android/hardware/vibrator/IVibrator.h>
-#include <android/hardware/vibrator/IVibratorManager.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
#include <cmath>
#include <future>
-using android::ProcessState;
-using android::sp;
-using android::String16;
-using android::binder::Status;
-using android::hardware::vibrator::BnVibratorCallback;
-using android::hardware::vibrator::CompositeEffect;
-using android::hardware::vibrator::CompositePrimitive;
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
-using android::hardware::vibrator::IVibrator;
-using android::hardware::vibrator::IVibratorManager;
+#include "test_utils.h"
+
+using aidl::android::hardware::vibrator::BnVibratorCallback;
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::IVibrator;
+using aidl::android::hardware::vibrator::IVibratorManager;
using std::chrono::high_resolution_clock;
-const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
- android::enum_range<Effect>().end()};
-const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
- android::enum_range<EffectStrength>().end()};
-const std::vector<CompositePrimitive> kPrimitives{android::enum_range<CompositePrimitive>().begin(),
- android::enum_range<CompositePrimitive>().end()};
+const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
+ ndk::enum_range<Effect>().end()};
+const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
+ ndk::enum_range<EffectStrength>().end()};
+const std::vector<CompositePrimitive> kPrimitives{ndk::enum_range<CompositePrimitive>().begin(),
+ ndk::enum_range<CompositePrimitive>().end()};
class CompletionCallback : public BnVibratorCallback {
public:
CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
- Status onComplete() override {
+ ndk::ScopedAStatus onComplete() override {
mCallback();
- return Status::ok();
+ return ndk::ScopedAStatus::ok();
}
private:
@@ -60,55 +58,50 @@
class VibratorAidl : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- manager = android::waitForDeclaredService<IVibratorManager>(String16(GetParam().c_str()));
+ auto serviceName = GetParam().c_str();
+ manager = IVibratorManager::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(serviceName)));
ASSERT_NE(manager, nullptr);
- ASSERT_TRUE(manager->getCapabilities(&capabilities).isOk());
- EXPECT_TRUE(manager->getVibratorIds(&vibratorIds).isOk());
+ EXPECT_OK(manager->getCapabilities(&capabilities));
+ EXPECT_OK(manager->getVibratorIds(&vibratorIds));
}
- sp<IVibratorManager> manager;
+ std::shared_ptr<IVibratorManager> manager;
int32_t capabilities;
std::vector<int32_t> vibratorIds;
};
-inline bool isUnknownOrUnsupported(Status status) {
- return status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
- status.transactionError() == android::UNKNOWN_TRANSACTION;
-}
-
TEST_P(VibratorAidl, ValidateExistingVibrators) {
- sp<IVibrator> vibrator;
- for (auto& id : vibratorIds) {
- EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ std::shared_ptr<IVibrator> vibrator;
+ for (int32_t id : vibratorIds) {
+ EXPECT_OK(manager->getVibrator(id, &vibrator));
ASSERT_NE(vibrator, nullptr);
}
}
TEST_P(VibratorAidl, GetVibratorWithInvalidId) {
int32_t invalidId = *max_element(vibratorIds.begin(), vibratorIds.end()) + 1;
- sp<IVibrator> vibrator;
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- manager->getVibrator(invalidId, &vibrator).exceptionCode());
+ std::shared_ptr<IVibrator> vibrator;
+ EXPECT_ILLEGAL_ARGUMENT(manager->getVibrator(invalidId, &vibrator));
ASSERT_EQ(vibrator, nullptr);
}
TEST_P(VibratorAidl, ValidatePrepareSyncedExistingVibrators) {
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
if (vibratorIds.empty()) return;
- EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
- EXPECT_TRUE(manager->cancelSynced().isOk());
+ EXPECT_OK(manager->prepareSynced(vibratorIds));
+ EXPECT_OK(manager->cancelSynced());
}
TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) {
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
std::vector<int32_t> emptyIds;
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, manager->prepareSynced(emptyIds).exceptionCode());
+ EXPECT_ILLEGAL_ARGUMENT(manager->prepareSynced(emptyIds));
}
TEST_P(VibratorAidl, PrepareSyncedNotSupported) {
if (!(capabilities & IVibratorManager::CAP_SYNC)) {
- Status status = manager->prepareSynced(vibratorIds);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(manager->prepareSynced(vibratorIds));
}
}
@@ -117,15 +110,14 @@
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
uint32_t durationMs = 250;
- EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
- sp<IVibrator> vibrator;
- for (auto& id : vibratorIds) {
- EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ EXPECT_OK(manager->prepareSynced(vibratorIds));
+ std::shared_ptr<IVibrator> vibrator;
+ for (int32_t id : vibratorIds) {
+ EXPECT_OK(manager->getVibrator(id, &vibrator));
ASSERT_NE(vibrator, nullptr);
- Status status = vibrator->on(durationMs, nullptr);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->on(durationMs, nullptr));
}
- EXPECT_TRUE(manager->cancelSynced().isOk());
+ EXPECT_OK(manager->cancelSynced());
}
}
@@ -133,16 +125,16 @@
if (vibratorIds.empty()) return;
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
- EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
- sp<IVibrator> vibrator;
- for (auto& id : vibratorIds) {
- EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ EXPECT_OK(manager->prepareSynced(vibratorIds));
+ std::shared_ptr<IVibrator> vibrator;
+ for (int32_t id : vibratorIds) {
+ EXPECT_OK(manager->getVibrator(id, &vibrator));
ASSERT_NE(vibrator, nullptr);
int32_t lengthMs = 0;
- Status status = vibrator->perform(kEffects[0], kEffectStrengths[0], nullptr, &lengthMs);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(
+ vibrator->perform(kEffects[0], kEffectStrengths[0], nullptr, &lengthMs));
}
- EXPECT_TRUE(manager->cancelSynced().isOk());
+ EXPECT_OK(manager->cancelSynced());
}
}
@@ -157,15 +149,14 @@
effect.scale = 1.0f;
composite.emplace_back(effect);
- EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
- sp<IVibrator> vibrator;
- for (auto& id : vibratorIds) {
- EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ EXPECT_OK(manager->prepareSynced(vibratorIds));
+ std::shared_ptr<IVibrator> vibrator;
+ for (int32_t id : vibratorIds) {
+ EXPECT_OK(manager->getVibrator(id, &vibrator));
ASSERT_NE(vibrator, nullptr);
- Status status = vibrator->compose(composite, nullptr);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->compose(composite, nullptr));
}
- EXPECT_TRUE(manager->cancelSynced().isOk());
+ EXPECT_OK(manager->cancelSynced());
}
}
@@ -177,51 +168,58 @@
std::promise<void> completionPromise;
std::future<void> completionFuture{completionPromise.get_future()};
- sp<CompletionCallback> callback =
- new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>(
+ [&completionPromise] { completionPromise.set_value(); });
uint32_t durationMs = 250;
std::chrono::milliseconds timeout{durationMs * 2};
- EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
- sp<IVibrator> vibrator;
- for (auto& id : vibratorIds) {
- EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk());
+ EXPECT_OK(manager->prepareSynced(vibratorIds));
+ std::shared_ptr<IVibrator> vibrator;
+ for (int32_t id : vibratorIds) {
+ EXPECT_OK(manager->getVibrator(id, &vibrator));
ASSERT_NE(vibrator, nullptr);
- EXPECT_TRUE(vibrator->on(durationMs, nullptr).isOk());
+ EXPECT_OK(vibrator->on(durationMs, nullptr));
}
- EXPECT_TRUE(manager->triggerSynced(callback).isOk());
+ EXPECT_OK(manager->triggerSynced(callback));
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
- EXPECT_TRUE(manager->cancelSynced().isOk());
+ EXPECT_OK(manager->cancelSynced());
}
TEST_P(VibratorAidl, TriggerSyncNotSupported) {
if (!(capabilities & IVibratorManager::CAP_SYNC)) {
- Status status = manager->triggerSynced(nullptr);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(manager->triggerSynced(nullptr));
}
}
TEST_P(VibratorAidl, TriggerCallbackNotSupported) {
if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) {
- sp<CompletionCallback> callback = new CompletionCallback([] {});
- EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
- Status status = manager->triggerSynced(callback);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
- EXPECT_TRUE(manager->cancelSynced().isOk());
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
+ EXPECT_OK(manager->prepareSynced(vibratorIds));
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(manager->triggerSynced(callback));
+ EXPECT_OK(manager->cancelSynced());
}
}
+std::vector<std::string> FindVibratorManagerNames() {
+ std::vector<std::string> names;
+ constexpr auto callback = [](const char* instance, void* context) {
+ std::string fullName = std::string(IVibratorManager::descriptor) + "/" + instance;
+ static_cast<std::vector<std::string>*>(context)->emplace_back(fullName);
+ };
+ AServiceManager_forEachDeclaredInstance(IVibratorManager::descriptor,
+ static_cast<void*>(&names), callback);
+ return names;
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
-INSTANTIATE_TEST_SUITE_P(
- Vibrator, VibratorAidl,
- testing::ValuesIn(android::getAidlHalInstanceNames(IVibratorManager::descriptor)),
- android::PrintInstanceNameToString);
+INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(FindVibratorManagerNames()),
+ android::PrintInstanceNameToString);
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
- ProcessState::self()->setThreadPoolMaxThreadCount(1);
- ProcessState::self()->startThreadPool();
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
return RUN_ALL_TESTS();
}
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index db474d6..bc017ae 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -15,38 +15,51 @@
*/
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
-#include <android/hardware/vibrator/BnVibratorCallback.h>
-#include <android/hardware/vibrator/IVibrator.h>
-#include <android/hardware/vibrator/IVibratorManager.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
+#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibratorManager.h>
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/persistable_bundle_aidl.h>
#include <cmath>
+#include <cstdlib>
+#include <ctime>
#include <future>
+#include <iomanip>
+#include <iostream>
+#include <random>
-using android::ProcessState;
-using android::sp;
-using android::String16;
-using android::binder::Status;
-using android::hardware::vibrator::ActivePwle;
-using android::hardware::vibrator::BnVibratorCallback;
-using android::hardware::vibrator::Braking;
-using android::hardware::vibrator::BrakingPwle;
-using android::hardware::vibrator::CompositeEffect;
-using android::hardware::vibrator::CompositePrimitive;
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
-using android::hardware::vibrator::IVibrator;
-using android::hardware::vibrator::IVibratorManager;
-using android::hardware::vibrator::PrimitivePwle;
+#include "persistable_bundle_utils.h"
+#include "pwle_v2_utils.h"
+#include "test_utils.h"
+
+using aidl::android::hardware::vibrator::ActivePwle;
+using aidl::android::hardware::vibrator::BnVibratorCallback;
+using aidl::android::hardware::vibrator::Braking;
+using aidl::android::hardware::vibrator::BrakingPwle;
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::IVibrator;
+using aidl::android::hardware::vibrator::IVibratorManager;
+using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::PwleV2OutputMapEntry;
+using aidl::android::hardware::vibrator::PwleV2Primitive;
+using aidl::android::hardware::vibrator::VendorEffect;
+using aidl::android::os::PersistableBundle;
using std::chrono::high_resolution_clock;
using namespace ::std::chrono_literals;
-const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
- android::enum_range<Effect>().end()};
-const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
- android::enum_range<EffectStrength>().end()};
+namespace pwle_v2_utils = aidl::android::hardware::vibrator::testing::pwlev2;
+
+const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
+ ndk::enum_range<Effect>().end()};
+const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
+ ndk::enum_range<EffectStrength>().end()};
const std::vector<Effect> kInvalidEffects = {
static_cast<Effect>(static_cast<int32_t>(kEffects.front()) - 1),
@@ -59,8 +72,7 @@
};
const std::vector<CompositePrimitive> kCompositePrimitives{
- android::enum_range<CompositePrimitive>().begin(),
- android::enum_range<CompositePrimitive>().end()};
+ ndk::enum_range<CompositePrimitive>().begin(), ndk::enum_range<CompositePrimitive>().end()};
const std::vector<CompositePrimitive> kRequiredPrimitives = {
CompositePrimitive::CLICK, CompositePrimitive::LIGHT_TICK,
@@ -74,14 +86,39 @@
};
// Timeout to wait for vibration callback completion.
-static constexpr auto VIBRATION_CALLBACK_TIMEOUT = 100ms;
+static constexpr std::chrono::milliseconds VIBRATION_CALLBACK_TIMEOUT = 100ms;
+
+static constexpr int32_t VENDOR_EFFECTS_MIN_VERSION = 3;
+static constexpr int32_t PWLE_V2_MIN_VERSION = 3;
+
+static std::vector<std::string> findVibratorManagerNames() {
+ std::vector<std::string> names;
+ constexpr auto callback = [](const char* instance, void* context) {
+ auto fullName = std::string(IVibratorManager::descriptor) + "/" + instance;
+ static_cast<std::vector<std::string>*>(context)->emplace_back(fullName);
+ };
+ AServiceManager_forEachDeclaredInstance(IVibratorManager::descriptor,
+ static_cast<void*>(&names), callback);
+ return names;
+}
+
+static std::vector<std::string> findUnmanagedVibratorNames() {
+ std::vector<std::string> names;
+ constexpr auto callback = [](const char* instance, void* context) {
+ auto fullName = std::string(IVibrator::descriptor) + "/" + instance;
+ static_cast<std::vector<std::string>*>(context)->emplace_back(fullName);
+ };
+ AServiceManager_forEachDeclaredInstance(IVibrator::descriptor, static_cast<void*>(&names),
+ callback);
+ return names;
+}
class CompletionCallback : public BnVibratorCallback {
public:
CompletionCallback(const std::function<void()> &callback) : mCallback(callback) {}
- Status onComplete() override {
+ ndk::ScopedAStatus onComplete() override {
mCallback();
- return Status::ok();
+ return ndk::ScopedAStatus::ok();
}
private:
@@ -93,88 +130,89 @@
virtual void SetUp() override {
int32_t managerIdx = std::get<0>(GetParam());
int32_t vibratorId = std::get<1>(GetParam());
- auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
if (managerIdx < 0) {
// Testing a unmanaged vibrator, using vibratorId as index from registered HALs
- auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
- ASSERT_LT(vibratorId, vibratorAidlNames.size());
- auto vibratorName = String16(vibratorAidlNames[vibratorId].c_str());
- vibrator = android::waitForDeclaredService<IVibrator>(vibratorName);
+ std::vector<std::string> vibratorNames = findUnmanagedVibratorNames();
+ ASSERT_LT(vibratorId, vibratorNames.size());
+ vibrator = IVibrator::fromBinder(ndk::SpAIBinder(
+ AServiceManager_waitForService(vibratorNames[vibratorId].c_str())));
} else {
// Testing a managed vibrator, using vibratorId to retrieve it from the manager
- ASSERT_LT(managerIdx, managerAidlNames.size());
- auto managerName = String16(managerAidlNames[managerIdx].c_str());
- auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
- auto vibratorResult = vibratorManager->getVibrator(vibratorId, &vibrator);
- ASSERT_TRUE(vibratorResult.isOk());
+ std::vector<std::string> managerNames = findVibratorManagerNames();
+ ASSERT_LT(managerIdx, managerNames.size());
+ auto vibratorManager = IVibratorManager::fromBinder(ndk::SpAIBinder(
+ AServiceManager_waitForService(managerNames[managerIdx].c_str())));
+ EXPECT_OK(vibratorManager->getVibrator(vibratorId, &vibrator))
+ << "\n For vibrator id: " << vibratorId;
}
ASSERT_NE(vibrator, nullptr);
- ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
+ EXPECT_OK(vibrator->getInterfaceVersion(&version));
+ EXPECT_OK(vibrator->getCapabilities(&capabilities));
}
virtual void TearDown() override {
// Reset vibrator state between tests.
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->off());
}
- sp<IVibrator> vibrator;
+ std::shared_ptr<IVibrator> vibrator;
+ int32_t version;
int32_t capabilities;
};
-inline bool isUnknownOrUnsupported(Status status) {
- return status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
- status.transactionError() == android::UNKNOWN_TRANSACTION;
-}
-
-static float getResonantFrequencyHz(sp<IVibrator> vibrator, int32_t capabilities) {
+static float getResonantFrequencyHz(const std::shared_ptr<IVibrator>& vibrator,
+ int32_t capabilities) {
float resonantFrequencyHz;
- Status status = vibrator->getResonantFrequency(&resonantFrequencyHz);
+ ndk::ScopedAStatus status = vibrator->getResonantFrequency(&resonantFrequencyHz);
if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) {
+ EXPECT_OK(std::move(status));
EXPECT_GT(resonantFrequencyHz, 0);
- EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
}
return resonantFrequencyHz;
}
-static float getFrequencyResolutionHz(sp<IVibrator> vibrator, int32_t capabilities) {
+static float getFrequencyResolutionHz(const std::shared_ptr<IVibrator>& vibrator,
+ int32_t capabilities) {
float freqResolutionHz;
- Status status = vibrator->getFrequencyResolution(&freqResolutionHz);
+ ndk::ScopedAStatus status = vibrator->getFrequencyResolution(&freqResolutionHz);
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
+ EXPECT_OK(std::move(status));
EXPECT_GT(freqResolutionHz, 0);
- EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
}
return freqResolutionHz;
}
-static float getFrequencyMinimumHz(sp<IVibrator> vibrator, int32_t capabilities) {
+static float getFrequencyMinimumHz(const std::shared_ptr<IVibrator>& vibrator,
+ int32_t capabilities) {
float freqMinimumHz;
- Status status = vibrator->getFrequencyMinimum(&freqMinimumHz);
+ ndk::ScopedAStatus status = vibrator->getFrequencyMinimum(&freqMinimumHz);
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
- EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
+ EXPECT_OK(std::move(status));
float resonantFrequencyHz = getResonantFrequencyHz(vibrator, capabilities);
EXPECT_GT(freqMinimumHz, 0);
EXPECT_LE(freqMinimumHz, resonantFrequencyHz);
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
}
return freqMinimumHz;
}
-static float getFrequencyMaximumHz(sp<IVibrator> vibrator, int32_t capabilities) {
+static float getFrequencyMaximumHz(const std::shared_ptr<IVibrator>& vibrator,
+ int32_t capabilities) {
std::vector<float> bandwidthAmplitudeMap;
- Status status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
+ ndk::ScopedAStatus status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
- EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
+ EXPECT_OK(std::move(status));
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
}
float freqMaximumHz = ((bandwidthAmplitudeMap.size() - 1) *
@@ -191,7 +229,8 @@
return 1.0;
}
-static ActivePwle composeValidActivePwle(sp<IVibrator> vibrator, int32_t capabilities) {
+static ActivePwle composeValidActivePwle(const std::shared_ptr<IVibrator>& vibrator,
+ int32_t capabilities) {
float frequencyHz;
if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) {
frequencyHz = getResonantFrequencyHz(vibrator, capabilities);
@@ -212,9 +251,9 @@
}
TEST_P(VibratorAidl, OnThenOffBeforeTimeout) {
- EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
+ EXPECT_OK(vibrator->on(2000, nullptr /*callback*/));
sleep(1);
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->off());
}
TEST_P(VibratorAidl, OnWithCallback) {
@@ -223,26 +262,25 @@
std::promise<void> completionPromise;
std::future<void> completionFuture{completionPromise.get_future()};
- sp<CompletionCallback> callback =
- new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>(
+ [&completionPromise] { completionPromise.set_value(); });
uint32_t durationMs = 250;
auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
- EXPECT_TRUE(vibrator->on(durationMs, callback).isOk());
+ EXPECT_OK(vibrator->on(durationMs, callback));
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->off());
}
TEST_P(VibratorAidl, OnCallbackNotSupported) {
if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) {
- sp<CompletionCallback> callback = new CompletionCallback([] {});
- Status status = vibrator->on(250, callback);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->on(250, callback));
}
}
TEST_P(VibratorAidl, ValidateEffect) {
std::vector<Effect> supported;
- ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
+ EXPECT_OK(vibrator->getSupportedEffects(&supported));
for (Effect effect : kEffects) {
bool isEffectSupported =
@@ -250,15 +288,18 @@
for (EffectStrength strength : kEffectStrengths) {
int32_t lengthMs = 0;
- Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
+ ndk::ScopedAStatus status =
+ vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
if (isEffectSupported) {
- EXPECT_TRUE(status.isOk()) << toString(effect) << " " << toString(strength);
+ EXPECT_OK(std::move(status))
+ << "\n For effect: " << toString(effect) << " " << toString(strength);
EXPECT_GT(lengthMs, 0);
usleep(lengthMs * 1000);
+ EXPECT_OK(vibrator->off());
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status))
- << status << " " << toString(effect) << " " << toString(strength);
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status))
+ << "\n For effect: " << toString(effect) << " " << toString(strength);
}
}
}
@@ -269,7 +310,7 @@
return;
std::vector<Effect> supported;
- ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
+ EXPECT_OK(vibrator->getSupportedEffects(&supported));
for (Effect effect : kEffects) {
bool isEffectSupported =
@@ -278,25 +319,26 @@
for (EffectStrength strength : kEffectStrengths) {
std::promise<void> completionPromise;
std::future<void> completionFuture{completionPromise.get_future()};
- sp<CompletionCallback> callback =
- new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>(
+ [&completionPromise] { completionPromise.set_value(); });
int lengthMs = 0;
- Status status = vibrator->perform(effect, strength, callback, &lengthMs);
+ ndk::ScopedAStatus status = vibrator->perform(effect, strength, callback, &lengthMs);
if (isEffectSupported) {
- EXPECT_TRUE(status.isOk());
+ EXPECT_OK(std::move(status))
+ << "\n For effect: " << toString(effect) << " " << toString(strength);
EXPECT_GT(lengthMs, 0);
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status))
+ << "\n For effect: " << toString(effect) << " " << toString(strength);
}
- if (!status.isOk())
- continue;
+ if (lengthMs <= 0) continue;
auto timeout = std::chrono::milliseconds(lengthMs) + VIBRATION_CALLBACK_TIMEOUT;
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->off());
}
}
}
@@ -307,10 +349,10 @@
for (Effect effect : kEffects) {
for (EffectStrength strength : kEffectStrengths) {
- sp<CompletionCallback> callback = new CompletionCallback([] {});
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
int lengthMs;
- Status status = vibrator->perform(effect, strength, callback, &lengthMs);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->perform(effect, strength, callback, &lengthMs))
+ << "\n For effect: " << toString(effect) << " " << toString(strength);
}
}
}
@@ -319,53 +361,182 @@
for (Effect effect : kInvalidEffects) {
for (EffectStrength strength : kEffectStrengths) {
int32_t lengthMs;
- Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
- EXPECT_TRUE(isUnknownOrUnsupported(status))
- << status << toString(effect) << " " << toString(strength);
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(
+ vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs))
+ << "\n For effect: " << toString(effect) << " " << toString(strength);
}
}
for (Effect effect : kEffects) {
for (EffectStrength strength : kInvalidEffectStrengths) {
int32_t lengthMs;
- Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
- EXPECT_TRUE(isUnknownOrUnsupported(status))
- << status << " " << toString(effect) << " " << toString(strength);
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(
+ vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs))
+ << "\n For effect: " << toString(effect) << " " << toString(strength);
}
}
}
+TEST_P(VibratorAidl, PerformVendorEffectSupported) {
+ if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) return;
+
+ float scale = 0.0f;
+ float vendorScale = 0.0f;
+ for (EffectStrength strength : kEffectStrengths) {
+ PersistableBundle vendorData;
+ ::aidl::android::hardware::vibrator::testing::fillBasicData(&vendorData);
+
+ PersistableBundle nestedData;
+ ::aidl::android::hardware::vibrator::testing::fillBasicData(&nestedData);
+ vendorData.putPersistableBundle("test_nested_bundle", nestedData);
+
+ VendorEffect effect;
+ effect.vendorData = vendorData;
+ effect.strength = strength;
+ effect.scale = scale;
+ effect.vendorScale = vendorScale;
+ scale += 0.5f;
+ vendorScale += 0.2f;
+
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
+ ndk::ScopedAStatus status = vibrator->performVendorEffect(effect, callback);
+
+ // No expectations on the actual status, the effect might be refused with illegal argument
+ // or the vendor might return a service-specific error code.
+ EXPECT_TRUE(status.getExceptionCode() != EX_UNSUPPORTED_OPERATION &&
+ status.getStatus() != STATUS_UNKNOWN_TRANSACTION)
+ << status << "\n For vendor effect with strength" << toString(strength)
+ << " and scale " << effect.scale;
+
+ if (status.isOk()) {
+ // Generic vendor data should not trigger vibrations, but if it does trigger one
+ // then we make sure the vibrator is reset by triggering off().
+ EXPECT_OK(vibrator->off());
+ }
+ }
+}
+
+TEST_P(VibratorAidl, PerformVendorEffectStability) {
+ if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) return;
+
+ // Run some iterations of performVendorEffect with randomized vendor data to check basic
+ // stability of the implementation.
+ uint8_t iterations = 200;
+
+ for (EffectStrength strength : kEffectStrengths) {
+ float scale = 0.5f;
+ float vendorScale = 0.2f;
+ for (uint8_t i = 0; i < iterations; i++) {
+ PersistableBundle vendorData;
+ ::aidl::android::hardware::vibrator::testing::fillRandomData(&vendorData);
+
+ VendorEffect effect;
+ effect.vendorData = vendorData;
+ effect.strength = strength;
+ effect.scale = scale;
+ effect.vendorScale = vendorScale;
+ scale *= 2;
+ vendorScale *= 1.5f;
+
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
+ ndk::ScopedAStatus status = vibrator->performVendorEffect(effect, callback);
+
+ // No expectations on the actual status, the effect might be refused with illegal
+ // argument or the vendor might return a service-specific error code.
+ EXPECT_TRUE(status.getExceptionCode() != EX_UNSUPPORTED_OPERATION &&
+ status.getStatus() != STATUS_UNKNOWN_TRANSACTION)
+ << status << "\n For random vendor effect with strength " << toString(strength)
+ << " and scale " << effect.scale;
+
+ if (status.isOk()) {
+ // Random vendor data should not trigger vibrations, but if it does trigger one
+ // then we make sure the vibrator is reset by triggering off().
+ EXPECT_OK(vibrator->off());
+ }
+ }
+ }
+}
+
+TEST_P(VibratorAidl, PerformVendorEffectEmptyVendorData) {
+ if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) return;
+
+ for (EffectStrength strength : kEffectStrengths) {
+ VendorEffect effect;
+ effect.strength = strength;
+ effect.scale = 1.0f;
+ effect.vendorScale = 1.0f;
+
+ ndk::ScopedAStatus status = vibrator->performVendorEffect(effect, nullptr /*callback*/);
+
+ EXPECT_TRUE(status.getExceptionCode() == EX_SERVICE_SPECIFIC)
+ << status << "\n For vendor effect with strength " << toString(strength)
+ << " and scale " << effect.scale;
+ }
+}
+
+TEST_P(VibratorAidl, PerformVendorEffectInvalidScale) {
+ if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) return;
+
+ VendorEffect effect;
+ effect.strength = EffectStrength::MEDIUM;
+
+ effect.scale = -1.0f;
+ effect.vendorScale = 1.0f;
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->performVendorEffect(effect, nullptr /*callback*/));
+
+ effect.scale = 1.0f;
+ effect.vendorScale = -1.0f;
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->performVendorEffect(effect, nullptr /*callback*/));
+}
+
+TEST_P(VibratorAidl, PerformVendorEffectUnsupported) {
+ if (version < VENDOR_EFFECTS_MIN_VERSION) {
+ EXPECT_EQ(capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS, 0)
+ << "Vibrator version " << version << " should not report vendor effects capability";
+ }
+ if (capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) return;
+
+ for (EffectStrength strength : kEffectStrengths) {
+ VendorEffect effect;
+ effect.strength = strength;
+ effect.scale = 1.0f;
+ effect.vendorScale = 1.0f;
+
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->performVendorEffect(effect, nullptr /*callback*/))
+ << "\n For vendor effect with strength " << toString(strength);
+ }
+}
+
TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
- EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
- EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
- EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
+ EXPECT_OK(vibrator->setAmplitude(0.1f));
+ EXPECT_OK(vibrator->on(2000, nullptr /*callback*/));
+ EXPECT_OK(vibrator->setAmplitude(0.5f));
sleep(1);
- EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
+ EXPECT_OK(vibrator->setAmplitude(1.0f));
sleep(1);
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->off());
}
}
TEST_P(VibratorAidl, AmplitudeOutsideRangeFails) {
if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(0).exceptionCode());
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(1.1).exceptionCode());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->setAmplitude(-1));
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->setAmplitude(0));
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->setAmplitude(1.1));
}
}
TEST_P(VibratorAidl, AmplitudeReturnsUnsupportedMatchingCapabilities) {
if ((capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
- Status status = vibrator->setAmplitude(1);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->setAmplitude(1));
}
}
TEST_P(VibratorAidl, ChangeVibrationExternalControl) {
if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
- EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
+ EXPECT_OK(vibrator->setExternalControl(true));
sleep(1);
- EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
+ EXPECT_OK(vibrator->setExternalControl(false));
sleep(1);
}
}
@@ -375,15 +546,15 @@
(capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
- EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
+ EXPECT_OK(vibrator->setExternalControl(true));
- Status amplitudeStatus = vibrator->setAmplitude(0.5);
if (supportsExternalAmplitudeControl) {
- EXPECT_TRUE(amplitudeStatus.isOk());
+ EXPECT_OK(vibrator->setAmplitude(0.5));
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(amplitudeStatus)) << amplitudeStatus;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->setAmplitude(0.5));
}
- EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
+
+ EXPECT_OK(vibrator->setExternalControl(false));
} else {
EXPECT_FALSE(supportsExternalAmplitudeControl);
}
@@ -391,18 +562,16 @@
TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
- Status status = vibrator->setExternalControl(true);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->setExternalControl(true));
}
}
TEST_P(VibratorAidl, GetSupportedPrimitives) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
std::vector<CompositePrimitive> supported;
+ EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
- EXPECT_EQ(Status::EX_NONE, vibrator->getSupportedPrimitives(&supported).exceptionCode());
-
- for (auto primitive : kCompositePrimitives) {
+ for (CompositePrimitive primitive : kCompositePrimitives) {
bool isPrimitiveSupported =
std::find(supported.begin(), supported.end(), primitive) != supported.end();
bool isPrimitiveRequired =
@@ -417,22 +586,23 @@
TEST_P(VibratorAidl, GetPrimitiveDuration) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
std::vector<CompositePrimitive> supported;
- ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
+ EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
- for (auto primitive : kCompositePrimitives) {
+ for (CompositePrimitive primitive : kCompositePrimitives) {
bool isPrimitiveSupported =
std::find(supported.begin(), supported.end(), primitive) != supported.end();
int32_t duration;
- Status status = vibrator->getPrimitiveDuration(primitive, &duration);
-
if (isPrimitiveSupported) {
- EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
+ EXPECT_OK(vibrator->getPrimitiveDuration(primitive, &duration))
+ << "\n For primitive: " << toString(primitive) << " " << duration;
if (primitive != CompositePrimitive::NOOP) {
- ASSERT_GT(duration, 0) << toString(primitive) << " " << duration;
+ ASSERT_GT(duration, 0)
+ << "\n For primitive: " << toString(primitive) << " " << duration;
}
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->getPrimitiveDuration(primitive, &duration))
+ << "\n For primitive: " << toString(primitive);
}
}
}
@@ -446,14 +616,14 @@
std::vector<CompositePrimitive> supported;
int32_t maxDelay, maxSize;
- ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
- EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
- EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
+ EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
+ EXPECT_OK(vibrator->getCompositionDelayMax(&maxDelay));
+ EXPECT_OK(vibrator->getCompositionSizeMax(&maxSize));
std::vector<CompositeEffect> composite;
for (int i = 0; i < supported.size(); i++) {
- auto primitive = supported[i];
+ CompositePrimitive primitive = supported[i];
float t = static_cast<float>(i + 1) / supported.size();
CompositeEffect effect;
@@ -467,8 +637,8 @@
}
if (composite.size() != 0) {
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->compose(composite, nullptr));
+ EXPECT_OK(vibrator->off());
}
}
@@ -477,12 +647,12 @@
GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
}
- auto unsupported = kInvalidPrimitives;
+ std::vector<CompositePrimitive> unsupported(kInvalidPrimitives);
std::vector<CompositePrimitive> supported;
- ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
+ EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
- for (auto primitive : kCompositePrimitives) {
+ for (CompositePrimitive primitive : kCompositePrimitives) {
bool isPrimitiveSupported =
std::find(supported.begin(), supported.end(), primitive) != supported.end();
@@ -491,16 +661,15 @@
}
}
- for (auto primitive : unsupported) {
+ for (CompositePrimitive primitive : unsupported) {
std::vector<CompositeEffect> composite(1);
- for (auto& effect : composite) {
+ for (CompositeEffect& effect : composite) {
effect.delayMs = 0;
effect.primitive = primitive;
effect.scale = 1.0f;
}
- Status status = vibrator->compose(composite, nullptr);
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->compose(composite, nullptr));
}
}
@@ -516,18 +685,18 @@
effect.primitive = CompositePrimitive::CLICK;
effect.scale = std::nextafter(0.0f, -1.0f);
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->compose(composite, nullptr));
effect.scale = 0.0f;
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->compose(composite, nullptr));
+ EXPECT_OK(vibrator->off());
effect.scale = 1.0f;
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->compose(composite, nullptr));
+ EXPECT_OK(vibrator->off());
effect.scale = std::nextafter(1.0f, 2.0f);
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->compose(composite, nullptr));
}
TEST_P(VibratorAidl, ComposeDelayBoundary) {
@@ -537,7 +706,7 @@
int32_t maxDelay;
- EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
+ EXPECT_OK(vibrator->getCompositionDelayMax(&maxDelay));
std::vector<CompositeEffect> composite(1);
CompositeEffect& effect = composite[0];
@@ -546,19 +715,19 @@
effect.scale = 1.0f;
effect.delayMs = 0;
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->compose(composite, nullptr));
+ EXPECT_OK(vibrator->off());
effect.delayMs = 1;
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->compose(composite, nullptr));
+ EXPECT_OK(vibrator->off());
effect.delayMs = maxDelay;
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->compose(composite, nullptr));
+ EXPECT_OK(vibrator->off());
effect.delayMs = maxDelay + 1;
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->compose(composite, nullptr));
}
TEST_P(VibratorAidl, ComposeSizeBoundary) {
@@ -568,7 +737,7 @@
int32_t maxSize;
- EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
+ EXPECT_OK(vibrator->getCompositionSizeMax(&maxSize));
std::vector<CompositeEffect> composite(maxSize);
CompositeEffect effect;
@@ -578,11 +747,11 @@
effect.scale = 1.0f;
std::fill(composite.begin(), composite.end(), effect);
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->compose(composite, nullptr));
+ EXPECT_OK(vibrator->off());
composite.emplace_back(effect);
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->compose(composite, nullptr));
}
TEST_P(VibratorAidl, ComposeCallback) {
@@ -591,18 +760,17 @@
}
std::vector<CompositePrimitive> supported;
+ EXPECT_OK(vibrator->getSupportedPrimitives(&supported));
- ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
-
- for (auto primitive : supported) {
+ for (CompositePrimitive primitive : supported) {
if (primitive == CompositePrimitive::NOOP) {
continue;
}
std::promise<void> completionPromise;
std::future<void> completionFuture{completionPromise.get_future()};
- sp<CompletionCallback> callback =
- new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>(
+ [&completionPromise] { completionPromise.set_value(); });
CompositeEffect effect;
std::vector<CompositeEffect> composite;
int32_t durationMs;
@@ -615,50 +783,50 @@
effect.scale = 1.0f;
composite.emplace_back(effect);
- EXPECT_EQ(Status::EX_NONE,
- vibrator->getPrimitiveDuration(primitive, &durationMs).exceptionCode())
- << toString(primitive);
+ EXPECT_OK(vibrator->getPrimitiveDuration(primitive, &durationMs))
+ << "\n For primitive: " << toString(primitive);
duration = std::chrono::milliseconds(durationMs);
start = high_resolution_clock::now();
- EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
- << toString(primitive);
+ EXPECT_OK(vibrator->compose(composite, callback))
+ << "\n For primitive: " << toString(primitive);
EXPECT_EQ(completionFuture.wait_for(duration + VIBRATION_CALLBACK_TIMEOUT),
std::future_status::ready)
- << toString(primitive);
+ << "\n For primitive: " << toString(primitive);
end = high_resolution_clock::now();
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
- EXPECT_GE(elapsed.count(), duration.count()) << toString(primitive);
+ EXPECT_GE(elapsed.count(), duration.count())
+ << "\n For primitive: " << toString(primitive);
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->off()) << "\n For primitive: " << toString(primitive);
}
}
TEST_P(VibratorAidl, AlwaysOn) {
if (capabilities & IVibrator::CAP_ALWAYS_ON_CONTROL) {
std::vector<Effect> supported;
- ASSERT_TRUE(vibrator->getSupportedAlwaysOnEffects(&supported).isOk());
+ EXPECT_OK(vibrator->getSupportedAlwaysOnEffects(&supported));
for (Effect effect : kEffects) {
bool isEffectSupported =
std::find(supported.begin(), supported.end(), effect) != supported.end();
for (EffectStrength strength : kEffectStrengths) {
- Status status = vibrator->alwaysOnEnable(0, effect, strength);
+ ndk::ScopedAStatus status = vibrator->alwaysOnEnable(0, effect, strength);
if (isEffectSupported) {
- EXPECT_EQ(Status::EX_NONE, status.exceptionCode())
- << toString(effect) << " " << toString(strength);
+ EXPECT_OK(std::move(status))
+ << "\n For effect: " << toString(effect) << " " << toString(strength);
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status))
- << status << " " << toString(effect) << " " << toString(strength);
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status))
+ << "\n For effect: " << toString(effect) << " " << toString(strength);
}
}
}
- EXPECT_EQ(Status::EX_NONE, vibrator->alwaysOnDisable(0).exceptionCode());
+ EXPECT_OK(vibrator->alwaysOnDisable(0));
}
}
@@ -668,12 +836,12 @@
TEST_P(VibratorAidl, GetQFactor) {
float qFactor;
- Status status = vibrator->getQFactor(&qFactor);
+ ndk::ScopedAStatus status = vibrator->getQFactor(&qFactor);
if (capabilities & IVibrator::CAP_GET_Q_FACTOR) {
+ EXPECT_OK(std::move(status));
ASSERT_GT(qFactor, 0);
- EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
}
}
@@ -687,9 +855,9 @@
TEST_P(VibratorAidl, GetBandwidthAmplitudeMap) {
std::vector<float> bandwidthAmplitudeMap;
- Status status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
+ ndk::ScopedAStatus status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
- EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
+ EXPECT_OK(std::move(status));
ASSERT_FALSE(bandwidthAmplitudeMap.empty());
int minMapSize = (getResonantFrequencyHz(vibrator, capabilities) -
@@ -702,42 +870,42 @@
ASSERT_LE(e, 1.0);
}
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
}
}
TEST_P(VibratorAidl, GetPwlePrimitiveDurationMax) {
int32_t durationMs;
- Status status = vibrator->getPwlePrimitiveDurationMax(&durationMs);
+ ndk::ScopedAStatus status = vibrator->getPwlePrimitiveDurationMax(&durationMs);
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
+ EXPECT_OK(std::move(status));
ASSERT_NE(durationMs, 0);
- EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
}
}
TEST_P(VibratorAidl, GetPwleCompositionSizeMax) {
int32_t maxSize;
- Status status = vibrator->getPwleCompositionSizeMax(&maxSize);
+ ndk::ScopedAStatus status = vibrator->getPwleCompositionSizeMax(&maxSize);
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
+ EXPECT_OK(std::move(status));
ASSERT_NE(maxSize, 0);
- EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
}
}
TEST_P(VibratorAidl, GetSupportedBraking) {
std::vector<Braking> supported;
- Status status = vibrator->getSupportedBraking(&supported);
+ ndk::ScopedAStatus status = vibrator->getSupportedBraking(&supported);
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
bool isDefaultNoneSupported =
std::find(supported.begin(), supported.end(), Braking::NONE) != supported.end();
+ EXPECT_OK(std::move(status));
ASSERT_TRUE(isDefaultNoneSupported);
- EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
} else {
- EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
}
}
@@ -746,7 +914,7 @@
ActivePwle firstActive = composeValidActivePwle(vibrator, capabilities);
std::vector<Braking> supported;
- ASSERT_TRUE(vibrator->getSupportedBraking(&supported).isOk());
+ EXPECT_OK(vibrator->getSupportedBraking(&supported));
bool isClabSupported =
std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end();
BrakingPwle firstBraking;
@@ -765,11 +933,11 @@
secondBraking.braking = Braking::NONE;
secondBraking.duration = 10;
- auto pwleQueue =
- std::vector<PrimitivePwle>{firstActive, firstBraking, secondActive, secondBraking};
+ std::vector<PrimitivePwle> pwleQueue = {firstActive, firstBraking, secondActive,
+ secondBraking};
- EXPECT_EQ(Status::EX_NONE, vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->composePwle(pwleQueue, nullptr));
+ EXPECT_OK(vibrator->off());
}
}
@@ -780,8 +948,8 @@
std::promise<void> completionPromise;
std::future<void> completionFuture{completionPromise.get_future()};
- sp<CompletionCallback> callback =
- new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>(
+ [&completionPromise] { completionPromise.set_value(); });
int32_t segmentDurationMaxMs;
vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
uint32_t durationMs = segmentDurationMaxMs * 2 + 100; // Sum of 2 active and 1 braking below
@@ -790,27 +958,25 @@
ActivePwle active = composeValidActivePwle(vibrator, capabilities);
std::vector<Braking> supported;
- ASSERT_TRUE(vibrator->getSupportedBraking(&supported).isOk());
+ EXPECT_OK(vibrator->getSupportedBraking(&supported));
bool isClabSupported =
std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end();
BrakingPwle braking;
braking.braking = isClabSupported ? Braking::CLAB : Braking::NONE;
braking.duration = 100;
- auto pwleQueue = std::vector<PrimitivePwle>{active, braking, active};
+ std::vector<PrimitivePwle> pwleQueue = {active, braking, active};
- EXPECT_TRUE(vibrator->composePwle(pwleQueue, callback).isOk());
+ EXPECT_OK(vibrator->composePwle(pwleQueue, callback));
EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_OK(vibrator->off());
}
TEST_P(VibratorAidl, ComposePwleSegmentBoundary) {
if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
std::vector<PrimitivePwle> pwleQueue;
// test empty queue
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueue, nullptr));
ActivePwle active = composeValidActivePwle(vibrator, capabilities);
@@ -824,9 +990,7 @@
pwleQueue.emplace_back(std::move(pwle));
}
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueue, nullptr));
}
}
@@ -836,20 +1000,16 @@
active.startAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed
active.endAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed
- auto pwleQueueGreater = std::vector<PrimitivePwle>{active};
+ std::vector<PrimitivePwle> pwleQueueGreater = {active};
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueueGreater, nullptr));
active.startAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed
active.endAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed
- auto pwleQueueLess = std::vector<PrimitivePwle>{active};
+ std::vector<PrimitivePwle> pwleQueueLess = {active};
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueueLess, nullptr));
}
}
@@ -865,20 +1025,16 @@
freqMaximumHz + freqResolutionHz; // Frequency greater than allowed
active.endFrequency = freqMaximumHz + freqResolutionHz; // Frequency greater than allowed
- auto pwleQueueGreater = std::vector<PrimitivePwle>{active};
+ std::vector<PrimitivePwle> pwleQueueGreater = {active};
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueueGreater, nullptr));
active.startFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed
active.endFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed
- auto pwleQueueLess = std::vector<PrimitivePwle>{active};
+ std::vector<PrimitivePwle> pwleQueueLess = {active};
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueueLess, nullptr));
}
}
@@ -890,32 +1046,196 @@
vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
active.duration = segmentDurationMaxMs + 10; // Segment duration greater than allowed
- auto pwleQueue = std::vector<PrimitivePwle>{active};
+ std::vector<PrimitivePwle> pwleQueue = {active};
- EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
- vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
- EXPECT_TRUE(vibrator->off().isOk());
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueue, nullptr));
}
}
+TEST_P(VibratorAidl, PwleV2FrequencyToOutputAccelerationMapHasValidFrequencyRange) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
+ std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
+ ndk::ScopedAStatus status =
+ vibrator->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
+ EXPECT_OK(std::move(status));
+ ASSERT_FALSE(frequencyToOutputAccelerationMap.empty());
+ auto sharpnessRange =
+ pwle_v2_utils::getPwleV2SharpnessRange(vibrator, frequencyToOutputAccelerationMap);
+ // Validate the curve provides a usable sharpness range, which is a range of frequencies
+ // that are supported by the device.
+ ASSERT_TRUE(sharpnessRange.first >= 0);
+ // Validate that the sharpness range is a valid interval, not a single point.
+ ASSERT_TRUE(sharpnessRange.first < sharpnessRange.second);
+}
+
+TEST_P(VibratorAidl, GetPwleV2PrimitiveDurationMaxMillis) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
+ int32_t durationMs;
+ ndk::ScopedAStatus status = vibrator->getPwleV2PrimitiveDurationMaxMillis(&durationMs);
+ EXPECT_OK(std::move(status));
+ ASSERT_GT(durationMs, 0); // Ensure greater than zero
+ ASSERT_GE(durationMs, pwle_v2_utils::COMPOSE_PWLE_V2_MIN_REQUIRED_PRIMITIVE_MAX_DURATION_MS);
+}
+
+TEST_P(VibratorAidl, GetPwleV2CompositionSizeMax) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
+ int32_t maxSize;
+ ndk::ScopedAStatus status = vibrator->getPwleV2CompositionSizeMax(&maxSize);
+ EXPECT_OK(std::move(status));
+ ASSERT_GT(maxSize, 0); // Ensure greater than zero
+ ASSERT_GE(maxSize, pwle_v2_utils::COMPOSE_PWLE_V2_MIN_REQUIRED_SIZE);
+}
+
+TEST_P(VibratorAidl, GetPwleV2PrimitiveDurationMinMillis) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
+ int32_t durationMs;
+ ndk::ScopedAStatus status = vibrator->getPwleV2PrimitiveDurationMinMillis(&durationMs);
+ EXPECT_OK(std::move(status));
+ ASSERT_GT(durationMs, 0); // Ensure greater than zero
+ ASSERT_LE(durationMs, pwle_v2_utils::COMPOSE_PWLE_V2_MAX_ALLOWED_PRIMITIVE_MIN_DURATION_MS);
+}
+
+TEST_P(VibratorAidl, ComposeValidPwleV2Effect) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
+ EXPECT_OK(vibrator->composePwleV2(pwle_v2_utils::composeValidPwleV2Effect(vibrator), nullptr));
+ EXPECT_OK(vibrator->off());
+}
+
+TEST_P(VibratorAidl, ComposePwleV2Unsupported) {
+ if (version < PWLE_V2_MIN_VERSION) {
+ EXPECT_EQ(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2, 0)
+ << "Vibrator version " << version << " should not report PWLE V2 capability.";
+ }
+ if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) return;
+
+ std::vector<PwleV2Primitive> pwleEffect{
+ PwleV2Primitive(/*amplitude=*/1.0f, /*frequencyHz=*/100.0f, /*timeMillis=*/50)};
+
+ EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->composePwleV2(pwleEffect, nullptr));
+}
+
+TEST_P(VibratorAidl, ComposeValidPwleV2EffectWithCallback) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
+ std::promise<void> completionPromise;
+ std::future<void> completionFuture{completionPromise.get_future()};
+ auto callback = ndk::SharedRefBase::make<CompletionCallback>(
+ [&completionPromise] { completionPromise.set_value(); });
+
+ int32_t minDuration;
+ EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMinMillis(&minDuration));
+ auto timeout = std::chrono::milliseconds(minDuration) + VIBRATION_CALLBACK_TIMEOUT;
+ float minFrequency = pwle_v2_utils::getPwleV2FrequencyMinHz(vibrator);
+
+ EXPECT_OK(vibrator->composePwleV2(
+ {PwleV2Primitive(/*amplitude=*/0.5, minFrequency, minDuration)}, callback));
+ EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
+ EXPECT_OK(vibrator->off());
+}
+
+TEST_P(VibratorAidl, composePwleV2EffectWithTooManyPoints) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(
+ pwle_v2_utils::composePwleV2EffectWithTooManyPoints(vibrator), nullptr));
+}
+
+TEST_P(VibratorAidl, composeInvalidPwleV2Effect) {
+ if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+ GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+ return;
+ }
+
+ // Retrieve min and max durations
+ int32_t minDurationMs, maxDurationMs;
+ EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMinMillis(&minDurationMs));
+ EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMaxMillis(&maxDurationMs));
+
+ std::vector<PwleV2Primitive> composePwle;
+
+ // Negative amplitude
+ composePwle.push_back(PwleV2Primitive(/*amplitude=*/-0.8f, /*frequency=*/100, minDurationMs));
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
+ << "Composing PWLE V2 effect with negative amplitude should fail";
+ composePwle.clear();
+
+ // Amplitude exceeding 1.0
+ composePwle.push_back(PwleV2Primitive(/*amplitude=*/1.2f, /*frequency=*/100, minDurationMs));
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
+ << "Composing PWLE V2 effect with amplitude greater than 1.0 should fail";
+ composePwle.clear();
+
+ // Duration exceeding maximum
+ composePwle.push_back(
+ PwleV2Primitive(/*amplitude=*/0.2f, /*frequency=*/100, maxDurationMs + 10));
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
+ << "Composing PWLE V2 effect with duration exceeding maximum should fail";
+ composePwle.clear();
+
+ // Negative duration
+ composePwle.push_back(PwleV2Primitive(/*amplitude=*/0.2f, /*frequency=*/100, /*time=*/-1));
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
+ << "Composing PWLE V2 effect with negative duration should fail";
+ composePwle.clear();
+
+ // Frequency below minimum
+ float minFrequency = pwle_v2_utils::getPwleV2FrequencyMinHz(vibrator);
+ composePwle.push_back(PwleV2Primitive(/*amplitude=*/0.2f, minFrequency - 1, minDurationMs));
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
+ << "Composing PWLE V2 effect with frequency below minimum should fail";
+ composePwle.clear();
+
+ // Frequency above maximum
+ float maxFrequency = pwle_v2_utils::getPwleV2FrequencyMaxHz(vibrator);
+ composePwle.push_back(PwleV2Primitive(/*amplitude=*/0.2f, maxFrequency + 1, minDurationMs));
+ EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
+ << "Composing PWLE V2 effect with frequency above maximum should fail";
+}
+
std::vector<std::tuple<int32_t, int32_t>> GenerateVibratorMapping() {
std::vector<std::tuple<int32_t, int32_t>> tuples;
- auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
- std::vector<int32_t> vibratorIds;
- for (int i = 0; i < managerAidlNames.size(); i++) {
- auto managerName = String16(managerAidlNames[i].c_str());
- auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
+ std::vector<std::string> managerNames = findVibratorManagerNames();
+ std::vector<int32_t> vibratorIds;
+ for (int i = 0; i < managerNames.size(); i++) {
+ auto vibratorManager = IVibratorManager::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(managerNames[i].c_str())));
if (vibratorManager->getVibratorIds(&vibratorIds).isOk()) {
- for (auto &vibratorId : vibratorIds) {
- tuples.push_back(std::make_tuple(i, vibratorId));
+ for (int32_t vibratorId : vibratorIds) {
+ tuples.emplace_back(i, vibratorId);
}
}
}
- auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
- for (int i = 0; i < vibratorAidlNames.size(); i++) {
- tuples.push_back(std::make_tuple(-1, i));
+ std::vector<std::string> vibratorNames = findUnmanagedVibratorNames();
+ for (int i = 0; i < vibratorNames.size(); i++) {
+ tuples.emplace_back(-1, i);
}
return tuples;
@@ -935,8 +1255,11 @@
PrintGeneratedTest);
int main(int argc, char **argv) {
+ // Random values are used in the implementation.
+ std::srand(std::time(nullptr));
+
::testing::InitGoogleTest(&argc, argv);
- ProcessState::self()->setThreadPoolMaxThreadCount(1);
- ProcessState::self()->startThreadPool();
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
return RUN_ALL_TESTS();
}
diff --git a/vibrator/aidl/vts/persistable_bundle_utils.h b/vibrator/aidl/vts/persistable_bundle_utils.h
new file mode 100644
index 0000000..a765a49
--- /dev/null
+++ b/vibrator/aidl/vts/persistable_bundle_utils.h
@@ -0,0 +1,134 @@
+/*
+ * 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 VIBRATOR_HAL_PERSISTABLE_BUNDLE_UTILS_H
+#define VIBRATOR_HAL_PERSISTABLE_BUNDLE_UTILS_H
+
+#include <android/persistable_bundle_aidl.h>
+
+#include <cstdlib>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace vibrator {
+namespace testing {
+
+using aidl::android::os::PersistableBundle;
+
+namespace {
+
+template <typename T>
+T nextValue() {
+ return static_cast<T>(std::rand());
+}
+
+template <>
+std::string nextValue() {
+ std::string str;
+ uint8_t entryCount = nextValue<uint8_t>();
+ for (uint8_t i = 0; i < entryCount; i++) {
+ str.push_back(nextValue<char>());
+ }
+ return str;
+}
+
+template <typename T>
+T nextValue(T limit) {
+ assert(limit > 0);
+ return static_cast<T>(std::rand()) / (static_cast<T>(RAND_MAX / limit));
+}
+
+template <typename T>
+void fillVector(std::vector<T>* values) {
+ uint8_t entryCount = nextValue<uint8_t>();
+ for (uint8_t i = 0; i < entryCount; i++) {
+ values->push_back(nextValue<T>());
+ }
+}
+
+const std::vector<std::function<void(PersistableBundle*, const std::string&)>>
+ sPersistableBundleSetters = {[](PersistableBundle* bundle, const std::string& key) -> void {
+ bundle->putBoolean(key, nextValue<bool>());
+ },
+ [](PersistableBundle* bundle, const std::string& key) -> void {
+ bundle->putInt(key, nextValue<int32_t>());
+ },
+ [](PersistableBundle* bundle, const std::string& key) -> void {
+ bundle->putLong(key, nextValue<int64_t>());
+ },
+ [](PersistableBundle* bundle, const std::string& key) -> void {
+ bundle->putDouble(key, nextValue<double>());
+ },
+ [](PersistableBundle* bundle, const std::string& key) -> void {
+ bundle->putString(key, nextValue<std::string>());
+ },
+ [](PersistableBundle* bundle, const std::string& key) -> void {
+ std::vector<bool> value;
+ fillVector<bool>(&value);
+ bundle->putBooleanVector(key, value);
+ },
+ [](PersistableBundle* bundle, const std::string& key) -> void {
+ std::vector<int32_t> value;
+ fillVector<int32_t>(&value);
+ bundle->putIntVector(key, value);
+ },
+ [](PersistableBundle* bundle, const std::string& key) -> void {
+ std::vector<int64_t> value;
+ fillVector<int64_t>(&value);
+ bundle->putLongVector(key, value);
+ },
+ [](PersistableBundle* bundle, const std::string& key) -> void {
+ std::vector<double> value;
+ fillVector<double>(&value);
+ bundle->putDoubleVector(key, value);
+ },
+ [](PersistableBundle* bundle, const std::string& key) -> void {
+ std::vector<std::string> value;
+ fillVector<std::string>(&value);
+ bundle->putStringVector(key, value);
+ }};
+
+} // namespace
+
+void fillBasicData(PersistableBundle* bundle) {
+ bundle->putBoolean("test_bool", true);
+ bundle->putInt("test_int", 2147483647);
+ bundle->putLong("test_long", 2147483647L);
+ bundle->putDouble("test_double", 1.23);
+ bundle->putString("test_string", "test data");
+ bundle->putBooleanVector("test_bool_vector", {true, false, false});
+ bundle->putIntVector("test_int_vector", {1, 2, 3, 4});
+ bundle->putLongVector("test_long_vector", {100L, 200L, 300L});
+ bundle->putDoubleVector("test_double_vector", {1.1, 2.2});
+ bundle->putStringVector("test_string_vector", {"test", "val"});
+}
+
+void fillRandomData(PersistableBundle* bundle) {
+ uint8_t entryCount = nextValue<uint8_t>();
+ for (uint8_t i = 0; i < entryCount; i++) {
+ std::string key(nextValue<std::string>());
+ uint8_t setterIdx = nextValue<uint8_t>(sPersistableBundleSetters.size() - 1);
+ sPersistableBundleSetters[setterIdx](bundle, key);
+ }
+}
+
+} // namespace testing
+} // namespace vibrator
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+
+#endif // VIBRATOR_HAL_PERSISTABLE_BUNDLE_UTILS_H
diff --git a/vibrator/aidl/vts/pwle_v2_utils.h b/vibrator/aidl/vts/pwle_v2_utils.h
new file mode 100644
index 0000000..2163908
--- /dev/null
+++ b/vibrator/aidl/vts/pwle_v2_utils.h
@@ -0,0 +1,229 @@
+/*
+ * 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 VIBRATOR_HAL_PWLE_V2_UTILS_H
+#define VIBRATOR_HAL_PWLE_V2_UTILS_H
+
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include "test_utils.h"
+
+using aidl::android::hardware::vibrator::IVibrator;
+using aidl::android::hardware::vibrator::PwleV2OutputMapEntry;
+using aidl::android::hardware::vibrator::PwleV2Primitive;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace vibrator {
+namespace testing {
+namespace pwlev2 {
+
+static constexpr int32_t COMPOSE_PWLE_V2_MIN_REQUIRED_SIZE = 16;
+static constexpr int32_t COMPOSE_PWLE_V2_MIN_REQUIRED_PRIMITIVE_MAX_DURATION_MS = 1000;
+static constexpr int32_t COMPOSE_PWLE_V2_MAX_ALLOWED_PRIMITIVE_MIN_DURATION_MS = 20;
+static constexpr int32_t COMPOSE_PWLE_V2_MIN_REQUIRED_SENSITIVITY_DB_SL = 10;
+
+namespace {
+/**
+ * Returns a vector of (frequency in Hz, acceleration in dB) pairs, where the acceleration
+ * value denotes the minimum output required at the corresponding frequency to be perceptible
+ * by a human.
+ */
+static std::vector<std::pair<float, float>> getMinPerceptibleLevel() {
+ return {{0.4f, -97.81f}, {2.0f, -69.86f}, {3.0f, -62.81f}, {4.0f, -58.81f},
+ {5.0f, -56.69f}, {6.0f, -54.77f}, {7.2f, -52.85f}, {8.0f, -51.77f},
+ {8.64f, -50.84f}, {10.0f, -48.90f}, {10.37f, -48.52f}, {12.44f, -46.50f},
+ {14.93f, -44.43f}, {15.0f, -44.35f}, {17.92f, -41.96f}, {20.0f, -40.36f},
+ {21.5f, -39.60f}, {25.0f, -37.48f}, {25.8f, -36.93f}, {30.0f, -34.31f},
+ {35.0f, -33.13f}, {40.0f, -32.81f}, {50.0f, -31.94f}, {60.0f, -31.77f},
+ {70.0f, -31.59f}, {72.0f, -31.55f}, {80.0f, -31.77f}, {86.4f, -31.94f},
+ {90.0f, -31.73f}, {100.0f, -31.90f}, {103.68f, -31.77f}, {124.42f, -31.70f},
+ {149.3f, -31.38f}, {150.0f, -31.35f}, {179.16f, -31.02f}, {200.0f, -30.86f},
+ {215.0f, -30.35f}, {250.0f, -28.98f}, {258.0f, -28.68f}, {300.0f, -26.81f},
+ {400.0f, -19.81f}};
+}
+
+static float interpolateLinearly(const std::vector<float>& xAxis, const std::vector<float>& yAxis,
+ float x) {
+ EXPECT_TRUE(!xAxis.empty());
+ EXPECT_TRUE(xAxis.size() == yAxis.size());
+
+ if (x <= xAxis.front()) return yAxis.front();
+ if (x >= xAxis.back()) return yAxis.back();
+
+ auto it = std::upper_bound(xAxis.begin(), xAxis.end(), x);
+ int i = std::distance(xAxis.begin(), it) - 1; // Index of the lower bound
+
+ const float& x0 = xAxis[i];
+ const float& y0 = yAxis[i];
+ const float& x1 = xAxis[i + 1];
+ const float& y1 = yAxis[i + 1];
+
+ return y0 + (x - x0) * (y1 - y0) / (x1 - x0);
+}
+
+static float minPerceptibleDbCurve(float frequency) {
+ // Initialize minPerceptibleMap only once
+ static auto minPerceptibleMap = []() -> std::function<float(float)> {
+ static std::vector<float> minPerceptibleFrequencies;
+ static std::vector<float> minPerceptibleAccelerations;
+
+ auto minPerceptibleLevel = getMinPerceptibleLevel();
+ // Sort the 'minPerceptibleLevel' data in ascending order based on the
+ // frequency values (first element of each pair).
+ std::sort(minPerceptibleLevel.begin(), minPerceptibleLevel.end(),
+ [](const auto& a, const auto& b) { return a.first < b.first; });
+
+ for (const auto& entry : minPerceptibleLevel) {
+ minPerceptibleFrequencies.push_back(entry.first);
+ minPerceptibleAccelerations.push_back(entry.second);
+ }
+
+ return [&](float freq) {
+ return interpolateLinearly(minPerceptibleFrequencies, minPerceptibleAccelerations,
+ freq);
+ };
+ }();
+
+ return minPerceptibleMap(frequency);
+}
+
+static float convertSensitivityLevelToDecibel(int sl, float frequency) {
+ return sl + minPerceptibleDbCurve(frequency);
+}
+
+static float convertDecibelToAcceleration(float db) {
+ return std::pow(10.0f, db / 20.0f);
+}
+} // namespace
+
+static float convertSensitivityLevelToAcceleration(int sl, float frequency) {
+ return pwlev2::convertDecibelToAcceleration(
+ pwlev2::convertSensitivityLevelToDecibel(sl, frequency));
+}
+
+static float getPwleV2FrequencyMinHz(const std::shared_ptr<IVibrator>& vibrator) {
+ std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
+ EXPECT_OK(
+ vibrator->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap));
+ EXPECT_TRUE(!frequencyToOutputAccelerationMap.empty());
+ // We can't use ASSERT_TRUE() above because this is a non-void function,
+ // but we need to return to assure we don't crash from a null dereference.
+ if (frequencyToOutputAccelerationMap.empty()) {
+ return std::numeric_limits<float>::quiet_NaN();
+ }
+
+ auto entry = std::min_element(
+ frequencyToOutputAccelerationMap.begin(), frequencyToOutputAccelerationMap.end(),
+ [](const auto& a, const auto& b) { return a.frequencyHz < b.frequencyHz; });
+
+ return entry->frequencyHz;
+}
+
+static float getPwleV2FrequencyMaxHz(const std::shared_ptr<IVibrator>& vibrator) {
+ std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
+ EXPECT_OK(
+ vibrator->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap));
+ EXPECT_TRUE(!frequencyToOutputAccelerationMap.empty());
+ // We can't use ASSERT_TRUE() above because this is a non-void function,
+ // but we need to return to assure we don't crash from a null dereference.
+ if (frequencyToOutputAccelerationMap.empty()) {
+ return std::numeric_limits<float>::quiet_NaN();
+ }
+
+ auto entry = std::max_element(
+ frequencyToOutputAccelerationMap.begin(), frequencyToOutputAccelerationMap.end(),
+ [](const auto& a, const auto& b) { return a.frequencyHz < b.frequencyHz; });
+
+ return entry->frequencyHz;
+}
+
+static std::vector<PwleV2Primitive> composeValidPwleV2Effect(
+ const std::shared_ptr<IVibrator>& vibrator) {
+ int32_t minDurationMs;
+ EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMinMillis(&minDurationMs));
+ int32_t maxDurationMs;
+ EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMaxMillis(&maxDurationMs));
+ float minFrequency = getPwleV2FrequencyMinHz(vibrator);
+ float maxFrequency = getPwleV2FrequencyMaxHz(vibrator);
+ int32_t maxCompositionSize;
+ EXPECT_OK(vibrator->getPwleV2CompositionSizeMax(&maxCompositionSize));
+
+ std::vector<PwleV2Primitive> pwleEffect;
+
+ pwleEffect.emplace_back(0.1f, minFrequency, minDurationMs);
+ pwleEffect.emplace_back(0.5f, maxFrequency, maxDurationMs);
+
+ float variedFrequency = (minFrequency + maxFrequency) / 2.0f;
+ for (int i = 0; i < maxCompositionSize - 2; i++) {
+ pwleEffect.emplace_back(0.7f, variedFrequency, minDurationMs);
+ }
+
+ return pwleEffect;
+}
+
+static std::vector<PwleV2Primitive> composePwleV2EffectWithTooManyPoints(
+ const std::shared_ptr<IVibrator>& vibrator) {
+ int32_t minDurationMs, maxCompositionSize;
+ EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMinMillis(&minDurationMs));
+ EXPECT_OK(vibrator->getPwleV2CompositionSizeMax(&maxCompositionSize));
+ float maxFrequency = getPwleV2FrequencyMaxHz(vibrator);
+
+ std::vector<PwleV2Primitive> pwleEffect(maxCompositionSize + 1); // +1 to exceed the limit
+
+ std::fill(pwleEffect.begin(), pwleEffect.end(),
+ PwleV2Primitive(/*amplitude=*/0.2f, maxFrequency, minDurationMs));
+
+ return pwleEffect;
+}
+
+static std::pair<float, float> getPwleV2SharpnessRange(
+ const std::shared_ptr<IVibrator>& vibrator,
+ std::vector<PwleV2OutputMapEntry> freqToOutputAccelerationMap) {
+ std::pair<float, float> sharpnessRange = {-1, -1};
+
+ // Sort the entries by frequency in ascending order
+ std::sort(freqToOutputAccelerationMap.begin(), freqToOutputAccelerationMap.end(),
+ [](const auto& a, const auto& b) { return a.frequencyHz < b.frequencyHz; });
+
+ for (const auto& entry : freqToOutputAccelerationMap) {
+ float minAcceptableOutputAcceleration = convertSensitivityLevelToAcceleration(
+ pwlev2::COMPOSE_PWLE_V2_MIN_REQUIRED_SENSITIVITY_DB_SL, entry.frequencyHz);
+
+ if (sharpnessRange.first < 0 &&
+ minAcceptableOutputAcceleration <= entry.maxOutputAccelerationGs) {
+ sharpnessRange.first = entry.frequencyHz; // Found the lower bound
+ } else if (sharpnessRange.first >= 0 &&
+ minAcceptableOutputAcceleration >= entry.maxOutputAccelerationGs) {
+ sharpnessRange.second = entry.frequencyHz; // Found the upper bound
+ return sharpnessRange;
+ }
+ }
+
+ if (sharpnessRange.first >= 0) {
+ // If only the lower bound was found, set the upper bound to the max frequency.
+ sharpnessRange.second = getPwleV2FrequencyMaxHz(vibrator);
+ }
+
+ return sharpnessRange;
+}
+} // namespace pwlev2
+} // namespace testing
+} // namespace vibrator
+} // namespace hardware
+} // namespace android
+} // namespace aidl
+#endif // VIBRATOR_HAL_PWLE_V2_UTILS_H
diff --git a/vibrator/aidl/vts/test_utils.h b/vibrator/aidl/vts/test_utils.h
new file mode 100644
index 0000000..aaf3211
--- /dev/null
+++ b/vibrator/aidl/vts/test_utils.h
@@ -0,0 +1,60 @@
+/*
+ * 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 VIBRATOR_HAL_TEST_UTILS_H
+#define VIBRATOR_HAL_TEST_UTILS_H
+
+#include <android/binder_auto_utils.h>
+#include <gtest/gtest.h>
+
+#if !defined(EXPECT_OK)
+#define EXPECT_OK(expression) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const ::ndk::ScopedAStatus&& _status = (expression); _status.isOk()) \
+ ; \
+ else \
+ ADD_FAILURE() << "Expected STATUS_OK for: " << #expression << "\n Actual: " << _status
+#else
+#error Macro EXPECT_OK already defined unexpectedly
+#endif
+
+#if !defined(EXPECT_UNKNOWN_OR_UNSUPPORTED)
+#define EXPECT_UNKNOWN_OR_UNSUPPORTED(expression) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const ::ndk::ScopedAStatus&& _status = (expression); \
+ _status.getExceptionCode() == EX_UNSUPPORTED_OPERATION || \
+ _status.getStatus() == STATUS_UNKNOWN_TRANSACTION) \
+ ; \
+ else \
+ ADD_FAILURE() << "Expected STATUS_UNKNOWN_TRANSACTION or EX_UNSUPPORTED_OPERATION for: " \
+ << #expression << "\n Actual: " << _status
+#else
+#error Macro EXPECT_UNKNOWN_OR_UNSUPPORTED already defined unexpectedly
+#endif
+
+#if !defined(EXPECT_ILLEGAL_ARGUMENT)
+#define EXPECT_ILLEGAL_ARGUMENT(expression) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (const ::ndk::ScopedAStatus&& _status = (expression); \
+ _status.getExceptionCode() == EX_ILLEGAL_ARGUMENT) \
+ ; \
+ else \
+ ADD_FAILURE() << "Expected EX_ILLEGAL_ARGUMENT for: " << #expression \
+ << "\n Actual: " << _status
+#else
+#error Macro EXPECT_ILLEGAL_ARGUMENT already defined unexpectedly
+#endif
+
+#endif // VIBRATOR_HAL_TEST_UTILS_H
diff --git a/vibrator/bench/Android.bp b/vibrator/bench/Android.bp
index 87bdab4..cd56516 100644
--- a/vibrator/bench/Android.bp
+++ b/vibrator/bench/Android.bp
@@ -30,12 +30,12 @@
"benchmark.cpp",
],
shared_libs: [
- "android.hardware.vibrator-V2-cpp",
+ "android.hardware.vibrator-V3-ndk",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
"android.hardware.vibrator@1.3",
- "libbinder",
+ "libbinder_ndk",
"libhardware",
"libhidlbase",
"libutils",
diff --git a/vibrator/bench/benchmark.cpp b/vibrator/bench/benchmark.cpp
index deaa6f2..8fe9cf7 100644
--- a/vibrator/bench/benchmark.cpp
+++ b/vibrator/bench/benchmark.cpp
@@ -16,15 +16,14 @@
#include "benchmark/benchmark.h"
+#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
#include <android/hardware/vibrator/1.3/IVibrator.h>
-#include <android/hardware/vibrator/BnVibratorCallback.h>
-#include <android/hardware/vibrator/IVibrator.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
#include <future>
-using ::android::enum_range;
-using ::android::sp;
using ::android::hardware::hidl_enum_range;
using ::android::hardware::Return;
using ::android::hardware::details::hidl_enum_values;
@@ -33,10 +32,11 @@
using ::benchmark::kMicrosecond;
using ::benchmark::State;
using ::benchmark::internal::Benchmark;
+using ::ndk::enum_range;
using namespace ::std::chrono_literals;
-namespace Aidl = ::android::hardware::vibrator;
+namespace Aidl = ::aidl::android::hardware::vibrator;
namespace V1_0 = ::android::hardware::vibrator::V1_0;
namespace V1_1 = ::android::hardware::vibrator::V1_1;
namespace V1_2 = ::android::hardware::vibrator::V1_2;
@@ -56,8 +56,8 @@
class BaseBench : public Fixture {
public:
void SetUp(State& /*state*/) override {
- android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
- android::ProcessState::self()->startThreadPool();
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
}
void TearDown(State& /*state*/) override {
@@ -75,7 +75,7 @@
auto getOtherArg(const State& state, std::size_t index) const { return state.range(index + 0); }
protected:
- sp<I> mVibrator;
+ std::shared_ptr<I> mVibrator;
};
template <typename I>
@@ -83,7 +83,12 @@
public:
void SetUp(State& state) override {
BaseBench<I>::SetUp(state);
- this->mVibrator = I::getService();
+ auto service = I::getService();
+ if (service) {
+ this->mVibrator = std::shared_ptr<I>(service.release());
+ } else {
+ this->mVibrator = nullptr;
+ }
}
protected:
@@ -356,7 +361,9 @@
public:
void SetUp(State& state) override {
BaseBench::SetUp(state);
- this->mVibrator = android::waitForVintfService<Aidl::IVibrator>();
+ auto serviceName = std::string(Aidl::IVibrator::descriptor) + "/default";
+ this->mVibrator = Aidl::IVibrator::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
}
void TearDown(State& state) override {
@@ -373,14 +380,24 @@
return (deviceCapabilities & capabilities) == capabilities;
}
- bool shouldSkipWithError(State& state, const android::binder::Status&& status) {
+ bool shouldSkipWithError(State& state, const ndk::ScopedAStatus&& status) {
if (!status.isOk()) {
- state.SkipWithError(status.toString8().c_str());
+ state.SkipWithError(status.getMessage());
return true;
}
return false;
}
+ void waitForComplete(std::future<void>& callbackFuture) {
+ // Wait until the HAL has finished processing previous vibration before starting a new one,
+ // so the HAL state is consistent on each run and metrics are less noisy. Some of the newest
+ // HAL implementations are waiting on previous vibration cleanup and might be significantly
+ // slower, so make sure we measure vibrations on a clean slate.
+ if (callbackFuture.valid()) {
+ callbackFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT);
+ }
+ }
+
static void SlowBenchConfig(Benchmark* b) { b->Iterations(VIBRATION_ITERATIONS); }
};
@@ -397,18 +414,12 @@
HalCallback() = default;
~HalCallback() = default;
- android::binder::Status onComplete() override {
+ ndk::ScopedAStatus onComplete() override {
mPromise.set_value();
- return android::binder::Status::ok();
+ return ndk::ScopedAStatus::ok();
}
- void waitForComplete() {
- // Wait until the HAL has finished processing previous vibration before starting a new one,
- // so the HAL state is consistent on each run and metrics are less noisy. Some of the newest
- // HAL implementations are waiting on previous vibration cleanup and might be significantly
- // slower, so make sure we measure vibrations on a clean slate.
- mPromise.get_future().wait_for(VIBRATION_CALLBACK_TIMEOUT);
- }
+ std::future<void> getFuture() { return mPromise.get_future(); }
private:
std::promise<void> mPromise;
@@ -418,7 +429,11 @@
auto ms = MAX_ON_DURATION_MS;
for (auto _ : state) {
- auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
+ auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK)
+ ? ndk::SharedRefBase::make<HalCallback>()
+ : nullptr;
+ // Grab the future before callback promise is destroyed by the HAL.
+ auto cbFuture = cb ? cb->getFuture() : std::future<void>();
// Test
if (shouldSkipWithError(state, mVibrator->on(ms, cb))) {
@@ -430,9 +445,7 @@
if (shouldSkipWithError(state, mVibrator->off())) {
return;
}
- if (cb) {
- cb->waitForComplete();
- }
+ waitForComplete(cbFuture);
state.ResumeTiming();
}
});
@@ -441,7 +454,11 @@
auto ms = MAX_ON_DURATION_MS;
for (auto _ : state) {
- auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
+ auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK)
+ ? ndk::SharedRefBase::make<HalCallback>()
+ : nullptr;
+ // Grab the future before callback promise is destroyed by the HAL.
+ auto cbFuture = cb ? cb->getFuture() : std::future<void>();
// Setup
state.PauseTiming();
@@ -457,9 +474,7 @@
// Cleanup
state.PauseTiming();
- if (cb) {
- cb->waitForComplete();
- }
+ waitForComplete(cbFuture);
state.ResumeTiming();
}
});
@@ -483,7 +498,9 @@
return;
}
- auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
+ auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK)
+ ? ndk::SharedRefBase::make<HalCallback>()
+ : nullptr;
if (shouldSkipWithError(state, mVibrator->on(ms, cb))) {
return;
}
@@ -685,8 +702,11 @@
int32_t lengthMs = 0;
for (auto _ : state) {
- auto cb = hasCapabilities(Aidl::IVibrator::CAP_PERFORM_CALLBACK) ? new HalCallback()
- : nullptr;
+ auto cb = hasCapabilities(Aidl::IVibrator::CAP_PERFORM_CALLBACK)
+ ? ndk::SharedRefBase::make<HalCallback>()
+ : nullptr;
+ // Grab the future before callback promise is destroyed by the HAL.
+ auto cbFuture = cb ? cb->getFuture() : std::future<void>();
// Test
if (shouldSkipWithError(state, mVibrator->perform(effect, strength, cb, &lengthMs))) {
@@ -698,9 +718,7 @@
if (shouldSkipWithError(state, mVibrator->off())) {
return;
}
- if (cb) {
- cb->waitForComplete();
- }
+ waitForComplete(cbFuture);
state.ResumeTiming();
}
});
@@ -799,7 +817,9 @@
effects.push_back(effect);
for (auto _ : state) {
- auto cb = new HalCallback();
+ auto cb = ndk::SharedRefBase::make<HalCallback>();
+ // Grab the future before callback promise is moved and destroyed by the HAL.
+ auto cbFuture = cb->getFuture();
// Test
if (shouldSkipWithError(state, mVibrator->compose(effects, cb))) {
@@ -811,7 +831,7 @@
if (shouldSkipWithError(state, mVibrator->off())) {
return;
}
- cb->waitForComplete();
+ waitForComplete(cbFuture);
state.ResumeTiming();
}
});
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index d82450e..d99edaa 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -3394,6 +3394,7 @@
*legacy_request = {};
legacy_request->service_instance_id = aidl_request.bootstrappingInstanceId;
+ legacy_request->bootstrapping_instance_id = aidl_request.bootstrappingInstanceId;
legacy_request->rsp_code = aidl_request.acceptRequest ? NAN_BOOTSTRAPPING_REQUEST_ACCEPT
: NAN_BOOTSTRAPPING_REQUEST_REJECT;
legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index 9b9c565..fccfc15 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -62,7 +62,9 @@
std::vector<std::string> getNames(std::vector<std::shared_ptr<Iface>>& ifaces) {
std::vector<std::string> names;
for (const auto& iface : ifaces) {
- names.emplace_back(iface->getName());
+ if (iface) {
+ names.emplace_back(iface->getName());
+ }
}
return names;
}
@@ -971,6 +973,10 @@
}
std::shared_ptr<WifiNanIface> iface =
WifiNanIface::create(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
+ if (!iface) {
+ LOG(ERROR) << "Unable to create NAN iface";
+ return {nullptr, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
nan_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
if (!callback->onIfaceAdded(IfaceType::NAN_IFACE, ifname).isOk()) {
diff --git a/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp b/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
index 21d50ac..c68d8fd 100644
--- a/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
+++ b/wifi/aidl/vts/functional/wifi_aidl_test_utils.cpp
@@ -177,8 +177,7 @@
return iface;
}
-std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name) {
- std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+std::shared_ptr<IWifiApIface> getWifiApIface(std::shared_ptr<IWifiChip> wifi_chip) {
if (!wifi_chip.get()) {
return nullptr;
}
@@ -193,6 +192,11 @@
return iface;
}
+std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name) {
+ std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
+ return getWifiApIface(wifi_chip);
+}
+
std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip) {
if (!wifi_chip.get()) {
return nullptr;
diff --git a/wifi/aidl/vts/functional/wifi_aidl_test_utils.h b/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
index 1369dd4..9b47a9f 100644
--- a/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
+++ b/wifi/aidl/vts/functional/wifi_aidl_test_utils.h
@@ -40,6 +40,7 @@
std::shared_ptr<IWifiStaIface> getWifiStaIface(const char* instance_name);
std::shared_ptr<IWifiNanIface> getWifiNanIface(const char* instance_name);
std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name);
+std::shared_ptr<IWifiApIface> getWifiApIface(std::shared_ptr<IWifiChip> wifi_chip);
std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name);
std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip);
// Configure the chip in a mode to support the creation of the provided iface type.
diff --git a/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp
index d39cfb4..a58fd5b 100644
--- a/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_ap_iface_aidl_test.cpp
@@ -37,12 +37,21 @@
"/system/bin/cmd wifi get-softap-supported-features",
"wifi_softap_bridged_ap_supported");
stopWifiService(getInstanceName());
+
+ wifi_chip_ = getWifiChip(getInstanceName());
+ ASSERT_NE(nullptr, wifi_chip_.get());
+
+ bool isApSupported = doesChipSupportConcurrencyType(wifi_chip_, IfaceConcurrencyType::AP);
+ if (!isApSupported) {
+ GTEST_SKIP() << "AP interfaces are not supported";
+ }
}
void TearDown() override { stopWifiService(getInstanceName()); }
protected:
bool isBridgedSupport_ = false;
+ std::shared_ptr<IWifiChip> wifi_chip_;
const char* getInstanceName() { return GetParam().c_str(); }
};
@@ -50,7 +59,7 @@
* SetMacAddress
*/
TEST_P(WifiApIfaceAidlTest, SetMacAddress) {
- std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(wifi_chip_);
ASSERT_NE(nullptr, wifi_ap_iface.get());
std::array<uint8_t, 6> mac = {0x12, 0x22, 0x33, 0x52, 0x10, 0x44};
EXPECT_TRUE(wifi_ap_iface->setMacAddress(mac).isOk());
@@ -60,7 +69,7 @@
* SetCountryCode
*/
TEST_P(WifiApIfaceAidlTest, SetCountryCode) {
- std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(wifi_chip_);
ASSERT_NE(nullptr, wifi_ap_iface.get());
const std::array<uint8_t, 2> country_code = {0x55, 0x53};
@@ -71,7 +80,7 @@
* GetFactoryMacAddress
*/
TEST_P(WifiApIfaceAidlTest, GetFactoryMacAddress) {
- std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(wifi_chip_);
ASSERT_NE(nullptr, wifi_ap_iface.get());
std::array<uint8_t, 6> mac;
@@ -84,7 +93,7 @@
* GetBridgedInstances - non-bridged mode
*/
TEST_P(WifiApIfaceAidlTest, GetBridgedInstances) {
- std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(wifi_chip_);
ASSERT_NE(nullptr, wifi_ap_iface.get());
std::vector<std::string> instances;
@@ -99,7 +108,7 @@
if (!isBridgedSupport_) {
GTEST_SKIP() << "Missing Bridged AP support";
}
- std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(getInstanceName());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(wifi_chip_);
ASSERT_NE(nullptr, wifi_ap_iface.get());
std::vector<std::string> instances;
@@ -111,7 +120,7 @@
* ResetToFactoryMacAddress - non-bridged mode
*/
TEST_P(WifiApIfaceAidlTest, ResetToFactoryMacAddress) {
- std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(getInstanceName());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getWifiApIface(wifi_chip_);
ASSERT_NE(nullptr, wifi_ap_iface.get());
EXPECT_TRUE(wifi_ap_iface->resetToFactoryMacAddress().isOk());
}
@@ -123,7 +132,7 @@
if (!isBridgedSupport_) {
GTEST_SKIP() << "Missing Bridged AP support";
}
- std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(getInstanceName());
+ std::shared_ptr<IWifiApIface> wifi_ap_iface = getBridgedWifiApIface(wifi_chip_);
ASSERT_NE(nullptr, wifi_ap_iface.get());
EXPECT_TRUE(wifi_ap_iface->resetToFactoryMacAddress().isOk());
}
diff --git a/wifi/hostapd/aidl/Android.bp b/wifi/hostapd/aidl/Android.bp
index 2e4d4d1..88f4ef2 100644
--- a/wifi/hostapd/aidl/Android.bp
+++ b/wifi/hostapd/aidl/Android.bp
@@ -65,5 +65,5 @@
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/BandMask.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/BandMask.aidl
index b1e7f66..fa9f198 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/BandMask.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/BandMask.aidl
@@ -34,8 +34,8 @@
package android.hardware.wifi.hostapd;
@Backing(type="int") @VintfStability
enum BandMask {
- BAND_2_GHZ = 1,
- BAND_5_GHZ = 2,
- BAND_6_GHZ = 4,
- BAND_60_GHZ = 8,
+ BAND_2_GHZ = (1 << 0) /* 1 */,
+ BAND_5_GHZ = (1 << 1) /* 2 */,
+ BAND_6_GHZ = (1 << 2) /* 4 */,
+ BAND_60_GHZ = (1 << 3) /* 8 */,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/EncryptionType.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/EncryptionType.aidl
index a7b20fa..840b875 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/EncryptionType.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/EncryptionType.aidl
@@ -34,11 +34,11 @@
package android.hardware.wifi.hostapd;
@Backing(type="int") @VintfStability
enum EncryptionType {
- NONE = 0,
- WPA = 1,
- WPA2 = 2,
- WPA3_SAE_TRANSITION = 3,
- WPA3_SAE = 4,
- WPA3_OWE_TRANSITION = 5,
- WPA3_OWE = 6,
+ NONE,
+ WPA,
+ WPA2,
+ WPA3_SAE_TRANSITION,
+ WPA3_SAE,
+ WPA3_OWE_TRANSITION,
+ WPA3_OWE,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl
index 5bb0d32..a0c1886 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl
@@ -34,7 +34,7 @@
package android.hardware.wifi.hostapd;
@Backing(type="int") @VintfStability
enum Generation {
- WIFI_STANDARD_UNKNOWN = -1,
+ WIFI_STANDARD_UNKNOWN = (-1) /* -1 */,
WIFI_STANDARD_LEGACY = 0,
WIFI_STANDARD_11N = 1,
WIFI_STANDARD_11AC = 2,
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HostapdStatusCode.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HostapdStatusCode.aidl
index 548e497..7edff15 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HostapdStatusCode.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HostapdStatusCode.aidl
@@ -34,10 +34,10 @@
package android.hardware.wifi.hostapd;
@Backing(type="int") @VintfStability
enum HostapdStatusCode {
- SUCCESS = 0,
- FAILURE_UNKNOWN = 1,
- FAILURE_ARGS_INVALID = 2,
- FAILURE_IFACE_UNKNOWN = 3,
- FAILURE_IFACE_EXISTS = 4,
- FAILURE_CLIENT_UNKNOWN = 5,
+ SUCCESS,
+ FAILURE_UNKNOWN,
+ FAILURE_ARGS_INVALID,
+ FAILURE_IFACE_UNKNOWN,
+ FAILURE_IFACE_EXISTS,
+ FAILURE_CLIENT_UNKNOWN,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
index 64367bb..8da3441 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
@@ -38,4 +38,6 @@
android.hardware.wifi.hostapd.HwModeParams hwModeParams;
android.hardware.wifi.hostapd.ChannelParams[] channelParams;
@nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+ @nullable String[] instanceIdentities;
+ boolean isMlo;
}
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
index 3f8ee39..bb646e3 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
@@ -41,4 +41,12 @@
* Optional vendor-specific configuration parameters.
*/
@nullable OuiKeyedData[] vendorData;
+ /**
+ * The list of the instance identities.
+ */
+ @nullable String[] instanceIdentities;
+ /**
+ * Whether the current iface is MLO.
+ */
+ boolean isMlo;
}
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index f614679..bf1b0d0 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -21,7 +21,7 @@
"libvndksupport",
],
static_libs: [
- "android.hardware.wifi.hostapd-V2-ndk",
+ "android.hardware.wifi.hostapd-V3-ndk",
"VtsHalWifiV1_0TargetTestUtil",
"VtsHalWifiV1_5TargetTestUtil",
"VtsHalWifiV1_6TargetTestUtil",
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h b/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h
index 55034d1..4e490d9 100644
--- a/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h
@@ -2972,11 +2972,17 @@
u16 publish_subscribe_id;
/*
- This Id is the Peer Instance that is passed as
- part of earlier MatchInd/FollowupInd message.
+ Same as the bootstrapping_instance_id
*/
u32 service_instance_id;
+ /*
+ Unique Instance Id corresponding to a service/session.
+ This is similar to the publish_id generated on the
+ publisher side
+ */
+ u32 bootstrapping_instance_id;
+
/* Discovery MAC addr of the peer/initiator */
u8 peer_disc_mac_addr[NAN_MAC_ADDR_LEN];