1 /*
2 * Copyright (C) 2019 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 #include <android-base/logging.h>
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20
21 #include "Vibrator.h"
22 #include "mocks.h"
23 #include "types.h"
24 #include "utils.h"
25
26 namespace aidl {
27 namespace android {
28 namespace hardware {
29 namespace vibrator {
30
31 using ::testing::_;
32 using ::testing::AnyNumber;
33 using ::testing::AnyOf;
34 using ::testing::Assign;
35 using ::testing::Combine;
36 using ::testing::DoAll;
37 using ::testing::DoDefault;
38 using ::testing::Exactly;
39 using ::testing::ExpectationSet;
40 using ::testing::Mock;
41 using ::testing::Range;
42 using ::testing::Return;
43 using ::testing::Sequence;
44 using ::testing::SetArgPointee;
45 using ::testing::SetArgReferee;
46 using ::testing::Test;
47 using ::testing::TestParamInfo;
48 using ::testing::ValuesIn;
49 using ::testing::WithParamInterface;
50
51 // Constants With Prescribed Values
52
53 static const std::map<EffectTuple, EffectSequence> EFFECT_SEQUENCES{
54 {{Effect::CLICK, EffectStrength::LIGHT}, {1, 2}},
55 {{Effect::CLICK, EffectStrength::MEDIUM}, {1, 0}},
56 {{Effect::CLICK, EffectStrength::STRONG}, {1, 0}},
57 {{Effect::TICK, EffectStrength::LIGHT}, {2, 2}},
58 {{Effect::TICK, EffectStrength::MEDIUM}, {2, 0}},
59 {{Effect::TICK, EffectStrength::STRONG}, {2, 0}},
60 {{Effect::DOUBLE_CLICK, EffectStrength::LIGHT}, {3, 2}},
61 {{Effect::DOUBLE_CLICK, EffectStrength::MEDIUM}, {3, 0}},
62 {{Effect::DOUBLE_CLICK, EffectStrength::STRONG}, {3, 0}},
63 {{Effect::HEAVY_CLICK, EffectStrength::LIGHT}, {4, 2}},
64 {{Effect::HEAVY_CLICK, EffectStrength::MEDIUM}, {4, 0}},
65 {{Effect::HEAVY_CLICK, EffectStrength::STRONG}, {4, 0}},
66 {{Effect::TEXTURE_TICK, EffectStrength::LIGHT}, {2, 2}},
67 {{Effect::TEXTURE_TICK, EffectStrength::MEDIUM}, {2, 0}},
68 {{Effect::TEXTURE_TICK, EffectStrength::STRONG}, {2, 0}},
69 };
70
freqPeriodFormula(uint32_t in)71 static uint32_t freqPeriodFormula(uint32_t in) {
72 return 1000000000 / (24615 * in);
73 }
74
75 template <typename... T>
76 class VibratorTestTemplate : public Test, public WithParamInterface<std::tuple<bool, T...>> {
77 public:
GetDynamicConfig(typename VibratorTestTemplate::ParamType param)78 static auto GetDynamicConfig(typename VibratorTestTemplate::ParamType param) {
79 return std::get<0>(param);
80 }
81 template <std::size_t I>
GetOtherParam(typename VibratorTestTemplate::ParamType param)82 static auto GetOtherParam(typename VibratorTestTemplate::ParamType param) {
83 return std::get<I + 1>(param);
84 }
85
PrintParam(const TestParamInfo<typename VibratorTestTemplate::ParamType> & info)86 static auto PrintParam(const TestParamInfo<typename VibratorTestTemplate::ParamType> &info) {
87 auto dynamic = GetDynamicConfig(info.param);
88 return std::string() + (dynamic ? "Dynamic" : "Static") + "Config";
89 }
90
MakeParam(bool dynamicConfig,T...others)91 static auto MakeParam(bool dynamicConfig, T... others) {
92 return std::make_tuple(dynamicConfig, others...);
93 }
94
SetUp()95 void SetUp() override {
96 std::unique_ptr<MockApi> mockapi;
97 std::unique_ptr<MockCal> mockcal;
98
99 mCloseLoopThreshold = std::rand();
100 // ensure close-loop test is possible
101 if (mCloseLoopThreshold == UINT32_MAX) {
102 mCloseLoopThreshold--;
103 }
104
105 mShortLraPeriod = std::rand();
106 if (getDynamicConfig()) {
107 mLongFrequencyShift = std::rand();
108 mLongLraPeriod =
109 freqPeriodFormula(freqPeriodFormula(mShortLraPeriod) - mLongFrequencyShift);
110 mShortVoltageMax = std::rand();
111 mLongVoltageMax = std::rand();
112 }
113
114 mEffectDurations[Effect::CLICK] = std::rand();
115 mEffectDurations[Effect::TICK] = std::rand();
116 mEffectDurations[Effect::DOUBLE_CLICK] = std::rand();
117 mEffectDurations[Effect::HEAVY_CLICK] = std::rand();
118 mEffectDurations[Effect::TEXTURE_TICK] = mEffectDurations[Effect::TICK];
119
120 createMock(&mockapi, &mockcal);
121 createVibrator(std::move(mockapi), std::move(mockcal));
122 }
123
TearDown()124 void TearDown() override { deleteVibrator(); }
125
126 protected:
getDynamicConfig() const127 auto getDynamicConfig() const { return GetDynamicConfig(VibratorTestTemplate::GetParam()); }
128
createMock(std::unique_ptr<MockApi> * mockapi,std::unique_ptr<MockCal> * mockcal)129 void createMock(std::unique_ptr<MockApi> *mockapi, std::unique_ptr<MockCal> *mockcal) {
130 *mockapi = std::make_unique<MockApi>();
131 *mockcal = std::make_unique<MockCal>();
132
133 mMockApi = mockapi->get();
134 mMockCal = mockcal->get();
135
136 ON_CALL(*mMockApi, destructor()).WillByDefault(Assign(&mMockApi, nullptr));
137 ON_CALL(*mMockApi, setOlLraPeriod(_)).WillByDefault(Return(true));
138 ON_CALL(*mMockApi, setActivate(_)).WillByDefault(Return(true));
139 ON_CALL(*mMockApi, setDuration(_)).WillByDefault(Return(true));
140 ON_CALL(*mMockApi, setMode(_)).WillByDefault(Return(true));
141 ON_CALL(*mMockApi, setCtrlLoop(_)).WillByDefault(Return(true));
142 ON_CALL(*mMockApi, setLraWaveShape(_)).WillByDefault(Return(true));
143 ON_CALL(*mMockApi, setOdClamp(_)).WillByDefault(Return(true));
144
145 ON_CALL(*mMockCal, destructor()).WillByDefault(Assign(&mMockCal, nullptr));
146 ON_CALL(*mMockCal, getLraPeriod(_))
147 .WillByDefault(DoAll(SetArgPointee<0>(mShortLraPeriod), Return(true)));
148 ON_CALL(*mMockCal, getCloseLoopThreshold(_))
149 .WillByDefault(DoAll(SetArgPointee<0>(mCloseLoopThreshold), Return(true)));
150 ON_CALL(*mMockCal, getDynamicConfig(_))
151 .WillByDefault(DoAll(SetArgPointee<0>(getDynamicConfig()), Return(true)));
152
153 if (getDynamicConfig()) {
154 ON_CALL(*mMockCal, getLongFrequencyShift(_))
155 .WillByDefault(DoAll(SetArgPointee<0>(mLongFrequencyShift), Return(true)));
156 ON_CALL(*mMockCal, getShortVoltageMax(_))
157 .WillByDefault(DoAll(SetArgPointee<0>(mShortVoltageMax), Return(true)));
158 ON_CALL(*mMockCal, getLongVoltageMax(_))
159 .WillByDefault(DoAll(SetArgPointee<0>(mLongVoltageMax), Return(true)));
160 }
161
162 ON_CALL(*mMockCal, getClickDuration(_))
163 .WillByDefault(
164 DoAll(SetArgPointee<0>(mEffectDurations[Effect::CLICK]), Return(true)));
165 ON_CALL(*mMockCal, getTickDuration(_))
166 .WillByDefault(
167 DoAll(SetArgPointee<0>(mEffectDurations[Effect::TICK]), Return(true)));
168 ON_CALL(*mMockCal, getDoubleClickDuration(_))
169 .WillByDefault(DoAll(SetArgPointee<0>(mEffectDurations[Effect::DOUBLE_CLICK]),
170 Return(true)));
171 ON_CALL(*mMockCal, getHeavyClickDuration(_))
172 .WillByDefault(DoAll(SetArgPointee<0>(mEffectDurations[Effect::HEAVY_CLICK]),
173 Return(true)));
174
175 relaxMock(false);
176 }
177
createVibrator(std::unique_ptr<MockApi> mockapi,std::unique_ptr<MockCal> mockcal,bool relaxed=true)178 void createVibrator(std::unique_ptr<MockApi> mockapi, std::unique_ptr<MockCal> mockcal,
179 bool relaxed = true) {
180 if (relaxed) {
181 relaxMock(true);
182 }
183 mVibrator = ndk::SharedRefBase::make<Vibrator>(std::move(mockapi), std::move(mockcal));
184 if (relaxed) {
185 relaxMock(false);
186 }
187 }
188
deleteVibrator(bool relaxed=true)189 void deleteVibrator(bool relaxed = true) {
190 if (relaxed) {
191 relaxMock(true);
192 }
193 mVibrator.reset();
194 }
195
relaxMock(bool relax)196 void relaxMock(bool relax) {
197 auto times = relax ? AnyNumber() : Exactly(0);
198
199 Mock::VerifyAndClearExpectations(mMockApi);
200 Mock::VerifyAndClearExpectations(mMockCal);
201
202 EXPECT_CALL(*mMockApi, destructor()).Times(times);
203 EXPECT_CALL(*mMockApi, setAutocal(_)).Times(times);
204 EXPECT_CALL(*mMockApi, setOlLraPeriod(_)).Times(times);
205 EXPECT_CALL(*mMockApi, setActivate(_)).Times(times);
206 EXPECT_CALL(*mMockApi, setDuration(_)).Times(times);
207 EXPECT_CALL(*mMockApi, setState(_)).Times(times);
208 EXPECT_CALL(*mMockApi, hasRtpInput()).Times(times);
209 EXPECT_CALL(*mMockApi, setRtpInput(_)).Times(times);
210 EXPECT_CALL(*mMockApi, setMode(_)).Times(times);
211 EXPECT_CALL(*mMockApi, setSequencer(_)).Times(times);
212 EXPECT_CALL(*mMockApi, setScale(_)).Times(times);
213 EXPECT_CALL(*mMockApi, setCtrlLoop(_)).Times(times);
214 EXPECT_CALL(*mMockApi, setLpTriggerEffect(_)).Times(times);
215 EXPECT_CALL(*mMockApi, setLpTriggerScale(_)).Times(times);
216 EXPECT_CALL(*mMockApi, setLraWaveShape(_)).Times(times);
217 EXPECT_CALL(*mMockApi, setOdClamp(_)).Times(times);
218 EXPECT_CALL(*mMockApi, debug(_)).Times(times);
219
220 EXPECT_CALL(*mMockCal, destructor()).Times(times);
221 EXPECT_CALL(*mMockCal, getAutocal(_)).Times(times);
222 EXPECT_CALL(*mMockCal, getLraPeriod(_)).Times(times);
223 EXPECT_CALL(*mMockCal, getCloseLoopThreshold(_)).Times(times);
224 EXPECT_CALL(*mMockCal, getDynamicConfig(_)).Times(times);
225 EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).Times(times);
226 EXPECT_CALL(*mMockCal, getShortVoltageMax(_)).Times(times);
227 EXPECT_CALL(*mMockCal, getLongVoltageMax(_)).Times(times);
228 EXPECT_CALL(*mMockCal, getClickDuration(_)).Times(times);
229 EXPECT_CALL(*mMockCal, getTickDuration(_)).Times(times);
230 EXPECT_CALL(*mMockCal, getDoubleClickDuration(_)).Times(times);
231 EXPECT_CALL(*mMockCal, getHeavyClickDuration(_)).Times(times);
232 EXPECT_CALL(*mMockCal, debug(_)).Times(times);
233 }
234
235 protected:
236 MockApi *mMockApi;
237 MockCal *mMockCal;
238 std::shared_ptr<IVibrator> mVibrator;
239
240 EffectDuration mCloseLoopThreshold;
241 uint32_t mLongFrequencyShift;
242 uint32_t mShortLraPeriod;
243 uint32_t mLongLraPeriod;
244 uint32_t mShortVoltageMax;
245 uint32_t mLongVoltageMax;
246 std::map<Effect, EffectDuration> mEffectDurations;
247 };
248
249 using BasicTest = VibratorTestTemplate<>;
250
TEST_P(BasicTest,Constructor)251 TEST_P(BasicTest, Constructor) {
252 std::unique_ptr<MockApi> mockapi;
253 std::unique_ptr<MockCal> mockcal;
254 std::string autocalVal = std::to_string(std::rand()) + " " + std::to_string(std::rand()) + " " +
255 std::to_string(std::rand());
256 Sequence autocalSeq, lraPeriodSeq;
257
258 EXPECT_CALL(*mMockApi, destructor()).WillOnce(DoDefault());
259 EXPECT_CALL(*mMockCal, destructor()).WillOnce(DoDefault());
260
261 deleteVibrator(false);
262
263 createMock(&mockapi, &mockcal);
264
265 EXPECT_CALL(*mMockApi, setState(true)).WillOnce(Return(true));
266
267 EXPECT_CALL(*mMockCal, getAutocal(_))
268 .InSequence(autocalSeq)
269 .WillOnce(DoAll(SetArgReferee<0>(autocalVal), Return(true)));
270 EXPECT_CALL(*mMockApi, setAutocal(autocalVal)).InSequence(autocalSeq).WillOnce(DoDefault());
271
272 EXPECT_CALL(*mMockCal, getLraPeriod(_)).InSequence(lraPeriodSeq).WillOnce(DoDefault());
273
274 EXPECT_CALL(*mMockCal, getCloseLoopThreshold(_)).WillOnce(DoDefault());
275 EXPECT_CALL(*mMockCal, getDynamicConfig(_)).WillOnce(DoDefault());
276
277 if (getDynamicConfig()) {
278 EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).WillOnce(DoDefault());
279 EXPECT_CALL(*mMockCal, getShortVoltageMax(_)).WillOnce(DoDefault());
280 EXPECT_CALL(*mMockCal, getLongVoltageMax(_)).WillOnce(DoDefault());
281 } else {
282 EXPECT_CALL(*mMockApi, setOlLraPeriod(mShortLraPeriod))
283 .InSequence(lraPeriodSeq)
284 .WillOnce(DoDefault());
285 }
286
287 EXPECT_CALL(*mMockCal, getClickDuration(_)).WillOnce(DoDefault());
288 EXPECT_CALL(*mMockCal, getTickDuration(_)).WillOnce(DoDefault());
289 EXPECT_CALL(*mMockCal, getDoubleClickDuration(_)).WillOnce(DoDefault());
290 EXPECT_CALL(*mMockCal, getHeavyClickDuration(_)).WillOnce(DoDefault());
291
292 createVibrator(std::move(mockapi), std::move(mockcal), false);
293 }
294
TEST_P(BasicTest,on)295 TEST_P(BasicTest, on) {
296 EffectDuration duration = std::rand();
297 ExpectationSet e;
298
299 e += EXPECT_CALL(*mMockApi, setCtrlLoop(_)).WillOnce(DoDefault());
300 e += EXPECT_CALL(*mMockApi, setMode("rtp")).WillOnce(DoDefault());
301 e += EXPECT_CALL(*mMockApi, setDuration(duration)).WillOnce(DoDefault());
302
303 if (getDynamicConfig()) {
304 e += EXPECT_CALL(*mMockApi, setLraWaveShape(0)).WillOnce(DoDefault());
305 e += EXPECT_CALL(*mMockApi, setOdClamp(mLongVoltageMax)).WillOnce(DoDefault());
306 e += EXPECT_CALL(*mMockApi, setOlLraPeriod(mLongLraPeriod)).WillOnce(DoDefault());
307 }
308
309 EXPECT_CALL(*mMockApi, setActivate(true)).After(e).WillOnce(DoDefault());
310
311 EXPECT_EQ(EX_NONE, mVibrator->on(duration, nullptr).getExceptionCode());
312 }
313
TEST_P(BasicTest,on_openLoop)314 TEST_P(BasicTest, on_openLoop) {
315 EffectDuration duration = mCloseLoopThreshold;
316
317 relaxMock(true);
318
319 EXPECT_CALL(*mMockApi, setCtrlLoop(true)).WillOnce(DoDefault());
320
321 EXPECT_EQ(EX_NONE, mVibrator->on(duration, nullptr).getExceptionCode());
322 }
323
TEST_P(BasicTest,on_closeLoop)324 TEST_P(BasicTest, on_closeLoop) {
325 EffectDuration duration = mCloseLoopThreshold + 1;
326
327 relaxMock(true);
328
329 EXPECT_CALL(*mMockApi, setCtrlLoop(false)).WillOnce(DoDefault());
330
331 EXPECT_EQ(EX_NONE, mVibrator->on(duration, nullptr).getExceptionCode());
332 }
333
TEST_P(BasicTest,off)334 TEST_P(BasicTest, off) {
335 EXPECT_CALL(*mMockApi, setActivate(false)).WillOnce(DoDefault());
336
337 EXPECT_EQ(EX_NONE, mVibrator->off().getExceptionCode());
338 }
339
TEST_P(BasicTest,supportsAmplitudeControl_supported)340 TEST_P(BasicTest, supportsAmplitudeControl_supported) {
341 EXPECT_CALL(*mMockApi, hasRtpInput()).WillOnce(Return(true));
342
343 int32_t capabilities;
344 EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
345 EXPECT_GT(capabilities & IVibrator::CAP_AMPLITUDE_CONTROL, 0);
346 }
347
TEST_P(BasicTest,supportsAmplitudeControl_unsupported)348 TEST_P(BasicTest, supportsAmplitudeControl_unsupported) {
349 EXPECT_CALL(*mMockApi, hasRtpInput()).WillOnce(Return(false));
350
351 int32_t capabilities;
352 EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
353 EXPECT_EQ(capabilities & IVibrator::CAP_AMPLITUDE_CONTROL, 0);
354 }
355
TEST_P(BasicTest,setAmplitude)356 TEST_P(BasicTest, setAmplitude) {
357 EffectAmplitude amplitude = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
358
359 EXPECT_CALL(*mMockApi, setRtpInput(amplitudeToRtpInput(amplitude))).WillOnce(Return(true));
360
361 EXPECT_EQ(EX_NONE, mVibrator->setAmplitude(amplitude).getExceptionCode());
362 }
363
TEST_P(BasicTest,supportsExternalControl_unsupported)364 TEST_P(BasicTest, supportsExternalControl_unsupported) {
365 EXPECT_CALL(*mMockApi, hasRtpInput()).WillOnce(Return(false));
366
367 int32_t capabilities;
368 EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
369 EXPECT_EQ(capabilities & IVibrator::CAP_EXTERNAL_CONTROL, 0);
370 }
371
TEST_P(BasicTest,setExternalControl_enable)372 TEST_P(BasicTest, setExternalControl_enable) {
373 EXPECT_EQ(EX_UNSUPPORTED_OPERATION, mVibrator->setExternalControl(true).getExceptionCode());
374 }
375
TEST_P(BasicTest,setExternalControl_disable)376 TEST_P(BasicTest, setExternalControl_disable) {
377 EXPECT_EQ(EX_UNSUPPORTED_OPERATION, mVibrator->setExternalControl(false).getExceptionCode());
378 }
379
380 INSTANTIATE_TEST_CASE_P(VibratorTests, BasicTest,
381 ValuesIn({BasicTest::MakeParam(false), BasicTest::MakeParam(true)}),
382 BasicTest::PrintParam);
383
384 class EffectsTest : public VibratorTestTemplate<EffectTuple> {
385 public:
GetEffectTuple(ParamType param)386 static auto GetEffectTuple(ParamType param) { return GetOtherParam<0>(param); }
387
PrintParam(const TestParamInfo<ParamType> & info)388 static auto PrintParam(const TestParamInfo<ParamType> &info) {
389 auto prefix = VibratorTestTemplate::PrintParam(info);
390 auto tuple = GetEffectTuple(info.param);
391 auto effect = std::get<0>(tuple);
392 auto strength = std::get<1>(tuple);
393 return prefix + "_" + toString(effect) + "_" + toString(strength);
394 }
395
396 protected:
getEffectTuple() const397 auto getEffectTuple() const { return GetEffectTuple(GetParam()); }
398 };
399
TEST_P(EffectsTest,perform)400 TEST_P(EffectsTest, perform) {
401 auto tuple = getEffectTuple();
402 auto effect = std::get<0>(tuple);
403 auto strength = std::get<1>(tuple);
404 auto seqIter = EFFECT_SEQUENCES.find(tuple);
405 auto durIter = mEffectDurations.find(effect);
406 EffectDuration duration;
407
408 if (seqIter != EFFECT_SEQUENCES.end() && durIter != mEffectDurations.end()) {
409 auto sequence = std::to_string(std::get<0>(seqIter->second)) + " 0";
410 auto scale = std::get<1>(seqIter->second);
411 ExpectationSet e;
412
413 duration = durIter->second;
414
415 e += EXPECT_CALL(*mMockApi, setSequencer(sequence)).WillOnce(Return(true));
416 e += EXPECT_CALL(*mMockApi, setScale(scale)).WillOnce(Return(true));
417 e += EXPECT_CALL(*mMockApi, setCtrlLoop(1)).WillOnce(DoDefault());
418 e += EXPECT_CALL(*mMockApi, setMode("waveform")).WillOnce(DoDefault());
419 e += EXPECT_CALL(*mMockApi, setDuration(duration)).WillOnce(DoDefault());
420
421 if (getDynamicConfig()) {
422 e += EXPECT_CALL(*mMockApi, setLraWaveShape(1)).WillOnce(DoDefault());
423 e += EXPECT_CALL(*mMockApi, setOdClamp(mShortVoltageMax)).WillOnce(DoDefault());
424 e += EXPECT_CALL(*mMockApi, setOlLraPeriod(mShortLraPeriod)).WillOnce(DoDefault());
425 }
426
427 EXPECT_CALL(*mMockApi, setActivate(true)).After(e).WillOnce(DoDefault());
428 } else {
429 duration = 0;
430 }
431
432 int32_t lengthMs;
433 ndk::ScopedAStatus status = mVibrator->perform(effect, strength, nullptr, &lengthMs);
434 if (duration) {
435 EXPECT_EQ(EX_NONE, status.getExceptionCode());
436 EXPECT_LE(duration, lengthMs);
437 } else {
438 EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
439 }
440 }
441
TEST_P(EffectsTest,alwaysOnEnable)442 TEST_P(EffectsTest, alwaysOnEnable) {
443 auto tuple = getEffectTuple();
444 auto effect = std::get<0>(tuple);
445 auto strength = std::get<1>(tuple);
446 auto seqIter = EFFECT_SEQUENCES.find(tuple);
447 bool supported = (seqIter != EFFECT_SEQUENCES.end());
448
449 if (supported) {
450 auto [index, scale] = seqIter->second;
451 EXPECT_CALL(*mMockApi, setLpTriggerEffect(index)).WillOnce(Return(true));
452 EXPECT_CALL(*mMockApi, setLpTriggerScale(scale)).WillOnce(Return(true));
453 }
454
455 ndk::ScopedAStatus status = mVibrator->alwaysOnEnable(0, effect, strength);
456 if (supported) {
457 EXPECT_EQ(EX_NONE, status.getExceptionCode());
458 } else {
459 EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
460 }
461 }
462
463 INSTANTIATE_TEST_CASE_P(VibratorTests, EffectsTest,
464 Combine(ValuesIn({false, true}),
465 Combine(ValuesIn(ndk::enum_range<Effect>().begin(),
466 ndk::enum_range<Effect>().end()),
467 ValuesIn(ndk::enum_range<EffectStrength>().begin(),
468 ndk::enum_range<EffectStrength>().end()))),
469 EffectsTest::PrintParam);
470
471 class AlwaysOnTest : public VibratorTestTemplate<int32_t> {
472 public:
GetId(ParamType param)473 static auto GetId(ParamType param) { return GetOtherParam<0>(param); }
474
PrintParam(const TestParamInfo<ParamType> & info)475 static auto PrintParam(const TestParamInfo<ParamType> &info) {
476 return std::to_string(GetId(info.param));
477 }
478
479 protected:
getId() const480 auto getId() const { return GetId(GetParam()); }
481 };
482
TEST_P(AlwaysOnTest,alwaysOnEnable)483 TEST_P(AlwaysOnTest, alwaysOnEnable) {
484 auto id = getId();
485 auto seqIter = EFFECT_SEQUENCES.begin();
486
487 std::advance(seqIter, std::rand() % EFFECT_SEQUENCES.size());
488
489 auto effect = std::get<0>(seqIter->first);
490 auto strength = std::get<1>(seqIter->first);
491 auto [index, scale] = seqIter->second;
492
493 EXPECT_CALL(*mMockApi, setLpTriggerEffect(index)).WillOnce(Return(true));
494 EXPECT_CALL(*mMockApi, setLpTriggerScale(scale)).WillOnce(Return(true));
495
496 ndk::ScopedAStatus status = mVibrator->alwaysOnEnable(id, effect, strength);
497 EXPECT_EQ(EX_NONE, status.getExceptionCode());
498 }
499
TEST_P(AlwaysOnTest,alwaysOnDisable)500 TEST_P(AlwaysOnTest, alwaysOnDisable) {
501 auto id = getId();
502
503 EXPECT_CALL(*mMockApi, setLpTriggerEffect(0)).WillOnce(Return(true));
504
505 ndk::ScopedAStatus status = mVibrator->alwaysOnDisable(id);
506 EXPECT_EQ(EX_NONE, status.getExceptionCode());
507 }
508
509 INSTANTIATE_TEST_CASE_P(VibratorTests, AlwaysOnTest, Combine(ValuesIn({false, true}), Range(0, 0)),
510 AlwaysOnTest::PrintParam);
511
512 } // namespace vibrator
513 } // namespace hardware
514 } // namespace android
515 } // namespace aidl
516