Loading services/vibratorservice/VibratorHalWrapper.cpp +80 −24 Original line number Diff line number Diff line Loading @@ -26,10 +26,12 @@ #include <vibratorservice/VibratorCallbackScheduler.h> #include <vibratorservice/VibratorHalWrapper.h> using android::hardware::vibrator::Braking; using android::hardware::vibrator::CompositeEffect; using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; using android::hardware::vibrator::PrimitivePwle; using std::chrono::milliseconds; Loading @@ -45,20 +47,6 @@ namespace vibrator { // ------------------------------------------------------------------------------------------------- template <class T> HalResult<T> loadCached(const std::function<HalResult<T>()>& loadFn, std::optional<T>& cache) { if (cache.has_value()) { // Return copy of cached value. return HalResult<T>::ok(*cache); } HalResult<T> ret = loadFn(); if (ret.isOk()) { // Cache copy of returned value. cache.emplace(ret.value()); } return ret; } template <class T> bool isStaticCastValid(Effect effect) { T castEffect = static_cast<T>(effect); Loading Loading @@ -141,15 +129,39 @@ Info HalWrapper::getInfo() { if (mInfoCache.mSupportedEffects.isFailed()) { mInfoCache.mSupportedEffects = getSupportedEffectsInternal(); } if (mInfoCache.mSupportedBraking.isFailed()) { mInfoCache.mSupportedBraking = getSupportedBrakingInternal(); } if (mInfoCache.mMinFrequency.isFailed()) { mInfoCache.mMinFrequency = getMinFrequencyInternal(); } if (mInfoCache.mResonantFrequency.isFailed()) { mInfoCache.mResonantFrequency = getResonantFrequencyInternal(); } if (mInfoCache.mFrequencyResolution.isFailed()) { mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal(); } if (mInfoCache.mQFactor.isFailed()) { mInfoCache.mQFactor = getQFactorInternal(); } if (mInfoCache.mMaxAmplitudes.isFailed()) { mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal(); } return mInfoCache.get(); } HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&, const std::function<void()>&) { ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL"); return HalResult<milliseconds>::unsupported(); } HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&, const std::function<void()>&) { ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL"); return HalResult<void>::unsupported(); } HalResult<Capabilities> HalWrapper::getCapabilities() { std::lock_guard<std::mutex> lock(mInfoMutex); if (mInfoCache.mCapabilities.isFailed()) { Loading Loading @@ -178,6 +190,11 @@ HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() { return HalResult<std::vector<Effect>>::unsupported(); } HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() { ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL"); return HalResult<std::vector<Braking>>::unsupported(); } HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() { ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL"); return HalResult<std::vector<CompositePrimitive>>::unsupported(); Loading @@ -189,16 +206,31 @@ HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal( return HalResult<std::vector<milliseconds>>::unsupported(); } HalResult<float> HalWrapper::getMinFrequencyInternal() { ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL"); return HalResult<float>::unsupported(); } HalResult<float> HalWrapper::getResonantFrequencyInternal() { ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL"); return HalResult<float>::unsupported(); } HalResult<float> HalWrapper::getFrequencyResolutionInternal() { ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL"); return HalResult<float>::unsupported(); } HalResult<float> HalWrapper::getQFactorInternal() { ALOGV("Skipped getQFactor because it's not available in Vibrator HAL"); return HalResult<float>::unsupported(); } HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() { ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL"); return HalResult<std::vector<float>>::unsupported(); } // ------------------------------------------------------------------------------------------------- HalResult<void> AidlHalWrapper::ping() { Loading Loading @@ -272,14 +304,14 @@ HalResult<milliseconds> AidlHalWrapper::performEffect( } HalResult<milliseconds> AidlHalWrapper::performComposedEffect( const std::vector<CompositeEffect>& primitiveEffects, const std::vector<CompositeEffect>& primitives, const std::function<void()>& completionCallback) { // This method should always support callbacks, so no need to double check. auto cb = new HalCallbackWrapper(completionCallback); auto durations = getPrimitiveDurations().valueOr({}); milliseconds duration(0); for (const auto& effect : primitiveEffects) { for (const auto& effect : primitives) { auto primitiveIdx = static_cast<size_t>(effect.primitive); if (primitiveIdx < durations.size()) { duration += durations[primitiveIdx]; Loading @@ -290,7 +322,14 @@ HalResult<milliseconds> AidlHalWrapper::performComposedEffect( duration += milliseconds(effect.delayMs); } return HalResult<milliseconds>::fromStatus(getHal()->compose(primitiveEffects, cb), duration); return HalResult<milliseconds>::fromStatus(getHal()->compose(primitives, cb), duration); } HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives, const std::function<void()>& completionCallback) { // This method should always support callbacks, so no need to double check. auto cb = new HalCallbackWrapper(completionCallback); return HalResult<void>::fromStatus(getHal()->composePwle(primitives, cb)); } HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() { Loading @@ -305,6 +344,12 @@ HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() { return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects); } HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() { std::vector<Braking> supportedBraking; auto result = getHal()->getSupportedBraking(&supportedBraking); return HalResult<std::vector<Braking>>::fromStatus(result, supportedBraking); } HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() { std::vector<CompositePrimitive> supportedPrimitives; auto result = getHal()->getSupportedPrimitives(&supportedPrimitives); Loading Loading @@ -335,18 +380,36 @@ HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsIntern return HalResult<std::vector<milliseconds>>::ok(durations); } HalResult<float> AidlHalWrapper::getMinFrequencyInternal() { float minFrequency = 0; auto result = getHal()->getFrequencyMinimum(&minFrequency); return HalResult<float>::fromStatus(result, minFrequency); } HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() { float f0 = 0; auto result = getHal()->getResonantFrequency(&f0); return HalResult<float>::fromStatus(result, f0); } HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() { float frequencyResolution = 0; auto result = getHal()->getFrequencyResolution(&frequencyResolution); return HalResult<float>::fromStatus(result, frequencyResolution); } HalResult<float> AidlHalWrapper::getQFactorInternal() { float qFactor = 0; auto result = getHal()->getQFactor(&qFactor); return HalResult<float>::fromStatus(result, qFactor); } HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() { std::vector<float> amplitudes; auto result = getHal()->getBandwidthAmplitudeMap(&litudes); return HalResult<std::vector<float>>::fromStatus(result, amplitudes); } sp<Aidl::IVibrator> AidlHalWrapper::getHal() { std::lock_guard<std::mutex> lock(mHandleMutex); return mHandle; Loading Loading @@ -411,13 +474,6 @@ HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) { return HalResult<void>::unsupported(); } template <typename I> HalResult<std::chrono::milliseconds> HidlHalWrapper<I>::performComposedEffect( const std::vector<CompositeEffect>&, const std::function<void()>&) { ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available"); return HalResult<std::chrono::milliseconds>::unsupported(); } template <typename I> HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() { hardware::Return<bool> result = getHal()->supportsAmplitudeControl(); Loading services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +40 −11 Original line number Diff line number Diff line Loading @@ -148,7 +148,8 @@ enum class Capabilities : int32_t { EXTERNAL_CONTROL = hardware::vibrator::IVibrator::CAP_EXTERNAL_CONTROL, EXTERNAL_AMPLITUDE_CONTROL = hardware::vibrator::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL, COMPOSE_EFFECTS = hardware::vibrator::IVibrator::CAP_COMPOSE_EFFECTS, ALWAYS_ON_CONTROL = hardware::vibrator::IVibrator::CAP_ALWAYS_ON_CONTROL COMPOSE_PWLE_EFFECTS = hardware::vibrator::IVibrator::CAP_COMPOSE_PWLE_EFFECTS, ALWAYS_ON_CONTROL = hardware::vibrator::IVibrator::CAP_ALWAYS_ON_CONTROL, }; inline Capabilities operator|(Capabilities lhs, Capabilities rhs) { Loading @@ -175,26 +176,36 @@ class Info { public: const HalResult<Capabilities> capabilities; const HalResult<std::vector<hardware::vibrator::Effect>> supportedEffects; const HalResult<std::vector<hardware::vibrator::Braking>> supportedBraking; const HalResult<std::vector<hardware::vibrator::CompositePrimitive>> supportedPrimitives; const HalResult<std::vector<std::chrono::milliseconds>> primitiveDurations; const HalResult<float> minFrequency; const HalResult<float> resonantFrequency; const HalResult<float> frequencyResolution; const HalResult<float> qFactor; const HalResult<std::vector<float>> maxAmplitudes; bool checkAndLogFailure(const char*) const { return capabilities.checkAndLogFailure("getCapabilities") || supportedEffects.checkAndLogFailure("getSupportedEffects") || supportedBraking.checkAndLogFailure("getSupportedBraking") || supportedPrimitives.checkAndLogFailure("getSupportedPrimitives") || primitiveDurations.checkAndLogFailure("getPrimitiveDuration") || minFrequency.checkAndLogFailure("getMinFrequency") || resonantFrequency.checkAndLogFailure("getResonantFrequency") || qFactor.checkAndLogFailure("getQFactor"); frequencyResolution.checkAndLogFailure("getFrequencyResolution") || qFactor.checkAndLogFailure("getQFactor") || maxAmplitudes.checkAndLogFailure("getMaxAmplitudes"); } }; class InfoCache { public: Info get() { return {mCapabilities, mSupportedEffects, mSupportedPrimitives, mPrimitiveDurations, mResonantFrequency, mQFactor}; return {mCapabilities, mSupportedEffects, mSupportedBraking, mSupportedPrimitives, mPrimitiveDurations, mMinFrequency, mResonantFrequency, mFrequencyResolution, mQFactor, mMaxAmplitudes}; } private: Loading @@ -202,12 +213,17 @@ private: HalResult<Capabilities> mCapabilities = HalResult<Capabilities>::failed(MSG); HalResult<std::vector<hardware::vibrator::Effect>> mSupportedEffects = HalResult<std::vector<hardware::vibrator::Effect>>::failed(MSG); HalResult<std::vector<hardware::vibrator::Braking>> mSupportedBraking = HalResult<std::vector<hardware::vibrator::Braking>>::failed(MSG); HalResult<std::vector<hardware::vibrator::CompositePrimitive>> mSupportedPrimitives = HalResult<std::vector<hardware::vibrator::CompositePrimitive>>::failed(MSG); HalResult<std::vector<std::chrono::milliseconds>> mPrimitiveDurations = HalResult<std::vector<std::chrono::milliseconds>>::failed(MSG); HalResult<float> mMinFrequency = HalResult<float>::failed(MSG); HalResult<float> mResonantFrequency = HalResult<float>::failed(MSG); HalResult<float> mFrequencyResolution = HalResult<float>::failed(MSG); HalResult<float> mQFactor = HalResult<float>::failed(MSG); HalResult<std::vector<float>> mMaxAmplitudes = HalResult<std::vector<float>>::failed(MSG); friend class HalWrapper; }; Loading Loading @@ -243,8 +259,12 @@ public: const std::function<void()>& completionCallback) = 0; virtual HalResult<std::chrono::milliseconds> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback) = 0; const std::vector<hardware::vibrator::CompositeEffect>& primitives, const std::function<void()>& completionCallback); virtual HalResult<void> performPwleEffect( const std::vector<hardware::vibrator::PrimitivePwle>& primitives, const std::function<void()>& completionCallback); protected: // Shared pointer to allow CallbackScheduler to outlive this wrapper. Loading @@ -257,12 +277,16 @@ protected: // Request vibrator info to HAL skipping cache. virtual HalResult<Capabilities> getCapabilitiesInternal() = 0; virtual HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal(); virtual HalResult<std::vector<hardware::vibrator::Braking>> getSupportedBrakingInternal(); virtual HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitivesInternal(); virtual HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal( const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives); virtual HalResult<float> getMinFrequencyInternal(); virtual HalResult<float> getResonantFrequencyInternal(); virtual HalResult<float> getFrequencyResolutionInternal(); virtual HalResult<float> getQFactorInternal(); virtual HalResult<std::vector<float>> getMaxAmplitudesInternal(); private: std::mutex mInfoMutex; Loading Loading @@ -303,19 +327,28 @@ public: const std::function<void()>& completionCallback) override final; HalResult<std::chrono::milliseconds> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, const std::vector<hardware::vibrator::CompositeEffect>& primitives, const std::function<void()>& completionCallback) override final; HalResult<void> performPwleEffect( const std::vector<hardware::vibrator::PrimitivePwle>& primitives, const std::function<void()>& completionCallback) override final; protected: HalResult<Capabilities> getCapabilitiesInternal() override final; HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal() override final; HalResult<std::vector<hardware::vibrator::Braking>> getSupportedBrakingInternal() override final; HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitivesInternal() override final; HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal( const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives) override final; HalResult<float> getMinFrequencyInternal() override final; HalResult<float> getResonantFrequencyInternal() override final; HalResult<float> getFrequencyResolutionInternal() override final; HalResult<float> getQFactorInternal() override final; HalResult<std::vector<float>> getMaxAmplitudesInternal() override final; private: const std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> mReconnectFn; Loading Loading @@ -347,10 +380,6 @@ public: hardware::vibrator::EffectStrength strength) override final; HalResult<void> alwaysOnDisable(int32_t id) override final; HalResult<std::chrono::milliseconds> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback) override final; protected: std::mutex mHandleMutex; sp<I> mHandle GUARDED_BY(mHandleMutex); Loading services/vibratorservice/test/VibratorHalControllerTest.cpp +0 −6 Original line number Diff line number Diff line Loading @@ -31,8 +31,6 @@ #include "test_utils.h" using android::hardware::vibrator::CompositeEffect; using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; Loading Loading @@ -71,10 +69,6 @@ public: (Effect effect, EffectStrength strength, const std::function<void()>& completionCallback), (override)); MOCK_METHOD(vibrator::HalResult<milliseconds>, performComposedEffect, (const std::vector<CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback), (override)); MOCK_METHOD(vibrator::HalResult<vibrator::Capabilities>, getCapabilitiesInternal, (), (override)); Loading services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp +92 −9 File changed.Preview size limit exceeded, changes collapsed. Show changes services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -31,11 +31,13 @@ namespace V1_0 = android::hardware::vibrator::V1_0; using android::hardware::vibrator::Braking; using android::hardware::vibrator::CompositeEffect; using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; using android::hardware::vibrator::IVibrator; using android::hardware::vibrator::PrimitivePwle; using namespace android; using namespace std::chrono_literals; Loading Loading @@ -201,10 +203,14 @@ TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoDoesNotCacheFailedResult) { vibrator::Info info = mWrapper->getInfo(); ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, info.capabilities.value()); ASSERT_TRUE(info.supportedEffects.isUnsupported()); ASSERT_TRUE(info.supportedBraking.isUnsupported()); ASSERT_TRUE(info.supportedPrimitives.isUnsupported()); ASSERT_TRUE(info.primitiveDurations.isUnsupported()); ASSERT_TRUE(info.minFrequency.isUnsupported()); ASSERT_TRUE(info.resonantFrequency.isUnsupported()); ASSERT_TRUE(info.frequencyResolution.isUnsupported()); ASSERT_TRUE(info.qFactor.isUnsupported()); ASSERT_TRUE(info.maxAmplitudes.isUnsupported()); } TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoWithoutAmplitudeControl) { Loading @@ -230,10 +236,14 @@ TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoCachesResult) { vibrator::Info info = mWrapper->getInfo(); ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, info.capabilities.value()); ASSERT_TRUE(info.supportedEffects.isUnsupported()); ASSERT_TRUE(info.supportedBraking.isUnsupported()); ASSERT_TRUE(info.supportedPrimitives.isUnsupported()); ASSERT_TRUE(info.primitiveDurations.isUnsupported()); ASSERT_TRUE(info.minFrequency.isUnsupported()); ASSERT_TRUE(info.resonantFrequency.isUnsupported()); ASSERT_TRUE(info.frequencyResolution.isUnsupported()); ASSERT_TRUE(info.qFactor.isUnsupported()); ASSERT_TRUE(info.maxAmplitudes.isUnsupported()); } TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformEffect) { Loading Loading @@ -320,3 +330,18 @@ TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformComposedEffectUnsupported) { // No callback is triggered. ASSERT_EQ(0, *callbackCounter.get()); } TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformPwleEffectUnsupported) { std::vector<PrimitivePwle> emptyPrimitives, multiplePrimitives; multiplePrimitives.push_back(vibrator::TestFactory::createActivePwle(0, 1, 0, 1, 10ms)); multiplePrimitives.push_back(vibrator::TestFactory::createBrakingPwle(Braking::NONE, 100ms)); std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); ASSERT_TRUE(mWrapper->performPwleEffect(emptyPrimitives, callback).isUnsupported()); ASSERT_TRUE(mWrapper->performPwleEffect(multiplePrimitives, callback).isUnsupported()); // No callback is triggered. ASSERT_EQ(0, *callbackCounter.get()); } Loading
services/vibratorservice/VibratorHalWrapper.cpp +80 −24 Original line number Diff line number Diff line Loading @@ -26,10 +26,12 @@ #include <vibratorservice/VibratorCallbackScheduler.h> #include <vibratorservice/VibratorHalWrapper.h> using android::hardware::vibrator::Braking; using android::hardware::vibrator::CompositeEffect; using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; using android::hardware::vibrator::PrimitivePwle; using std::chrono::milliseconds; Loading @@ -45,20 +47,6 @@ namespace vibrator { // ------------------------------------------------------------------------------------------------- template <class T> HalResult<T> loadCached(const std::function<HalResult<T>()>& loadFn, std::optional<T>& cache) { if (cache.has_value()) { // Return copy of cached value. return HalResult<T>::ok(*cache); } HalResult<T> ret = loadFn(); if (ret.isOk()) { // Cache copy of returned value. cache.emplace(ret.value()); } return ret; } template <class T> bool isStaticCastValid(Effect effect) { T castEffect = static_cast<T>(effect); Loading Loading @@ -141,15 +129,39 @@ Info HalWrapper::getInfo() { if (mInfoCache.mSupportedEffects.isFailed()) { mInfoCache.mSupportedEffects = getSupportedEffectsInternal(); } if (mInfoCache.mSupportedBraking.isFailed()) { mInfoCache.mSupportedBraking = getSupportedBrakingInternal(); } if (mInfoCache.mMinFrequency.isFailed()) { mInfoCache.mMinFrequency = getMinFrequencyInternal(); } if (mInfoCache.mResonantFrequency.isFailed()) { mInfoCache.mResonantFrequency = getResonantFrequencyInternal(); } if (mInfoCache.mFrequencyResolution.isFailed()) { mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal(); } if (mInfoCache.mQFactor.isFailed()) { mInfoCache.mQFactor = getQFactorInternal(); } if (mInfoCache.mMaxAmplitudes.isFailed()) { mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal(); } return mInfoCache.get(); } HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&, const std::function<void()>&) { ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL"); return HalResult<milliseconds>::unsupported(); } HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&, const std::function<void()>&) { ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL"); return HalResult<void>::unsupported(); } HalResult<Capabilities> HalWrapper::getCapabilities() { std::lock_guard<std::mutex> lock(mInfoMutex); if (mInfoCache.mCapabilities.isFailed()) { Loading Loading @@ -178,6 +190,11 @@ HalResult<std::vector<Effect>> HalWrapper::getSupportedEffectsInternal() { return HalResult<std::vector<Effect>>::unsupported(); } HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() { ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL"); return HalResult<std::vector<Braking>>::unsupported(); } HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() { ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL"); return HalResult<std::vector<CompositePrimitive>>::unsupported(); Loading @@ -189,16 +206,31 @@ HalResult<std::vector<milliseconds>> HalWrapper::getPrimitiveDurationsInternal( return HalResult<std::vector<milliseconds>>::unsupported(); } HalResult<float> HalWrapper::getMinFrequencyInternal() { ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL"); return HalResult<float>::unsupported(); } HalResult<float> HalWrapper::getResonantFrequencyInternal() { ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL"); return HalResult<float>::unsupported(); } HalResult<float> HalWrapper::getFrequencyResolutionInternal() { ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL"); return HalResult<float>::unsupported(); } HalResult<float> HalWrapper::getQFactorInternal() { ALOGV("Skipped getQFactor because it's not available in Vibrator HAL"); return HalResult<float>::unsupported(); } HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() { ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL"); return HalResult<std::vector<float>>::unsupported(); } // ------------------------------------------------------------------------------------------------- HalResult<void> AidlHalWrapper::ping() { Loading Loading @@ -272,14 +304,14 @@ HalResult<milliseconds> AidlHalWrapper::performEffect( } HalResult<milliseconds> AidlHalWrapper::performComposedEffect( const std::vector<CompositeEffect>& primitiveEffects, const std::vector<CompositeEffect>& primitives, const std::function<void()>& completionCallback) { // This method should always support callbacks, so no need to double check. auto cb = new HalCallbackWrapper(completionCallback); auto durations = getPrimitiveDurations().valueOr({}); milliseconds duration(0); for (const auto& effect : primitiveEffects) { for (const auto& effect : primitives) { auto primitiveIdx = static_cast<size_t>(effect.primitive); if (primitiveIdx < durations.size()) { duration += durations[primitiveIdx]; Loading @@ -290,7 +322,14 @@ HalResult<milliseconds> AidlHalWrapper::performComposedEffect( duration += milliseconds(effect.delayMs); } return HalResult<milliseconds>::fromStatus(getHal()->compose(primitiveEffects, cb), duration); return HalResult<milliseconds>::fromStatus(getHal()->compose(primitives, cb), duration); } HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives, const std::function<void()>& completionCallback) { // This method should always support callbacks, so no need to double check. auto cb = new HalCallbackWrapper(completionCallback); return HalResult<void>::fromStatus(getHal()->composePwle(primitives, cb)); } HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() { Loading @@ -305,6 +344,12 @@ HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() { return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects); } HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() { std::vector<Braking> supportedBraking; auto result = getHal()->getSupportedBraking(&supportedBraking); return HalResult<std::vector<Braking>>::fromStatus(result, supportedBraking); } HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() { std::vector<CompositePrimitive> supportedPrimitives; auto result = getHal()->getSupportedPrimitives(&supportedPrimitives); Loading Loading @@ -335,18 +380,36 @@ HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsIntern return HalResult<std::vector<milliseconds>>::ok(durations); } HalResult<float> AidlHalWrapper::getMinFrequencyInternal() { float minFrequency = 0; auto result = getHal()->getFrequencyMinimum(&minFrequency); return HalResult<float>::fromStatus(result, minFrequency); } HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() { float f0 = 0; auto result = getHal()->getResonantFrequency(&f0); return HalResult<float>::fromStatus(result, f0); } HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() { float frequencyResolution = 0; auto result = getHal()->getFrequencyResolution(&frequencyResolution); return HalResult<float>::fromStatus(result, frequencyResolution); } HalResult<float> AidlHalWrapper::getQFactorInternal() { float qFactor = 0; auto result = getHal()->getQFactor(&qFactor); return HalResult<float>::fromStatus(result, qFactor); } HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() { std::vector<float> amplitudes; auto result = getHal()->getBandwidthAmplitudeMap(&litudes); return HalResult<std::vector<float>>::fromStatus(result, amplitudes); } sp<Aidl::IVibrator> AidlHalWrapper::getHal() { std::lock_guard<std::mutex> lock(mHandleMutex); return mHandle; Loading Loading @@ -411,13 +474,6 @@ HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) { return HalResult<void>::unsupported(); } template <typename I> HalResult<std::chrono::milliseconds> HidlHalWrapper<I>::performComposedEffect( const std::vector<CompositeEffect>&, const std::function<void()>&) { ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available"); return HalResult<std::chrono::milliseconds>::unsupported(); } template <typename I> HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() { hardware::Return<bool> result = getHal()->supportsAmplitudeControl(); Loading
services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +40 −11 Original line number Diff line number Diff line Loading @@ -148,7 +148,8 @@ enum class Capabilities : int32_t { EXTERNAL_CONTROL = hardware::vibrator::IVibrator::CAP_EXTERNAL_CONTROL, EXTERNAL_AMPLITUDE_CONTROL = hardware::vibrator::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL, COMPOSE_EFFECTS = hardware::vibrator::IVibrator::CAP_COMPOSE_EFFECTS, ALWAYS_ON_CONTROL = hardware::vibrator::IVibrator::CAP_ALWAYS_ON_CONTROL COMPOSE_PWLE_EFFECTS = hardware::vibrator::IVibrator::CAP_COMPOSE_PWLE_EFFECTS, ALWAYS_ON_CONTROL = hardware::vibrator::IVibrator::CAP_ALWAYS_ON_CONTROL, }; inline Capabilities operator|(Capabilities lhs, Capabilities rhs) { Loading @@ -175,26 +176,36 @@ class Info { public: const HalResult<Capabilities> capabilities; const HalResult<std::vector<hardware::vibrator::Effect>> supportedEffects; const HalResult<std::vector<hardware::vibrator::Braking>> supportedBraking; const HalResult<std::vector<hardware::vibrator::CompositePrimitive>> supportedPrimitives; const HalResult<std::vector<std::chrono::milliseconds>> primitiveDurations; const HalResult<float> minFrequency; const HalResult<float> resonantFrequency; const HalResult<float> frequencyResolution; const HalResult<float> qFactor; const HalResult<std::vector<float>> maxAmplitudes; bool checkAndLogFailure(const char*) const { return capabilities.checkAndLogFailure("getCapabilities") || supportedEffects.checkAndLogFailure("getSupportedEffects") || supportedBraking.checkAndLogFailure("getSupportedBraking") || supportedPrimitives.checkAndLogFailure("getSupportedPrimitives") || primitiveDurations.checkAndLogFailure("getPrimitiveDuration") || minFrequency.checkAndLogFailure("getMinFrequency") || resonantFrequency.checkAndLogFailure("getResonantFrequency") || qFactor.checkAndLogFailure("getQFactor"); frequencyResolution.checkAndLogFailure("getFrequencyResolution") || qFactor.checkAndLogFailure("getQFactor") || maxAmplitudes.checkAndLogFailure("getMaxAmplitudes"); } }; class InfoCache { public: Info get() { return {mCapabilities, mSupportedEffects, mSupportedPrimitives, mPrimitiveDurations, mResonantFrequency, mQFactor}; return {mCapabilities, mSupportedEffects, mSupportedBraking, mSupportedPrimitives, mPrimitiveDurations, mMinFrequency, mResonantFrequency, mFrequencyResolution, mQFactor, mMaxAmplitudes}; } private: Loading @@ -202,12 +213,17 @@ private: HalResult<Capabilities> mCapabilities = HalResult<Capabilities>::failed(MSG); HalResult<std::vector<hardware::vibrator::Effect>> mSupportedEffects = HalResult<std::vector<hardware::vibrator::Effect>>::failed(MSG); HalResult<std::vector<hardware::vibrator::Braking>> mSupportedBraking = HalResult<std::vector<hardware::vibrator::Braking>>::failed(MSG); HalResult<std::vector<hardware::vibrator::CompositePrimitive>> mSupportedPrimitives = HalResult<std::vector<hardware::vibrator::CompositePrimitive>>::failed(MSG); HalResult<std::vector<std::chrono::milliseconds>> mPrimitiveDurations = HalResult<std::vector<std::chrono::milliseconds>>::failed(MSG); HalResult<float> mMinFrequency = HalResult<float>::failed(MSG); HalResult<float> mResonantFrequency = HalResult<float>::failed(MSG); HalResult<float> mFrequencyResolution = HalResult<float>::failed(MSG); HalResult<float> mQFactor = HalResult<float>::failed(MSG); HalResult<std::vector<float>> mMaxAmplitudes = HalResult<std::vector<float>>::failed(MSG); friend class HalWrapper; }; Loading Loading @@ -243,8 +259,12 @@ public: const std::function<void()>& completionCallback) = 0; virtual HalResult<std::chrono::milliseconds> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback) = 0; const std::vector<hardware::vibrator::CompositeEffect>& primitives, const std::function<void()>& completionCallback); virtual HalResult<void> performPwleEffect( const std::vector<hardware::vibrator::PrimitivePwle>& primitives, const std::function<void()>& completionCallback); protected: // Shared pointer to allow CallbackScheduler to outlive this wrapper. Loading @@ -257,12 +277,16 @@ protected: // Request vibrator info to HAL skipping cache. virtual HalResult<Capabilities> getCapabilitiesInternal() = 0; virtual HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal(); virtual HalResult<std::vector<hardware::vibrator::Braking>> getSupportedBrakingInternal(); virtual HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitivesInternal(); virtual HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal( const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives); virtual HalResult<float> getMinFrequencyInternal(); virtual HalResult<float> getResonantFrequencyInternal(); virtual HalResult<float> getFrequencyResolutionInternal(); virtual HalResult<float> getQFactorInternal(); virtual HalResult<std::vector<float>> getMaxAmplitudesInternal(); private: std::mutex mInfoMutex; Loading Loading @@ -303,19 +327,28 @@ public: const std::function<void()>& completionCallback) override final; HalResult<std::chrono::milliseconds> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, const std::vector<hardware::vibrator::CompositeEffect>& primitives, const std::function<void()>& completionCallback) override final; HalResult<void> performPwleEffect( const std::vector<hardware::vibrator::PrimitivePwle>& primitives, const std::function<void()>& completionCallback) override final; protected: HalResult<Capabilities> getCapabilitiesInternal() override final; HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal() override final; HalResult<std::vector<hardware::vibrator::Braking>> getSupportedBrakingInternal() override final; HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitivesInternal() override final; HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal( const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives) override final; HalResult<float> getMinFrequencyInternal() override final; HalResult<float> getResonantFrequencyInternal() override final; HalResult<float> getFrequencyResolutionInternal() override final; HalResult<float> getQFactorInternal() override final; HalResult<std::vector<float>> getMaxAmplitudesInternal() override final; private: const std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> mReconnectFn; Loading Loading @@ -347,10 +380,6 @@ public: hardware::vibrator::EffectStrength strength) override final; HalResult<void> alwaysOnDisable(int32_t id) override final; HalResult<std::chrono::milliseconds> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback) override final; protected: std::mutex mHandleMutex; sp<I> mHandle GUARDED_BY(mHandleMutex); Loading
services/vibratorservice/test/VibratorHalControllerTest.cpp +0 −6 Original line number Diff line number Diff line Loading @@ -31,8 +31,6 @@ #include "test_utils.h" using android::hardware::vibrator::CompositeEffect; using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; Loading Loading @@ -71,10 +69,6 @@ public: (Effect effect, EffectStrength strength, const std::function<void()>& completionCallback), (override)); MOCK_METHOD(vibrator::HalResult<milliseconds>, performComposedEffect, (const std::vector<CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback), (override)); MOCK_METHOD(vibrator::HalResult<vibrator::Capabilities>, getCapabilitiesInternal, (), (override)); Loading
services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp +92 −9 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -31,11 +31,13 @@ namespace V1_0 = android::hardware::vibrator::V1_0; using android::hardware::vibrator::Braking; using android::hardware::vibrator::CompositeEffect; using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; using android::hardware::vibrator::IVibrator; using android::hardware::vibrator::PrimitivePwle; using namespace android; using namespace std::chrono_literals; Loading Loading @@ -201,10 +203,14 @@ TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoDoesNotCacheFailedResult) { vibrator::Info info = mWrapper->getInfo(); ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, info.capabilities.value()); ASSERT_TRUE(info.supportedEffects.isUnsupported()); ASSERT_TRUE(info.supportedBraking.isUnsupported()); ASSERT_TRUE(info.supportedPrimitives.isUnsupported()); ASSERT_TRUE(info.primitiveDurations.isUnsupported()); ASSERT_TRUE(info.minFrequency.isUnsupported()); ASSERT_TRUE(info.resonantFrequency.isUnsupported()); ASSERT_TRUE(info.frequencyResolution.isUnsupported()); ASSERT_TRUE(info.qFactor.isUnsupported()); ASSERT_TRUE(info.maxAmplitudes.isUnsupported()); } TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoWithoutAmplitudeControl) { Loading @@ -230,10 +236,14 @@ TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoCachesResult) { vibrator::Info info = mWrapper->getInfo(); ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, info.capabilities.value()); ASSERT_TRUE(info.supportedEffects.isUnsupported()); ASSERT_TRUE(info.supportedBraking.isUnsupported()); ASSERT_TRUE(info.supportedPrimitives.isUnsupported()); ASSERT_TRUE(info.primitiveDurations.isUnsupported()); ASSERT_TRUE(info.minFrequency.isUnsupported()); ASSERT_TRUE(info.resonantFrequency.isUnsupported()); ASSERT_TRUE(info.frequencyResolution.isUnsupported()); ASSERT_TRUE(info.qFactor.isUnsupported()); ASSERT_TRUE(info.maxAmplitudes.isUnsupported()); } TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformEffect) { Loading Loading @@ -320,3 +330,18 @@ TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformComposedEffectUnsupported) { // No callback is triggered. ASSERT_EQ(0, *callbackCounter.get()); } TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformPwleEffectUnsupported) { std::vector<PrimitivePwle> emptyPrimitives, multiplePrimitives; multiplePrimitives.push_back(vibrator::TestFactory::createActivePwle(0, 1, 0, 1, 10ms)); multiplePrimitives.push_back(vibrator::TestFactory::createBrakingPwle(Braking::NONE, 100ms)); std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); ASSERT_TRUE(mWrapper->performPwleEffect(emptyPrimitives, callback).isUnsupported()); ASSERT_TRUE(mWrapper->performPwleEffect(multiplePrimitives, callback).isUnsupported()); // No callback is triggered. ASSERT_EQ(0, *callbackCounter.get()); }