diff options
| author | 2021-03-22 16:12:50 +0000 | |
|---|---|---|
| committer | 2021-03-25 13:20:44 +0000 | |
| commit | 92f2af5c90a0ca8e142dff737fd30d6b88f61e2c (patch) | |
| tree | c78d7c65adf2fd9530ca381cb71f7c2ea85795db | |
| parent | 965284b7d817bf2f5f300e3fe04b51dd4aec12d6 (diff) | |
Implement PWLE support
Implement support to new API method composePwle and related frequency
control getters.
Bug: 167947076
Test: libvibratorservice_test
Change-Id: I6f47ea771a19b1ae46370c5d82671f6420e39f8b
7 files changed, 274 insertions, 83 deletions
diff --git a/services/vibratorservice/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp index 3ebf9b6de8..1010aa5195 100644 --- a/services/vibratorservice/VibratorHalWrapper.cpp +++ b/services/vibratorservice/VibratorHalWrapper.cpp @@ -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; @@ -46,20 +48,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); auto iter = hardware::hidl_enum_range<T>(); @@ -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()) { @@ -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(); @@ -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() { @@ -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]; @@ -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() { @@ -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); @@ -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; @@ -412,13 +475,6 @@ HalResult<void> HidlHalWrapper<I>::alwaysOnDisable(int32_t) { } 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(); Capabilities capabilities = diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h index 3a90ce3557..8720d9da27 100644 --- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h @@ -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) { @@ -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: @@ -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; }; @@ -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. @@ -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; @@ -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; @@ -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); diff --git a/services/vibratorservice/test/VibratorHalControllerTest.cpp b/services/vibratorservice/test/VibratorHalControllerTest.cpp index c0185de329..279496a8b8 100644 --- a/services/vibratorservice/test/VibratorHalControllerTest.cpp +++ b/services/vibratorservice/test/VibratorHalControllerTest.cpp @@ -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; @@ -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)); diff --git a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp index b9e8d8d7b1..d1db82b4ca 100644 --- a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp +++ b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp @@ -76,20 +76,19 @@ public: MOCK_METHOD(Status, compose, (const std::vector<CompositeEffect>& e, const sp<IVibratorCallback>& cb), (override)); + MOCK_METHOD(Status, composePwle, + (const std::vector<PrimitivePwle>& e, const sp<IVibratorCallback>& cb), (override)); MOCK_METHOD(Status, getSupportedAlwaysOnEffects, (std::vector<Effect> * ret), (override)); MOCK_METHOD(Status, alwaysOnEnable, (int32_t id, Effect e, EffectStrength s), (override)); MOCK_METHOD(Status, alwaysOnDisable, (int32_t id), (override)); MOCK_METHOD(Status, getQFactor, (float * ret), (override)); MOCK_METHOD(Status, getResonantFrequency, (float * ret), (override)); - MOCK_METHOD(Status, getFrequencyResolution, (float *freqResolutionHz), (override)); - MOCK_METHOD(Status, getFrequencyMinimum, (float *freqMinimumHz), (override)); + MOCK_METHOD(Status, getFrequencyResolution, (float* ret), (override)); + MOCK_METHOD(Status, getFrequencyMinimum, (float* ret), (override)); MOCK_METHOD(Status, getBandwidthAmplitudeMap, (std::vector<float> * ret), (override)); - MOCK_METHOD(Status, getPwlePrimitiveDurationMax, (int32_t *durationMs), (override)); - MOCK_METHOD(Status, getPwleCompositionSizeMax, (int32_t *maxSize), (override)); + MOCK_METHOD(Status, getPwlePrimitiveDurationMax, (int32_t * ret), (override)); + MOCK_METHOD(Status, getPwleCompositionSizeMax, (int32_t * ret), (override)); MOCK_METHOD(Status, getSupportedBraking, (std::vector<Braking> * ret), (override)); - MOCK_METHOD(Status, composePwle, - (const std::vector<PrimitivePwle>& e, const sp<IVibratorCallback>& cb), - (override)); MOCK_METHOD(int32_t, getInterfaceVersion, (), (override)); MOCK_METHOD(std::string, getInterfaceHash, (), (override)); MOCK_METHOD(IBinder*, onAsBinder, (), (override)); @@ -301,10 +300,14 @@ TEST_F(VibratorHalWrapperAidlTest, TestAlwaysOnDisable) { } TEST_F(VibratorHalWrapperAidlTest, TestGetInfoDoesNotCacheFailedResult) { + constexpr float F_MIN = 100.f; constexpr float F0 = 123.f; + constexpr float F_RESOLUTION = 0.5f; constexpr float Q_FACTOR = 123.f; std::vector<Effect> supportedEffects = {Effect::CLICK, Effect::TICK}; std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::CLICK}; + std::vector<Braking> supportedBraking = {Braking::CLAB}; + std::vector<float> amplitudes = {0.f, 1.f, 0.f}; std::vector<std::chrono::milliseconds> primitiveDurations; constexpr auto primitiveRange = enum_range<CompositePrimitive>(); @@ -320,6 +323,10 @@ TEST_F(VibratorHalWrapperAidlTest, TestGetInfoDoesNotCacheFailedResult) { .Times(Exactly(2)) .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) .WillRepeatedly(DoAll(SetArgPointee<0>(supportedEffects), Return(Status()))); + EXPECT_CALL(*mMockHal.get(), getSupportedBraking(_)) + .Times(Exactly(2)) + .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) + .WillRepeatedly(DoAll(SetArgPointee<0>(supportedBraking), Return(Status()))); EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_)) .Times(Exactly(2)) .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) @@ -327,33 +334,54 @@ TEST_F(VibratorHalWrapperAidlTest, TestGetInfoDoesNotCacheFailedResult) { EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::CLICK), _)) .Times(Exactly(1)) .WillRepeatedly(DoAll(SetArgPointee<1>(10), Return(Status()))); + EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_)) + .Times(Exactly(2)) + .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) + .WillRepeatedly(DoAll(SetArgPointee<0>(F_MIN), Return(Status()))); EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_)) .Times(Exactly(2)) .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status()))); + EXPECT_CALL(*mMockHal.get(), getFrequencyResolution(_)) + .Times(Exactly(2)) + .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) + .WillRepeatedly(DoAll(SetArgPointee<0>(F_RESOLUTION), Return(Status()))); EXPECT_CALL(*mMockHal.get(), getQFactor(_)) .Times(Exactly(2)) .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) .WillRepeatedly(DoAll(SetArgPointee<0>(Q_FACTOR), Return(Status()))); + EXPECT_CALL(*mMockHal.get(), getBandwidthAmplitudeMap(_)) + .Times(Exactly(2)) + .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) + .WillRepeatedly(DoAll(SetArgPointee<0>(amplitudes), Return(Status()))); vibrator::Info failed = mWrapper->getInfo(); ASSERT_TRUE(failed.capabilities.isFailed()); ASSERT_TRUE(failed.supportedEffects.isFailed()); + ASSERT_TRUE(failed.supportedBraking.isFailed()); ASSERT_TRUE(failed.supportedPrimitives.isFailed()); ASSERT_TRUE(failed.primitiveDurations.isFailed()); + ASSERT_TRUE(failed.minFrequency.isFailed()); ASSERT_TRUE(failed.resonantFrequency.isFailed()); + ASSERT_TRUE(failed.frequencyResolution.isFailed()); ASSERT_TRUE(failed.qFactor.isFailed()); + ASSERT_TRUE(failed.maxAmplitudes.isFailed()); vibrator::Info successful = mWrapper->getInfo(); ASSERT_EQ(vibrator::Capabilities::ON_CALLBACK, successful.capabilities.value()); ASSERT_EQ(supportedEffects, successful.supportedEffects.value()); + ASSERT_EQ(supportedBraking, successful.supportedBraking.value()); ASSERT_EQ(supportedPrimitives, successful.supportedPrimitives.value()); ASSERT_EQ(primitiveDurations, successful.primitiveDurations.value()); + ASSERT_EQ(F_MIN, successful.minFrequency.value()); ASSERT_EQ(F0, successful.resonantFrequency.value()); + ASSERT_EQ(F_RESOLUTION, successful.frequencyResolution.value()); ASSERT_EQ(Q_FACTOR, successful.qFactor.value()); + ASSERT_EQ(amplitudes, successful.maxAmplitudes.value()); } -TEST_F(VibratorHalWrapperAidlTest, TestGetCapabilitiesCachesResult) { +TEST_F(VibratorHalWrapperAidlTest, TestGetInfoCachesResult) { + constexpr float F_MIN = 100.f; constexpr float F0 = 123.f; std::vector<Effect> supportedEffects = {Effect::CLICK, Effect::TICK}; @@ -363,14 +391,29 @@ TEST_F(VibratorHalWrapperAidlTest, TestGetCapabilitiesCachesResult) { EXPECT_CALL(*mMockHal.get(), getSupportedEffects(_)) .Times(Exactly(1)) .WillRepeatedly(DoAll(SetArgPointee<0>(supportedEffects), Return(Status()))); + EXPECT_CALL(*mMockHal.get(), getQFactor(_)) + .Times(Exactly(1)) + .WillRepeatedly( + Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_)) .Times(Exactly(1)) .WillRepeatedly( Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); + EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_)) + .Times(Exactly(1)) + .WillRepeatedly(DoAll(SetArgPointee<0>(F_MIN), Return(Status()))); EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_)) .Times(Exactly(1)) .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status()))); - EXPECT_CALL(*mMockHal.get(), getQFactor(_)) + EXPECT_CALL(*mMockHal.get(), getFrequencyResolution(_)) + .Times(Exactly(1)) + .WillRepeatedly( + Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); + EXPECT_CALL(*mMockHal.get(), getBandwidthAmplitudeMap(_)) + .Times(Exactly(1)) + .WillRepeatedly( + Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); + EXPECT_CALL(*mMockHal.get(), getSupportedBraking(_)) .Times(Exactly(1)) .WillRepeatedly( Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); @@ -385,10 +428,14 @@ TEST_F(VibratorHalWrapperAidlTest, TestGetCapabilitiesCachesResult) { vibrator::Info info = mWrapper->getInfo(); ASSERT_EQ(vibrator::Capabilities::ON_CALLBACK, info.capabilities.value()); ASSERT_EQ(supportedEffects, info.supportedEffects.value()); + ASSERT_TRUE(info.supportedBraking.isUnsupported()); ASSERT_TRUE(info.supportedPrimitives.isUnsupported()); ASSERT_TRUE(info.primitiveDurations.isUnsupported()); + ASSERT_EQ(F_MIN, info.minFrequency.value()); ASSERT_EQ(F0, info.resonantFrequency.value()); + ASSERT_TRUE(info.frequencyResolution.isUnsupported()); ASSERT_TRUE(info.qFactor.isUnsupported()); + ASSERT_TRUE(info.maxAmplitudes.isUnsupported()); } TEST_F(VibratorHalWrapperAidlTest, TestPerformEffectWithCallbackSupport) { @@ -581,3 +628,39 @@ TEST_F(VibratorHalWrapperAidlTest, TestPerformComposedCachesPrimitiveDurationsAn ASSERT_EQ(114ms, result.value()); // Cached durations not fetched again, same duration returned. ASSERT_EQ(3, *callbackCounter.get()); } + +TEST_F(VibratorHalWrapperAidlTest, TestPerformPwleEffect) { + 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)); + + { + InSequence seq; + EXPECT_CALL(*mMockHal.get(), composePwle(Eq(emptyPrimitives), _)) + .Times(Exactly(1)) + .WillRepeatedly(Return( + Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); + EXPECT_CALL(*mMockHal.get(), composePwle(Eq(multiplePrimitives), _)) + .Times(Exactly(2)) + .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) + .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status()))); + ; + } + + std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>(); + auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get()); + + auto result = mWrapper->performPwleEffect(emptyPrimitives, callback); + ASSERT_TRUE(result.isUnsupported()); + // Callback not triggered on failure + ASSERT_EQ(0, *callbackCounter.get()); + + result = mWrapper->performPwleEffect(multiplePrimitives, callback); + ASSERT_TRUE(result.isFailed()); + // Callback not triggered for unsupported + ASSERT_EQ(0, *callbackCounter.get()); + + result = mWrapper->performPwleEffect(multiplePrimitives, callback); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(1, *callbackCounter.get()); +} diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp index 954477b50a..96b2582f90 100644 --- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp +++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp @@ -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; @@ -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) { @@ -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) { @@ -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()); +} diff --git a/services/vibratorservice/test/VibratorManagerHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorManagerHalWrapperAidlTest.cpp index 406a470e9f..3de157667c 100644 --- a/services/vibratorservice/test/VibratorManagerHalWrapperAidlTest.cpp +++ b/services/vibratorservice/test/VibratorManagerHalWrapperAidlTest.cpp @@ -40,6 +40,8 @@ using android::hardware::vibrator::PrimitivePwle; using namespace android; using namespace testing; +static const auto OFF_FN = [](std::shared_ptr<vibrator::HalWrapper> hal) { return hal->off(); }; + class MockBinder : public BBinder { public: MOCK_METHOD(status_t, linkToDeath, @@ -70,20 +72,19 @@ public: MOCK_METHOD(Status, compose, (const std::vector<CompositeEffect>& e, const sp<IVibratorCallback>& cb), (override)); + MOCK_METHOD(Status, composePwle, + (const std::vector<PrimitivePwle>& e, const sp<IVibratorCallback>& cb), (override)); MOCK_METHOD(Status, getSupportedAlwaysOnEffects, (std::vector<Effect> * ret), (override)); MOCK_METHOD(Status, alwaysOnEnable, (int32_t id, Effect e, EffectStrength s), (override)); MOCK_METHOD(Status, alwaysOnDisable, (int32_t id), (override)); MOCK_METHOD(Status, getQFactor, (float * ret), (override)); MOCK_METHOD(Status, getResonantFrequency, (float * ret), (override)); - MOCK_METHOD(Status, getFrequencyResolution, (float *freqResolutionHz), (override)); - MOCK_METHOD(Status, getFrequencyMinimum, (float *freqMinimumHz), (override)); + MOCK_METHOD(Status, getFrequencyResolution, (float* ret), (override)); + MOCK_METHOD(Status, getFrequencyMinimum, (float* ret), (override)); MOCK_METHOD(Status, getBandwidthAmplitudeMap, (std::vector<float> * ret), (override)); - MOCK_METHOD(Status, getPwlePrimitiveDurationMax, (int32_t *durationMs), (override)); - MOCK_METHOD(Status, getPwleCompositionSizeMax, (int32_t *maxSize), (override)); + MOCK_METHOD(Status, getPwlePrimitiveDurationMax, (int32_t * ret), (override)); + MOCK_METHOD(Status, getPwleCompositionSizeMax, (int32_t * ret), (override)); MOCK_METHOD(Status, getSupportedBraking, (std::vector<Braking> * ret), (override)); - MOCK_METHOD(Status, composePwle, - (const std::vector<PrimitivePwle>& e, const sp<IVibratorCallback>& cb), - (override)); MOCK_METHOD(int32_t, getInterfaceVersion, (), (override)); MOCK_METHOD(std::string, getInterfaceHash, (), (override)); MOCK_METHOD(IBinder*, onAsBinder, (), (override)); @@ -256,31 +257,11 @@ TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorRecoversVibratorPointer Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))) .WillRepeatedly(DoAll(SetArgPointee<1>(mMockVibrator), Return(Status()))); - EXPECT_CALL(*mMockVibrator.get(), getCapabilities(_)) + EXPECT_CALL(*mMockVibrator.get(), off()) .Times(Exactly(3)) .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) - .WillRepeatedly(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status()))); - - EXPECT_CALL(*mMockVibrator.get(), getSupportedEffects(_)) - .Times(Exactly(1)) - .WillOnce( - Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); - - EXPECT_CALL(*mMockVibrator.get(), getSupportedPrimitives(_)) - .Times(Exactly(1)) - .WillOnce( - Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); - - EXPECT_CALL(*mMockVibrator.get(), getResonantFrequency(_)) - .Times(Exactly(1)) - .WillOnce( - Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); - - EXPECT_CALL(*mMockVibrator.get(), getQFactor(_)) - .Times(Exactly(1)) - .WillOnce( - Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))); + .WillRepeatedly(Return(Status())); // Get vibrator controller is successful even if first getVibrator. auto result = mWrapper->getVibrator(kVibratorId); @@ -290,10 +271,10 @@ TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorRecoversVibratorPointer auto vibrator = result.value(); // First getVibrator call fails. ASSERT_FALSE(vibrator->init()); - // First and second getCapabilities calls fail, reload IVibrator with getVibrator. - ASSERT_TRUE(vibrator->getInfo().capabilities.isFailed()); - // Third call to getCapabilities worked after IVibrator reloaded. - ASSERT_FALSE(vibrator->getInfo().capabilities.isFailed()); + // First and second off() calls fail, reload IVibrator with getVibrator. + ASSERT_TRUE(vibrator->doWithRetry<void>(OFF_FN, "off").isFailed()); + // Third call to off() worked after IVibrator reloaded. + ASSERT_TRUE(vibrator->doWithRetry<void>(OFF_FN, "off").isOk()); } TEST_F(VibratorManagerHalWrapperAidlTest, TestPrepareSynced) { diff --git a/services/vibratorservice/test/test_utils.h b/services/vibratorservice/test/test_utils.h index 8d0b22e14c..1933a118ef 100644 --- a/services/vibratorservice/test/test_utils.h +++ b/services/vibratorservice/test/test_utils.h @@ -25,8 +25,12 @@ namespace android { namespace vibrator { +using ::android::hardware::vibrator::ActivePwle; +using ::android::hardware::vibrator::Braking; +using ::android::hardware::vibrator::BrakingPwle; using ::android::hardware::vibrator::CompositeEffect; using ::android::hardware::vibrator::CompositePrimitive; +using ::android::hardware::vibrator::PrimitivePwle; // ------------------------------------------------------------------------------------------------- @@ -53,6 +57,25 @@ public: return effect; } + static PrimitivePwle createActivePwle(float startAmplitude, float startFrequency, + float endAmplitude, float endFrequency, + std::chrono::milliseconds duration) { + ActivePwle pwle; + pwle.startAmplitude = startAmplitude; + pwle.endAmplitude = endAmplitude; + pwle.startFrequency = startFrequency; + pwle.endFrequency = endFrequency; + pwle.duration = duration.count(); + return pwle; + } + + static PrimitivePwle createBrakingPwle(Braking braking, std::chrono::milliseconds duration) { + BrakingPwle pwle; + pwle.braking = braking; + pwle.duration = duration.count(); + return pwle; + } + static std::function<void()> createCountingCallback(int32_t* counter) { return [counter]() { *counter += 1; }; } |