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 "VibratorHalWrapperAidlTest"
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 using android::binder::Status;
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::IVibratorCallback;
41 using android::hardware::vibrator::PrimitivePwle;
42
43 using namespace android;
44 using namespace std::chrono_literals;
45 using namespace testing;
46
47 // -------------------------------------------------------------------------------------------------
48
49 class MockBinder : public BBinder {
50 public:
51 MOCK_METHOD(status_t, linkToDeath,
52 (const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags), (override));
53 MOCK_METHOD(status_t, unlinkToDeath,
54 (const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
55 wp<DeathRecipient>* outRecipient),
56 (override));
57 MOCK_METHOD(status_t, pingBinder, (), (override));
58 };
59
60 class MockIVibrator : public IVibrator {
61 public:
62 MOCK_METHOD(Status, getCapabilities, (int32_t * ret), (override));
63 MOCK_METHOD(Status, off, (), (override));
64 MOCK_METHOD(Status, on, (int32_t timeout, const sp<IVibratorCallback>& cb), (override));
65 MOCK_METHOD(Status, perform,
66 (Effect e, EffectStrength s, const sp<IVibratorCallback>& cb, int32_t* ret),
67 (override));
68 MOCK_METHOD(Status, getSupportedEffects, (std::vector<Effect> * ret), (override));
69 MOCK_METHOD(Status, setAmplitude, (float amplitude), (override));
70 MOCK_METHOD(Status, setExternalControl, (bool enabled), (override));
71 MOCK_METHOD(Status, getCompositionDelayMax, (int32_t * ret), (override));
72 MOCK_METHOD(Status, getCompositionSizeMax, (int32_t * ret), (override));
73 MOCK_METHOD(Status, getSupportedPrimitives, (std::vector<CompositePrimitive> * ret),
74 (override));
75 MOCK_METHOD(Status, getPrimitiveDuration, (CompositePrimitive p, int32_t* ret), (override));
76 MOCK_METHOD(Status, compose,
77 (const std::vector<CompositeEffect>& e, const sp<IVibratorCallback>& cb),
78 (override));
79 MOCK_METHOD(Status, composePwle,
80 (const std::vector<PrimitivePwle>& e, const sp<IVibratorCallback>& cb), (override));
81 MOCK_METHOD(Status, getSupportedAlwaysOnEffects, (std::vector<Effect> * ret), (override));
82 MOCK_METHOD(Status, alwaysOnEnable, (int32_t id, Effect e, EffectStrength s), (override));
83 MOCK_METHOD(Status, alwaysOnDisable, (int32_t id), (override));
84 MOCK_METHOD(Status, getQFactor, (float * ret), (override));
85 MOCK_METHOD(Status, getResonantFrequency, (float * ret), (override));
86 MOCK_METHOD(Status, getFrequencyResolution, (float* ret), (override));
87 MOCK_METHOD(Status, getFrequencyMinimum, (float* ret), (override));
88 MOCK_METHOD(Status, getBandwidthAmplitudeMap, (std::vector<float> * ret), (override));
89 MOCK_METHOD(Status, getPwlePrimitiveDurationMax, (int32_t * ret), (override));
90 MOCK_METHOD(Status, getPwleCompositionSizeMax, (int32_t * ret), (override));
91 MOCK_METHOD(Status, getSupportedBraking, (std::vector<Braking> * ret), (override));
92 MOCK_METHOD(int32_t, getInterfaceVersion, (), (override));
93 MOCK_METHOD(std::string, getInterfaceHash, (), (override));
94 MOCK_METHOD(IBinder*, onAsBinder, (), (override));
95 };
96
97 // -------------------------------------------------------------------------------------------------
98
99 class VibratorHalWrapperAidlTest : public Test {
100 public:
SetUp()101 void SetUp() override {
102 mMockBinder = new StrictMock<MockBinder>();
103 mMockHal = new StrictMock<MockIVibrator>();
104 mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>();
105 mWrapper = std::make_unique<vibrator::AidlHalWrapper>(mMockScheduler, mMockHal);
106 ASSERT_NE(mWrapper, nullptr);
107 }
108
109 protected:
110 std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr;
111 std::unique_ptr<vibrator::HalWrapper> mWrapper = nullptr;
112 sp<StrictMock<MockIVibrator>> mMockHal = nullptr;
113 sp<StrictMock<MockBinder>> mMockBinder = nullptr;
114 };
115
116 // -------------------------------------------------------------------------------------------------
117
ACTION(TriggerCallbackInArg1)118 ACTION(TriggerCallbackInArg1) {
119 if (arg1 != nullptr) {
120 arg1->onComplete();
121 }
122 }
123
ACTION(TriggerCallbackInArg2)124 ACTION(TriggerCallbackInArg2) {
125 if (arg2 != nullptr) {
126 arg2->onComplete();
127 }
128 }
129
TEST_F(VibratorHalWrapperAidlTest,TestPing)130 TEST_F(VibratorHalWrapperAidlTest, TestPing) {
131 EXPECT_CALL(*mMockHal.get(), onAsBinder())
132 .Times(Exactly(2))
133 .WillRepeatedly(Return(mMockBinder.get()));
134 EXPECT_CALL(*mMockBinder.get(), pingBinder())
135 .Times(Exactly(2))
136 .WillOnce(Return(android::OK))
137 .WillRepeatedly(Return(android::DEAD_OBJECT));
138
139 ASSERT_TRUE(mWrapper->ping().isOk());
140 ASSERT_TRUE(mWrapper->ping().isFailed());
141 }
142
TEST_F(VibratorHalWrapperAidlTest,TestOnWithCallbackSupport)143 TEST_F(VibratorHalWrapperAidlTest, TestOnWithCallbackSupport) {
144 {
145 InSequence seq;
146 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
147 .Times(Exactly(1))
148 .WillRepeatedly(
149 DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
150 EXPECT_CALL(*mMockHal.get(), on(Eq(10), _))
151 .Times(Exactly(1))
152 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
153 EXPECT_CALL(*mMockHal.get(), on(Eq(100), _))
154 .Times(Exactly(1))
155 .WillRepeatedly(Return(
156 Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
157 EXPECT_CALL(*mMockHal.get(), on(Eq(1000), _))
158 .Times(Exactly(1))
159 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
160 }
161
162 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
163 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
164
165 ASSERT_TRUE(mWrapper->on(10ms, callback).isOk());
166 ASSERT_EQ(1, *callbackCounter.get());
167
168 ASSERT_TRUE(mWrapper->on(100ms, callback).isUnsupported());
169 // Callback not triggered for unsupported
170 ASSERT_EQ(1, *callbackCounter.get());
171
172 ASSERT_TRUE(mWrapper->on(1000ms, callback).isFailed());
173 // Callback not triggered on failure
174 ASSERT_EQ(1, *callbackCounter.get());
175 }
176
TEST_F(VibratorHalWrapperAidlTest,TestOnWithoutCallbackSupport)177 TEST_F(VibratorHalWrapperAidlTest, TestOnWithoutCallbackSupport) {
178 {
179 InSequence seq;
180 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
181 .Times(Exactly(1))
182 .WillRepeatedly(
183 DoAll(SetArgPointee<0>(IVibrator::CAP_COMPOSE_EFFECTS), Return(Status())));
184 EXPECT_CALL(*mMockHal.get(), on(Eq(10), _))
185 .Times(Exactly(1))
186 .WillRepeatedly(Return(Status()));
187 EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
188 .Times(Exactly(1))
189 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
190 EXPECT_CALL(*mMockHal.get(), on(Eq(11), _))
191 .Times(Exactly(1))
192 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
193 EXPECT_CALL(*mMockHal.get(), on(Eq(12), _))
194 .Times(Exactly(1))
195 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
196 }
197
198 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
199 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
200
201 ASSERT_TRUE(mWrapper->on(10ms, callback).isOk());
202 ASSERT_EQ(1, *callbackCounter.get());
203
204 ASSERT_TRUE(mWrapper->on(11ms, callback).isUnsupported());
205 ASSERT_TRUE(mWrapper->on(12ms, callback).isFailed());
206
207 // Callback not triggered for unsupported and on failure
208 ASSERT_EQ(1, *callbackCounter.get());
209 }
210
TEST_F(VibratorHalWrapperAidlTest,TestOff)211 TEST_F(VibratorHalWrapperAidlTest, TestOff) {
212 EXPECT_CALL(*mMockHal.get(), off())
213 .Times(Exactly(3))
214 .WillOnce(Return(Status()))
215 .WillOnce(
216 Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)))
217 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
218
219 ASSERT_TRUE(mWrapper->off().isOk());
220 ASSERT_TRUE(mWrapper->off().isUnsupported());
221 ASSERT_TRUE(mWrapper->off().isFailed());
222 }
223
TEST_F(VibratorHalWrapperAidlTest,TestSetAmplitude)224 TEST_F(VibratorHalWrapperAidlTest, TestSetAmplitude) {
225 {
226 InSequence seq;
227 EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.1f))).Times(Exactly(1));
228 EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.2f)))
229 .Times(Exactly(1))
230 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
231 EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.5f)))
232 .Times(Exactly(1))
233 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
234 }
235
236 ASSERT_TRUE(mWrapper->setAmplitude(0.1f).isOk());
237 ASSERT_TRUE(mWrapper->setAmplitude(0.2f).isUnsupported());
238 ASSERT_TRUE(mWrapper->setAmplitude(0.5f).isFailed());
239 }
240
TEST_F(VibratorHalWrapperAidlTest,TestSetExternalControl)241 TEST_F(VibratorHalWrapperAidlTest, TestSetExternalControl) {
242 {
243 InSequence seq;
244 EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(true))).Times(Exactly(1));
245 EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(false)))
246 .Times(Exactly(2))
247 .WillOnce(Return(
248 Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)))
249 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
250 }
251
252 ASSERT_TRUE(mWrapper->setExternalControl(true).isOk());
253 ASSERT_TRUE(mWrapper->setExternalControl(false).isUnsupported());
254 ASSERT_TRUE(mWrapper->setExternalControl(false).isFailed());
255 }
256
TEST_F(VibratorHalWrapperAidlTest,TestAlwaysOnEnable)257 TEST_F(VibratorHalWrapperAidlTest, TestAlwaysOnEnable) {
258 {
259 InSequence seq;
260 EXPECT_CALL(*mMockHal.get(),
261 alwaysOnEnable(Eq(1), Eq(Effect::CLICK), Eq(EffectStrength::LIGHT)))
262 .Times(Exactly(1));
263 EXPECT_CALL(*mMockHal.get(),
264 alwaysOnEnable(Eq(2), Eq(Effect::TICK), Eq(EffectStrength::MEDIUM)))
265 .Times(Exactly(1))
266 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
267 EXPECT_CALL(*mMockHal.get(),
268 alwaysOnEnable(Eq(3), Eq(Effect::POP), Eq(EffectStrength::STRONG)))
269 .Times(Exactly(1))
270 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
271 }
272
273 auto result = mWrapper->alwaysOnEnable(1, Effect::CLICK, EffectStrength::LIGHT);
274 ASSERT_TRUE(result.isOk());
275 result = mWrapper->alwaysOnEnable(2, Effect::TICK, EffectStrength::MEDIUM);
276 ASSERT_TRUE(result.isUnsupported());
277 result = mWrapper->alwaysOnEnable(3, Effect::POP, EffectStrength::STRONG);
278 ASSERT_TRUE(result.isFailed());
279 }
280
TEST_F(VibratorHalWrapperAidlTest,TestAlwaysOnDisable)281 TEST_F(VibratorHalWrapperAidlTest, TestAlwaysOnDisable) {
282 {
283 InSequence seq;
284 EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(1))).Times(Exactly(1));
285 EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(2)))
286 .Times(Exactly(1))
287 .WillRepeatedly(Return(
288 Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
289 EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(3)))
290 .Times(Exactly(1))
291 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
292 }
293
294 ASSERT_TRUE(mWrapper->alwaysOnDisable(1).isOk());
295 ASSERT_TRUE(mWrapper->alwaysOnDisable(2).isUnsupported());
296 ASSERT_TRUE(mWrapper->alwaysOnDisable(3).isFailed());
297 }
298
TEST_F(VibratorHalWrapperAidlTest,TestGetInfoDoesNotCacheFailedResult)299 TEST_F(VibratorHalWrapperAidlTest, TestGetInfoDoesNotCacheFailedResult) {
300 constexpr float F_MIN = 100.f;
301 constexpr float F0 = 123.f;
302 constexpr float F_RESOLUTION = 0.5f;
303 constexpr float Q_FACTOR = 123.f;
304 constexpr int32_t COMPOSITION_SIZE_MAX = 10;
305 constexpr int32_t PWLE_SIZE_MAX = 20;
306 constexpr int32_t PRIMITIVE_DELAY_MAX = 100;
307 constexpr int32_t PWLE_DURATION_MAX = 200;
308 std::vector<Effect> supportedEffects = {Effect::CLICK, Effect::TICK};
309 std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::CLICK};
310 std::vector<Braking> supportedBraking = {Braking::CLAB};
311 std::vector<float> amplitudes = {0.f, 1.f, 0.f};
312
313 std::vector<std::chrono::milliseconds> primitiveDurations;
314 constexpr auto primitiveRange = enum_range<CompositePrimitive>();
315 constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
316 primitiveDurations.resize(primitiveCount);
317 primitiveDurations[static_cast<size_t>(CompositePrimitive::CLICK)] = 10ms;
318
319 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
320 .Times(Exactly(2))
321 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
322 .WillRepeatedly(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
323 EXPECT_CALL(*mMockHal.get(), getSupportedEffects(_))
324 .Times(Exactly(2))
325 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
326 .WillRepeatedly(DoAll(SetArgPointee<0>(supportedEffects), Return(Status())));
327 EXPECT_CALL(*mMockHal.get(), getSupportedBraking(_))
328 .Times(Exactly(2))
329 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
330 .WillRepeatedly(DoAll(SetArgPointee<0>(supportedBraking), Return(Status())));
331 EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
332 .Times(Exactly(2))
333 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
334 .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status())));
335 EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::CLICK), _))
336 .Times(Exactly(1))
337 .WillRepeatedly(DoAll(SetArgPointee<1>(10), Return(Status())));
338 EXPECT_CALL(*mMockHal.get(), getCompositionSizeMax(_))
339 .Times(Exactly(2))
340 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
341 .WillRepeatedly(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX), Return(Status())));
342 EXPECT_CALL(*mMockHal.get(), getCompositionDelayMax(_))
343 .Times(Exactly(2))
344 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
345 .WillRepeatedly(DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(Status())));
346 EXPECT_CALL(*mMockHal.get(), getPwlePrimitiveDurationMax(_))
347 .Times(Exactly(2))
348 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
349 .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(Status())));
350 EXPECT_CALL(*mMockHal.get(), getPwleCompositionSizeMax(_))
351 .Times(Exactly(2))
352 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
353 .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(Status())));
354 EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_))
355 .Times(Exactly(2))
356 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
357 .WillRepeatedly(DoAll(SetArgPointee<0>(F_MIN), Return(Status())));
358 EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_))
359 .Times(Exactly(2))
360 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
361 .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status())));
362 EXPECT_CALL(*mMockHal.get(), getFrequencyResolution(_))
363 .Times(Exactly(2))
364 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
365 .WillRepeatedly(DoAll(SetArgPointee<0>(F_RESOLUTION), Return(Status())));
366 EXPECT_CALL(*mMockHal.get(), getQFactor(_))
367 .Times(Exactly(2))
368 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
369 .WillRepeatedly(DoAll(SetArgPointee<0>(Q_FACTOR), Return(Status())));
370 EXPECT_CALL(*mMockHal.get(), getBandwidthAmplitudeMap(_))
371 .Times(Exactly(2))
372 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
373 .WillRepeatedly(DoAll(SetArgPointee<0>(amplitudes), Return(Status())));
374
375 vibrator::Info failed = mWrapper->getInfo();
376 ASSERT_TRUE(failed.capabilities.isFailed());
377 ASSERT_TRUE(failed.supportedEffects.isFailed());
378 ASSERT_TRUE(failed.supportedBraking.isFailed());
379 ASSERT_TRUE(failed.supportedPrimitives.isFailed());
380 ASSERT_TRUE(failed.primitiveDurations.isFailed());
381 ASSERT_TRUE(failed.primitiveDelayMax.isFailed());
382 ASSERT_TRUE(failed.pwlePrimitiveDurationMax.isFailed());
383 ASSERT_TRUE(failed.compositionSizeMax.isFailed());
384 ASSERT_TRUE(failed.pwleSizeMax.isFailed());
385 ASSERT_TRUE(failed.minFrequency.isFailed());
386 ASSERT_TRUE(failed.resonantFrequency.isFailed());
387 ASSERT_TRUE(failed.frequencyResolution.isFailed());
388 ASSERT_TRUE(failed.qFactor.isFailed());
389 ASSERT_TRUE(failed.maxAmplitudes.isFailed());
390
391 vibrator::Info successful = mWrapper->getInfo();
392 ASSERT_EQ(vibrator::Capabilities::ON_CALLBACK, successful.capabilities.value());
393 ASSERT_EQ(supportedEffects, successful.supportedEffects.value());
394 ASSERT_EQ(supportedBraking, successful.supportedBraking.value());
395 ASSERT_EQ(supportedPrimitives, successful.supportedPrimitives.value());
396 ASSERT_EQ(primitiveDurations, successful.primitiveDurations.value());
397 ASSERT_EQ(std::chrono::milliseconds(PRIMITIVE_DELAY_MAX), successful.primitiveDelayMax.value());
398 ASSERT_EQ(std::chrono::milliseconds(PWLE_DURATION_MAX),
399 successful.pwlePrimitiveDurationMax.value());
400 ASSERT_EQ(COMPOSITION_SIZE_MAX, successful.compositionSizeMax.value());
401 ASSERT_EQ(PWLE_SIZE_MAX, successful.pwleSizeMax.value());
402 ASSERT_EQ(F_MIN, successful.minFrequency.value());
403 ASSERT_EQ(F0, successful.resonantFrequency.value());
404 ASSERT_EQ(F_RESOLUTION, successful.frequencyResolution.value());
405 ASSERT_EQ(Q_FACTOR, successful.qFactor.value());
406 ASSERT_EQ(amplitudes, successful.maxAmplitudes.value());
407 }
408
TEST_F(VibratorHalWrapperAidlTest,TestGetInfoCachesResult)409 TEST_F(VibratorHalWrapperAidlTest, TestGetInfoCachesResult) {
410 constexpr float F_MIN = 100.f;
411 constexpr float F0 = 123.f;
412 constexpr int32_t COMPOSITION_SIZE_MAX = 10;
413 constexpr int32_t PWLE_SIZE_MAX = 20;
414 constexpr int32_t PRIMITIVE_DELAY_MAX = 100;
415 constexpr int32_t PWLE_DURATION_MAX = 200;
416 std::vector<Effect> supportedEffects = {Effect::CLICK, Effect::TICK};
417
418 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
419 .Times(Exactly(1))
420 .WillRepeatedly(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
421 EXPECT_CALL(*mMockHal.get(), getSupportedEffects(_))
422 .Times(Exactly(1))
423 .WillRepeatedly(DoAll(SetArgPointee<0>(supportedEffects), Return(Status())));
424 EXPECT_CALL(*mMockHal.get(), getQFactor(_))
425 .Times(Exactly(1))
426 .WillRepeatedly(
427 Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
428 EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
429 .Times(Exactly(1))
430 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
431 EXPECT_CALL(*mMockHal.get(), getCompositionSizeMax(_))
432 .Times(Exactly(1))
433 .WillRepeatedly(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX), Return(Status())));
434 EXPECT_CALL(*mMockHal.get(), getCompositionDelayMax(_))
435 .Times(Exactly(1))
436 .WillRepeatedly(DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(Status())));
437 EXPECT_CALL(*mMockHal.get(), getPwlePrimitiveDurationMax(_))
438 .Times(Exactly(1))
439 .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(Status())));
440 EXPECT_CALL(*mMockHal.get(), getPwleCompositionSizeMax(_))
441 .Times(Exactly(1))
442 .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(Status())));
443 EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_))
444 .Times(Exactly(1))
445 .WillRepeatedly(DoAll(SetArgPointee<0>(F_MIN), Return(Status())));
446 EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_))
447 .Times(Exactly(1))
448 .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status())));
449 EXPECT_CALL(*mMockHal.get(), getFrequencyResolution(_))
450 .Times(Exactly(1))
451 .WillRepeatedly(
452 Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
453 EXPECT_CALL(*mMockHal.get(), getBandwidthAmplitudeMap(_))
454 .Times(Exactly(1))
455 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
456 EXPECT_CALL(*mMockHal.get(), getSupportedBraking(_))
457 .Times(Exactly(1))
458 .WillRepeatedly(
459 Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
460
461 std::vector<std::thread> threads;
462 for (int i = 0; i < 10; i++) {
463 threads.push_back(
464 std::thread([&]() { ASSERT_TRUE(mWrapper->getInfo().capabilities.isOk()); }));
465 }
466 std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
467
468 vibrator::Info info = mWrapper->getInfo();
469 ASSERT_EQ(vibrator::Capabilities::ON_CALLBACK, info.capabilities.value());
470 ASSERT_EQ(supportedEffects, info.supportedEffects.value());
471 ASSERT_TRUE(info.supportedBraking.isUnsupported());
472 ASSERT_TRUE(info.supportedPrimitives.isUnsupported());
473 ASSERT_TRUE(info.primitiveDurations.isUnsupported());
474 ASSERT_EQ(std::chrono::milliseconds(PRIMITIVE_DELAY_MAX), info.primitiveDelayMax.value());
475 ASSERT_EQ(std::chrono::milliseconds(PWLE_DURATION_MAX), info.pwlePrimitiveDurationMax.value());
476 ASSERT_EQ(COMPOSITION_SIZE_MAX, info.compositionSizeMax.value());
477 ASSERT_EQ(PWLE_SIZE_MAX, info.pwleSizeMax.value());
478 ASSERT_EQ(F_MIN, info.minFrequency.value());
479 ASSERT_EQ(F0, info.resonantFrequency.value());
480 ASSERT_TRUE(info.frequencyResolution.isUnsupported());
481 ASSERT_TRUE(info.qFactor.isUnsupported());
482 ASSERT_TRUE(info.maxAmplitudes.isUnsupported());
483 }
484
TEST_F(VibratorHalWrapperAidlTest,TestPerformEffectWithCallbackSupport)485 TEST_F(VibratorHalWrapperAidlTest, TestPerformEffectWithCallbackSupport) {
486 {
487 InSequence seq;
488 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
489 .Times(Exactly(1))
490 .WillRepeatedly(
491 DoAll(SetArgPointee<0>(IVibrator::CAP_PERFORM_CALLBACK), Return(Status())));
492 EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::CLICK), Eq(EffectStrength::LIGHT), _, _))
493 .Times(Exactly(1))
494 .WillRepeatedly(
495 DoAll(SetArgPointee<3>(1000), TriggerCallbackInArg2(), Return(Status())));
496 EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::POP), Eq(EffectStrength::MEDIUM), _, _))
497 .Times(Exactly(1))
498 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
499 EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::THUD), Eq(EffectStrength::STRONG), _, _))
500 .Times(Exactly(1))
501 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
502 }
503
504 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
505 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
506
507 auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback);
508 ASSERT_TRUE(result.isOk());
509 ASSERT_EQ(1000ms, result.value());
510 ASSERT_EQ(1, *callbackCounter.get());
511
512 result = mWrapper->performEffect(Effect::POP, EffectStrength::MEDIUM, callback);
513 ASSERT_TRUE(result.isUnsupported());
514 // Callback not triggered for unsupported
515 ASSERT_EQ(1, *callbackCounter.get());
516
517 result = mWrapper->performEffect(Effect::THUD, EffectStrength::STRONG, callback);
518 ASSERT_TRUE(result.isFailed());
519 // Callback not triggered on failure
520 ASSERT_EQ(1, *callbackCounter.get());
521 }
522
TEST_F(VibratorHalWrapperAidlTest,TestPerformEffectWithoutCallbackSupport)523 TEST_F(VibratorHalWrapperAidlTest, TestPerformEffectWithoutCallbackSupport) {
524 {
525 InSequence seq;
526 EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
527 .Times(Exactly(1))
528 .WillRepeatedly(
529 DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
530 EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::CLICK), Eq(EffectStrength::LIGHT), _, _))
531 .Times(Exactly(1))
532 .WillRepeatedly(DoAll(SetArgPointee<3>(10), Return(Status())));
533 EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
534 .Times(Exactly(1))
535 .WillRepeatedly(vibrator::TriggerSchedulerCallback());
536 EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::POP), Eq(EffectStrength::MEDIUM), _, _))
537 .Times(Exactly(1))
538 .WillRepeatedly(Return(
539 Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
540 EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::THUD), Eq(EffectStrength::STRONG), _, _))
541 .Times(Exactly(1))
542 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
543 }
544
545 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
546 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
547
548 auto result = mWrapper->performEffect(Effect::CLICK, EffectStrength::LIGHT, callback);
549 ASSERT_TRUE(result.isOk());
550 ASSERT_EQ(10ms, result.value());
551 ASSERT_EQ(1, *callbackCounter.get());
552
553 result = mWrapper->performEffect(Effect::POP, EffectStrength::MEDIUM, callback);
554 ASSERT_TRUE(result.isUnsupported());
555
556 result = mWrapper->performEffect(Effect::THUD, EffectStrength::STRONG, callback);
557 ASSERT_TRUE(result.isFailed());
558
559 // Callback not triggered for unsupported and on failure
560 ASSERT_EQ(1, *callbackCounter.get());
561 }
562
TEST_F(VibratorHalWrapperAidlTest,TestPerformComposedEffect)563 TEST_F(VibratorHalWrapperAidlTest, TestPerformComposedEffect) {
564 std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::CLICK,
565 CompositePrimitive::SPIN,
566 CompositePrimitive::THUD};
567 std::vector<CompositeEffect> emptyEffects, singleEffect, multipleEffects;
568 singleEffect.push_back(
569 vibrator::TestFactory::createCompositeEffect(CompositePrimitive::CLICK, 10ms, 0.0f));
570 multipleEffects.push_back(
571 vibrator::TestFactory::createCompositeEffect(CompositePrimitive::SPIN, 100ms, 0.5f));
572 multipleEffects.push_back(
573 vibrator::TestFactory::createCompositeEffect(CompositePrimitive::THUD, 1000ms, 1.0f));
574
575 {
576 InSequence seq;
577 EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
578 .Times(Exactly(1))
579 .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status())));
580 EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::CLICK), _))
581 .Times(Exactly(1))
582 .WillRepeatedly(DoAll(SetArgPointee<1>(1), Return(Status())));
583 EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::SPIN), _))
584 .Times(Exactly(1))
585 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
586 EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::THUD), _))
587 .Times(Exactly(1))
588 .WillRepeatedly(DoAll(SetArgPointee<1>(3), Return(Status())));
589
590 EXPECT_CALL(*mMockHal.get(), compose(Eq(emptyEffects), _))
591 .Times(Exactly(1))
592 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
593 EXPECT_CALL(*mMockHal.get(), compose(Eq(singleEffect), _))
594 .Times(Exactly(1))
595 .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
596 EXPECT_CALL(*mMockHal.get(), compose(Eq(multipleEffects), _))
597 .Times(Exactly(1))
598 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
599 }
600
601 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
602 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
603
604 auto result = mWrapper->performComposedEffect(emptyEffects, callback);
605 ASSERT_TRUE(result.isOk());
606 ASSERT_EQ(0ms, result.value());
607 ASSERT_EQ(1, *callbackCounter.get());
608
609 result = mWrapper->performComposedEffect(singleEffect, callback);
610 ASSERT_TRUE(result.isUnsupported());
611 // Callback not triggered for unsupported
612 ASSERT_EQ(1, *callbackCounter.get());
613
614 result = mWrapper->performComposedEffect(multipleEffects, callback);
615 ASSERT_TRUE(result.isFailed());
616 // Callback not triggered on failure
617 ASSERT_EQ(1, *callbackCounter.get());
618 }
619
TEST_F(VibratorHalWrapperAidlTest,TestPerformComposedCachesPrimitiveDurationsAndIgnoresFailures)620 TEST_F(VibratorHalWrapperAidlTest, TestPerformComposedCachesPrimitiveDurationsAndIgnoresFailures) {
621 std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::SPIN,
622 CompositePrimitive::THUD};
623 std::vector<CompositeEffect> multipleEffects;
624 multipleEffects.push_back(
625 vibrator::TestFactory::createCompositeEffect(CompositePrimitive::SPIN, 10ms, 0.5f));
626 multipleEffects.push_back(
627 vibrator::TestFactory::createCompositeEffect(CompositePrimitive::THUD, 100ms, 1.0f));
628
629 {
630 InSequence seq;
631 EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
632 .Times(Exactly(1))
633 .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status())));
634 EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::SPIN), _))
635 .Times(Exactly(1))
636 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
637 EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::THUD), _))
638 .Times(Exactly(1))
639 .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
640 EXPECT_CALL(*mMockHal.get(), compose(Eq(multipleEffects), _))
641 .Times(Exactly(1))
642 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
643
644 EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::SPIN), _))
645 .Times(Exactly(1))
646 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
647 EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::THUD), _))
648 .Times(Exactly(1))
649 .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
650 EXPECT_CALL(*mMockHal.get(), compose(Eq(multipleEffects), _))
651 .Times(Exactly(2))
652 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
653 }
654
655 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
656 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
657
658 auto result = mWrapper->performComposedEffect(multipleEffects, callback);
659 ASSERT_TRUE(result.isOk());
660 ASSERT_EQ(112ms, result.value()); // Failed primitive durations counted as 1.
661 ASSERT_EQ(1, *callbackCounter.get());
662
663 result = mWrapper->performComposedEffect(multipleEffects, callback);
664 ASSERT_TRUE(result.isOk());
665 ASSERT_EQ(114ms, result.value()); // Second fetch succeeds and returns primitive duration.
666 ASSERT_EQ(2, *callbackCounter.get());
667
668 result = mWrapper->performComposedEffect(multipleEffects, callback);
669 ASSERT_TRUE(result.isOk());
670 ASSERT_EQ(114ms, result.value()); // Cached durations not fetched again, same duration returned.
671 ASSERT_EQ(3, *callbackCounter.get());
672 }
673
TEST_F(VibratorHalWrapperAidlTest,TestPerformPwleEffect)674 TEST_F(VibratorHalWrapperAidlTest, TestPerformPwleEffect) {
675 std::vector<PrimitivePwle> emptyPrimitives, multiplePrimitives;
676 multiplePrimitives.push_back(vibrator::TestFactory::createActivePwle(0, 1, 0, 1, 10ms));
677 multiplePrimitives.push_back(vibrator::TestFactory::createBrakingPwle(Braking::NONE, 100ms));
678
679 {
680 InSequence seq;
681 EXPECT_CALL(*mMockHal.get(), composePwle(Eq(emptyPrimitives), _))
682 .Times(Exactly(1))
683 .WillRepeatedly(Return(
684 Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
685 EXPECT_CALL(*mMockHal.get(), composePwle(Eq(multiplePrimitives), _))
686 .Times(Exactly(2))
687 .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
688 .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
689 }
690
691 std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
692 auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
693
694 auto result = mWrapper->performPwleEffect(emptyPrimitives, callback);
695 ASSERT_TRUE(result.isUnsupported());
696 // Callback not triggered on failure
697 ASSERT_EQ(0, *callbackCounter.get());
698
699 result = mWrapper->performPwleEffect(multiplePrimitives, callback);
700 ASSERT_TRUE(result.isFailed());
701 // Callback not triggered for unsupported
702 ASSERT_EQ(0, *callbackCounter.get());
703
704 result = mWrapper->performPwleEffect(multiplePrimitives, callback);
705 ASSERT_TRUE(result.isOk());
706 ASSERT_EQ(1, *callbackCounter.get());
707 }
708