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::Return;
42 using ::testing::Sequence;
43 using ::testing::SetArgPointee;
44 using ::testing::SetArgReferee;
45 using ::testing::Test;
46 using ::testing::TestParamInfo;
47 using ::testing::ValuesIn;
48 using ::testing::WithParamInterface;
49
50 // Constants With Prescribed Values
51
52 static const std::map<EffectTuple, EffectSequence> EFFECT_SEQUENCES{
53 {{Effect::CLICK, EffectStrength::LIGHT}, {"1 0", 2}},
54 {{Effect::CLICK, EffectStrength::MEDIUM}, {"1 0", 0}},
55 {{Effect::CLICK, EffectStrength::STRONG}, {"1 0", 0}},
56 {{Effect::TICK, EffectStrength::LIGHT}, {"2 0", 2}},
57 {{Effect::TICK, EffectStrength::MEDIUM}, {"2 0", 0}},
58 {{Effect::TICK, EffectStrength::STRONG}, {"2 0", 0}},
59 {{Effect::DOUBLE_CLICK, EffectStrength::LIGHT}, {"3 0", 2}},
60 {{Effect::DOUBLE_CLICK, EffectStrength::MEDIUM}, {"3 0", 0}},
61 {{Effect::DOUBLE_CLICK, EffectStrength::STRONG}, {"3 0", 0}},
62 {{Effect::HEAVY_CLICK, EffectStrength::LIGHT}, {"4 0", 2}},
63 {{Effect::HEAVY_CLICK, EffectStrength::MEDIUM}, {"4 0", 0}},
64 {{Effect::HEAVY_CLICK, EffectStrength::STRONG}, {"4 0", 0}},
65 {{Effect::TEXTURE_TICK, EffectStrength::LIGHT}, {"2 0", 2}},
66 {{Effect::TEXTURE_TICK, EffectStrength::MEDIUM}, {"2 0", 0}},
67 {{Effect::TEXTURE_TICK, EffectStrength::STRONG}, {"2 0", 0}},
68 };
69
freqPeriodFormula(uint32_t in)70 static uint32_t freqPeriodFormula(uint32_t in) {
71 return 1000000000 / (24615 * in);
72 }
73
74 template <typename... T>
75 class VibratorTestTemplate : public Test, public WithParamInterface<std::tuple<bool, T...>> {
76 public:
GetDynamicConfig(typename VibratorTestTemplate::ParamType param)77 static auto GetDynamicConfig(typename VibratorTestTemplate::ParamType param) {
78 return std::get<0>(param);
79 }
80 template <std::size_t I>
GetOtherParam(typename VibratorTestTemplate::ParamType param)81 static auto GetOtherParam(typename VibratorTestTemplate::ParamType param) {
82 return std::get<I + 1>(param);
83 }
84
PrintParam(const TestParamInfo<typename VibratorTestTemplate::ParamType> & info)85 static auto PrintParam(const TestParamInfo<typename VibratorTestTemplate::ParamType> &info) {
86 auto dynamic = GetDynamicConfig(info.param);
87 return std::string() + (dynamic ? "Dynamic" : "Static") + "Config";
88 }
89
MakeParam(bool dynamicConfig,T...others)90 static auto MakeParam(bool dynamicConfig, T... others) {
91 return std::make_tuple(dynamicConfig, others...);
92 }
93
SetUp()94 void SetUp() override {
95 std::unique_ptr<MockApi> mockapi;
96 std::unique_ptr<MockCal> mockcal;
97
98 mCloseLoopThreshold = std::rand();
99 // ensure close-loop test is possible
100 if (mCloseLoopThreshold == UINT32_MAX) {
101 mCloseLoopThreshold--;
102 }
103
104 mShortLraPeriod = std::rand();
105 if (getDynamicConfig()) {
106 mLongFrequencyShift = std::rand();
107 mLongLraPeriod =
108 freqPeriodFormula(freqPeriodFormula(mShortLraPeriod) - mLongFrequencyShift);
109 mShortVoltageMax = std::rand();
110 mLongVoltageMax = std::rand();
111 }
112
113 mEffectDurations[Effect::CLICK] = std::rand();
114 mEffectDurations[Effect::TICK] = std::rand();
115 mEffectDurations[Effect::DOUBLE_CLICK] = std::rand();
116 mEffectDurations[Effect::HEAVY_CLICK] = std::rand();
117 mEffectDurations[Effect::TEXTURE_TICK] = mEffectDurations[Effect::TICK];
118
119 createMock(&mockapi, &mockcal);
120 createVibrator(std::move(mockapi), std::move(mockcal));
121 }
122
TearDown()123 void TearDown() override { deleteVibrator(); }
124
125 protected:
getDynamicConfig() const126 auto getDynamicConfig() const { return GetDynamicConfig(VibratorTestTemplate::GetParam()); }
127
createMock(std::unique_ptr<MockApi> * mockapi,std::unique_ptr<MockCal> * mockcal)128 void createMock(std::unique_ptr<MockApi> *mockapi, std::unique_ptr<MockCal> *mockcal) {
129 *mockapi = std::make_unique<MockApi>();
130 *mockcal = std::make_unique<MockCal>();
131
132 mMockApi = mockapi->get();
133 mMockCal = mockcal->get();
134
135 ON_CALL(*mMockApi, destructor()).WillByDefault(Assign(&mMockApi, nullptr));
136 ON_CALL(*mMockApi, setOlLraPeriod(_)).WillByDefault(Return(true));
137 ON_CALL(*mMockApi, setActivate(_)).WillByDefault(Return(true));
138 ON_CALL(*mMockApi, setDuration(_)).WillByDefault(Return(true));
139 ON_CALL(*mMockApi, setMode(_)).WillByDefault(Return(true));
140 ON_CALL(*mMockApi, setCtrlLoop(_)).WillByDefault(Return(true));
141 ON_CALL(*mMockApi, setLraWaveShape(_)).WillByDefault(Return(true));
142 ON_CALL(*mMockApi, setOdClamp(_)).WillByDefault(Return(true));
143
144 ON_CALL(*mMockCal, destructor()).WillByDefault(Assign(&mMockCal, nullptr));
145 ON_CALL(*mMockCal, getLraPeriod(_))
146 .WillByDefault(DoAll(SetArgPointee<0>(mShortLraPeriod), Return(true)));
147 ON_CALL(*mMockCal, getCloseLoopThreshold(_))
148 .WillByDefault(DoAll(SetArgPointee<0>(mCloseLoopThreshold), Return(true)));
149 ON_CALL(*mMockCal, getDynamicConfig(_))
150 .WillByDefault(DoAll(SetArgPointee<0>(getDynamicConfig()), Return(true)));
151
152 if (getDynamicConfig()) {
153 ON_CALL(*mMockCal, getLongFrequencyShift(_))
154 .WillByDefault(DoAll(SetArgPointee<0>(mLongFrequencyShift), Return(true)));
155 ON_CALL(*mMockCal, getShortVoltageMax(_))
156 .WillByDefault(DoAll(SetArgPointee<0>(mShortVoltageMax), Return(true)));
157 ON_CALL(*mMockCal, getLongVoltageMax(_))
158 .WillByDefault(DoAll(SetArgPointee<0>(mLongVoltageMax), Return(true)));
159 }
160
161 ON_CALL(*mMockCal, getClickDuration(_))
162 .WillByDefault(
163 DoAll(SetArgPointee<0>(mEffectDurations[Effect::CLICK]), Return(true)));
164 ON_CALL(*mMockCal, getTickDuration(_))
165 .WillByDefault(
166 DoAll(SetArgPointee<0>(mEffectDurations[Effect::TICK]), Return(true)));
167 ON_CALL(*mMockCal, getDoubleClickDuration(_))
168 .WillByDefault(DoAll(SetArgPointee<0>(mEffectDurations[Effect::DOUBLE_CLICK]),
169 Return(true)));
170 ON_CALL(*mMockCal, getHeavyClickDuration(_))
171 .WillByDefault(DoAll(SetArgPointee<0>(mEffectDurations[Effect::HEAVY_CLICK]),
172 Return(true)));
173
174 relaxMock(false);
175 }
176
createVibrator(std::unique_ptr<MockApi> mockapi,std::unique_ptr<MockCal> mockcal,bool relaxed=true)177 void createVibrator(std::unique_ptr<MockApi> mockapi, std::unique_ptr<MockCal> mockcal,
178 bool relaxed = true) {
179 if (relaxed) {
180 relaxMock(true);
181 }
182 mVibrator = ndk::SharedRefBase::make<Vibrator>(std::move(mockapi), std::move(mockcal));
183 if (relaxed) {
184 relaxMock(false);
185 }
186 }
187
deleteVibrator(bool relaxed=true)188 void deleteVibrator(bool relaxed = true) {
189 if (relaxed) {
190 relaxMock(true);
191 }
192 mVibrator.reset();
193 }
194
relaxMock(bool relax)195 void relaxMock(bool relax) {
196 auto times = relax ? AnyNumber() : Exactly(0);
197
198 Mock::VerifyAndClearExpectations(mMockApi);
199 Mock::VerifyAndClearExpectations(mMockCal);
200
201 EXPECT_CALL(*mMockApi, destructor()).Times(times);
202 EXPECT_CALL(*mMockApi, setAutocal(_)).Times(times);
203 EXPECT_CALL(*mMockApi, setOlLraPeriod(_)).Times(times);
204 EXPECT_CALL(*mMockApi, setActivate(_)).Times(times);
205 EXPECT_CALL(*mMockApi, setDuration(_)).Times(times);
206 EXPECT_CALL(*mMockApi, setState(_)).Times(times);
207 EXPECT_CALL(*mMockApi, hasRtpInput()).Times(times);
208 EXPECT_CALL(*mMockApi, setRtpInput(_)).Times(times);
209 EXPECT_CALL(*mMockApi, setMode(_)).Times(times);
210 EXPECT_CALL(*mMockApi, setSequencer(_)).Times(times);
211 EXPECT_CALL(*mMockApi, setScale(_)).Times(times);
212 EXPECT_CALL(*mMockApi, setCtrlLoop(_)).Times(times);
213 EXPECT_CALL(*mMockApi, setLpTriggerEffect(_)).Times(times);
214 EXPECT_CALL(*mMockApi, setLraWaveShape(_)).Times(times);
215 EXPECT_CALL(*mMockApi, setOdClamp(_)).Times(times);
216 EXPECT_CALL(*mMockApi, debug(_)).Times(times);
217
218 EXPECT_CALL(*mMockCal, destructor()).Times(times);
219 EXPECT_CALL(*mMockCal, getAutocal(_)).Times(times);
220 EXPECT_CALL(*mMockCal, getLraPeriod(_)).Times(times);
221 EXPECT_CALL(*mMockCal, getCloseLoopThreshold(_)).Times(times);
222 EXPECT_CALL(*mMockCal, getDynamicConfig(_)).Times(times);
223 EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).Times(times);
224 EXPECT_CALL(*mMockCal, getShortVoltageMax(_)).Times(times);
225 EXPECT_CALL(*mMockCal, getLongVoltageMax(_)).Times(times);
226 EXPECT_CALL(*mMockCal, getClickDuration(_)).Times(times);
227 EXPECT_CALL(*mMockCal, getTickDuration(_)).Times(times);
228 EXPECT_CALL(*mMockCal, getDoubleClickDuration(_)).Times(times);
229 EXPECT_CALL(*mMockCal, getHeavyClickDuration(_)).Times(times);
230 EXPECT_CALL(*mMockCal, debug(_)).Times(times);
231 }
232
233 protected:
234 MockApi *mMockApi;
235 MockCal *mMockCal;
236 std::shared_ptr<IVibrator> mVibrator;
237
238 EffectDuration mCloseLoopThreshold;
239 uint32_t mLongFrequencyShift;
240 uint32_t mShortLraPeriod;
241 uint32_t mLongLraPeriod;
242 uint32_t mShortVoltageMax;
243 uint32_t mLongVoltageMax;
244 std::map<Effect, EffectDuration> mEffectDurations;
245 };
246
247 using BasicTest = VibratorTestTemplate<>;
248
TEST_P(BasicTest,Constructor)249 TEST_P(BasicTest, Constructor) {
250 std::unique_ptr<MockApi> mockapi;
251 std::unique_ptr<MockCal> mockcal;
252 std::string autocalVal = std::to_string(std::rand()) + " " + std::to_string(std::rand()) + " " +
253 std::to_string(std::rand());
254 Sequence autocalSeq, lraPeriodSeq;
255
256 EXPECT_CALL(*mMockApi, destructor()).WillOnce(DoDefault());
257 EXPECT_CALL(*mMockCal, destructor()).WillOnce(DoDefault());
258
259 deleteVibrator(false);
260
261 createMock(&mockapi, &mockcal);
262
263 EXPECT_CALL(*mMockApi, setState(true)).WillOnce(Return(true));
264
265 EXPECT_CALL(*mMockCal, getAutocal(_))
266 .InSequence(autocalSeq)
267 .WillOnce(DoAll(SetArgReferee<0>(autocalVal), Return(true)));
268 EXPECT_CALL(*mMockApi, setAutocal(autocalVal)).InSequence(autocalSeq).WillOnce(DoDefault());
269
270 EXPECT_CALL(*mMockCal, getLraPeriod(_)).InSequence(lraPeriodSeq).WillOnce(DoDefault());
271
272 EXPECT_CALL(*mMockCal, getCloseLoopThreshold(_)).WillOnce(DoDefault());
273 EXPECT_CALL(*mMockCal, getDynamicConfig(_)).WillOnce(DoDefault());
274
275 if (getDynamicConfig()) {
276 EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).WillOnce(DoDefault());
277 EXPECT_CALL(*mMockCal, getShortVoltageMax(_)).WillOnce(DoDefault());
278 EXPECT_CALL(*mMockCal, getLongVoltageMax(_)).WillOnce(DoDefault());
279 } else {
280 EXPECT_CALL(*mMockApi, setOlLraPeriod(mShortLraPeriod))
281 .InSequence(lraPeriodSeq)
282 .WillOnce(DoDefault());
283 }
284
285 EXPECT_CALL(*mMockCal, getClickDuration(_)).WillOnce(DoDefault());
286 EXPECT_CALL(*mMockCal, getTickDuration(_)).WillOnce(DoDefault());
287 EXPECT_CALL(*mMockCal, getDoubleClickDuration(_)).WillOnce(DoDefault());
288 EXPECT_CALL(*mMockCal, getHeavyClickDuration(_)).WillOnce(DoDefault());
289
290 EXPECT_CALL(*mMockApi, setLpTriggerEffect(1)).WillOnce(Return(true));
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::get<0>(seqIter->second);
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
442 INSTANTIATE_TEST_CASE_P(VibratorTests, EffectsTest,
443 Combine(ValuesIn({false, true}),
444 Combine(ValuesIn(ndk::enum_range<Effect>().begin(),
445 ndk::enum_range<Effect>().end()),
446 ValuesIn(ndk::enum_range<EffectStrength>().begin(),
447 ndk::enum_range<EffectStrength>().end()))),
448 EffectsTest::PrintParam);
449
450 } // namespace vibrator
451 } // namespace hardware
452 } // namespace android
453 } // namespace aidl
454