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

Commit cfd81154 authored by Lais Andrade's avatar Lais Andrade
Browse files

Add reconnect method to vibrator HalWrapper

This will allow us to keep the wrapper when the vibrator HAL service
becomes unavailable (and also keep cached capabilities that won't change
for a device). This also makes the connect code in HalController
simpler, since it doesn't need to keep as many boolean flags to avoid
trying to reconnect to unavailable HAL versions.

Bug: b/153418251
Test: atest libvibratorservice_test
Change-Id: Ied50dd85a5fbba33d6bc58f73e626bb6df37b362
parent c6a2f3a4
Loading
Loading
Loading
Loading
+46 −58
Original line number Original line Diff line number Diff line
@@ -47,117 +47,105 @@ namespace vibrator {


static constexpr int MAX_RETRIES = 1;
static constexpr int MAX_RETRIES = 1;


template <typename T>
std::shared_ptr<HalWrapper> HalConnector::connect(std::shared_ptr<CallbackScheduler> scheduler) {
using hal_connect_fn = std::function<sp<T>()>;

template <typename T>
sp<T> connectToHal(bool* halExists, const hal_connect_fn<T>& connectFn, const char* halName) {
    if (!*halExists) {
        return nullptr;
    }
    sp<T> hal = connectFn();
    if (hal) {
        ALOGV("Successfully connected to Vibrator HAL %s service.", halName);
    } else {
        ALOGV("Vibrator HAL %s service not available.", halName);
        *halExists = false;
    }
    return hal;
}

sp<Aidl::IVibrator> connectToAidl() {
    static bool gHalExists = true;
    static hal_connect_fn<Aidl::IVibrator> connectFn = []() {
        return waitForVintfService<Aidl::IVibrator>();
    };
    return connectToHal(&gHalExists, connectFn, "AIDL");
}

sp<V1_0::IVibrator> connectToHidl() {
    static bool gHalExists = true;
    static bool gHalExists = true;
    static hal_connect_fn<V1_0::IVibrator> connectFn = []() {
    if (!gHalExists) {
        return V1_0::IVibrator::getService();
        // We already tried to connect to all of the vibrator HAL versions and none was available.
    };
        return nullptr;
    return connectToHal(&gHalExists, connectFn, "v1.0");
    }
    }


// -------------------------------------------------------------------------------------------------
    sp<Aidl::IVibrator> aidlHal = waitForVintfService<Aidl::IVibrator>();

std::shared_ptr<HalWrapper> HalConnector::connect(std::shared_ptr<CallbackScheduler> scheduler) {
    sp<Aidl::IVibrator> aidlHal = connectToAidl();
    if (aidlHal) {
    if (aidlHal) {
        ALOGV("Successfully connected to Vibrator HAL AIDL service.");
        return std::make_shared<AidlHalWrapper>(std::move(scheduler), aidlHal);
        return std::make_shared<AidlHalWrapper>(std::move(scheduler), aidlHal);
    }
    }
    sp<V1_0::IVibrator> halV1_0 = connectToHidl();

    sp<V1_0::IVibrator> halV1_0 = V1_0::IVibrator::getService();
    if (halV1_0 == nullptr) {
    if (halV1_0 == nullptr) {
        // No Vibrator HAL service available.
        ALOGV("Vibrator HAL service not available.");
        gHalExists = false;
        return nullptr;
        return nullptr;
    }
    }

    sp<V1_3::IVibrator> halV1_3 = V1_3::IVibrator::castFrom(halV1_0);
    sp<V1_3::IVibrator> halV1_3 = V1_3::IVibrator::castFrom(halV1_0);
    if (halV1_3) {
    if (halV1_3) {
        ALOGV("Successfully converted to Vibrator HAL v1.3 service.");
        ALOGV("Successfully connected to Vibrator HAL v1.3 service.");
        return std::make_shared<HidlHalWrapperV1_3>(std::move(scheduler), halV1_3);
        return std::make_shared<HidlHalWrapperV1_3>(std::move(scheduler), halV1_3);
    }
    }
    sp<V1_2::IVibrator> halV1_2 = V1_2::IVibrator::castFrom(halV1_0);
    sp<V1_2::IVibrator> halV1_2 = V1_2::IVibrator::castFrom(halV1_0);
    if (halV1_2) {
    if (halV1_2) {
        ALOGV("Successfully converted to Vibrator HAL v1.2 service.");
        ALOGV("Successfully connected to Vibrator HAL v1.2 service.");
        return std::make_shared<HidlHalWrapperV1_2>(std::move(scheduler), halV1_2);
        return std::make_shared<HidlHalWrapperV1_2>(std::move(scheduler), halV1_2);
    }
    }
    sp<V1_1::IVibrator> halV1_1 = V1_1::IVibrator::castFrom(halV1_0);
    sp<V1_1::IVibrator> halV1_1 = V1_1::IVibrator::castFrom(halV1_0);
    if (halV1_1) {
    if (halV1_1) {
        ALOGV("Successfully converted to Vibrator HAL v1.1 service.");
        ALOGV("Successfully connected to Vibrator HAL v1.1 service.");
        return std::make_shared<HidlHalWrapperV1_1>(std::move(scheduler), halV1_1);
        return std::make_shared<HidlHalWrapperV1_1>(std::move(scheduler), halV1_1);
    }
    }
    ALOGV("Successfully connected to Vibrator HAL v1.0 service.");
    return std::make_shared<HidlHalWrapperV1_0>(std::move(scheduler), halV1_0);
    return std::make_shared<HidlHalWrapperV1_0>(std::move(scheduler), halV1_0);
}
}


// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------


std::shared_ptr<HalWrapper> HalController::initHal() {
    std::lock_guard<std::mutex> lock(mConnectedHalMutex);
    if (mConnectedHal == nullptr) {
        mConnectedHal = mHalConnector->connect(mCallbackScheduler);
    }
    return mConnectedHal;
}

template <typename T>
template <typename T>
HalResult<T> HalController::processHalResult(HalResult<T> result, const char* functionName) {
HalResult<T> HalController::processHalResult(HalResult<T> result, const char* functionName) {
    if (result.isFailed()) {
    if (result.isFailed()) {
        ALOGE("%s failed: Vibrator HAL not available", functionName);
        ALOGE("%s failed: Vibrator HAL not available", functionName);
        std::lock_guard<std::mutex> lock(mConnectedHalMutex);
        std::lock_guard<std::mutex> lock(mConnectedHalMutex);
        // Drop HAL handle. This will force future api calls to reconnect.
        mConnectedHal->tryReconnect();
        mConnectedHal = nullptr;
    }
    }
    return result;
    return result;
}
}


template <typename T>
template <typename T>
HalResult<T> HalController::apply(HalController::hal_fn<T>& halFn, const char* functionName) {
HalResult<T> HalController::apply(HalController::hal_fn<T>& halFn, const char* functionName) {
    std::shared_ptr<HalWrapper> hal = initHal();
    std::shared_ptr<HalWrapper> hal = nullptr;
    if (hal == nullptr) {
    {
        std::lock_guard<std::mutex> lock(mConnectedHalMutex);
        if (mConnectedHal == nullptr) {
            // Init was never called, so connect to HAL for the first time during this call.
            mConnectedHal = mHalConnector->connect(mCallbackScheduler);

            if (mConnectedHal == nullptr) {
                ALOGV("Skipped %s because Vibrator HAL is not available", functionName);
                ALOGV("Skipped %s because Vibrator HAL is not available", functionName);
                return HalResult<T>::unsupported();
                return HalResult<T>::unsupported();
            }
            }
        }
        hal = mConnectedHal;
    }


    HalResult<T> ret = processHalResult(halFn(hal), functionName);
    HalResult<T> ret = processHalResult(halFn(hal), functionName);
    for (int i = 0; i < MAX_RETRIES && ret.isFailed(); i++) {
    for (int i = 0; i < MAX_RETRIES && ret.isFailed(); i++) {
        hal = initHal();
        if (hal) {
        ret = processHalResult(halFn(hal), functionName);
        ret = processHalResult(halFn(hal), functionName);
    }
    }
    }


    return ret;
    return ret;
}
}


// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------


void HalController::init() {
    std::lock_guard<std::mutex> lock(mConnectedHalMutex);
    if (mConnectedHal == nullptr) {
        mConnectedHal = mHalConnector->connect(mCallbackScheduler);
    }
}

HalResult<void> HalController::ping() {
HalResult<void> HalController::ping() {
    hal_fn<void> pingFn = [](std::shared_ptr<HalWrapper> hal) { return hal->ping(); };
    hal_fn<void> pingFn = [](std::shared_ptr<HalWrapper> hal) { return hal->ping(); };
    return apply(pingFn, "ping");
    return apply(pingFn, "ping");
}
}


void HalController::tryReconnect() {
    std::lock_guard<std::mutex> lock(mConnectedHalMutex);
    if (mConnectedHal == nullptr) {
        mConnectedHal = mHalConnector->connect(mCallbackScheduler);
    } else {
        mConnectedHal->tryReconnect();
    }
}

HalResult<void> HalController::on(milliseconds timeout,
HalResult<void> HalController::on(milliseconds timeout,
                                  const std::function<void()>& completionCallback) {
                                  const std::function<void()>& completionCallback) {
    hal_fn<void> onFn = [&](std::shared_ptr<HalWrapper> hal) {
    hal_fn<void> onFn = [&](std::shared_ptr<HalWrapper> hal) {
+118 −86
Original line number Original line Diff line number Diff line
@@ -149,10 +149,18 @@ private:
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------


HalResult<void> AidlHalWrapper::ping() {
HalResult<void> AidlHalWrapper::ping() {
    return IInterface::asBinder(mHandle)->pingBinder() ? HalResult<void>::ok()
    return IInterface::asBinder(getHal())->pingBinder() ? HalResult<void>::ok()
                                                        : HalResult<void>::failed();
                                                        : HalResult<void>::failed();
}
}


void AidlHalWrapper::tryReconnect() {
    sp<Aidl::IVibrator> newHandle = checkVintfService<Aidl::IVibrator>();
    if (newHandle) {
        std::lock_guard<std::mutex> lock(mHandleMutex);
        mHandle = std::move(newHandle);
    }
}

HalResult<void> AidlHalWrapper::on(milliseconds timeout,
HalResult<void> AidlHalWrapper::on(milliseconds timeout,
                                   const std::function<void()>& completionCallback) {
                                   const std::function<void()>& completionCallback) {
    HalResult<Capabilities> capabilities = getCapabilities();
    HalResult<Capabilities> capabilities = getCapabilities();
@@ -160,7 +168,7 @@ HalResult<void> AidlHalWrapper::on(milliseconds timeout,
            static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
            static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
    auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
    auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;


    auto ret = HalResult<void>::fromStatus(mHandle->on(timeout.count(), cb));
    auto ret = HalResult<void>::fromStatus(getHal()->on(timeout.count(), cb));
    if (!supportsCallback && ret.isOk()) {
    if (!supportsCallback && ret.isOk()) {
        mCallbackScheduler->schedule(completionCallback, timeout);
        mCallbackScheduler->schedule(completionCallback, timeout);
    }
    }
@@ -169,24 +177,24 @@ HalResult<void> AidlHalWrapper::on(milliseconds timeout,
}
}


HalResult<void> AidlHalWrapper::off() {
HalResult<void> AidlHalWrapper::off() {
    return HalResult<void>::fromStatus(mHandle->off());
    return HalResult<void>::fromStatus(getHal()->off());
}
}


HalResult<void> AidlHalWrapper::setAmplitude(int32_t amplitude) {
HalResult<void> AidlHalWrapper::setAmplitude(int32_t amplitude) {
    float convertedAmplitude = static_cast<float>(amplitude) / std::numeric_limits<uint8_t>::max();
    float convertedAmplitude = static_cast<float>(amplitude) / std::numeric_limits<uint8_t>::max();
    return HalResult<void>::fromStatus(mHandle->setAmplitude(convertedAmplitude));
    return HalResult<void>::fromStatus(getHal()->setAmplitude(convertedAmplitude));
}
}


HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
HalResult<void> AidlHalWrapper::setExternalControl(bool enabled) {
    return HalResult<void>::fromStatus(mHandle->setExternalControl(enabled));
    return HalResult<void>::fromStatus(getHal()->setExternalControl(enabled));
}
}


HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
HalResult<void> AidlHalWrapper::alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) {
    return HalResult<void>::fromStatus(mHandle->alwaysOnEnable(id, effect, strength));
    return HalResult<void>::fromStatus(getHal()->alwaysOnEnable(id, effect, strength));
}
}


HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
HalResult<void> AidlHalWrapper::alwaysOnDisable(int32_t id) {
    return HalResult<void>::fromStatus(mHandle->alwaysOnDisable(id));
    return HalResult<void>::fromStatus(getHal()->alwaysOnDisable(id));
}
}


HalResult<Capabilities> AidlHalWrapper::getCapabilities() {
HalResult<Capabilities> AidlHalWrapper::getCapabilities() {
@@ -210,7 +218,7 @@ HalResult<milliseconds> AidlHalWrapper::performEffect(
    auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
    auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;


    int32_t lengthMs;
    int32_t lengthMs;
    auto result = mHandle->perform(effect, strength, cb, &lengthMs);
    auto result = getHal()->perform(effect, strength, cb, &lengthMs);
    milliseconds length = milliseconds(lengthMs);
    milliseconds length = milliseconds(lengthMs);


    auto ret = HalResult<milliseconds>::fromStatus(result, length);
    auto ret = HalResult<milliseconds>::fromStatus(result, length);
@@ -226,31 +234,47 @@ HalResult<void> AidlHalWrapper::performComposedEffect(
        const std::function<void()>& completionCallback) {
        const std::function<void()>& completionCallback) {
    // This method should always support callbacks, so no need to double check.
    // This method should always support callbacks, so no need to double check.
    auto cb = new HalCallbackWrapper(completionCallback);
    auto cb = new HalCallbackWrapper(completionCallback);
    return HalResult<void>::fromStatus(mHandle->compose(primitiveEffects, cb));
    return HalResult<void>::fromStatus(getHal()->compose(primitiveEffects, cb));
}
}


HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
    int32_t capabilities = 0;
    int32_t capabilities = 0;
    auto result = mHandle->getCapabilities(&capabilities);
    auto result = getHal()->getCapabilities(&capabilities);
    return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
    return HalResult<Capabilities>::fromStatus(result, static_cast<Capabilities>(capabilities));
}
}


HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
    std::vector<Effect> supportedEffects;
    std::vector<Effect> supportedEffects;
    auto result = mHandle->getSupportedEffects(&supportedEffects);
    auto result = getHal()->getSupportedEffects(&supportedEffects);
    return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
    return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
}
}


sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
    std::lock_guard<std::mutex> lock(mHandleMutex);
    return mHandle;
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------


HalResult<void> HidlHalWrapperV1_0::ping() {
template <typename I>
    auto result = mHandleV1_0->ping();
HalResult<void> HidlHalWrapper<I>::ping() {
    auto result = getHal()->ping();
    return HalResult<void>::fromReturn(result);
    return HalResult<void>::fromReturn(result);
}
}


HalResult<void> HidlHalWrapperV1_0::on(milliseconds timeout,
template <typename I>
void HidlHalWrapper<I>::tryReconnect() {
    sp<I> newHandle = I::tryGetService();
    if (newHandle) {
        std::lock_guard<std::mutex> lock(mHandleMutex);
        mHandle = std::move(newHandle);
    }
}

template <typename I>
HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
                                      const std::function<void()>& completionCallback) {
                                      const std::function<void()>& completionCallback) {
    auto result = mHandleV1_0->on(timeout.count());
    auto result = getHal()->on(timeout.count());
    auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
    auto ret = HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
    if (ret.isOk()) {
    if (ret.isOk()) {
        mCallbackScheduler->schedule(completionCallback, timeout);
        mCallbackScheduler->schedule(completionCallback, timeout);
@@ -258,69 +282,68 @@ HalResult<void> HidlHalWrapperV1_0::on(milliseconds timeout,
    return ret;
    return ret;
}
}


HalResult<void> HidlHalWrapperV1_0::off() {
template <typename I>
    auto result = mHandleV1_0->off();
HalResult<void> HidlHalWrapper<I>::off() {
    auto result = getHal()->off();
    return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
    return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
}
}


HalResult<void> HidlHalWrapperV1_0::setAmplitude(int32_t amplitude) {
template <typename I>
    auto result = mHandleV1_0->setAmplitude(static_cast<uint8_t>(amplitude));
HalResult<void> HidlHalWrapper<I>::setAmplitude(int32_t amplitude) {
    auto result = getHal()->setAmplitude(static_cast<uint8_t>(amplitude));
    return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
    return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
}
}


HalResult<void> HidlHalWrapperV1_0::setExternalControl(bool) {
template <typename I>
HalResult<void> HidlHalWrapper<I>::setExternalControl(bool) {
    ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
    ALOGV("Skipped setExternalControl because Vibrator HAL does not support it");
    return HalResult<void>::unsupported();
    return HalResult<void>::unsupported();
}
}


HalResult<void> HidlHalWrapperV1_0::alwaysOnEnable(int32_t, Effect, EffectStrength) {
template <typename I>
HalResult<void> HidlHalWrapper<I>::alwaysOnEnable(int32_t, Effect, EffectStrength) {
    ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
    ALOGV("Skipped alwaysOnEnable because Vibrator HAL AIDL is not available");
    return HalResult<void>::unsupported();
    return HalResult<void>::unsupported();
}
}


HalResult<void> HidlHalWrapperV1_0::alwaysOnDisable(int32_t) {
template <typename I>
HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) {
    ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
    ALOGV("Skipped alwaysOnDisable because Vibrator HAL AIDL is not available");
    return HalResult<void>::unsupported();
    return HalResult<void>::unsupported();
}
}


HalResult<Capabilities> HidlHalWrapperV1_0::getCapabilities() {
template <typename I>
HalResult<Capabilities> HidlHalWrapper<I>::getCapabilities() {
    std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
    std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
    return loadCached<Capabilities>(std::bind(&HidlHalWrapperV1_0::getCapabilitiesInternal, this),
    return loadCached<Capabilities>(std::bind(&HidlHalWrapper<I>::getCapabilitiesInternal, this),
                                    mCapabilities);
                                    mCapabilities);
}
}


HalResult<std::vector<Effect>> HidlHalWrapperV1_0::getSupportedEffects() {
template <typename I>
HalResult<std::vector<Effect>> HidlHalWrapper<I>::getSupportedEffects() {
    ALOGV("Skipped getSupportedEffects because Vibrator HAL AIDL is not available");
    ALOGV("Skipped getSupportedEffects because Vibrator HAL AIDL is not available");
    return HalResult<std::vector<Effect>>::unsupported();
    return HalResult<std::vector<Effect>>::unsupported();
}
}


HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
template <typename I>
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
HalResult<void> HidlHalWrapper<I>::performComposedEffect(const std::vector<CompositeEffect>&,
    if (isStaticCastValid<V1_0::Effect>(effect)) {
        return performInternalV1_0(effect, strength, completionCallback);
    }

    ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
          Aidl::toString(effect).c_str());
    return HalResult<milliseconds>::unsupported();
}

HalResult<void> HidlHalWrapperV1_0::performComposedEffect(const std::vector<CompositeEffect>&,
                                                         const std::function<void()>&) {
                                                         const std::function<void()>&) {
    ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available");
    ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available");
    return HalResult<void>::unsupported();
    return HalResult<void>::unsupported();
}
}


HalResult<Capabilities> HidlHalWrapperV1_0::getCapabilitiesInternal() {
template <typename I>
    hardware::Return<bool> result = mHandleV1_0->supportsAmplitudeControl();
HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
    hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
    Capabilities capabilities =
    Capabilities capabilities =
            result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
            result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
    return HalResult<Capabilities>::fromReturn(result, capabilities);
    return HalResult<Capabilities>::fromReturn(result, capabilities);
}
}


template <class I, class T>
template <typename I>
HalResult<milliseconds> HidlHalWrapperV1_0::performInternal(
template <typename T>
        perform_fn<I, T> performFn, sp<I> handle, T effect, EffectStrength strength,
HalResult<milliseconds> HidlHalWrapper<I>::performInternal(
        perform_fn<T> performFn, sp<I> handle, T effect, EffectStrength strength,
        const std::function<void()>& completionCallback) {
        const std::function<void()>& completionCallback) {
    V1_0::Status status;
    V1_0::Status status;
    int32_t lengthMs;
    int32_t lengthMs;
@@ -341,10 +364,24 @@ HalResult<milliseconds> HidlHalWrapperV1_0::performInternal(
    return ret;
    return ret;
}
}


HalResult<milliseconds> HidlHalWrapperV1_0::performInternalV1_0(
template <typename I>
sp<I> HidlHalWrapper<I>::getHal() {
    std::lock_guard<std::mutex> lock(mHandleMutex);
    return mHandle;
}

// -------------------------------------------------------------------------------------------------

HalResult<milliseconds> HidlHalWrapperV1_0::performEffect(
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
    V1_0::Effect e = static_cast<V1_0::Effect>(effect);
    if (isStaticCastValid<V1_0::Effect>(effect)) {
    return performInternal(&V1_0::IVibrator::perform, mHandleV1_0, e, strength, completionCallback);
        return performInternal(&V1_0::IVibrator::perform, getHal(),
                               static_cast<V1_0::Effect>(effect), strength, completionCallback);
    }

    ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
          Aidl::toString(effect).c_str());
    return HalResult<milliseconds>::unsupported();
}
}


// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
@@ -352,10 +389,12 @@ HalResult<milliseconds> HidlHalWrapperV1_0::performInternalV1_0(
HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
    if (isStaticCastValid<V1_0::Effect>(effect)) {
    if (isStaticCastValid<V1_0::Effect>(effect)) {
        return performInternalV1_0(effect, strength, completionCallback);
        return performInternal(&V1_1::IVibrator::perform, getHal(),
                               static_cast<V1_0::Effect>(effect), strength, completionCallback);
    }
    }
    if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
    if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
        return performInternalV1_1(effect, strength, completionCallback);
        return performInternal(&V1_1::IVibrator::perform_1_1, getHal(),
                               static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
    }
    }


    ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
    ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
@@ -363,25 +402,21 @@ HalResult<milliseconds> HidlHalWrapperV1_1::performEffect(
    return HalResult<milliseconds>::unsupported();
    return HalResult<milliseconds>::unsupported();
}
}


HalResult<milliseconds> HidlHalWrapperV1_1::performInternalV1_1(
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
    V1_1::Effect_1_1 e = static_cast<V1_1::Effect_1_1>(effect);
    return performInternal(&V1_1::IVibrator::perform_1_1, mHandleV1_1, e, strength,
                           completionCallback);
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------


HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
    if (isStaticCastValid<V1_0::Effect>(effect)) {
    if (isStaticCastValid<V1_0::Effect>(effect)) {
        return performInternalV1_0(effect, strength, completionCallback);
        return performInternal(&V1_2::IVibrator::perform, getHal(),
                               static_cast<V1_0::Effect>(effect), strength, completionCallback);
    }
    }
    if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
    if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
        return performInternalV1_1(effect, strength, completionCallback);
        return performInternal(&V1_2::IVibrator::perform_1_1, getHal(),
                               static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
    }
    }
    if (isStaticCastValid<V1_2::Effect>(effect)) {
    if (isStaticCastValid<V1_2::Effect>(effect)) {
        return performInternalV1_2(effect, strength, completionCallback);
        return performInternal(&V1_2::IVibrator::perform_1_2, getHal(),
                               static_cast<V1_2::Effect>(effect), strength, completionCallback);
    }
    }


    ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
    ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
@@ -389,33 +424,30 @@ HalResult<milliseconds> HidlHalWrapperV1_2::performEffect(
    return HalResult<milliseconds>::unsupported();
    return HalResult<milliseconds>::unsupported();
}
}


HalResult<milliseconds> HidlHalWrapperV1_2::performInternalV1_2(
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
    V1_2::Effect e = static_cast<V1_2::Effect>(effect);
    return performInternal(&V1_2::IVibrator::perform_1_2, mHandleV1_2, e, strength,
                           completionCallback);
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------


HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
HalResult<void> HidlHalWrapperV1_3::setExternalControl(bool enabled) {
    auto result = mHandleV1_3->setExternalControl(static_cast<uint32_t>(enabled));
    auto result = getHal()->setExternalControl(static_cast<uint32_t>(enabled));
    return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
    return HalResult<void>::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
}
}


HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
    if (isStaticCastValid<V1_0::Effect>(effect)) {
    if (isStaticCastValid<V1_0::Effect>(effect)) {
        return performInternalV1_0(effect, strength, completionCallback);
        return performInternal(&V1_3::IVibrator::perform, getHal(),
                               static_cast<V1_0::Effect>(effect), strength, completionCallback);
    }
    }
    if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
    if (isStaticCastValid<V1_1::Effect_1_1>(effect)) {
        return performInternalV1_1(effect, strength, completionCallback);
        return performInternal(&V1_3::IVibrator::perform_1_1, getHal(),
                               static_cast<V1_1::Effect_1_1>(effect), strength, completionCallback);
    }
    }
    if (isStaticCastValid<V1_2::Effect>(effect)) {
    if (isStaticCastValid<V1_2::Effect>(effect)) {
        return performInternalV1_2(effect, strength, completionCallback);
        return performInternal(&V1_3::IVibrator::perform_1_2, getHal(),
                               static_cast<V1_2::Effect>(effect), strength, completionCallback);
    }
    }
    if (isStaticCastValid<V1_3::Effect>(effect)) {
    if (isStaticCastValid<V1_3::Effect>(effect)) {
        return performInternalV1_3(effect, strength, completionCallback);
        return performInternal(&V1_3::IVibrator::perform_1_3, getHal(),
                               static_cast<V1_3::Effect>(effect), strength, completionCallback);
    }
    }


    ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
    ALOGV("Skipped performEffect because Vibrator HAL does not support effect %s",
@@ -424,23 +456,23 @@ HalResult<milliseconds> HidlHalWrapperV1_3::performEffect(
}
}


HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
HalResult<Capabilities> HidlHalWrapperV1_3::getCapabilitiesInternal() {
    HalResult<Capabilities> parentResult = HidlHalWrapperV1_2::getCapabilitiesInternal();
    sp<V1_3::IVibrator> hal = getHal();
    if (!parentResult.isOk()) {
    auto amplitudeResult = hal->supportsAmplitudeControl();
        // Loading for previous HAL versions already failed, so propagate failure.
    if (!amplitudeResult.isOk()) {
        return parentResult;
        return HalResult<Capabilities>::failed();
    }
    }


    Capabilities capabilities = parentResult.value();
    auto externalControlResult = hal->supportsExternalControl();
    auto result = mHandleV1_3->supportsExternalControl();
    Capabilities capabilities = Capabilities::NONE;
    capabilities |= result.withDefault(false) ? Capabilities::EXTERNAL_CONTROL : Capabilities::NONE;

    return HalResult<Capabilities>::fromReturn(result, capabilities);
    if (amplitudeResult.withDefault(false)) {
        capabilities |= Capabilities::AMPLITUDE_CONTROL;
    }
    if (externalControlResult.withDefault(false)) {
        capabilities |= Capabilities::EXTERNAL_CONTROL;
    }
    }


HalResult<milliseconds> HidlHalWrapperV1_3::performInternalV1_3(
    return HalResult<Capabilities>::fromReturn(externalControlResult, capabilities);
        Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) {
    V1_3::Effect e = static_cast<V1_3::Effect>(effect);
    return performInternal(&V1_3::IVibrator::perform_1_3, mHandleV1_3, e, strength,
                           completionCallback);
}
}


// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
+3 −2
Original line number Original line Diff line number Diff line
@@ -51,7 +51,10 @@ public:
            mConnectedHal(nullptr) {}
            mConnectedHal(nullptr) {}
    virtual ~HalController() = default;
    virtual ~HalController() = default;


    void init();

    HalResult<void> ping() final override;
    HalResult<void> ping() final override;
    void tryReconnect() final override;


    HalResult<void> on(std::chrono::milliseconds timeout,
    HalResult<void> on(std::chrono::milliseconds timeout,
                       const std::function<void()>& completionCallback) final override;
                       const std::function<void()>& completionCallback) final override;
@@ -81,8 +84,6 @@ private:
    // Shared pointer to allow local copies to be used by different threads.
    // Shared pointer to allow local copies to be used by different threads.
    std::shared_ptr<HalWrapper> mConnectedHal GUARDED_BY(mConnectedHalMutex);
    std::shared_ptr<HalWrapper> mConnectedHal GUARDED_BY(mConnectedHalMutex);


    std::shared_ptr<HalWrapper> initHal();

    template <typename T>
    template <typename T>
    HalResult<T> processHalResult(HalResult<T> result, const char* functionName);
    HalResult<T> processHalResult(HalResult<T> result, const char* functionName);


+76 −77

File changed.

Preview size limit exceeded, changes collapsed.

+32 −14

File changed.

Preview size limit exceeded, changes collapsed.