Add new TEXTURE_TICK constant.
Unlike TICK, this is specifically meant to be called repeatedly in
reaction to small movements in order to replicate a specific texture.
Bug: 111461797
Test: VTS
Change-Id: If21687b5fed5f578a638017abc9ce479a122612d
diff --git a/current.txt b/current.txt
index 88d2e11..b91f3f9 100644
--- a/current.txt
+++ b/current.txt
@@ -544,7 +544,8 @@
61bc302e7c974c59b25898c585c6e9685e8a81021b1bed3eedf5224198f2785a android.hardware.usb@1.2::IUsb
46996cd2a1c66261a75a1f6ecada77eeb5861eb264fa39b996548fe0a7f22dd3 android.hardware.usb@1.2::IUsbCallback
3bbaa8cbc5d6b1da21f5509b2b641e05fc7eeca1354751eb1bb3cf37f89aa32f android.hardware.usb@1.2::types
-92c1a726c80970d623b891f7c2f9a989a40a15ee1244092b49f4eb6adcdce4e9 android.hardware.vibrator@1.3::IVibrator
+0f7ff73793548d5154014059b7e0fe9ef6355d32218ace157954d02055f5248b android.hardware.vibrator@1.3::IVibrator
+2e313dc27a1327a29862ab3e085917f75c9e996f7c8df5a0ce37b9a0ed076b80 android.hardware.vibrator@1.3::types
f19832856a3f53ced5ef91d3cc630a57fb7f4d4ce15f364dbed09099b89f6830 android.hardware.wifi@1.3::IWifi
7c6799c19bfdb3dec016b751556fe246cf7d37191ee7bb82a0091ab9fbf6f2fb android.hardware.wifi@1.3::IWifiChip
3bef30e8b61ab050c0f6fd26572712be5ebb7707d624c9aa6c74bbb9d6a5b4a9 android.hardware.wifi@1.3::IWifiStaIface
diff --git a/vibrator/1.3/Android.bp b/vibrator/1.3/Android.bp
index 28370d6..a2ff784 100644
--- a/vibrator/1.3/Android.bp
+++ b/vibrator/1.3/Android.bp
@@ -8,6 +8,7 @@
},
srcs: [
"IVibrator.hal",
+ "types.hal",
],
interfaces: [
"android.hardware.vibrator@1.0",
diff --git a/vibrator/1.3/IVibrator.hal b/vibrator/1.3/IVibrator.hal
index 01c2801..1c870ee 100644
--- a/vibrator/1.3/IVibrator.hal
+++ b/vibrator/1.3/IVibrator.hal
@@ -16,6 +16,7 @@
package android.hardware.vibrator@1.3;
+import @1.0::EffectStrength;
import @1.0::Status;
import @1.2::IVibrator;
@@ -41,4 +42,18 @@
* not supported by the device.
*/
setExternalControl(bool enabled) generates (Status status);
+
+ /**
+ * Fire off a predefined haptic event.
+ *
+ * @param event The type of haptic event to trigger.
+ * @return status Whether the effect was successfully performed or not. Must
+ * return Status::UNSUPPORTED_OPERATION if the effect is not supported.
+ * @return lengthMs The length of time the event is expected to take in
+ * milliseconds. This doesn't need to be perfectly accurate, but should be a reasonable
+ * approximation. Should be a positive, non-zero value if the returned status is Status::OK,
+ * and set to 0 otherwise.
+ */
+ perform_1_3(Effect effect, EffectStrength strength)
+ generates (Status status, uint32_t lengthMs);
};
diff --git a/vibrator/1.3/example/Vibrator.cpp b/vibrator/1.3/example/Vibrator.cpp
index bb9a057..eb50187 100644
--- a/vibrator/1.3/example/Vibrator.cpp
+++ b/vibrator/1.3/example/Vibrator.cpp
@@ -74,22 +74,9 @@
// Methods from ::android::hardware::vibrator::V1_2::IVibrator follow.
-Return<void> Vibrator::perform_1_2(Effect effect, EffectStrength strength, perform_cb _hidl_cb) {
- uint8_t amplitude;
- uint32_t ms;
- Status status;
-
- ALOGI("Perform: Effect %s\n", effectToName(effect));
-
- amplitude = strengthToAmplitude(strength);
- setAmplitude(amplitude);
-
- ms = effectToMs(effect);
- status = activate(ms);
-
- _hidl_cb(status, ms);
-
- return Void();
+Return<void> Vibrator::perform_1_2(V1_2::Effect effect, EffectStrength strength,
+ perform_cb _hidl_cb) {
+ return perform_1_3(static_cast<V1_3::Effect>(effect), strength, _hidl_cb);
}
// Methods from ::android::hardware::vibrator::V1_3::IVibrator follow.
@@ -110,6 +97,24 @@
}
}
+Return<void> Vibrator::perform_1_3(Effect effect, EffectStrength strength, perform_cb _hidl_cb) {
+ uint8_t amplitude;
+ uint32_t ms;
+ Status status;
+
+ ALOGI("Perform: Effect %s\n", effectToName(effect));
+
+ amplitude = strengthToAmplitude(strength);
+ setAmplitude(amplitude);
+
+ ms = effectToMs(effect);
+ status = activate(ms);
+
+ _hidl_cb(status, ms);
+
+ return Void();
+}
+
// Private methods follow.
Status Vibrator::enable(bool enabled) {
@@ -184,6 +189,7 @@
case Effect::DOUBLE_CLICK:
return 15;
case Effect::TICK:
+ case Effect::TEXTURE_TICK:
return 5;
case Effect::THUD:
return 5;
diff --git a/vibrator/1.3/example/Vibrator.h b/vibrator/1.3/example/Vibrator.h
index a931b63..8cf0b1e 100644
--- a/vibrator/1.3/example/Vibrator.h
+++ b/vibrator/1.3/example/Vibrator.h
@@ -27,7 +27,6 @@
using android::hardware::vibrator::V1_0::EffectStrength;
using android::hardware::vibrator::V1_0::Status;
-using android::hardware::vibrator::V1_2::Effect;
class Vibrator : public IVibrator {
public:
@@ -46,11 +45,13 @@
perform_cb _hidl_cb) override;
// Methods from ::android::hardware::vibrator::V1_2::IVibrator follow.
- Return<void> perform_1_2(Effect effect, EffectStrength strength, perform_cb _hidl_cb) override;
+ Return<void> perform_1_2(V1_2::Effect effect, EffectStrength strength,
+ perform_cb _hidl_cb) override;
// Methods from ::android::hardware::vibrator::V1_3::IVibrator follow.
Return<bool> supportsExternalControl() override;
Return<Status> setExternalControl(bool enabled) override;
+ Return<void> perform_1_3(Effect effect, EffectStrength strength, perform_cb _hidl_cb) override;
private:
Status enable(bool enabled);
diff --git a/vibrator/1.3/types.hal b/vibrator/1.3/types.hal
new file mode 100644
index 0000000..ceb62a5
--- /dev/null
+++ b/vibrator/1.3/types.hal
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package android.hardware.vibrator@1.3;
+
+import @1.2::Effect;
+
+enum Effect : @1.2::Effect {
+ /**
+ * A soft tick effect meant to be played as a texture.
+ *
+ * A soft, short sensation like the tick of a clock. Unlike regular effects, texture effects
+ * 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
+};
diff --git a/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
index a67d1dc..818f9c7 100644
--- a/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
+++ b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
@@ -24,9 +24,16 @@
#include <unistd.h>
using ::android::sp;
+using ::android::hardware::hidl_enum_range;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::vibrator::V1_0::EffectStrength;
using ::android::hardware::vibrator::V1_0::Status;
+using ::android::hardware::vibrator::V1_3::Effect;
using ::android::hardware::vibrator::V1_3::IVibrator;
+#define EXPECT_OK(ret) ASSERT_TRUE((ret).isOk())
+
// Test environment for Vibrator HIDL HAL.
class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
public:
@@ -71,6 +78,74 @@
}
}
+static void validatePerformEffectUnsupportedOperation(Status status, uint32_t lengthMs) {
+ ASSERT_EQ(Status::UNSUPPORTED_OPERATION, status);
+ ASSERT_EQ(static_cast<uint32_t>(0), lengthMs)
+ << "Effects that return UNSUPPORTED_OPERATION must have a duration of zero";
+}
+
+static void validatePerformEffect(Status status, uint32_t lengthMs) {
+ ASSERT_TRUE(status == Status::OK || status == Status::UNSUPPORTED_OPERATION);
+ if (status == Status::OK) {
+ ASSERT_LT(static_cast<uint32_t>(0), lengthMs)
+ << "Effects that return OK must return a positive duration";
+ } else {
+ validatePerformEffectUnsupportedOperation(status, lengthMs);
+ }
+}
+
+/*
+ * Test to make sure effects within the valid range return are either supported and return OK with
+ * a valid duration, or are unsupported and return UNSUPPORTED_OPERATION with a duration of 0.
+ */
+TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3) {
+ for (const auto& effect : hidl_enum_range<Effect>()) {
+ for (const auto& strength : hidl_enum_range<EffectStrength>()) {
+ EXPECT_OK(vibrator->perform_1_3(effect, strength, validatePerformEffect));
+ }
+ }
+}
+
+/*
+ * Test to make sure effect values above the valid range are rejected.
+ */
+TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_AboveValidRange) {
+ Effect effect = *std::prev(hidl_enum_range<Effect>().end());
+ Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) + 1);
+ EXPECT_OK(vibrator->perform_1_3(badEffect, EffectStrength::LIGHT,
+ validatePerformEffectUnsupportedOperation));
+}
+
+/*
+ * Test to make sure effect values below the valid range are rejected.
+ */
+TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_BelowValidRange) {
+ Effect effect = *hidl_enum_range<Effect>().begin();
+ Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) - 1);
+ EXPECT_OK(vibrator->perform_1_3(badEffect, EffectStrength::LIGHT,
+ validatePerformEffectUnsupportedOperation));
+}
+
+/*
+ * Test to make sure strength values above the valid range are rejected.
+ */
+TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_AboveValidRange) {
+ EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
+ EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
+ EXPECT_OK(vibrator->perform_1_3(Effect::THUD, badStrength,
+ validatePerformEffectUnsupportedOperation));
+}
+
+/*
+ * Test to make sure strength values below the valid range are rejected.
+ */
+TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_BelowValidRange) {
+ EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
+ EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
+ EXPECT_OK(vibrator->perform_1_3(Effect::THUD, badStrength,
+ validatePerformEffectUnsupportedOperation));
+}
+
int main(int argc, char** argv) {
::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);