Merge changes I208e5601,I9009e38d

* changes:
  vibrator: Add "Light Tick" Primitive
  vibrator: Compose API Related Improvements
This commit is contained in:
Treehugger Robot 2020-01-29 04:26:36 +00:00 committed by Gerrit Code Review
commit 9b295325ee
5 changed files with 96 additions and 2 deletions

View file

@ -49,4 +49,9 @@ enum CompositePrimitive {
* A haptic effect that simulates quick downwards movement with gravity.
*/
QUICK_FALL,
/**
* This very short effect should produce a light crisp sensation intended
* to be used repetitively for dynamic feedback.
*/
LIGHT_TICK,
}

View file

@ -157,13 +157,32 @@ interface IVibrator {
*/
int getCompositionSizeMax();
/**
* List of supported effect primitive.
*
* Return the effect primitives which are supported by the compose API.
* Implementations are expected to support all primitives of the interface
* version that they implement.
*/
CompositePrimitive[] getSupportedPrimitives();
/**
* Retrieve effect primitive's duration in milliseconds.
*
* Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
*
* @return Best effort estimation of effect primitive's duration.
* @param primitive Effect primitive being queried.
*/
int getPrimitiveDuration(CompositePrimitive primitive);
/**
* Fire off a string of effect primitives, combined to perform richer effects.
*
* Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
*
* Doing this operation while the vibrator is already on is undefined behavior. Clients should
* explicitly call off.
* explicitly call off. IVibratorCallback.onComplete() support is required for this API.
*
* @param composite Array of composition parameters.
*/

View file

@ -113,6 +113,26 @@ ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t* maxSize) {
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector<CompositePrimitive>* supported) {
*supported = {
CompositePrimitive::NOOP, CompositePrimitive::CLICK,
CompositePrimitive::THUD, CompositePrimitive::SPIN,
CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
CompositePrimitive::QUICK_FALL, CompositePrimitive::LIGHT_TICK,
};
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive primitive,
int32_t* durationMs) {
if (primitive != CompositePrimitive::NOOP) {
*durationMs = 100;
} else {
*durationMs = 0;
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composite,
const std::shared_ptr<IVibratorCallback>& callback) {
if (composite.size() > kComposeSizeMax) {
@ -127,7 +147,7 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composi
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
if (e.primitive < CompositePrimitive::NOOP ||
e.primitive > CompositePrimitive::QUICK_FALL) {
e.primitive > CompositePrimitive::LIGHT_TICK) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
}

View file

@ -36,6 +36,9 @@ class Vibrator : public BnVibrator {
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;

View file

@ -261,6 +261,29 @@ TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
}
}
TEST_P(VibratorAidl, GetSupportedPrimitives) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
std::vector<CompositePrimitive> supported;
EXPECT_EQ(Status::EX_NONE, vibrator->getSupportedPrimitives(&supported).exceptionCode());
std::sort(supported.begin(), supported.end());
EXPECT_EQ(kCompositePrimitives, supported);
}
}
TEST_P(VibratorAidl, GetPrimitiveDuration) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
int32_t duration;
for (auto primitive : kCompositePrimitives) {
EXPECT_EQ(Status::EX_NONE,
vibrator->getPrimitiveDuration(primitive, &duration).exceptionCode());
}
}
}
TEST_P(VibratorAidl, ComposeValidPrimitives) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
int32_t maxDelay, maxSize;
@ -357,6 +380,30 @@ TEST_P(VibratorAidl, CompseSizeBoundary) {
}
}
TEST_P(VibratorAidl, ComposeCallback) {
if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
std::promise<void> completionPromise;
std::future<void> completionFuture{completionPromise.get_future()};
sp<CompletionCallback> callback =
new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
CompositePrimitive primitive = CompositePrimitive::CLICK;
CompositeEffect effect;
std::vector<CompositeEffect> composite;
int32_t duration;
effect.delayMs = 0;
effect.primitive = primitive;
effect.scale = 1.0f;
composite.emplace_back(effect);
EXPECT_EQ(Status::EX_NONE,
vibrator->getPrimitiveDuration(primitive, &duration).exceptionCode());
EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode());
EXPECT_EQ(completionFuture.wait_for(std::chrono::milliseconds(duration * 2)),
std::future_status::ready);
}
}
TEST_P(VibratorAidl, AlwaysOn) {
if (capabilities & IVibrator::CAP_ALWAYS_ON_CONTROL) {
std::vector<Effect> supported;