• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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