vibrator: add getSupportedEffects
It's a real gap in this interface, since we need to call perform to
understand if an effect is supported.
Bug: 141828236
Test: atest VtsHalVibratorTargetTest
Change-Id: Iffbd9c0acf5e4c368767c7718025a4aef8f44ce3
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
index b2008f4..d21274b 100644
--- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
@@ -74,6 +74,14 @@
int perform(in Effect effect, in EffectStrength strength, in IVibratorCallback callback);
/**
+ * List supported effects.
+ *
+ * Return the effects which are supported (an effect is expected to be supported at every
+ * strength level.
+ */
+ Effect[] getSupportedEffects();
+
+ /**
* Sets the motor's vibrational amplitude.
*
* Changes the force being produced by the underlying motor.
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index cdf8e09..2aec8c5 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -78,6 +78,11 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect>* _aidl_return) {
+ *_aidl_return = {Effect::CLICK, Effect::TICK};
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Vibrator::setAmplitude(int32_t amplitude) {
LOG(INFO) << "Vibrator set amplitude: " << amplitude;
if (amplitude <= 0 || amplitude > 255) {
diff --git a/vibrator/aidl/default/Vibrator.h b/vibrator/aidl/default/Vibrator.h
index 77e96e3..14e7292 100644
--- a/vibrator/aidl/default/Vibrator.h
+++ b/vibrator/aidl/default/Vibrator.h
@@ -31,6 +31,7 @@
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(int32_t amplitude) override;
ndk::ScopedAStatus setExternalControl(bool enabled) override;
};
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 33bcaf5..b0e6c72 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -32,6 +32,7 @@
using android::hardware::vibrator::EffectStrength;
using android::hardware::vibrator::IVibrator;
+// TODO(b/143992652): autogenerate
const std::vector<Effect> kEffects = {
Effect::CLICK, Effect::DOUBLE_CLICK, Effect::TICK, Effect::THUD,
Effect::POP, Effect::HEAVY_CLICK, Effect::RINGTONE_1, Effect::RINGTONE_2,
@@ -40,6 +41,7 @@
Effect::RINGTONE_11, Effect::RINGTONE_12, Effect::RINGTONE_13, Effect::RINGTONE_14,
Effect::RINGTONE_15, Effect::TEXTURE_TICK};
+// TODO(b/143992652): autogenerate
const std::vector<EffectStrength> kEffectStrengths = {EffectStrength::LIGHT, EffectStrength::MEDIUM,
EffectStrength::STRONG};
@@ -105,15 +107,22 @@
}
TEST_P(VibratorAidl, ValidateEffect) {
+ std::vector<Effect> supported;
+ ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
+
for (Effect effect : kEffects) {
+ bool isEffectSupported =
+ std::find(supported.begin(), supported.end(), effect) != supported.end();
+
for (EffectStrength strength : kEffectStrengths) {
int32_t lengthMs = 0;
Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
- EXPECT_TRUE(status.isOk() ||
- status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION);
- if (status.isOk()) {
+
+ if (isEffectSupported) {
+ EXPECT_TRUE(status.isOk());
EXPECT_GT(lengthMs, 0);
} else {
+ EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
EXPECT_EQ(lengthMs, 0);
}
}
@@ -123,16 +132,29 @@
TEST_P(VibratorAidl, ValidateEffectWithCallback) {
if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
+ std::vector<Effect> supported;
+ ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
+
for (Effect effect : kEffects) {
+ bool isEffectSupported =
+ std::find(supported.begin(), supported.end(), effect) != supported.end();
+
for (EffectStrength strength : kEffectStrengths) {
std::promise<void> completionPromise;
std::future<void> completionFuture{completionPromise.get_future()};
sp<CompletionCallback> callback =
new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
- int lengthMs;
+ int lengthMs = 0;
Status status = vibrator->perform(effect, strength, callback, &lengthMs);
- EXPECT_TRUE(status.isOk() ||
- status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION);
+
+ if (isEffectSupported) {
+ EXPECT_TRUE(status.isOk());
+ EXPECT_GT(lengthMs, 0);
+ } else {
+ EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
+ EXPECT_EQ(lengthMs, 0);
+ }
+
if (!status.isOk()) continue;
std::chrono::milliseconds timeout{lengthMs * 2};