Merge "Add amplitude control to vibrator HAL"
diff --git a/vibrator/1.0/Android.mk b/vibrator/1.0/Android.mk
index 4e1ba6a..d921a7e 100644
--- a/vibrator/1.0/Android.mk
+++ b/vibrator/1.0/Android.mk
@@ -17,6 +17,25 @@
#
+# Build types.hal (Effect)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Effect.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.vibrator@1.0::types.Effect
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (Status)
#
GEN := $(intermediates)/android/hardware/vibrator/V1_0/Status.java
@@ -73,6 +92,25 @@
#
+# Build types.hal (Effect)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Effect.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.vibrator@1.0::types.Effect
+
+$(GEN): $(LOCAL_PATH)/types.hal
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
# Build types.hal (Status)
#
GEN := $(intermediates)/android/hardware/vibrator/V1_0/Status.java
@@ -114,5 +152,39 @@
include $(BUILD_STATIC_JAVA_LIBRARY)
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.vibrator@1.0-java-constants
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Constants.java
+$(GEN): $(HIDL)
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/IVibrator.hal
+
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+ -Ljava-constants \
+ -randroid.hardware:hardware/interfaces \
+ -randroid.hidl:system/libhidl/transport \
+ android.hardware.vibrator@1.0
+
+$(GEN):
+ $(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+# Avoid dependency cycle of framework.jar -> this-library -> framework.jar
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-oj
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/vibrator/1.0/IVibrator.hal b/vibrator/1.0/IVibrator.hal
index 0a4ffca..757ad0d 100644
--- a/vibrator/1.0/IVibrator.hal
+++ b/vibrator/1.0/IVibrator.hal
@@ -17,7 +17,8 @@
package android.hardware.vibrator@1.0;
interface IVibrator {
- /** Turn on vibrator
+ /**
+ * Turn on vibrator
*
* This function must only be called after the previous timeout has expired or
* was canceled (through off()).
@@ -26,10 +27,46 @@
*/
on(uint32_t timeoutMs) generates (Status vibratorOnRet);
- /** Turn off vibrator
+ /**
+ * Turn off vibrator
*
* Cancel a previously-started vibration, if any.
* @return vibratorOffRet whether vibrator command was successful or not.
*/
off() generates (Status vibratorOffRet);
+
+ /**
+ * Returns whether the vibrator supports changes to its vibrational amplitude.
+ */
+ supportsAmplitudeControl() generates (bool supports);
+
+ /**
+ * Sets the motor's vibrational amplitude.
+ *
+ * Changes the force being produced by the underlying motor.
+ *
+ * @param amplitude The unitless force setting. Note that this number must
+ * be between 1 and 255, inclusive. If the motor does not
+ * have exactly 255 steps, it must do it's best to map it
+ * onto the number of steps it does have.
+ * @return status Whether the command was successful or not. Must return
+ * Status::UNSUPPORTED_OPERATION if setting the amplitude is
+ * not supported by the device.
+ */
+ setAmplitude(uint8_t amplitude) 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 is 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(Effect effect, EffectStrength strength) generates (Status status, uint32_t lengthMs);
};
diff --git a/vibrator/1.0/default/Vibrator.cpp b/vibrator/1.0/default/Vibrator.cpp
index 8c82bcd..19cf3dc 100644
--- a/vibrator/1.0/default/Vibrator.cpp
+++ b/vibrator/1.0/default/Vibrator.cpp
@@ -16,6 +16,8 @@
#define LOG_TAG "VibratorService"
+#include <inttypes.h>
+
#include <log/log.h>
#include <hardware/hardware.h>
@@ -36,7 +38,7 @@
int32_t ret = mDevice->vibrator_on(mDevice, timeout_ms);
if (ret != 0) {
ALOGE("on command failed : %s", strerror(-ret));
- return Status::ERR;
+ return Status::UNKNOWN_ERROR;
}
return Status::OK;
}
@@ -45,11 +47,24 @@
int32_t ret = mDevice->vibrator_off(mDevice);
if (ret != 0) {
ALOGE("off command failed : %s", strerror(-ret));
- return Status::ERR;
+ return Status::UNKNOWN_ERROR;
}
return Status::OK;
}
+Return<bool> Vibrator::supportsAmplitudeControl() {
+ return false;
+}
+
+Return<Status> Vibrator::setAmplitude(uint8_t) {
+ return Status::UNSUPPORTED_OPERATION;
+}
+
+Return<void> Vibrator::perform(Effect, EffectStrength, perform_cb _hidl_cb) {
+ _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
+ return Void();
+}
+
IVibrator* HIDL_FETCH_IVibrator(const char * /*hal*/) {
vibrator_device_t *vib_device;
const hw_module_t *hw_module = nullptr;
diff --git a/vibrator/1.0/default/Vibrator.h b/vibrator/1.0/default/Vibrator.h
index 061b364..bea6ea8 100644
--- a/vibrator/1.0/default/Vibrator.h
+++ b/vibrator/1.0/default/Vibrator.h
@@ -26,23 +26,18 @@
namespace V1_0 {
namespace implementation {
-using ::android::hardware::vibrator::V1_0::IVibrator;
-using ::android::hardware::vibrator::V1_0::Status;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
struct Vibrator : public IVibrator {
Vibrator(vibrator_device_t *device);
// Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
Return<Status> on(uint32_t timeoutMs) override;
Return<Status> off() override;
+ Return<bool> supportsAmplitudeControl() override;
+ Return<Status> setAmplitude(uint8_t amplitude) override;
+ Return<void> perform(Effect effect, EffectStrength strength, perform_cb _hidl_cb) override;
- private:
- vibrator_device_t *mDevice;
+private:
+ vibrator_device_t *mDevice;
};
extern "C" IVibrator* HIDL_FETCH_IVibrator(const char* name);
diff --git a/vibrator/1.0/types.hal b/vibrator/1.0/types.hal
index 8fc5683..a080c07 100644
--- a/vibrator/1.0/types.hal
+++ b/vibrator/1.0/types.hal
@@ -16,7 +16,33 @@
package android.hardware.vibrator@1.0;
-enum Status: uint32_t {
- OK = 0,
- ERR = 1
+enum Status : uint32_t {
+ OK,
+ UNKNOWN_ERROR,
+ BAD_VALUE,
+ UNSUPPORTED_OPERATION
+};
+
+@export
+enum Effect : uint32_t {
+ /**
+ * A single click effect.
+ *
+ * This effect should produce a sharp, crisp click sensation.
+ */
+ CLICK,
+ /**
+ * A double click effect.
+ *
+ * This effect should produce two sequential sharp, crisp click sensations with a minimal
+ * amount of time between them.
+ */
+ DOUBLE_CLICK
+};
+
+@export
+enum EffectStrength : uint8_t {
+ LIGHT,
+ MEDIUM,
+ STRONG
};
diff --git a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
index a978f2c..f415ad5 100644
--- a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
+++ b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
@@ -22,6 +22,8 @@
#include <VtsHalHidlTargetTestBase.h>
#include <unistd.h>
+using ::android::hardware::vibrator::V1_0::Effect;
+using ::android::hardware::vibrator::V1_0::EffectStrength;
using ::android::hardware::vibrator::V1_0::IVibrator;
using ::android::hardware::vibrator::V1_0::Status;
using ::android::hardware::Return;
@@ -50,12 +52,49 @@
private:
};
+static void validatePerformEffect(Status status, uint32_t lengthMs) {
+ ASSERT_TRUE(status == Status::OK || status == Status::UNSUPPORTED_OPERATION);
+ if (status == Status::OK) {
+ ASSERT_GT(lengthMs, static_cast<uint32_t>(0));
+ } else {
+ ASSERT_EQ(lengthMs, static_cast<uint32_t>(0));
+ }
+}
+
TEST_F(VibratorHidlTest, OnThenOffBeforeTimeout) {
EXPECT_EQ(Status::OK, vibrator->on(2000));
sleep(1);
EXPECT_EQ(Status::OK, vibrator->off());
}
+TEST_F(VibratorHidlTest, PerformEffect) {
+ vibrator->perform(Effect::CLICK, EffectStrength::MEDIUM, validatePerformEffect);
+ vibrator->perform(Effect::DOUBLE_CLICK, EffectStrength::LIGHT, validatePerformEffect);
+}
+
+TEST_F(VibratorHidlTest, ChangeVibrationalAmplitude) {
+ if (vibrator->supportsAmplitudeControl()) {
+ EXPECT_EQ(Status::OK, vibrator->setAmplitude(1));
+ EXPECT_EQ(Status::OK, vibrator->on(2000));
+ EXPECT_EQ(Status::OK, vibrator->setAmplitude(128));
+ sleep(1);
+ EXPECT_EQ(Status::OK, vibrator->setAmplitude(255));
+ sleep(1);
+ }
+}
+
+TEST_F(VibratorHidlTest, AmplitudeOutsideRangeFails) {
+ if (vibrator->supportsAmplitudeControl()) {
+ EXPECT_EQ(Status::BAD_VALUE, vibrator->setAmplitude(0));
+ }
+}
+
+TEST_F(VibratorHidlTest, SetAmplitudeReturnUnsupportedOperationIfNotSupported) {
+ if (!vibrator->supportsAmplitudeControl()) {
+ EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setAmplitude(1));
+ }
+}
+
int main(int argc, char **argv) {
::testing::AddGlobalTestEnvironment(new VibratorHidlEnvironment);
::testing::InitGoogleTest(&argc, argv);