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_3Test"
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 namespace V1_1 = android::hardware::vibrator::V1_1;
34 namespace V1_2 = android::hardware::vibrator::V1_2;
35 namespace V1_3 = android::hardware::vibrator::V1_3;
36
37 using android::hardware::vibrator::Effect;
38 using android::hardware::vibrator::EffectStrength;
39 using android::hardware::vibrator::IVibrator;
40
41 using namespace android;
42 using namespace std::chrono_literals;
43 using namespace testing;
44
45 // -------------------------------------------------------------------------------------------------
46
47 class MockIVibratorV1_3 : public V1_3::IVibrator {
48 public:
49 MOCK_METHOD(hardware::Return<V1_0::Status>, on, (uint32_t timeoutMs), (override));
50 MOCK_METHOD(hardware::Return<V1_0::Status>, off, (), (override));
51 MOCK_METHOD(hardware::Return<bool>, supportsAmplitudeControl, (), (override));
52 MOCK_METHOD(hardware::Return<bool>, supportsExternalControl, (), (override));
53 MOCK_METHOD(hardware::Return<V1_0::Status>, setAmplitude, (uint8_t amplitude), (override));
54 MOCK_METHOD(hardware::Return<V1_0::Status>, setExternalControl, (bool enabled), (override));
55 MOCK_METHOD(hardware::Return<void>, perform,
56 (V1_0::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override));
57 MOCK_METHOD(hardware::Return<void>, perform_1_1,
58 (V1_1::Effect_1_1 effect, V1_0::EffectStrength strength, perform_cb cb),
59 (override));
60 MOCK_METHOD(hardware::Return<void>, perform_1_2,
61 (V1_2::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override));
62 MOCK_METHOD(hardware::Return<void>, perform_1_3,
63 (V1_3::Effect effect, V1_0::EffectStrength strength, perform_cb cb), (override));
64 };
65
66 // -------------------------------------------------------------------------------------------------
67
68 class VibratorHalWrapperHidlV1_3Test : public Test {
69 public:
SetUp()70 void SetUp() override {
71 mMockHal = new StrictMock<MockIVibratorV1_3>();
72 mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>();
73 mWrapper = std::make_unique<vibrator::HidlHalWrapperV1_3>(mMockScheduler, mMockHal);
74 ASSERT_NE(mWrapper, nullptr);
75 }
76
77 protected:
78 std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr;
79 std::unique_ptr<vibrator::HalWrapper> mWrapper = nullptr;
80 sp<StrictMock<MockIVibratorV1_3>> mMockHal = nullptr;
81 };
82
83 // -------------------------------------------------------------------------------------------------
84
TEST_F(VibratorHalWrapperHidlV1_3Test,TestSetExternalControl)85 TEST_F(VibratorHalWrapperHidlV1_3Test, TestSetExternalControl) {
86 {
87 InSequence seq;
88 EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(true)))
89 .Times(Exactly(2))
90 .WillOnce([]() { return hardware::Return<V1_0::Status>(V1_0::Status::OK); })
91 .WillRepeatedly([]() {
92 return hardware::Return<V1_0::Status>(V1_0::Status::UNSUPPORTED_OPERATION);
93 });
94 EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(false)))
95 .Times(Exactly(2))
96 .WillOnce([]() { return hardware::Return<V1_0::Status>(V1_0::Status::BAD_VALUE); })
97 .WillRepeatedly([]() {
98 return hardware::Return<V1_0::Status>(hardware::Status::fromExceptionCode(-1));
99 });
100 }
101
102 ASSERT_TRUE(mWrapper->setExternalControl(true).isOk());
103 ASSERT_TRUE(mWrapper->setExternalControl(true).isUnsupported());
104 ASSERT_TRUE(mWrapper->setExternalControl(false).isFailed());
105 ASSERT_TRUE(mWrapper->setExternalControl(false).isFailed());
106 }
107
TEST_F(VibratorHalWrapperHidlV1_3Test,TestGetInfoSuccessful)108 TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoSuccessful) {
109 {
110 InSequence seq;
111 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl())
112 .Times(Exactly(1))
113 .WillRepeatedly([]() { return hardware::Return<bool>(true); });
114 EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() {
115 return hardware::Return<bool>(true);
116 });
117 }
118
119 ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL | vibrator::Capabilities::EXTERNAL_CONTROL |
120 vibrator::Capabilities::EXTERNAL_AMPLITUDE_CONTROL,
121 mWrapper->getInfo().capabilities.value());
122 }
123
TEST_F(VibratorHalWrapperHidlV1_3Test,TestGetInfoOnlyAmplitudeControl)124 TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoOnlyAmplitudeControl) {
125 {
126 InSequence seq;
127 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()).Times(Exactly(1)).WillOnce([]() {
128 return hardware::Return<bool>(true);
129 });
130 EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() {
131 return hardware::Return<bool>(false);
132 });
133 }
134
135 ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, mWrapper->getInfo().capabilities.value());
136 }
137
TEST_F(VibratorHalWrapperHidlV1_3Test,TestGetInfoOnlyExternalControl)138 TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoOnlyExternalControl) {
139 {
140 InSequence seq;
141 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl()).Times(Exactly(1)).WillOnce([]() {
142 return hardware::Return<bool>(false);
143 });
144 EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() {
145 return hardware::Return<bool>(true);
146 });
147 }
148
149 ASSERT_EQ(vibrator::Capabilities::EXTERNAL_CONTROL, mWrapper->getInfo().capabilities.value());
150 }
151
TEST_F(VibratorHalWrapperHidlV1_3Test,TestGetInfoNoCapabilities)152 TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoNoCapabilities) {
153 {
154 InSequence seq;
155 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl())
156 .Times(Exactly(1))
157 .WillRepeatedly([]() { return hardware::Return<bool>(false); });
158 EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() {
159 return hardware::Return<bool>(false);
160 });
161 }
162
163 ASSERT_EQ(vibrator::Capabilities::NONE, mWrapper->getInfo().capabilities.value());
164 }
165
TEST_F(VibratorHalWrapperHidlV1_3Test,TestGetInfoFailed)166 TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoFailed) {
167 {
168 InSequence seq;
169 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl())
170 .Times(Exactly(1))
171 .WillRepeatedly([]() {
172 return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1));
173 });
174
175 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl())
176 .Times(Exactly(1))
177 .WillRepeatedly([]() { return hardware::Return<bool>(true); });
178 EXPECT_CALL(*mMockHal.get(), supportsExternalControl())
179 .Times(Exactly(1))
180 .WillRepeatedly([]() {
181 return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1));
182 });
183 }
184
185 ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed());
186 ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed());
187 }
188
TEST_F(VibratorHalWrapperHidlV1_3Test,TestGetInfoCachesResult)189 TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoCachesResult) {
190 {
191 InSequence seq;
192 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl())
193 .Times(Exactly(1))
194 .WillRepeatedly([]() { return hardware::Return<bool>(true); });
195 EXPECT_CALL(*mMockHal.get(), supportsExternalControl()).Times(Exactly(1)).WillOnce([]() {
196 return hardware::Return<bool>(false);
197 });
198 }
199
200 std::vector<std::thread> threads;
201 for (int i = 0; i < 10; i++) {
202 threads.push_back(
203 std::thread([&]() { ASSERT_TRUE(mWrapper->getInfo().capabilities.isOk()); }));
204 }
205 std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
206
207 ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, mWrapper->getInfo().capabilities.value());
208 }
209
TEST_F(VibratorHalWrapperHidlV1_3Test,TestGetInfoDoesNotCacheFailedResult)210 TEST_F(VibratorHalWrapperHidlV1_3Test, TestGetInfoDoesNotCacheFailedResult) {
211 {
212 InSequence seq;
213 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl())
214 .Times(Exactly(1))
215 .WillRepeatedly([]() {
216 return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1));
217 });
218
219 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl())
220 .Times(Exactly(1))
221 .WillRepeatedly([]() { return hardware::Return<bool>(true); });
222 EXPECT_CALL(*mMockHal.get(), supportsExternalControl())
223 .Times(Exactly(1))
224 .WillRepeatedly([]() {
225 return hardware::Return<bool>(hardware::Status::fromExceptionCode(-1));
226 });
227
228 EXPECT_CALL(*mMockHal.get(), supportsAmplitudeControl())
229 .Times(Exactly(1))
230 .WillRepeatedly([]() { return hardware::Return<bool>(true); });
231 EXPECT_CALL(*mMockHal.get(), supportsExternalControl())
232 .Times(Exactly(1))
233 .WillRepeatedly([]() { return hardware::Return<bool>(false); });
234 }
235
236 // Call to supportsAmplitudeControl failed.
237 ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed());
238
239 // Call to supportsExternalControl failed.
240 ASSERT_TRUE(mWrapper->getInfo().capabilities.isFailed());
241
242 // Returns successful result from third call.
243 ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, mWrapper->getInfo().capabilities.value());
244
245 // Returns cached successful result.
246 ASSERT_EQ(vibrator::Capabilities::AMPLITUDE_CONTROL, mWrapper->getInfo().capabilities.value());
247 }
248
TEST_F(VibratorHalWrapperHidlV1_3Test,TestPerformEffectV1_0)249 TEST_F(VibratorHalWrapperHidlV1_3Test, TestPerformEffectV1_0) {
250 {
251 InSequence seq;
252 EXPECT_CALL(*mMockHal.get(),
253 perform(Eq(V1_0::Effect::CLICK), Eq(V1_0::EffectStrength::LIGHT), _))
254 .Times(Exactly(1))
255 .WillRepeatedly(
256 [](V1_0::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) {
257 cb(V1_0::Status::OK, 10);
258 return hardware::Return<void>();
259 });
260 EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
261 .Times(Exactly(1))
262 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
263 }
264
265 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
266 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
267 auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback);
268
269 ASSERT_TRUE(result.isOk());
270 ASSERT_EQ(10ms, result.value());
271 ASSERT_EQ(1, *callbackCounter.get());
272 }
273
TEST_F(VibratorHalWrapperHidlV1_3Test,TestPerformEffectV1_1)274 TEST_F(VibratorHalWrapperHidlV1_3Test, TestPerformEffectV1_1) {
275 {
276 InSequence seq;
277 EXPECT_CALL(*mMockHal.get(),
278 perform_1_1(Eq(V1_1::Effect_1_1::TICK), Eq(V1_0::EffectStrength::LIGHT), _))
279 .Times(Exactly(1))
280 .WillRepeatedly([](V1_1::Effect_1_1, V1_0::EffectStrength,
281 MockIVibratorV1_3::perform_cb cb) {
282 cb(V1_0::Status::OK, 10);
283 return hardware::Return<void>();
284 });
285 EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
286 .Times(Exactly(1))
287 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
288 }
289
290 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
291 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
292 auto result = mWrapper->performEffect(Effect::TICK, EffectStrength::LIGHT, callback);
293
294 ASSERT_TRUE(result.isOk());
295 ASSERT_EQ(10ms, result.value());
296 ASSERT_EQ(1, *callbackCounter.get());
297 }
298
TEST_F(VibratorHalWrapperHidlV1_3Test,TestPerformEffectV1_2)299 TEST_F(VibratorHalWrapperHidlV1_3Test, TestPerformEffectV1_2) {
300 {
301 InSequence seq;
302 EXPECT_CALL(*mMockHal.get(),
303 perform_1_2(Eq(V1_2::Effect::THUD), Eq(V1_0::EffectStrength::LIGHT), _))
304 .Times(Exactly(1))
305 .WillRepeatedly(
306 [](V1_2::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) {
307 cb(V1_0::Status::OK, 10);
308 return hardware::Return<void>();
309 });
310 EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
311 .Times(Exactly(1))
312 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
313 }
314
315 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
316 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
317 auto result = mWrapper->performEffect(Effect::THUD, EffectStrength::LIGHT, callback);
318
319 ASSERT_TRUE(result.isOk());
320 ASSERT_EQ(10ms, result.value());
321 ASSERT_EQ(1, *callbackCounter.get());
322 }
323
TEST_F(VibratorHalWrapperHidlV1_3Test,TestPerformEffectV1_3)324 TEST_F(VibratorHalWrapperHidlV1_3Test, TestPerformEffectV1_3) {
325 {
326 InSequence seq;
327 EXPECT_CALL(*mMockHal.get(),
328 perform_1_3(Eq(V1_3::Effect::TEXTURE_TICK), Eq(V1_0::EffectStrength::LIGHT), _))
329 .Times(Exactly(1))
330 .WillRepeatedly(
331 [](V1_3::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) {
332 cb(V1_0::Status::OK, 10);
333 return hardware::Return<void>();
334 });
335 EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
336 .Times(Exactly(1))
337 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
338 EXPECT_CALL(*mMockHal.get(),
339 perform_1_3(Eq(V1_3::Effect::TEXTURE_TICK), Eq(V1_0::EffectStrength::MEDIUM),
340 _))
341 .Times(Exactly(1))
342 .WillRepeatedly(
343 [](V1_3::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) {
344 cb(V1_0::Status::UNSUPPORTED_OPERATION, 0);
345 return hardware::Return<void>();
346 });
347 EXPECT_CALL(*mMockHal.get(),
348 perform_1_3(Eq(V1_3::Effect::TEXTURE_TICK), Eq(V1_0::EffectStrength::STRONG),
349 _))
350 .Times(Exactly(2))
351 .WillOnce([](V1_3::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb cb) {
352 cb(V1_0::Status::BAD_VALUE, 0);
353 return hardware::Return<void>();
354 })
355 .WillRepeatedly(
356 [](V1_3::Effect, V1_0::EffectStrength, MockIVibratorV1_3::perform_cb) {
357 return hardware::Return<void>(hardware::Status::fromExceptionCode(-1));
358 });
359 }
360
361 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
362 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
363
364 auto result = mWrapper->performEffect(Effect::TEXTURE_TICK, EffectStrength::LIGHT, callback);
365 ASSERT_TRUE(result.isOk());
366 ASSERT_EQ(10ms, result.value());
367 ASSERT_EQ(1, *callbackCounter.get());
368
369 result = mWrapper->performEffect(Effect::TEXTURE_TICK, EffectStrength::MEDIUM, callback);
370 ASSERT_TRUE(result.isUnsupported());
371
372 result = mWrapper->performEffect(Effect::TEXTURE_TICK, EffectStrength::STRONG, callback);
373 ASSERT_TRUE(result.isFailed());
374
375 result = mWrapper->performEffect(Effect::TEXTURE_TICK, EffectStrength::STRONG, callback);
376 ASSERT_TRUE(result.isFailed());
377
378 // Callback not triggered for unsupported and on failure
379 ASSERT_EQ(1, *callbackCounter.get());
380 }
381