• 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_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