diff --git a/vibrator/1.0/Android.mk b/vibrator/1.0/Android.mk index 4e1ba6a623..d921a7e9e1 100644 --- a/vibrator/1.0/Android.mk +++ b/vibrator/1.0/Android.mk @@ -16,6 +16,25 @@ LOCAL_JAVA_LIBRARIES := \ android.hidl.base@1.0-java \ +# +# 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) # @@ -72,6 +91,25 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ android.hidl.base@1.0-java-static \ +# +# 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) # @@ -114,5 +152,39 @@ LOCAL_GENERATED_SOURCES += $(GEN) 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 0a4ffca969..757ad0d74f 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 @@ interface IVibrator { */ 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 8c82bcd5d6..19cf3dc850 100644 --- a/vibrator/1.0/default/Vibrator.cpp +++ b/vibrator/1.0/default/Vibrator.cpp @@ -16,6 +16,8 @@ #define LOG_TAG "VibratorService" +#include + #include #include @@ -36,7 +38,7 @@ Return Vibrator::on(uint32_t timeout_ms) { 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 @@ Return Vibrator::off() { 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 Vibrator::supportsAmplitudeControl() { + return false; +} + +Return Vibrator::setAmplitude(uint8_t) { + return Status::UNSUPPORTED_OPERATION; +} + +Return 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 061b36410e..bea6ea8f3a 100644 --- a/vibrator/1.0/default/Vibrator.h +++ b/vibrator/1.0/default/Vibrator.h @@ -26,23 +26,18 @@ namespace vibrator { 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 on(uint32_t timeoutMs) override; Return off() override; + Return supportsAmplitudeControl() override; + Return setAmplitude(uint8_t amplitude) override; + Return 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 8fc5683ddd..a080c07911 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 a978f2c3e0..f415ad5191 100644 --- a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp +++ b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp @@ -22,6 +22,8 @@ #include #include +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 @@ class VibratorHidlEnvironment : public ::testing::Environment { 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(0)); + } else { + ASSERT_EQ(lengthMs, static_cast(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);