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 android {
27 namespace hardware {
28 namespace vibrator {
29 namespace V1_3 {
30 namespace implementation {
31 
32 using ::android::hardware::vibrator::V1_0::EffectStrength;
33 using ::android::hardware::vibrator::V1_0::Status;
34 
35 using ::testing::_;
36 using ::testing::AnyNumber;
37 using ::testing::AnyOf;
38 using ::testing::Assign;
39 using ::testing::Combine;
40 using ::testing::DoAll;
41 using ::testing::DoDefault;
42 using ::testing::Exactly;
43 using ::testing::ExpectationSet;
44 using ::testing::Mock;
45 using ::testing::Return;
46 using ::testing::Sequence;
47 using ::testing::SetArgPointee;
48 using ::testing::SetArgReferee;
49 using ::testing::Test;
50 using ::testing::TestParamInfo;
51 using ::testing::ValuesIn;
52 using ::testing::WithParamInterface;
53 
54 // Constants With Prescribed Values
55 
56 static const std::map<EffectTuple, EffectSequence> EFFECT_SEQUENCES{
57     {{Effect::CLICK, EffectStrength::LIGHT}, {"1 0", 2}},
58     {{Effect::CLICK, EffectStrength::MEDIUM}, {"1 0", 0}},
59     {{Effect::CLICK, EffectStrength::STRONG}, {"1 0", 0}},
60     {{Effect::TICK, EffectStrength::LIGHT}, {"2 0", 2}},
61     {{Effect::TICK, EffectStrength::MEDIUM}, {"2 0", 0}},
62     {{Effect::TICK, EffectStrength::STRONG}, {"2 0", 0}},
63     {{Effect::DOUBLE_CLICK, EffectStrength::LIGHT}, {"3 0", 2}},
64     {{Effect::DOUBLE_CLICK, EffectStrength::MEDIUM}, {"3 0", 0}},
65     {{Effect::DOUBLE_CLICK, EffectStrength::STRONG}, {"3 0", 0}},
66     {{Effect::HEAVY_CLICK, EffectStrength::LIGHT}, {"4 0", 2}},
67     {{Effect::HEAVY_CLICK, EffectStrength::MEDIUM}, {"4 0", 0}},
68     {{Effect::HEAVY_CLICK, EffectStrength::STRONG}, {"4 0", 0}},
69     {{Effect::TEXTURE_TICK, EffectStrength::LIGHT}, {"2 0", 2}},
70     {{Effect::TEXTURE_TICK, EffectStrength::MEDIUM}, {"2 0", 0}},
71     {{Effect::TEXTURE_TICK, EffectStrength::STRONG}, {"2 0", 0}},
72 };
73 
freqPeriodFormula(uint32_t in)74 static uint32_t freqPeriodFormula(uint32_t in) {
75     return 1000000000 / (24615 * in);
76 }
77 
78 template <typename... T>
79 class VibratorTestTemplate : public Test, public WithParamInterface<std::tuple<bool, T...>> {
80   public:
GetDynamicConfig(typename VibratorTestTemplate::ParamType param)81     static auto GetDynamicConfig(typename VibratorTestTemplate::ParamType param) {
82         return std::get<0>(param);
83     }
84     template <std::size_t I>
GetOtherParam(typename VibratorTestTemplate::ParamType param)85     static auto GetOtherParam(typename VibratorTestTemplate::ParamType param) {
86         return std::get<I + 1>(param);
87     }
88 
PrintParam(const TestParamInfo<typename VibratorTestTemplate::ParamType> & info)89     static auto PrintParam(const TestParamInfo<typename VibratorTestTemplate::ParamType> &info) {
90         auto dynamic = GetDynamicConfig(info.param);
91         return std::string() + (dynamic ? "Dynamic" : "Static") + "Config";
92     }
93 
MakeParam(bool dynamicConfig,T...others)94     static auto MakeParam(bool dynamicConfig, T... others) {
95         return std::make_tuple(dynamicConfig, others...);
96     }
97 
SetUp()98     void SetUp() override {
99         std::unique_ptr<MockApi> mockapi;
100         std::unique_ptr<MockCal> mockcal;
101 
102         mCloseLoopThreshold = std::rand();
103         // ensure close-loop test is possible
104         if (mCloseLoopThreshold == UINT32_MAX) {
105             mCloseLoopThreshold--;
106         }
107 
108         mShortLraPeriod = std::rand();
109         if (getDynamicConfig()) {
110             mLongFrequencyShift = std::rand();
111             mLongLraPeriod =
112                 freqPeriodFormula(freqPeriodFormula(mShortLraPeriod) - mLongFrequencyShift);
113             mShortVoltageMax = std::rand();
114             mLongVoltageMax = std::rand();
115         }
116 
117         mEffectDurations[Effect::CLICK] = std::rand();
118         mEffectDurations[Effect::TICK] = std::rand();
119         mEffectDurations[Effect::DOUBLE_CLICK] = std::rand();
120         mEffectDurations[Effect::HEAVY_CLICK] = std::rand();
121         mEffectDurations[Effect::TEXTURE_TICK] = mEffectDurations[Effect::TICK];
122 
123         createMock(&mockapi, &mockcal);
124         createVibrator(std::move(mockapi), std::move(mockcal));
125     }
126 
TearDown()127     void TearDown() override { deleteVibrator(); }
128 
129   protected:
getDynamicConfig() const130     auto getDynamicConfig() const { return GetDynamicConfig(VibratorTestTemplate::GetParam()); }
131 
createMock(std::unique_ptr<MockApi> * mockapi,std::unique_ptr<MockCal> * mockcal)132     void createMock(std::unique_ptr<MockApi> *mockapi, std::unique_ptr<MockCal> *mockcal) {
133         *mockapi = std::make_unique<MockApi>();
134         *mockcal = std::make_unique<MockCal>();
135 
136         mMockApi = mockapi->get();
137         mMockCal = mockcal->get();
138 
139         ON_CALL(*mMockApi, destructor()).WillByDefault(Assign(&mMockApi, nullptr));
140         ON_CALL(*mMockApi, setOlLraPeriod(_)).WillByDefault(Return(true));
141         ON_CALL(*mMockApi, setActivate(_)).WillByDefault(Return(true));
142         ON_CALL(*mMockApi, setDuration(_)).WillByDefault(Return(true));
143         ON_CALL(*mMockApi, setMode(_)).WillByDefault(Return(true));
144         ON_CALL(*mMockApi, setCtrlLoop(_)).WillByDefault(Return(true));
145         ON_CALL(*mMockApi, setLraWaveShape(_)).WillByDefault(Return(true));
146         ON_CALL(*mMockApi, setOdClamp(_)).WillByDefault(Return(true));
147 
148         ON_CALL(*mMockCal, destructor()).WillByDefault(Assign(&mMockCal, nullptr));
149         ON_CALL(*mMockCal, getLraPeriod(_))
150             .WillByDefault(DoAll(SetArgPointee<0>(mShortLraPeriod), Return(true)));
151         ON_CALL(*mMockCal, getCloseLoopThreshold(_))
152             .WillByDefault(DoAll(SetArgPointee<0>(mCloseLoopThreshold), Return(true)));
153         ON_CALL(*mMockCal, getDynamicConfig(_))
154             .WillByDefault(DoAll(SetArgPointee<0>(getDynamicConfig()), Return(true)));
155 
156         if (getDynamicConfig()) {
157             ON_CALL(*mMockCal, getLongFrequencyShift(_))
158                 .WillByDefault(DoAll(SetArgPointee<0>(mLongFrequencyShift), Return(true)));
159             ON_CALL(*mMockCal, getShortVoltageMax(_))
160                 .WillByDefault(DoAll(SetArgPointee<0>(mShortVoltageMax), Return(true)));
161             ON_CALL(*mMockCal, getLongVoltageMax(_))
162                 .WillByDefault(DoAll(SetArgPointee<0>(mLongVoltageMax), Return(true)));
163         }
164 
165         ON_CALL(*mMockCal, getClickDuration(_))
166             .WillByDefault(DoAll(SetArgPointee<0>(mEffectDurations[Effect::CLICK]), Return(true)));
167         ON_CALL(*mMockCal, getTickDuration(_))
168             .WillByDefault(DoAll(SetArgPointee<0>(mEffectDurations[Effect::TICK]), Return(true)));
169         ON_CALL(*mMockCal, getDoubleClickDuration(_))
170             .WillByDefault(
171                 DoAll(SetArgPointee<0>(mEffectDurations[Effect::DOUBLE_CLICK]), Return(true)));
172         ON_CALL(*mMockCal, getHeavyClickDuration(_))
173             .WillByDefault(
174                 DoAll(SetArgPointee<0>(mEffectDurations[Effect::HEAVY_CLICK]), Return(true)));
175 
176         relaxMock(false);
177     }
178 
createVibrator(std::unique_ptr<MockApi> mockapi,std::unique_ptr<MockCal> mockcal,bool relaxed=true)179     void createVibrator(std::unique_ptr<MockApi> mockapi, std::unique_ptr<MockCal> mockcal,
180                         bool relaxed = true) {
181         if (relaxed) {
182             relaxMock(true);
183         }
184         mVibrator = new Vibrator(std::move(mockapi), std::move(mockcal));
185         if (relaxed) {
186             relaxMock(false);
187         }
188     }
189 
deleteVibrator(bool relaxed=true)190     void deleteVibrator(bool relaxed = true) {
191         if (relaxed) {
192             relaxMock(true);
193         }
194         mVibrator.clear();
195     }
196 
relaxMock(bool relax)197     void relaxMock(bool relax) {
198         auto times = relax ? AnyNumber() : Exactly(0);
199 
200         Mock::VerifyAndClearExpectations(mMockApi);
201         Mock::VerifyAndClearExpectations(mMockCal);
202 
203         EXPECT_CALL(*mMockApi, destructor()).Times(times);
204         EXPECT_CALL(*mMockApi, setAutocal(_)).Times(times);
205         EXPECT_CALL(*mMockApi, setOlLraPeriod(_)).Times(times);
206         EXPECT_CALL(*mMockApi, setActivate(_)).Times(times);
207         EXPECT_CALL(*mMockApi, setDuration(_)).Times(times);
208         EXPECT_CALL(*mMockApi, setState(_)).Times(times);
209         EXPECT_CALL(*mMockApi, hasRtpInput()).Times(times);
210         EXPECT_CALL(*mMockApi, setRtpInput(_)).Times(times);
211         EXPECT_CALL(*mMockApi, setMode(_)).Times(times);
212         EXPECT_CALL(*mMockApi, setSequencer(_)).Times(times);
213         EXPECT_CALL(*mMockApi, setScale(_)).Times(times);
214         EXPECT_CALL(*mMockApi, setCtrlLoop(_)).Times(times);
215         EXPECT_CALL(*mMockApi, setLpTriggerEffect(_)).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     sp<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     EXPECT_CALL(*mMockApi, setLpTriggerEffect(1)).WillOnce(Return(true));
293 
294     createVibrator(std::move(mockapi), std::move(mockcal), false);
295 }
296 
TEST_P(BasicTest,on)297 TEST_P(BasicTest, on) {
298     EffectDuration duration = std::rand();
299     ExpectationSet e;
300 
301     e += EXPECT_CALL(*mMockApi, setCtrlLoop(_)).WillOnce(DoDefault());
302     e += EXPECT_CALL(*mMockApi, setMode("rtp")).WillOnce(DoDefault());
303     e += EXPECT_CALL(*mMockApi, setDuration(duration)).WillOnce(DoDefault());
304 
305     if (getDynamicConfig()) {
306         e += EXPECT_CALL(*mMockApi, setLraWaveShape(0)).WillOnce(DoDefault());
307         e += EXPECT_CALL(*mMockApi, setOdClamp(mLongVoltageMax)).WillOnce(DoDefault());
308         e += EXPECT_CALL(*mMockApi, setOlLraPeriod(mLongLraPeriod)).WillOnce(DoDefault());
309     }
310 
311     EXPECT_CALL(*mMockApi, setActivate(true)).After(e).WillOnce(DoDefault());
312 
313     EXPECT_EQ(Status::OK, mVibrator->on(duration));
314 }
315 
TEST_P(BasicTest,on_openLoop)316 TEST_P(BasicTest, on_openLoop) {
317     EffectDuration duration = mCloseLoopThreshold;
318 
319     relaxMock(true);
320 
321     EXPECT_CALL(*mMockApi, setCtrlLoop(true)).WillOnce(DoDefault());
322 
323     EXPECT_EQ(Status::OK, mVibrator->on(duration));
324 }
325 
TEST_P(BasicTest,on_closeLoop)326 TEST_P(BasicTest, on_closeLoop) {
327     EffectDuration duration = mCloseLoopThreshold + 1;
328 
329     relaxMock(true);
330 
331     EXPECT_CALL(*mMockApi, setCtrlLoop(false)).WillOnce(DoDefault());
332 
333     EXPECT_EQ(Status::OK, mVibrator->on(duration));
334 }
335 
TEST_P(BasicTest,off)336 TEST_P(BasicTest, off) {
337     EXPECT_CALL(*mMockApi, setActivate(false)).WillOnce(DoDefault());
338 
339     EXPECT_EQ(Status::OK, mVibrator->off());
340 }
341 
TEST_P(BasicTest,supportsAmplitudeControl_supported)342 TEST_P(BasicTest, supportsAmplitudeControl_supported) {
343     EXPECT_CALL(*mMockApi, hasRtpInput()).WillOnce(Return(true));
344 
345     EXPECT_EQ(true, mVibrator->supportsAmplitudeControl());
346 }
347 
TEST_P(BasicTest,supportsAmplitudeControl_unsupported)348 TEST_P(BasicTest, supportsAmplitudeControl_unsupported) {
349     EXPECT_CALL(*mMockApi, hasRtpInput()).WillOnce(Return(false));
350 
351     EXPECT_EQ(false, mVibrator->supportsAmplitudeControl());
352 }
353 
TEST_P(BasicTest,setAmplitude)354 TEST_P(BasicTest, setAmplitude) {
355     EffectAmplitude amplitude = std::rand();
356 
357     EXPECT_CALL(*mMockApi, setRtpInput(amplitudeToRtpInput(amplitude))).WillOnce(Return(true));
358 
359     EXPECT_EQ(Status::OK, mVibrator->setAmplitude(amplitude));
360 }
361 
TEST_P(BasicTest,supportsExternalControl_unsupported)362 TEST_P(BasicTest, supportsExternalControl_unsupported) {
363     EXPECT_EQ(false, mVibrator->supportsExternalControl());
364 }
365 
TEST_P(BasicTest,setExternalControl_enable)366 TEST_P(BasicTest, setExternalControl_enable) {
367     EXPECT_EQ(Status::UNSUPPORTED_OPERATION, mVibrator->setExternalControl(true));
368 }
369 
TEST_P(BasicTest,setExternalControl_disable)370 TEST_P(BasicTest, setExternalControl_disable) {
371     EXPECT_EQ(Status::UNSUPPORTED_OPERATION, mVibrator->setExternalControl(false));
372 }
373 
374 INSTANTIATE_TEST_CASE_P(VibratorTests, BasicTest,
375                         ValuesIn({BasicTest::MakeParam(false), BasicTest::MakeParam(true)}),
376                         BasicTest::PrintParam);
377 
378 class EffectsTest : public VibratorTestTemplate<EffectTuple> {
379   public:
GetEffectTuple(ParamType param)380     static auto GetEffectTuple(ParamType param) { return GetOtherParam<0>(param); }
381 
PrintParam(const TestParamInfo<ParamType> & info)382     static auto PrintParam(const TestParamInfo<ParamType> &info) {
383         auto prefix = VibratorTestTemplate::PrintParam(info);
384         auto tuple = GetEffectTuple(info.param);
385         auto effect = std::get<0>(tuple);
386         auto strength = std::get<1>(tuple);
387         return prefix + "_" + toString(effect) + "_" + toString(strength);
388     }
389 
390   protected:
getEffectTuple() const391     auto getEffectTuple() const { return GetEffectTuple(GetParam()); }
392 };
393 
TEST_P(EffectsTest,perform)394 TEST_P(EffectsTest, perform) {
395     auto tuple = getEffectTuple();
396     auto effect = std::get<0>(tuple);
397     auto strength = std::get<1>(tuple);
398     auto seqIter = EFFECT_SEQUENCES.find(tuple);
399     auto durIter = mEffectDurations.find(effect);
400     EffectDuration duration;
401 
402     if (seqIter != EFFECT_SEQUENCES.end() && durIter != mEffectDurations.end()) {
403         auto sequence = std::get<0>(seqIter->second);
404         auto scale = std::get<1>(seqIter->second);
405         ExpectationSet e;
406 
407         duration = durIter->second;
408 
409         e += EXPECT_CALL(*mMockApi, setSequencer(sequence)).WillOnce(Return(true));
410         e += EXPECT_CALL(*mMockApi, setScale(scale)).WillOnce(Return(true));
411         e += EXPECT_CALL(*mMockApi, setCtrlLoop(1)).WillOnce(DoDefault());
412         e += EXPECT_CALL(*mMockApi, setMode("waveform")).WillOnce(DoDefault());
413         e += EXPECT_CALL(*mMockApi, setDuration(duration)).WillOnce(DoDefault());
414 
415         if (getDynamicConfig()) {
416             e += EXPECT_CALL(*mMockApi, setLraWaveShape(1)).WillOnce(DoDefault());
417             e += EXPECT_CALL(*mMockApi, setOdClamp(mShortVoltageMax)).WillOnce(DoDefault());
418             e += EXPECT_CALL(*mMockApi, setOlLraPeriod(mShortLraPeriod)).WillOnce(DoDefault());
419         }
420 
421         EXPECT_CALL(*mMockApi, setActivate(true)).After(e).WillOnce(DoDefault());
422     } else {
423         duration = 0;
424     }
425 
426     mVibrator->perform_1_3(effect, strength, [&](Status status, uint32_t lengthMs) {
427         if (duration) {
428             EXPECT_EQ(Status::OK, status);
429             EXPECT_LE(duration, lengthMs);
430         } else {
431             EXPECT_EQ(Status::UNSUPPORTED_OPERATION, status);
432             EXPECT_EQ(0, lengthMs);
433         }
434     });
435 }
436 
437 INSTANTIATE_TEST_CASE_P(VibratorTests, EffectsTest,
438                         Combine(ValuesIn({false, true}),
439                                 Combine(ValuesIn(hidl_enum_range<Effect>().begin(),
440                                                  hidl_enum_range<Effect>().end()),
441                                         ValuesIn(hidl_enum_range<EffectStrength>().begin(),
442                                                  hidl_enum_range<EffectStrength>().end()))),
443                         EffectsTest::PrintParam);
444 
445 }  // namespace implementation
446 }  // namespace V1_3
447 }  // namespace vibrator
448 }  // namespace hardware
449 }  // namespace android
450