diff options
| author | 2021-03-13 00:59:23 +0000 | |
|---|---|---|
| committer | 2021-03-13 00:59:23 +0000 | |
| commit | 93af2abe1e8a27803c88036d98d0f251cbab9a13 (patch) | |
| tree | 8f75ccb2c92ea3aa320f22e28955d7d2373a11bb | |
| parent | c04b9206d9942fbff1642eea1599f68743dced6b (diff) | |
| parent | ba9a6ce97aead81c2bddd7bd4b79e8205fbd39a1 (diff) | |
Merge "Add support for querying resonant frequency and Q factor." into sc-dev
6 files changed, 184 insertions, 13 deletions
diff --git a/services/vibratorservice/VibratorHalController.cpp b/services/vibratorservice/VibratorHalController.cpp index 537e49bc0a..2de2e0e133 100644 --- a/services/vibratorservice/VibratorHalController.cpp +++ b/services/vibratorservice/VibratorHalController.cpp @@ -209,6 +209,18 @@ HalResult<std::vector<CompositePrimitive>> HalController::getSupportedPrimitives return apply(getSupportedPrimitivesFn, "getSupportedPrimitives"); } +HalResult<float> HalController::getResonantFrequency() { + hal_fn<float> getResonantFrequencyFn = [](std::shared_ptr<HalWrapper> hal) { + return hal->getResonantFrequency(); + }; + return apply(getResonantFrequencyFn, "getResonantFrequency"); +} + +HalResult<float> HalController::getQFactor() { + hal_fn<float> getQFactorFn = [](std::shared_ptr<HalWrapper> hal) { return hal->getQFactor(); }; + return apply(getQFactorFn, "getQFactor"); +} + HalResult<milliseconds> HalController::performEffect( Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) { hal_fn<milliseconds> performEffectFn = [&](std::shared_ptr<HalWrapper> hal) { diff --git a/services/vibratorservice/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp index 6faab38c51..3d20fa1273 100644 --- a/services/vibratorservice/VibratorHalWrapper.cpp +++ b/services/vibratorservice/VibratorHalWrapper.cpp @@ -205,6 +205,17 @@ HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitive mSupportedPrimitives); } +HalResult<float> AidlHalWrapper::getResonantFrequency() { + std::lock_guard<std::mutex> lock(mResonantFrequencyMutex); + return loadCached<float>(std::bind(&AidlHalWrapper::getResonantFrequencyInternal, this), + mResonantFrequency); +} + +HalResult<float> AidlHalWrapper::getQFactor() { + std::lock_guard<std::mutex> lock(mQFactorMutex); + return loadCached<float>(std::bind(&AidlHalWrapper::getQFactorInternal, this), mQFactor); +} + HalResult<milliseconds> AidlHalWrapper::performEffect( Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) { HalResult<Capabilities> capabilities = getCapabilities(); @@ -283,6 +294,18 @@ HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitive return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives); } +HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() { + float f0 = 0; + auto result = getHal()->getResonantFrequency(&f0); + return HalResult<float>::fromStatus(result, f0); +} + +HalResult<float> AidlHalWrapper::getQFactorInternal() { + float qFactor = 0; + auto result = getHal()->getQFactor(&qFactor); + return HalResult<float>::fromStatus(result, qFactor); +} + sp<Aidl::IVibrator> AidlHalWrapper::getHal() { std::lock_guard<std::mutex> lock(mHandleMutex); return mHandle; @@ -366,6 +389,18 @@ HalResult<std::vector<CompositePrimitive>> HidlHalWrapper<I>::getSupportedPrimit } template <typename I> +HalResult<float> HidlHalWrapper<I>::getResonantFrequency() { + ALOGV("Skipped getResonantFrequency because Vibrator HAL AIDL is not available"); + return HalResult<float>::unsupported(); +} + +template <typename I> +HalResult<float> HidlHalWrapper<I>::getQFactor() { + ALOGV("Skipped getQFactor because Vibrator HAL AIDL is not available"); + return HalResult<float>::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"); diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalController.h b/services/vibratorservice/include/vibratorservice/VibratorHalController.h index 16d571d2af..14ec7b29d8 100644 --- a/services/vibratorservice/include/vibratorservice/VibratorHalController.h +++ b/services/vibratorservice/include/vibratorservice/VibratorHalController.h @@ -73,6 +73,9 @@ public: HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitives() final override; + HalResult<float> getResonantFrequency() final override; + HalResult<float> getQFactor() final override; + HalResult<std::chrono::milliseconds> performEffect( hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength, const std::function<void()>& completionCallback) final override; diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h index e22ad340a3..039a2d99c3 100644 --- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h @@ -185,6 +185,9 @@ public: virtual HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitives() = 0; + virtual HalResult<float> getResonantFrequency() = 0; + virtual HalResult<float> getQFactor() = 0; + virtual HalResult<std::chrono::milliseconds> performEffect( hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength, const std::function<void()>& completionCallback) = 0; @@ -232,6 +235,9 @@ public: HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitives() override final; + HalResult<float> getResonantFrequency() override final; + HalResult<float> getQFactor() override final; + HalResult<std::chrono::milliseconds> performEffect( hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength, const std::function<void()>& completionCallback) override final; @@ -246,6 +252,8 @@ private: std::mutex mCapabilitiesMutex; std::mutex mSupportedEffectsMutex; std::mutex mSupportedPrimitivesMutex; + std::mutex mResonantFrequencyMutex; + std::mutex mQFactorMutex; sp<hardware::vibrator::IVibrator> mHandle GUARDED_BY(mHandleMutex); std::optional<Capabilities> mCapabilities GUARDED_BY(mCapabilitiesMutex); std::optional<std::vector<hardware::vibrator::Effect>> mSupportedEffects @@ -254,6 +262,8 @@ private: GUARDED_BY(mSupportedPrimitivesMutex); std::vector<std::optional<std::chrono::milliseconds>> mPrimitiveDurations GUARDED_BY(mSupportedPrimitivesMutex); + std::optional<float> mResonantFrequency GUARDED_BY(mResonantFrequencyMutex); + std::optional<float> mQFactor GUARDED_BY(mQFactorMutex); // Loads and caches from IVibrator. HalResult<std::chrono::milliseconds> getPrimitiveDuration( @@ -263,6 +273,10 @@ private: HalResult<Capabilities> getCapabilitiesInternal(); HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal(); HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitivesInternal(); + + HalResult<float> getResonantFrequencyInternal(); + HalResult<float> getQFactorInternal(); + sp<hardware::vibrator::IVibrator> getHal(); }; @@ -293,6 +307,9 @@ public: HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitives() override final; + HalResult<float> getResonantFrequency() override final; + HalResult<float> getQFactor() override final; + HalResult<std::chrono::milliseconds> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, const std::function<void()>& completionCallback) override final; diff --git a/services/vibratorservice/test/VibratorHalControllerTest.cpp b/services/vibratorservice/test/VibratorHalControllerTest.cpp index c4b39edec4..0c3924772c 100644 --- a/services/vibratorservice/test/VibratorHalControllerTest.cpp +++ b/services/vibratorservice/test/VibratorHalControllerTest.cpp @@ -67,6 +67,10 @@ public: MOCK_METHOD(vibrator::HalResult<std::vector<Effect>>, getSupportedEffects, (), (override)); MOCK_METHOD(vibrator::HalResult<std::vector<CompositePrimitive>>, getSupportedPrimitives, (), (override)); + + MOCK_METHOD(vibrator::HalResult<float>, getResonantFrequency, (), (override)); + MOCK_METHOD(vibrator::HalResult<float>, getQFactor, (), (override)); + MOCK_METHOD(vibrator::HalResult<milliseconds>, performEffect, (Effect effect, EffectStrength strength, const std::function<void()>& completionCallback), @@ -106,6 +110,8 @@ protected: vibrator::HalResult<vibrator::Capabilities> capabilitiesResult, vibrator::HalResult<std::vector<Effect>> effectsResult, vibrator::HalResult<std::vector<CompositePrimitive>> primitivesResult, + vibrator::HalResult<float> resonantFrequencyResult, + vibrator::HalResult<float> qFactorResult, vibrator::HalResult<milliseconds> durationResult) { EXPECT_CALL(*mMockHal.get(), ping()) .Times(Exactly(cardinality)) @@ -138,6 +144,12 @@ protected: EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives()) .Times(Exactly(cardinality)) .WillRepeatedly(Return(primitivesResult)); + EXPECT_CALL(*mMockHal.get(), getResonantFrequency()) + .Times(Exactly(cardinality)) + .WillRepeatedly(Return(resonantFrequencyResult)); + EXPECT_CALL(*mMockHal.get(), getQFactor()) + .Times(Exactly(cardinality)) + .WillRepeatedly(Return(qFactorResult)); EXPECT_CALL(*mMockHal.get(), performEffect(Eq(Effect::CLICK), Eq(EffectStrength::LIGHT), _)) .Times(Exactly(cardinality)) .WillRepeatedly(Return(durationResult)); @@ -147,7 +159,7 @@ protected: if (cardinality > 1) { // One reconnection call after each failure. - EXPECT_CALL(*mMockHal.get(), tryReconnect()).Times(Exactly(12 * cardinality)); + EXPECT_CALL(*mMockHal.get(), tryReconnect()).Times(Exactly(14 * cardinality)); } } }; @@ -164,23 +176,21 @@ TEST_F(VibratorHalControllerTest, TestInit) { } TEST_F(VibratorHalControllerTest, TestApiCallsAreForwardedToHal) { - std::vector<Effect> effects; - effects.push_back(Effect::CLICK); - effects.push_back(Effect::TICK); - std::vector<CompositePrimitive> primitives; - primitives.push_back(CompositePrimitive::CLICK); - primitives.push_back(CompositePrimitive::THUD); - std::vector<CompositeEffect> compositeEffects; - compositeEffects.push_back( - vibrator::TestFactory::createCompositeEffect(CompositePrimitive::SPIN, 100ms, 0.5f)); - compositeEffects.push_back( - vibrator::TestFactory::createCompositeEffect(CompositePrimitive::THUD, 1000ms, 1.0f)); + std::vector<Effect> effects = {Effect::CLICK, Effect::TICK}; + std::vector<CompositePrimitive> primitives = {CompositePrimitive::CLICK, + CompositePrimitive::THUD}; + constexpr float F0 = 123.f; + constexpr float Q_FACTOR = 12.f; + const std::vector<CompositeEffect> compositeEffects = + {vibrator::TestFactory::createCompositeEffect(CompositePrimitive::SPIN, 100ms, 0.5f), + vibrator::TestFactory::createCompositeEffect(CompositePrimitive::THUD, 1000ms, 1.0f)}; setHalExpectations(/* cardinality= */ 1, compositeEffects, vibrator::HalResult<void>::ok(), vibrator::HalResult<vibrator::Capabilities>::ok( vibrator::Capabilities::ON_CALLBACK), vibrator::HalResult<std::vector<Effect>>::ok(effects), vibrator::HalResult<std::vector<CompositePrimitive>>::ok(primitives), + vibrator::HalResult<float>::ok(F0), vibrator::HalResult<float>::ok(Q_FACTOR), vibrator::HalResult<milliseconds>::ok(100ms)); ASSERT_TRUE(mController->ping().isOk()); @@ -203,6 +213,14 @@ TEST_F(VibratorHalControllerTest, TestApiCallsAreForwardedToHal) { ASSERT_TRUE(getSupportedPrimitivesResult.isOk()); ASSERT_EQ(primitives, getSupportedPrimitivesResult.value()); + auto getResonantFrequencyResult = mController->getResonantFrequency(); + ASSERT_TRUE(getResonantFrequencyResult.isOk()); + ASSERT_EQ(F0, getResonantFrequencyResult.value()); + + auto getQFactorResult = mController->getQFactor(); + ASSERT_TRUE(getQFactorResult.isOk()); + ASSERT_EQ(Q_FACTOR, getQFactorResult.value()); + auto performEffectResult = mController->performEffect(Effect::CLICK, EffectStrength::LIGHT, []() {}); ASSERT_TRUE(performEffectResult.isOk()); @@ -222,6 +240,8 @@ TEST_F(VibratorHalControllerTest, TestUnsupportedApiResultDoNotResetHalConnectio vibrator::HalResult<vibrator::Capabilities>::unsupported(), vibrator::HalResult<std::vector<Effect>>::unsupported(), vibrator::HalResult<std::vector<CompositePrimitive>>::unsupported(), + vibrator::HalResult<float>::unsupported(), + vibrator::HalResult<float>::unsupported(), vibrator::HalResult<milliseconds>::unsupported()); ASSERT_EQ(0, mConnectCounter); @@ -237,6 +257,8 @@ TEST_F(VibratorHalControllerTest, TestUnsupportedApiResultDoNotResetHalConnectio ASSERT_TRUE(mController->getCapabilities().isUnsupported()); ASSERT_TRUE(mController->getSupportedEffects().isUnsupported()); ASSERT_TRUE(mController->getSupportedPrimitives().isUnsupported()); + ASSERT_TRUE(mController->getResonantFrequency().isUnsupported()); + ASSERT_TRUE(mController->getQFactor().isUnsupported()); ASSERT_TRUE(mController->performEffect(Effect::CLICK, EffectStrength::LIGHT, []() {}) .isUnsupported()); ASSERT_TRUE(mController->performComposedEffect(std::vector<CompositeEffect>(), []() {}) @@ -251,6 +273,8 @@ TEST_F(VibratorHalControllerTest, TestFailedApiResultResetsHalConnection) { vibrator::HalResult<vibrator::Capabilities>::failed("message"), vibrator::HalResult<std::vector<Effect>>::failed("message"), vibrator::HalResult<std::vector<CompositePrimitive>>::failed("message"), + vibrator::HalResult<float>::failed("message"), + vibrator::HalResult<float>::failed("message"), vibrator::HalResult<milliseconds>::failed("message")); ASSERT_EQ(0, mConnectCounter); @@ -265,6 +289,8 @@ TEST_F(VibratorHalControllerTest, TestFailedApiResultResetsHalConnection) { ASSERT_TRUE(mController->getCapabilities().isFailed()); ASSERT_TRUE(mController->getSupportedEffects().isFailed()); ASSERT_TRUE(mController->getSupportedPrimitives().isFailed()); + ASSERT_TRUE(mController->getResonantFrequency().isFailed()); + ASSERT_TRUE(mController->getQFactor().isFailed()); ASSERT_TRUE( mController->performEffect(Effect::CLICK, EffectStrength::LIGHT, []() {}).isFailed()); ASSERT_TRUE( @@ -327,13 +353,15 @@ TEST_F(VibratorHalControllerTest, TestNoVibratorReturnsUnsupportedAndAttemptsToR ASSERT_TRUE(mController->getCapabilities().isUnsupported()); ASSERT_TRUE(mController->getSupportedEffects().isUnsupported()); ASSERT_TRUE(mController->getSupportedPrimitives().isUnsupported()); + ASSERT_TRUE(mController->getResonantFrequency().isUnsupported()); + ASSERT_TRUE(mController->getQFactor().isUnsupported()); ASSERT_TRUE(mController->performEffect(Effect::CLICK, EffectStrength::LIGHT, []() {}) .isUnsupported()); ASSERT_TRUE(mController->performComposedEffect(std::vector<CompositeEffect>(), []() {}) .isUnsupported()); // One connection attempt per api call. - ASSERT_EQ(13, mConnectCounter); + ASSERT_EQ(15, mConnectCounter); } TEST_F(VibratorHalControllerTest, TestScheduledCallbackSurvivesReconnection) { diff --git a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp index 8b5caa5f82..5d77595b6b 100644 --- a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp +++ b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp @@ -413,6 +413,82 @@ TEST_F(VibratorHalWrapperAidlTest, TestGetSupportedPrimitivesCachesResult) { ASSERT_EQ(supportedPrimitives, result.value()); } +TEST_F(VibratorHalWrapperAidlTest, TestGetResonantFrequencyDoesNotCacheFailedResult) { + constexpr float F0 = 123.f; + EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_)) + .Times(Exactly(3)) + .WillOnce( + Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))) + .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) + .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status()))); + + ASSERT_TRUE(mWrapper->getResonantFrequency().isUnsupported()); + ASSERT_TRUE(mWrapper->getResonantFrequency().isFailed()); + + auto result = mWrapper->getResonantFrequency(); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(F0, result.value()); +} + +TEST_F(VibratorHalWrapperAidlTest, TestGetResonantFrequencyCachesResult) { + constexpr float F0 = 123.f; + EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_)) + .Times(Exactly(1)) + .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status()))); + + std::vector<std::thread> threads; + for (int i = 0; i < 10; i++) { + threads.push_back(std::thread([&]() { + auto result = mWrapper->getResonantFrequency(); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(F0, result.value()); + })); + } + std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); }); + + auto result = mWrapper->getResonantFrequency(); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(F0, result.value()); +} + +TEST_F(VibratorHalWrapperAidlTest, TestGetQFactorDoesNotCacheFailedResult) { + constexpr float Q_FACTOR = 123.f; + EXPECT_CALL(*mMockHal.get(), getQFactor(_)) + .Times(Exactly(3)) + .WillOnce( + Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))) + .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) + .WillRepeatedly(DoAll(SetArgPointee<0>(Q_FACTOR), Return(Status()))); + + ASSERT_TRUE(mWrapper->getQFactor().isUnsupported()); + ASSERT_TRUE(mWrapper->getQFactor().isFailed()); + + auto result = mWrapper->getQFactor(); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(Q_FACTOR, result.value()); +} + +TEST_F(VibratorHalWrapperAidlTest, TestGetQFactorCachesResult) { + constexpr float Q_FACTOR = 123.f; + EXPECT_CALL(*mMockHal.get(), getQFactor(_)) + .Times(Exactly(1)) + .WillRepeatedly(DoAll(SetArgPointee<0>(Q_FACTOR), Return(Status()))); + + std::vector<std::thread> threads; + for (int i = 0; i < 10; i++) { + threads.push_back(std::thread([&]() { + auto result = mWrapper->getQFactor(); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(Q_FACTOR, result.value()); + })); + } + std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); }); + + auto result = mWrapper->getQFactor(); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(Q_FACTOR, result.value()); +} + TEST_F(VibratorHalWrapperAidlTest, TestPerformEffectWithCallbackSupport) { { InSequence seq; |