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

Commit 9b295325 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I208e5601,I9009e38d

* changes:
  vibrator: Add "Light Tick" Primitive
  vibrator: Compose API Related Improvements
parents 8aa8655f fe5d3986
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -49,4 +49,9 @@ enum CompositePrimitive {
     * A haptic effect that simulates quick downwards movement with gravity.
     * A haptic effect that simulates quick downwards movement with gravity.
     */
     */
    QUICK_FALL,
    QUICK_FALL,
    /**
     * This very short effect should produce a light crisp sensation intended
     * to be used repetitively for dynamic feedback.
     */
    LIGHT_TICK,
}
}
+20 −1
Original line number Original line Diff line number Diff line
@@ -157,13 +157,32 @@ interface IVibrator {
     */
     */
    int getCompositionSizeMax();
    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.
     * Fire off a string of effect primitives, combined to perform richer effects.
     *
     *
     * Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
     * Support is reflected in getCapabilities (CAP_COMPOSE_EFFECTS).
     *
     *
     * Doing this operation while the vibrator is already on is undefined behavior. Clients should
     * 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.
     * @param composite Array of composition parameters.
     */
     */
+21 −1
Original line number Original line Diff line number Diff line
@@ -113,6 +113,26 @@ ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t* maxSize) {
    return ndk::ScopedAStatus::ok();
    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,
ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composite,
                                     const std::shared_ptr<IVibratorCallback>& callback) {
                                     const std::shared_ptr<IVibratorCallback>& callback) {
    if (composite.size() > kComposeSizeMax) {
    if (composite.size() > kComposeSizeMax) {
@@ -127,7 +147,7 @@ ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& composi
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
        }
        }
        if (e.primitive < CompositePrimitive::NOOP ||
        if (e.primitive < CompositePrimitive::NOOP ||
            e.primitive > CompositePrimitive::QUICK_FALL) {
            e.primitive > CompositePrimitive::LIGHT_TICK) {
            return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
            return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
        }
        }
    }
    }
+3 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,9 @@ class Vibrator : public BnVibrator {
    ndk::ScopedAStatus setExternalControl(bool enabled) override;
    ndk::ScopedAStatus setExternalControl(bool enabled) override;
    ndk::ScopedAStatus getCompositionDelayMax(int32_t* maxDelayMs);
    ndk::ScopedAStatus getCompositionDelayMax(int32_t* maxDelayMs);
    ndk::ScopedAStatus getCompositionSizeMax(int32_t* maxSize);
    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,
    ndk::ScopedAStatus compose(const std::vector<CompositeEffect>& composite,
                               const std::shared_ptr<IVibratorCallback>& callback) override;
                               const std::shared_ptr<IVibratorCallback>& callback) override;
    ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect>* _aidl_return) override;
    ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect>* _aidl_return) override;
+47 −0
Original line number Original line 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) {
TEST_P(VibratorAidl, ComposeValidPrimitives) {
    if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
    if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
        int32_t maxDelay, maxSize;
        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) {
TEST_P(VibratorAidl, AlwaysOn) {
    if (capabilities & IVibrator::CAP_ALWAYS_ON_CONTROL) {
    if (capabilities & IVibrator::CAP_ALWAYS_ON_CONTROL) {
        std::vector<Effect> supported;
        std::vector<Effect> supported;