Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 523e2960 authored by Harpreet \"Eli\" Sangha's avatar Harpreet \"Eli\" Sangha Committed by Harpreet "Eli" Sangha
Browse files

vibrator: Compose API Related Improvements



- Allow querying duration of each primitive.
- Allow querying of supported primitives.
- Enforce all-of-nothing requirement for supported primitives via VTS.
- Enforce callback support requirement via VTS.

Bug: 139762802
Bug: 147852209
Test: atest VtsHalVibratorTargetTest
Change-Id: I9009e38d446ed9ea38b3a9d6eb8dd55e6be2792f
Merged-In: I9009e38d446ed9ea38b3a9d6eb8dd55e6be2792f
Signed-off-by: default avatarHarpreet \"Eli\" Sangha <eliptus@google.com>
parent 80da44e9
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -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.
     */
+20 −0
Original line number Diff line number Diff line
@@ -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,
    };
    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) {
+3 −0
Original line number Diff line number Diff line
@@ -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;
+47 −0
Original line number Diff line number Diff line
@@ -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;