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

Commit 58a0f5f1 authored by Lais Andrade's avatar Lais Andrade Committed by Android (Google) Code Review
Browse files

Merge "Add wrapper for IVibratorManager.aidl to native vibrator service"

parents 67fcdbb0 98c97036
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ cc_library_shared {
        "libhidlbase",
        "liblog",
        "libutils",
        "android.hardware.vibrator-cpp",
        "android.hardware.vibrator-unstable-cpp",
        "android.hardware.vibrator@1.0",
        "android.hardware.vibrator@1.1",
        "android.hardware.vibrator@1.2",
+5 −29
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
#define LOG_TAG "VibratorHalWrapper"

#include <android/hardware/vibrator/1.3/IVibrator.h>
#include <android/hardware/vibrator/BnVibratorCallback.h>
#include <android/hardware/vibrator/IVibrator.h>
#include <hardware/vibrator.h>

@@ -72,17 +71,6 @@ const constexpr char* STATUS_T_ERROR_MESSAGE_PREFIX = "status_t = ";
const constexpr char* STATUS_V_1_0_ERROR_MESSAGE_PREFIX =
        "android::hardware::vibrator::V1_0::Status = ";

template <typename T>
HalResult<T> HalResult<T>::fromStatus(binder::Status status, T data) {
    if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
        return HalResult<T>::unsupported();
    }
    if (status.isOk()) {
        return HalResult<T>::ok(data);
    }
    return HalResult<T>::failed(std::string(status.toString8().c_str()));
}

template <typename T>
HalResult<T> HalResult<T>::fromStatus(V1_0::Status status, T data) {
    switch (status) {
@@ -145,28 +133,16 @@ HalResult<void> HalResult<void>::fromReturn(hardware::Return<R>& ret) {

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

class HalCallbackWrapper : public Aidl::BnVibratorCallback {
public:
    HalCallbackWrapper(std::function<void()> completionCallback)
          : mCompletionCallback(completionCallback) {}

    binder::Status onComplete() override {
        mCompletionCallback();
        return binder::Status::ok();
    }

private:
    const std::function<void()> mCompletionCallback;
};

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

HalResult<void> AidlHalWrapper::ping() {
    return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
}

void AidlHalWrapper::tryReconnect() {
    sp<Aidl::IVibrator> newHandle = checkVintfService<Aidl::IVibrator>();
    auto result = mReconnectFn();
    if (!result.isOk()) {
        return;
    }
    sp<Aidl::IVibrator> newHandle = result.value();
    if (newHandle) {
        std::lock_guard<std::mutex> lock(mHandleMutex);
        mHandle = std::move(newHandle);
+137 −1
Original line number Diff line number Diff line
@@ -20,11 +20,14 @@

#include <vibratorservice/VibratorManagerHalWrapper.h>

namespace Aidl = android::hardware::vibrator;

namespace android {

namespace vibrator {

constexpr int32_t SINGLE_VIBRATOR_ID = 0;
const constexpr char* MISSING_VIBRATOR_MESSAGE_PREFIX = "No vibrator with id=";

HalResult<void> LegacyManagerHalWrapper::ping() {
    return mController->ping();
@@ -34,6 +37,10 @@ void LegacyManagerHalWrapper::tryReconnect() {
    mController->tryReconnect();
}

HalResult<ManagerCapabilities> LegacyManagerHalWrapper::getCapabilities() {
    return HalResult<ManagerCapabilities>::ok(ManagerCapabilities::NONE);
}

HalResult<std::vector<int32_t>> LegacyManagerHalWrapper::getVibratorIds() {
    if (mController->init()) {
        return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>(1, SINGLE_VIBRATOR_ID));
@@ -47,7 +54,7 @@ HalResult<std::shared_ptr<HalController>> LegacyManagerHalWrapper::getVibrator(i
        return HalResult<std::shared_ptr<HalController>>::ok(mController);
    }
    // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
    return HalResult<std::shared_ptr<HalController>>::failed("No vibrator with id = " +
    return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX +
                                                             std::to_string(id));
}

@@ -63,6 +70,135 @@ HalResult<void> LegacyManagerHalWrapper::cancelSynced() {
    return HalResult<void>::unsupported();
}

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

std::shared_ptr<HalWrapper> AidlManagerHalWrapper::ManagedHalConnector::connect(
        std::shared_ptr<CallbackScheduler> callbackScheduler) {
    std::function<HalResult<sp<Aidl::IVibrator>>()> reconnectFn = [&]() {
        sp<Aidl::IVibrator> vibrator;
        auto result = this->mManager->getHal()->getVibrator(this->mVibratorId, &vibrator);
        return HalResult<sp<Aidl::IVibrator>>::fromStatus(result, vibrator);
    };
    auto result = reconnectFn();
    if (!result.isOk()) {
        return nullptr;
    }
    auto vibrator = result.value();
    if (!vibrator) {
        return nullptr;
    }
    return std::move(std::make_unique<AidlHalWrapper>(std::move(callbackScheduler),
                                                      std::move(vibrator), reconnectFn));
}

HalResult<void> AidlManagerHalWrapper::ping() {
    return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
}

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

HalResult<ManagerCapabilities> AidlManagerHalWrapper::getCapabilities() {
    std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
    if (mCapabilities.has_value()) {
        // Return copy of cached value.
        return HalResult<ManagerCapabilities>::ok(*mCapabilities);
    }
    int32_t cap = 0;
    auto result = getHal()->getCapabilities(&cap);
    auto ret = HalResult<ManagerCapabilities>::fromStatus(result,
                                                          static_cast<ManagerCapabilities>(cap));
    if (ret.isOk()) {
        // Cache copy of returned value.
        mCapabilities.emplace(ret.value());
    }
    return ret;
}

HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() {
    std::lock_guard<std::mutex> lock(mVibratorsMutex);
    if (mVibratorIds.has_value()) {
        // Return copy of cached values.
        return HalResult<std::vector<int32_t>>::ok(*mVibratorIds);
    }
    std::vector<int32_t> ids;
    auto result = getHal()->getVibratorIds(&ids);
    auto ret = HalResult<std::vector<int32_t>>::fromStatus(result, ids);
    if (ret.isOk()) {
        // Cache copy of returned value and the individual controllers.
        mVibratorIds.emplace(ret.value());
        for (auto& id : ids) {
            auto connector = std::make_unique<ManagedHalConnector>(this, id);
            auto controller =
                    std::make_unique<HalController>(std::move(connector), mCallbackScheduler);
            mVibrators[id] = std::move(controller);
        }
    }
    return ret;
}

HalResult<std::shared_ptr<HalController>> AidlManagerHalWrapper::getVibrator(int32_t id) {
    // Make sure we cache vibrator ids and initialize the individual controllers.
    getVibratorIds();
    std::lock_guard<std::mutex> lock(mVibratorsMutex);
    auto it = mVibrators.find(id);
    if (it != mVibrators.end()) {
        return HalResult<std::shared_ptr<HalController>>::ok(it->second);
    }
    return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX +
                                                             std::to_string(id));
}

HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) {
    auto ret = HalResult<void>::fromStatus(getHal()->prepareSynced(ids));
    if (ret.isOk()) {
        // Force reload of all vibrator controllers that were prepared for a sync operation here.
        // This will trigger calls to getVibrator(id) on each controller, so they can use the
        // latest service provided by this manager.
        std::lock_guard<std::mutex> lock(mVibratorsMutex);
        for (auto& id : ids) {
            auto it = mVibrators.find(id);
            if (it != mVibrators.end()) {
                it->second->tryReconnect();
            }
        }
    }
    return ret;
}

HalResult<void> AidlManagerHalWrapper::triggerSynced(
        const std::function<void()>& completionCallback) {
    HalResult<ManagerCapabilities> capabilities = getCapabilities();
    bool supportsCallback = capabilities.isOk() &&
            static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK);
    auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
    return HalResult<void>::fromStatus(getHal()->triggerSynced(cb));
}

HalResult<void> AidlManagerHalWrapper::cancelSynced() {
    auto ret = HalResult<void>::fromStatus(getHal()->cancelSynced());
    if (ret.isOk()) {
        // Force reload of all vibrator controllers that were prepared for a sync operation before.
        // This will trigger calls to getVibrator(id) on each controller, so they can use the
        // latest service provided by this manager.
        std::lock_guard<std::mutex> lock(mVibratorsMutex);
        for (auto& entry : mVibrators) {
            entry.second->tryReconnect();
        }
    }
    return ret;
}

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

}; // namespace vibrator

}; // namespace android
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ cc_benchmark {
        "liblog",
        "libutils",
        "libvibratorservice",
        "android.hardware.vibrator-cpp",
        "android.hardware.vibrator-unstable-cpp",
        "android.hardware.vibrator@1.0",
        "android.hardware.vibrator@1.1",
        "android.hardware.vibrator@1.2",
+35 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <android-base/thread_annotations.h>
#include <android/hardware/vibrator/1.3/IVibrator.h>
#include <android/hardware/vibrator/BnVibratorCallback.h>
#include <android/hardware/vibrator/IVibrator.h>
#include <binder/IServiceManager.h>

@@ -40,7 +41,15 @@ public:
    }
    static HalResult<T> unsupported() { return HalResult("", /* unsupported= */ true); }

    static HalResult<T> fromStatus(binder::Status status, T data);
    static HalResult<T> fromStatus(binder::Status status, T data) {
        if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
            return HalResult<T>::unsupported();
        }
        if (status.isOk()) {
            return HalResult<T>::ok(data);
        }
        return HalResult<T>::failed(std::string(status.toString8().c_str()));
    }
    static HalResult<T> fromStatus(hardware::vibrator::V1_0::Status status, T data);

    template <typename R>
@@ -99,6 +108,20 @@ private:
          : mErrorMessage(std::move(errorMessage)), mFailed(true), mUnsupported(false) {}
};

class HalCallbackWrapper : public hardware::vibrator::BnVibratorCallback {
public:
    HalCallbackWrapper(std::function<void()> completionCallback)
          : mCompletionCallback(completionCallback) {}

    binder::Status onComplete() override {
        mCompletionCallback();
        return binder::Status::ok();
    }

private:
    const std::function<void()> mCompletionCallback;
};

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

// Vibrator HAL capabilities.
@@ -178,9 +201,16 @@ protected:
// Wrapper for the AIDL Vibrator HAL.
class AidlHalWrapper : public HalWrapper {
public:
    AidlHalWrapper(std::shared_ptr<CallbackScheduler> scheduler,
                   sp<hardware::vibrator::IVibrator> handle)
          : HalWrapper(std::move(scheduler)), mHandle(std::move(handle)) {}
    AidlHalWrapper(
            std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::IVibrator> handle,
            std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> reconnectFn =
                    []() {
                        return HalResult<sp<hardware::vibrator::IVibrator>>::ok(
                                checkVintfService<hardware::vibrator::IVibrator>());
                    })
          : HalWrapper(std::move(scheduler)),
            mReconnectFn(reconnectFn),
            mHandle(std::move(handle)) {}
    virtual ~AidlHalWrapper() = default;

    HalResult<void> ping() override final;
@@ -211,6 +241,7 @@ public:
            const std::function<void()>& completionCallback) override final;

private:
    const std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> mReconnectFn;
    std::mutex mHandleMutex;
    std::mutex mCapabilitiesMutex;
    std::mutex mSupportedEffectsMutex;
Loading