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