1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "VibratorHalWrapperHidlV1_0Test"
18
19 #include <android/hardware/vibrator/IVibrator.h>
20
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23
24 #include <utils/Log.h>
25 #include <thread>
26
27 #include <vibratorservice/VibratorCallbackScheduler.h>
28 #include <vibratorservice/VibratorHalWrapper.h>
29
30 #include "test_utils.h"
31
32 namespace V1_0 = android::hardware::vibrator::V1_0;
33
34 using android::hardware::vibrator::Braking;
35 using android::hardware::vibrator::CompositeEffect;
36 using android::hardware::vibrator::CompositePrimitive;
37 using android::hardware::vibrator::Effect;
38 using android::hardware::vibrator::EffectStrength;
39 using android::hardware::vibrator::IVibrator;
40 using android::hardware::vibrator::PrimitivePwle;
41
42 using namespace android;
43 using namespace std::chrono_literals;
44 using namespace testing;
45
46 // -------------------------------------------------------------------------------------------------
47
48 class MockIVibratorV1_0 : public V1_0::IVibrator {
49 public:
50 MOCK_METHOD(hardware::Return<void>, ping, (), (override));
51 MOCK_METHOD(hardware::Return<V1_0::Status>, on, (uint32_t timeoutMs), (override));
52 MOCK_METHOD(hardware::Return<V1_0::Status>, off, (), (override));
53 MOCK_METHOD(hardware::Return<bool>, supportsAmplitudeControl, (), (override));
54 MOCK_METHOD(hardware::Return<V1_0::Status>, setAmplitude, (uint8_t amplitude), (override));
55 MOCK_METHOD(hardware::Return<void>, perform,
56 (V1_0::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override));
57 };
58
59 // -------------------------------------------------------------------------------------------------
60
61 class VibratorHalWrapperHidlV1_0Test : public Test {
62 public:
SetUp()63 void SetUp() override {
64 mMockHal = new StrictMock<MockIVibratorV1_0>();
65 mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>();
66 mWrapper = std::make_unique<vibrator::HidlHalWrapperV1_0>(mMockScheduler, mMockHal);
67 ASSERT_NE(mWrapper, nullptr);
68 }
69
70 protected:
71 std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr;
72 std::unique_ptr<vibrator::HalWrapper> mWrapper = nullptr;
73 sp<StrictMock<MockIVibratorV1_0>> mMockHal = nullptr;
74 };
75
76 // -------------------------------------------------------------------------------------------------
77
TEST_F(VibratorHalWrapperHidlV1_0Test,TestPing)78 TEST_F(VibratorHalWrapperHidlV1_0Test, TestPing) {
79 EXPECT_CALL(*mMockHal.get(), ping())
80 .Times(Exactly(2))
81 .WillOnce([]() { return hardware::Return<void>(); })
82 .WillRepeatedly([]() {
83 return hardware::Return<void>(hardware::Status::fromExceptionCode(-1));
84 });
85
86 ASSERT_TRUE(mWrapper->ping().isOk());
87 ASSERT_TRUE(mWrapper->ping().isFailed());
88 }
89
TEST_F(VibratorHalWrapperHidlV1_0Test,TestOn)90 TEST_F(VibratorHalWrapperHidlV1_0Test, TestOn) {
91 {
92 InSequence seq;
93 EXPECT_CALL(*mMockHal.get(), on(Eq(static_cast<uint32_t>(1))))
94 .Times(Exactly(1))
95 .WillRepeatedly(
96 [](uint32_t) { return hardware::Return<V1_0::Status>(V1_0::Status::OK); });
97 EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(1ms)))
98 .Times(Exactly(1))
99 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
100 EXPECT_CALL(*mMockHal.get(), on(Eq(static_cast<uint32_t>(10))))
101 .Times(Exactly(1))
102 .WillRepeatedly([](uint32_t) {
103 return hardware::Return<V1_0::Status>(V1_0::Status::UNSUPPORTED_OPERATION);
104 });
105 EXPECT_CALL(*mMockHal.get(), on(Eq(static_cast<uint32_t>(11))))
106 .Times(Exactly(1))
107 .WillRepeatedly([](uint32_t) {
108 return hardware::Return<V1_0::Status>(V1_0::Status::BAD_VALUE);
109 });
110 EXPECT_CALL(*mMockHal.get(), on(Eq(static_cast<uint32_t>(12))))
111 .Times(Exactly(1))
112 .WillRepeatedly([](uint32_t) {
113 return hardware::Return<V1_0::Status>(hardware::Status::fromExceptionCode(-1));
114 });
115 }
116
117 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
118 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
119
120 ASSERT_TRUE(mWrapper->on(1ms, callback).isOk());
121 ASSERT_EQ(1, *callbackCounter.get());
122
123 ASSERT_TRUE(mWrapper->on(10ms, callback).isUnsupported());
124 ASSERT_TRUE(mWrapper->on(11ms, callback).isFailed());
125 ASSERT_TRUE(mWrapper->on(12ms, callback).isFailed());
126
127 // Callback not triggered for unsupported and on failure
128 ASSERT_EQ(1, *callbackCounter.get());
129 }
130
TEST_F(VibratorHalWrapperHidlV1_0Test,TestOff)131 TEST_F(VibratorHalWrapperHidlV1_0Test, TestOff) {
132 EXPECT_CALL(*mMockHal.get(), off())
133 .Times(Exactly(4))
134 .WillOnce([]() { return hardware::Return<V1_0::Status>(V1_0::Status::OK); })
135 .WillOnce([]() {
136 return hardware::Return<V1_0::Status>(V1_0::Status::UNSUPPORTED_OPERATION);
137 })
138 .WillOnce([]() { return hardware::Return<V1_0::Status>(V1_0::Status::BAD_VALUE); })
139 .WillRepeatedly([]() {
140 return hardware::Return<V1_0::Status>(hardware::Status::fromExceptionCode(-1));
141 });
142
143 ASSERT_TRUE(mWrapper->off().isOk());
144 ASSERT_TRUE(mWrapper->off().isUnsupported());
145 ASSERT_TRUE(mWrapper->off().isFailed());
146 ASSERT_TRUE(mWrapper->off().isFailed());
147 }
148
TEST_F(VibratorHalWrapperHidlV1_0Test,TestSetAmplitude)149 TEST_F(VibratorHalWrapperHidlV1_0Test, TestSetAmplitude) {
150 {
151 InSequence seq;
152 EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(static_cast<uint8_t>(1))))
153 .Times(Exactly(1))
154 .WillRepeatedly(
155 [](uint8_t) { return hardware::Return<V1_0::Status>(V1_0::Status::OK); });
156 EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(static_cast<uint8_t>(2))))
157 .Times(Exactly(1))
158 .WillRepeatedly([](uint8_t) {
159 return hardware::Return<V1_0::Status>(V1_0::Status::UNSUPPORTED_OPERATION);
160 });
161 EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(static_cast<uint8_t>(3))))
162 .Times(Exactly(1))
163 .WillRepeatedly([](uint8_t) {
164 return hardware::Return<V1_0::Status>(V1_0::Status::BAD_VALUE);
165 });
166 EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(static_cast<uint8_t>(4))))
167 .Times(Exactly(1))
168 .WillRepeatedly([](uint8_t) {
169 return hardware::Return<V1_0::Status>(hardware::Status::fromExceptionCode(-1));
170 });
171 }
172
173 auto maxAmplitude = std::numeric_limits<uint8_t>::max();
174 ASSERT_TRUE(mWrapper->setAmplitude(1.0f / maxAmplitude).isOk());
175 ASSERT_TRUE(mWrapper->setAmplitude(2.0f / maxAmplitude).isUnsupported());
176 ASSERT_TRUE(mWrapper->setAmplitude(3.0f / maxAmplitude).isFailed());
177 ASSERT_TRUE(mWrapper->setAmplitude(4.0f / maxAmplitude).isFailed());
178 }
179
TEST_F(VibratorHalWrapperHidlV1_0Test,TestSetExternalControlUnsupported)180 TEST_F(VibratorHalWrapperHidlV1_0Test, TestSetExternalControlUnsupported) {
181 ASSERT_TRUE(mWrapper->setExternalControl(true).isUnsupported());
182 ASSERT_TRUE(mWrapper->setExternalControl(false).isUnsupported());
183 }
184
TEST_F(VibratorHalWrapperHidlV1_0Test,TestAlwaysOnEnableUnsupported)185 TEST_F(VibratorHalWrapperHidlV1_0Test, TestAlwaysOnEnableUnsupported) {
186 ASSERT_TRUE(mWrapper->alwaysOnEnable(1, Effect::CLICK, EffectStrength::LIGHT).isUnsupported());
187 }
188
TEST_F(VibratorHalWrapperHidlV1_0Test,TestAlwaysOnDisableUnsupported)189 TEST_F(VibratorHalWrapperHidlV1_0Test, TestAlwaysOnDisableUnsupported) {
190 ASSERT_TRUE(mWrapper->alwaysOnDisable(1).isUnsupported());
191 }
192
TEST_F(VibratorHalWrapperHidlV1_0Test,TestGetInfoDoesNotCacheFailedResult)193 TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoDoesNotCacheFailedResult) {
194 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl())
195 .Times(Exactly(2))
196 .WillOnce([]() {
197 return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1));
198 })
199 .WillRepeatedly([]() { return hardware::Return<bool>(true); });
200
201 ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed());
202
203 vibrator::Info info = mWrapper->getInfo();
204 ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, info.capabilities.value());
205 ASSERT_TRUE(info.supportedEffects.isUnsupported());
206 ASSERT_TRUE(info.supportedBraking.isUnsupported());
207 ASSERT_TRUE(info.supportedPrimitives.isUnsupported());
208 ASSERT_TRUE(info.primitiveDurations.isUnsupported());
209 ASSERT_TRUE(info.primitiveDelayMax.isUnsupported());
210 ASSERT_TRUE(info.pwlePrimitiveDurationMax.isUnsupported());
211 ASSERT_TRUE(info.compositionSizeMax.isUnsupported());
212 ASSERT_TRUE(info.pwleSizeMax.isUnsupported());
213 ASSERT_TRUE(info.minFrequency.isUnsupported());
214 ASSERT_TRUE(info.resonantFrequency.isUnsupported());
215 ASSERT_TRUE(info.frequencyResolution.isUnsupported());
216 ASSERT_TRUE(info.qFactor.isUnsupported());
217 ASSERT_TRUE(info.maxAmplitudes.isUnsupported());
218 }
219
TEST_F(VibratorHalWrapperHidlV1_0Test,TestGetInfoWithoutAmplitudeControl)220 TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoWithoutAmplitudeControl) {
221 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()).Times(Exactly(1)).WillRepeatedly([]() {
222 return hardware::Return<bool>(false);
223 });
224
225 ASSERT_EQ(vibrator::Capabilities::NONE, mWrapper->getInfo().capabilities.value());
226 }
227
TEST_F(VibratorHalWrapperHidlV1_0Test,TestGetInfoCachesResult)228 TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoCachesResult) {
229 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()).Times(Exactly(1)).WillRepeatedly([]() {
230 return hardware::Return<bool>(true);
231 });
232
233 std::vector<std::thread> threads;
234 for (int i = 0; i < 10; i++) {
235 threads.push_back(
236 std::thread([&]() { ASSERT_TRUE(mWrapper->getInfo().capabilities.isOk()); }));
237 }
238 std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
239
240 vibrator::Info info = mWrapper->getInfo();
241 ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, info.capabilities.value());
242 ASSERT_TRUE(info.supportedEffects.isUnsupported());
243 ASSERT_TRUE(info.supportedBraking.isUnsupported());
244 ASSERT_TRUE(info.supportedPrimitives.isUnsupported());
245 ASSERT_TRUE(info.primitiveDurations.isUnsupported());
246 ASSERT_TRUE(info.minFrequency.isUnsupported());
247 ASSERT_TRUE(info.resonantFrequency.isUnsupported());
248 ASSERT_TRUE(info.frequencyResolution.isUnsupported());
249 ASSERT_TRUE(info.qFactor.isUnsupported());
250 ASSERT_TRUE(info.maxAmplitudes.isUnsupported());
251 }
252
TEST_F(VibratorHalWrapperHidlV1_0Test,TestPerformEffect)253 TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformEffect) {
254 {
255 InSequence seq;
256 EXPECT_CALL(*mMockHal.get(),
257 perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::LIGHT), _))
258 .Times(Exactly(1))
259 .WillRepeatedly(
260 [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_0::perform_cb cb) {
261 cb(V1_0::Status::OK, 10);
262 return hardware::Return<void>();
263 });
264 EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
265 .Times(Exactly(1))
266 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
267 EXPECT_CALL(*mMockHal.get(),
268 perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::MEDIUM), _))
269 .Times(Exactly(1))
270 .WillRepeatedly(
271 [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_0::perform_cb cb) {
272 cb(V1_0::Status::UNSUPPORTED_OPERATION, 10);
273 return hardware::Return<void>();
274 });
275 EXPECT_CALL(*mMockHal.get(),
276 perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::STRONG), _))
277 .Times(Exactly(2))
278 .WillOnce([](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_0::perform_cb cb) {
279 cb(V1_0::Status::BAD_VALUE, 10);
280 return hardware::Return<void>();
281 })
282 .WillRepeatedly(
283 [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_0::perform_cb) {
284 return hardware::Return<void>(hardware::Status::fromExceptionCode(-1));
285 });
286 }
287
288 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
289 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
290
291 auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback);
292 ASSERT_TRUE(result.isOk());
293 ASSERT_EQ(10ms, result.value());
294 ASSERT_EQ(1, *callbackCounter.get());
295
296 result = mWrapper->performEffect(Effect::CLICK, EffectStrength::MEDIUM, callback);
297 ASSERT_TRUE(result.isUnsupported());
298
299 result = mWrapper->performEffect(Effect::CLICK, EffectStrength::STRONG, callback);
300 ASSERT_TRUE(result.isFailed());
301
302 result = mWrapper->performEffect(Effect::CLICK, EffectStrength::STRONG, callback);
303 ASSERT_TRUE(result.isFailed());
304
305 // Callback not triggered for unsupported and on failure
306 ASSERT_EQ(1, *callbackCounter.get());
307 }
308
TEST_F(VibratorHalWrapperHidlV1_0Test,TestPerformEffectUnsupported)309 TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformEffectUnsupported) {
310 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
311 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
312 // Using TICK that is only available in v1.1
313 auto result = mWrapper->performEffect(Effect::TICK, EffectStrength::LIGHT, callback);
314 ASSERT_TRUE(result.isUnsupported());
315 // No callback is triggered.
316 ASSERT_EQ(0, *callbackCounter.get());
317 }
318
TEST_F(VibratorHalWrapperHidlV1_0Test,TestPerformComposedEffectUnsupported)319 TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformComposedEffectUnsupported) {
320 std::vector<CompositeEffect> emptyEffects, singleEffect, multipleEffects;
321 singleEffect.push_back(
322 vibrator::TestFactory::createCompositeEffect(CompositePrimitive::CLICK, 10ms, 0.0f));
323 multipleEffects.push_back(
324 vibrator::TestFactory::createCompositeEffect(CompositePrimitive::SPIN, 100ms, 0.5f));
325 multipleEffects.push_back(
326 vibrator::TestFactory::createCompositeEffect(CompositePrimitive::THUD, 1000ms, 1.0f));
327
328 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
329 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
330
331 ASSERT_TRUE(mWrapper->performComposedEffect(singleEffect, callback).isUnsupported());
332 ASSERT_TRUE(mWrapper->performComposedEffect(multipleEffects, callback).isUnsupported());
333
334 // No callback is triggered.
335 ASSERT_EQ(0, *callbackCounter.get());
336 }
337
TEST_F(VibratorHalWrapperHidlV1_0Test,TestPerformPwleEffectUnsupported)338 TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformPwleEffectUnsupported) {
339 std::vector<PrimitivePwle> emptyPrimitives, multiplePrimitives;
340 multiplePrimitives.push_back(vibrator::TestFactory::createActivePwle(0, 1, 0, 1, 10ms));
341 multiplePrimitives.push_back(vibrator::TestFactory::createBrakingPwle(Braking::NONE, 100ms));
342
343 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
344 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
345
346 ASSERT_TRUE(mWrapper->performPwleEffect(emptyPrimitives, callback).isUnsupported());
347 ASSERT_TRUE(mWrapper->performPwleEffect(multiplePrimitives, callback).isUnsupported());
348
349 // No callback is triggered.
350 ASSERT_EQ(0, *callbackCounter.get());
351 }
352