diff options
7 files changed, 113 insertions, 7 deletions
diff --git a/services/vibratorservice/VibratorHalController.cpp b/services/vibratorservice/VibratorHalController.cpp index a9da74fea3..46175ad834 100644 --- a/services/vibratorservice/VibratorHalController.cpp +++ b/services/vibratorservice/VibratorHalController.cpp @@ -28,6 +28,7 @@ #include <vibratorservice/VibratorHalWrapper.h> using android::hardware::vibrator::CompositeEffect; +using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; @@ -201,6 +202,12 @@ HalResult<std::vector<Effect>> HalController::getSupportedEffects() { return apply(getSupportedEffectsFn, "getSupportedEffects"); } +HalResult<std::vector<CompositePrimitive>> HalController::getSupportedPrimitives() { + hal_fn<std::vector<CompositePrimitive>> getSupportedPrimitivesFn = + [](std::shared_ptr<HalWrapper> hal) { return hal->getSupportedPrimitives(); }; + return apply(getSupportedPrimitivesFn, "getSupportedPrimitives"); +} + 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 ee891def11..ce20aeb7dc 100644 --- a/services/vibratorservice/VibratorHalWrapper.cpp +++ b/services/vibratorservice/VibratorHalWrapper.cpp @@ -27,6 +27,7 @@ #include <vibratorservice/VibratorHalWrapper.h> using android::hardware::vibrator::CompositeEffect; +using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; @@ -221,6 +222,13 @@ HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffects() { mSupportedEffects); } +HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitives() { + std::lock_guard<std::mutex> lock(mSupportedPrimitivesMutex); + return loadCached<std::vector< + CompositePrimitive>>(std::bind(&AidlHalWrapper::getSupportedPrimitivesInternal, this), + mSupportedPrimitives); +} + HalResult<milliseconds> AidlHalWrapper::performEffect( Effect effect, EffectStrength strength, const std::function<void()>& completionCallback) { HalResult<Capabilities> capabilities = getCapabilities(); @@ -260,6 +268,12 @@ HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() { return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects); } +HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() { + std::vector<CompositePrimitive> supportedPrimitives; + auto result = getHal()->getSupportedPrimitives(&supportedPrimitives); + return HalResult<std::vector<CompositePrimitive>>::fromStatus(result, supportedPrimitives); +} + sp<Aidl::IVibrator> AidlHalWrapper::getHal() { std::lock_guard<std::mutex> lock(mHandleMutex); return mHandle; @@ -337,6 +351,12 @@ HalResult<std::vector<Effect>> HidlHalWrapper<I>::getSupportedEffects() { } template <typename I> +HalResult<std::vector<CompositePrimitive>> HidlHalWrapper<I>::getSupportedPrimitives() { + ALOGV("Skipped getSupportedPrimitives because Vibrator HAL AIDL is not available"); + return HalResult<std::vector<CompositePrimitive>>::unsupported(); +} + +template <typename I> HalResult<void> 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 daf2c8c01e..3b61f42544 100644 --- a/services/vibratorservice/include/vibratorservice/VibratorHalController.h +++ b/services/vibratorservice/include/vibratorservice/VibratorHalController.h @@ -69,6 +69,8 @@ public: HalResult<Capabilities> getCapabilities() final override; HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffects() final override; + HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitives() + final override; HalResult<std::chrono::milliseconds> performEffect( hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength, diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h index 6e36bd6350..7b99bbb43e 100644 --- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h +++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h @@ -156,6 +156,8 @@ public: virtual HalResult<Capabilities> getCapabilities() = 0; virtual HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffects() = 0; + virtual HalResult<std::vector<hardware::vibrator::CompositePrimitive>> + getSupportedPrimitives() = 0; virtual HalResult<std::chrono::milliseconds> performEffect( hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength, @@ -194,6 +196,8 @@ public: HalResult<Capabilities> getCapabilities() override final; HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffects() override final; + HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitives() + override final; HalResult<std::chrono::milliseconds> performEffect( hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength, @@ -207,14 +211,18 @@ private: std::mutex mHandleMutex; std::mutex mCapabilitiesMutex; std::mutex mSupportedEffectsMutex; + std::mutex mSupportedPrimitivesMutex; sp<hardware::vibrator::IVibrator> mHandle GUARDED_BY(mHandleMutex); std::optional<Capabilities> mCapabilities GUARDED_BY(mCapabilitiesMutex); std::optional<std::vector<hardware::vibrator::Effect>> mSupportedEffects GUARDED_BY(mSupportedEffectsMutex); + std::optional<std::vector<hardware::vibrator::CompositePrimitive>> mSupportedPrimitives + GUARDED_BY(mSupportedPrimitivesMutex); // Loads directly from IVibrator handle, skipping caches. HalResult<Capabilities> getCapabilitiesInternal(); HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal(); + HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitivesInternal(); sp<hardware::vibrator::IVibrator> getHal(); }; @@ -242,6 +250,8 @@ public: HalResult<Capabilities> getCapabilities() override final; HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffects() override final; + HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitives() + override final; HalResult<void> performComposedEffect( const std::vector<hardware::vibrator::CompositeEffect>& primitiveEffects, diff --git a/services/vibratorservice/test/VibratorHalControllerTest.cpp b/services/vibratorservice/test/VibratorHalControllerTest.cpp index 8155df0377..f04e0162b9 100644 --- a/services/vibratorservice/test/VibratorHalControllerTest.cpp +++ b/services/vibratorservice/test/VibratorHalControllerTest.cpp @@ -65,6 +65,8 @@ public: MOCK_METHOD(vibrator::HalResult<void>, alwaysOnDisable, (int32_t id), (override)); MOCK_METHOD(vibrator::HalResult<vibrator::Capabilities>, getCapabilities, (), (override)); MOCK_METHOD(vibrator::HalResult<std::vector<Effect>>, getSupportedEffects, (), (override)); + MOCK_METHOD(vibrator::HalResult<std::vector<CompositePrimitive>>, getSupportedPrimitives, (), + (override)); MOCK_METHOD(vibrator::HalResult<milliseconds>, performEffect, (Effect effect, EffectStrength strength, const std::function<void()>& completionCallback), @@ -132,6 +134,7 @@ protected: vibrator::HalResult<void> voidResult, vibrator::HalResult<vibrator::Capabilities> capabilitiesResult, vibrator::HalResult<std::vector<Effect>> effectsResult, + vibrator::HalResult<std::vector<CompositePrimitive>> primitivesResult, vibrator::HalResult<milliseconds> durationResult) { EXPECT_CALL(*mMockHal.get(), ping()) .Times(Exactly(cardinality)) @@ -161,6 +164,9 @@ protected: EXPECT_CALL(*mMockHal.get(), getSupportedEffects()) .Times(Exactly(cardinality)) .WillRepeatedly(Return(effectsResult)); + EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives()) + .Times(Exactly(cardinality)) + .WillRepeatedly(Return(primitivesResult)); EXPECT_CALL(*mMockHal.get(), performEffect(Eq(Effect::CLICK), Eq(EffectStrength::LIGHT), _)) .Times(Exactly(cardinality)) .WillRepeatedly(Return(durationResult)); @@ -170,7 +176,7 @@ protected: if (cardinality > 1) { // One reconnection call after each failure. - EXPECT_CALL(*mMockHal.get(), tryReconnect()).Times(Exactly(11 * cardinality)); + EXPECT_CALL(*mMockHal.get(), tryReconnect()).Times(Exactly(12 * cardinality)); } } }; @@ -187,9 +193,12 @@ TEST_F(VibratorHalControllerTest, TestInit) { } TEST_F(VibratorHalControllerTest, TestApiCallsAreForwardedToHal) { - std::vector<Effect> supportedEffects; - supportedEffects.push_back(Effect::CLICK); - supportedEffects.push_back(Effect::TICK); + 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)); @@ -199,7 +208,8 @@ TEST_F(VibratorHalControllerTest, TestApiCallsAreForwardedToHal) { setHalExpectations(/* cardinality= */ 1, compositeEffects, vibrator::HalResult<void>::ok(), vibrator::HalResult<vibrator::Capabilities>::ok( vibrator::Capabilities::ON_CALLBACK), - vibrator::HalResult<std::vector<Effect>>::ok(supportedEffects), + vibrator::HalResult<std::vector<Effect>>::ok(effects), + vibrator::HalResult<std::vector<CompositePrimitive>>::ok(primitives), vibrator::HalResult<milliseconds>::ok(100ms)); ASSERT_TRUE(mController->ping().isOk()); @@ -216,7 +226,11 @@ TEST_F(VibratorHalControllerTest, TestApiCallsAreForwardedToHal) { auto getSupportedEffectsResult = mController->getSupportedEffects(); ASSERT_TRUE(getSupportedEffectsResult.isOk()); - ASSERT_EQ(supportedEffects, getSupportedEffectsResult.value()); + ASSERT_EQ(effects, getSupportedEffectsResult.value()); + + auto getSupportedPrimitivesResult = mController->getSupportedPrimitives(); + ASSERT_TRUE(getSupportedPrimitivesResult.isOk()); + ASSERT_EQ(primitives, getSupportedPrimitivesResult.value()); auto performEffectResult = mController->performEffect(Effect::CLICK, EffectStrength::LIGHT, []() {}); @@ -233,6 +247,7 @@ TEST_F(VibratorHalControllerTest, TestUnsupportedApiResultDoNotResetHalConnectio vibrator::HalResult<void>::unsupported(), vibrator::HalResult<vibrator::Capabilities>::unsupported(), vibrator::HalResult<std::vector<Effect>>::unsupported(), + vibrator::HalResult<std::vector<CompositePrimitive>>::unsupported(), vibrator::HalResult<milliseconds>::unsupported()); ASSERT_EQ(0, mConnectCounter); @@ -247,6 +262,7 @@ TEST_F(VibratorHalControllerTest, TestUnsupportedApiResultDoNotResetHalConnectio ASSERT_TRUE(mController->alwaysOnDisable(1).isUnsupported()); ASSERT_TRUE(mController->getCapabilities().isUnsupported()); ASSERT_TRUE(mController->getSupportedEffects().isUnsupported()); + ASSERT_TRUE(mController->getSupportedPrimitives().isUnsupported()); ASSERT_TRUE(mController->performEffect(Effect::CLICK, EffectStrength::LIGHT, []() {}) .isUnsupported()); ASSERT_TRUE(mController->performComposedEffect(std::vector<CompositeEffect>(), []() {}) @@ -260,6 +276,7 @@ TEST_F(VibratorHalControllerTest, TestFailedApiResultResetsHalConnection) { vibrator::HalResult<void>::failed("message"), vibrator::HalResult<vibrator::Capabilities>::failed("message"), vibrator::HalResult<std::vector<Effect>>::failed("message"), + vibrator::HalResult<std::vector<CompositePrimitive>>::failed("message"), vibrator::HalResult<milliseconds>::failed("message")); ASSERT_EQ(0, mConnectCounter); @@ -273,6 +290,7 @@ TEST_F(VibratorHalControllerTest, TestFailedApiResultResetsHalConnection) { ASSERT_TRUE(mController->alwaysOnDisable(1).isFailed()); ASSERT_TRUE(mController->getCapabilities().isFailed()); ASSERT_TRUE(mController->getSupportedEffects().isFailed()); + ASSERT_TRUE(mController->getSupportedPrimitives().isFailed()); ASSERT_TRUE( mController->performEffect(Effect::CLICK, EffectStrength::LIGHT, []() {}).isFailed()); ASSERT_TRUE( @@ -331,13 +349,14 @@ TEST_F(VibratorHalControllerTest, TestNoVibratorReturnsUnsupportedAndAttemptsToR ASSERT_TRUE(mController->alwaysOnDisable(1).isUnsupported()); ASSERT_TRUE(mController->getCapabilities().isUnsupported()); ASSERT_TRUE(mController->getSupportedEffects().isUnsupported()); + ASSERT_TRUE(mController->getSupportedPrimitives().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(11, mConnectCounter); + ASSERT_EQ(12, mConnectCounter); } TEST_F(VibratorHalControllerTest, TestScheduledCallbackSurvivesReconnection) { diff --git a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp index 3e06c95620..96b76ba2fe 100644 --- a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp +++ b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp @@ -367,6 +367,50 @@ TEST_F(VibratorHalWrapperAidlTest, TestGetSupportedEffectsCachesResult) { ASSERT_EQ(supportedEffects, result.value()); } +TEST_F(VibratorHalWrapperAidlTest, TestGetSupportedPrimitivesDoesNotCacheFailedResult) { + std::vector<CompositePrimitive> supportedPrimitives; + supportedPrimitives.push_back(CompositePrimitive::CLICK); + supportedPrimitives.push_back(CompositePrimitive::THUD); + + EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_)) + .Times(Exactly(3)) + .WillOnce( + Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION))) + .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY))) + .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status()))); + + ASSERT_TRUE(mWrapper->getSupportedPrimitives().isUnsupported()); + ASSERT_TRUE(mWrapper->getSupportedPrimitives().isFailed()); + + auto result = mWrapper->getSupportedPrimitives(); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(supportedPrimitives, result.value()); +} + +TEST_F(VibratorHalWrapperAidlTest, TestGetSupportedPrimitivesCachesResult) { + std::vector<CompositePrimitive> supportedPrimitives; + supportedPrimitives.push_back(CompositePrimitive::CLICK); + supportedPrimitives.push_back(CompositePrimitive::THUD); + + EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_)) + .Times(Exactly(1)) + .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status()))); + + std::vector<std::thread> threads; + for (int i = 0; i < 10; i++) { + threads.push_back(std::thread([&]() { + auto result = mWrapper->getSupportedPrimitives(); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(supportedPrimitives, result.value()); + })); + } + std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); }); + + auto result = mWrapper->getSupportedPrimitives(); + ASSERT_TRUE(result.isOk()); + ASSERT_EQ(supportedPrimitives, result.value()); +} + TEST_F(VibratorHalWrapperAidlTest, TestPerformEffectWithCallbackSupport) { { InSequence seq; diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp index 7eb4059279..06aa36f91a 100644 --- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp +++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp @@ -236,6 +236,10 @@ TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetSupportedEffectsUnsupported) { ASSERT_TRUE(mWrapper->getSupportedEffects().isUnsupported()); } +TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetSupportedPrimitivesUnsupported) { + ASSERT_TRUE(mWrapper->getSupportedPrimitives().isUnsupported()); +} + TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformEffect) { { InSequence seq; |