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