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

Commit 390e3363 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Vibrator Service: Allow HAL Version Checking"

parents 1b55ffcd e0b7951d
Loading
Loading
Loading
Loading
+45 −25
Original line number Diff line number Diff line
@@ -56,18 +56,19 @@ inline Return<R> NullptrStatus() {
    return Return<R>{Status::fromExceptionCode(Status::EX_NULL_POINTER)};
}

// Helper used to transparently deal with the vibrator HAL becoming unavailable.
template<class R, class I, class... Args0, class... Args1>
Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
template <typename I>
class HalWrapper {
  public:
    static std::unique_ptr<HalWrapper> Create() {
        // Assume that if getService returns a nullptr, HAL is not available on the
        // device.
    static sp<I> sHal = I::getService();
    static bool sAvailable = sHal != nullptr;

    if (!sAvailable) {
        return NullptrStatus<R>();
        auto hal = I::getService();
        return hal ? std::unique_ptr<HalWrapper>(new HalWrapper(std::move(hal))) : nullptr;
    }

    // Helper used to transparently deal with the vibrator HAL becoming unavailable.
    template<class R, class... Args0, class... Args1>
    Return<R> call(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
        // Return<R> doesn't have a default constructor, so make a Return<R> with
        // STATUS::EX_NONE.
        using ::android::hardware::Status;
@@ -75,8 +76,8 @@ Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {

        // Note that ret is guaranteed to be changed after this loop.
        for (int i = 0; i < NUM_TRIES; ++i) {
        ret = (sHal == nullptr) ? NullptrStatus<R>()
                : (*sHal.*fn)(std::forward<Args1>(args1)...);
            ret = (mHal == nullptr) ? NullptrStatus<R>()
                    : (*mHal.*fn)(std::forward<Args1>(args1)...);

            if (ret.isOk()) {
                break;
@@ -84,11 +85,30 @@ Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {

            ALOGE("Failed to issue command to vibrator HAL. Retrying.");
            // Restoring connection to the HAL.
        sHal = I::tryGetService();
            mHal = I::tryGetService();
        }
        return ret;
    }

  private:
    HalWrapper(sp<I> &&hal) : mHal(std::move(hal)) {}

  private:
    sp<I> mHal;
};

template <typename I>
static auto getHal() {
    static auto sHalWrapper = HalWrapper<I>::Create();
    return sHalWrapper.get();
}

template<class R, class I, class... Args0, class... Args1>
Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
    auto hal = getHal<I>();
    return hal ? hal->call(fn, std::forward<Args1>(args1)...) : NullptrStatus<R>();
}

template<class R>
bool isValidEffect(jlong effect) {
    if (effect < 0) {