Add getSupportedPrimitives to vibrator HAL wrapper
Expose the IVibrator.aidl getSupportedPrimitives method to be used by
the VibratorService.
Fix: b/163484172
Test: atest libvibratorservice_test
Change-Id: I6dfa0df6993837c45365a2f2c051cb1462b9d155
diff --git a/services/vibratorservice/VibratorHalController.cpp b/services/vibratorservice/VibratorHalController.cpp
index a9da74f..46175ad 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 @@
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 ee891de..ce20aeb 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 @@
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 @@
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 @@
}
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 daf2c8c..3b61f42 100644
--- a/services/vibratorservice/include/vibratorservice/VibratorHalController.h
+++ b/services/vibratorservice/include/vibratorservice/VibratorHalController.h
@@ -69,6 +69,8 @@
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 6e36bd6..7b99bbb 100644
--- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
+++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
@@ -156,6 +156,8 @@
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 @@
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 @@
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 @@
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 8155df0..f04e016 100644
--- a/services/vibratorservice/test/VibratorHalControllerTest.cpp
+++ b/services/vibratorservice/test/VibratorHalControllerTest.cpp
@@ -65,6 +65,8 @@
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 @@
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 @@
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 @@
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, 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 3e06c95..96b76ba 100644
--- a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
@@ -367,6 +367,50 @@
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 7eb4059..06aa36f 100644
--- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
@@ -236,6 +236,10 @@
ASSERT_TRUE(mWrapper->getSupportedEffects().isUnsupported());
}
+TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetSupportedPrimitivesUnsupported) {
+ ASSERT_TRUE(mWrapper->getSupportedPrimitives().isUnsupported());
+}
+
TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformEffect) {
{
InSequence seq;