Loading services/core/jni/com_android_server_VibratorService.cpp +45 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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) { Loading Loading
services/core/jni/com_android_server_VibratorService.cpp +45 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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) { Loading