• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <aidl/android/hardware/vibrator/BnVibratorCallback.h>
18 #include <android-base/logging.h>
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 #include <future>
23 
24 #include "Vibrator.h"
25 #include "mocks.h"
26 #include "types.h"
27 #include "utils.h"
28 
29 namespace aidl {
30 namespace android {
31 namespace hardware {
32 namespace vibrator {
33 
34 using ::testing::_;
35 using ::testing::AnyNumber;
36 using ::testing::Assign;
37 using ::testing::AtLeast;
38 using ::testing::AtMost;
39 using ::testing::Combine;
40 using ::testing::DoAll;
41 using ::testing::DoDefault;
42 using ::testing::Exactly;
43 using ::testing::Expectation;
44 using ::testing::ExpectationSet;
45 using ::testing::Ge;
46 using ::testing::Mock;
47 using ::testing::MockFunction;
48 using ::testing::Range;
49 using ::testing::Return;
50 using ::testing::Sequence;
51 using ::testing::SetArgPointee;
52 using ::testing::Test;
53 using ::testing::TestParamInfo;
54 using ::testing::ValuesIn;
55 using ::testing::WithParamInterface;
56 
57 // Forward Declarations
58 
59 static EffectQueue Queue(const QueueEffect &effect);
60 static EffectQueue Queue(const QueueDelay &delay);
61 template <typename T, typename U, typename... Args>
62 static EffectQueue Queue(const T &first, const U &second, Args... rest);
63 
64 static EffectLevel Level(float intensity);
65 static EffectScale Scale(float intensity);
66 
67 // Constants With Arbitrary Values
68 
69 static constexpr std::array<EffectLevel, 6> V_LEVELS{40, 50, 60, 70, 80, 90};
70 static constexpr std::array<EffectDuration, 10> EFFECT_DURATIONS{0,   0,   15,  0,   50,
71                                                                  100, 150, 200, 250, 8};
72 
73 // Constants With Prescribed Values
74 
75 static const std::map<Effect, EffectIndex> EFFECT_INDEX{
76         {Effect::CLICK, 2},
77         {Effect::TICK, 2},
78         {Effect::HEAVY_CLICK, 2},
79         {Effect::TEXTURE_TICK, 9},
80 };
81 
82 static constexpr EffectIndex QUEUE_INDEX{65534};
83 
84 static const EffectScale ON_GLOBAL_SCALE{levelToScale(V_LEVELS[5])};
85 static const EffectIndex ON_EFFECT_INDEX{0};
86 
87 static const std::map<EffectTuple, EffectScale> EFFECT_SCALE{
88         {{Effect::CLICK, EffectStrength::LIGHT}, Scale(0.7f * 0.5f)},
89         {{Effect::CLICK, EffectStrength::MEDIUM}, Scale(0.7f * 0.7f)},
90         {{Effect::CLICK, EffectStrength::STRONG}, Scale(0.7f * 1.0f)},
91         {{Effect::TICK, EffectStrength::LIGHT}, Scale(0.5f * 0.5f)},
92         {{Effect::TICK, EffectStrength::MEDIUM}, Scale(0.5f * 0.7f)},
93         {{Effect::TICK, EffectStrength::STRONG}, Scale(0.5f * 1.0f)},
94         {{Effect::HEAVY_CLICK, EffectStrength::LIGHT}, Scale(1.0f * 0.5f)},
95         {{Effect::HEAVY_CLICK, EffectStrength::MEDIUM}, Scale(1.0f * 0.7f)},
96         {{Effect::HEAVY_CLICK, EffectStrength::STRONG}, Scale(1.0f * 1.0f)},
97         {{Effect::TEXTURE_TICK, EffectStrength::LIGHT}, Scale(0.5f * 0.5f)},
98         {{Effect::TEXTURE_TICK, EffectStrength::MEDIUM}, Scale(0.5f * 0.7f)},
99         {{Effect::TEXTURE_TICK, EffectStrength::STRONG}, Scale(0.5f * 1.0f)},
100 };
101 
102 static const std::map<EffectTuple, EffectQueue> EFFECT_QUEUE{
103         {{Effect::DOUBLE_CLICK, EffectStrength::LIGHT},
104          Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(0.7f * 0.5f)}, 100,
105                QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(1.0f * 0.5f)})},
106         {{Effect::DOUBLE_CLICK, EffectStrength::MEDIUM},
107          Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(0.7f * 0.7f)}, 100,
108                QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(1.0f * 0.7f)})},
109         {{Effect::DOUBLE_CLICK, EffectStrength::STRONG},
110          Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(0.7f * 1.0f)}, 100,
111                QueueEffect{EFFECT_INDEX.at(Effect::CLICK), Level(1.0f * 1.0f)})},
112 };
113 
Queue(const QueueEffect & effect)114 EffectQueue Queue(const QueueEffect &effect) {
115     auto index = std::get<0>(effect);
116     auto level = std::get<1>(effect);
117     auto string = std::to_string(index) + "." + std::to_string(level);
118     auto duration = EFFECT_DURATIONS[index];
119     return {string, duration};
120 }
121 
Queue(const QueueDelay & delay)122 EffectQueue Queue(const QueueDelay &delay) {
123     auto string = std::to_string(delay);
124     return {string, delay};
125 }
126 
127 template <typename T, typename U, typename... Args>
Queue(const T & first,const U & second,Args...rest)128 EffectQueue Queue(const T &first, const U &second, Args... rest) {
129     auto head = Queue(first);
130     auto tail = Queue(second, rest...);
131     auto string = std::get<0>(head) + "," + std::get<0>(tail);
132     auto duration = std::get<1>(head) + std::get<1>(tail);
133     return {string, duration};
134 }
135 
Level(float intensity)136 static EffectLevel Level(float intensity) {
137     auto vMin = std::max(V_LEVELS[0] - (V_LEVELS[4] - V_LEVELS[0]) / 4.0f, 4.0f);
138     auto vMax = V_LEVELS[4];
139     return std::lround(intensity * (vMax - vMin)) + vMin;
140 }
141 
Scale(float intensity)142 static EffectScale Scale(float intensity) {
143     return levelToScale(Level(intensity));
144 }
145 
146 class VibratorTest : public Test {
147   public:
SetUp()148     void SetUp() override {
149         std::unique_ptr<MockApi> mockapi;
150         std::unique_ptr<MockCal> mockcal;
151 
152         createMock(&mockapi, &mockcal);
153         createVibrator(std::move(mockapi), std::move(mockcal));
154     }
155 
TearDown()156     void TearDown() override { deleteVibrator(); }
157 
158   protected:
createMock(std::unique_ptr<MockApi> * mockapi,std::unique_ptr<MockCal> * mockcal)159     void createMock(std::unique_ptr<MockApi> *mockapi, std::unique_ptr<MockCal> *mockcal) {
160         *mockapi = std::make_unique<MockApi>();
161         *mockcal = std::make_unique<MockCal>();
162 
163         mMockApi = mockapi->get();
164         mMockCal = mockcal->get();
165 
166         ON_CALL(*mMockApi, destructor()).WillByDefault(Assign(&mMockApi, nullptr));
167 
168         ON_CALL(*mMockApi, getEffectCount(_))
169                 .WillByDefault(DoAll(SetArgPointee<0>(EFFECT_DURATIONS.size()), Return(true)));
170 
171         ON_CALL(*mMockApi, setEffectIndex(_))
172                 .WillByDefault(Invoke(this, &VibratorTest::setEffectIndex));
173 
174         ON_CALL(*mMockApi, getEffectDuration(_))
175                 .WillByDefault(Invoke(this, &VibratorTest::getEffectDuration));
176 
177         ON_CALL(*mMockCal, destructor()).WillByDefault(Assign(&mMockCal, nullptr));
178 
179         ON_CALL(*mMockCal, getVolLevels(_))
180                 .WillByDefault(DoAll(SetArgPointee<0>(V_LEVELS), Return(true)));
181 
182         relaxMock(false);
183     }
184 
createVibrator(std::unique_ptr<MockApi> mockapi,std::unique_ptr<MockCal> mockcal,bool relaxed=true)185     void createVibrator(std::unique_ptr<MockApi> mockapi, std::unique_ptr<MockCal> mockcal,
186                         bool relaxed = true) {
187         if (relaxed) {
188             relaxMock(true);
189         }
190         mVibrator = ndk::SharedRefBase::make<Vibrator>(std::move(mockapi), std::move(mockcal));
191         if (relaxed) {
192             relaxMock(false);
193         }
194     }
195 
deleteVibrator(bool relaxed=true)196     void deleteVibrator(bool relaxed = true) {
197         if (relaxed) {
198             relaxMock(true);
199         }
200         mVibrator.reset();
201     }
202 
setEffectIndex(EffectIndex index)203     bool setEffectIndex(EffectIndex index) {
204         mEffectIndex = index;
205         return true;
206     }
207 
getEffectDuration(EffectDuration * duration)208     bool getEffectDuration(EffectDuration *duration) {
209         if (mEffectIndex < EFFECT_DURATIONS.size()) {
210             *duration = msToCycles(EFFECT_DURATIONS[mEffectIndex]);
211             return true;
212         } else {
213             return false;
214         }
215     }
216 
217   private:
relaxMock(bool relax)218     void relaxMock(bool relax) {
219         auto times = relax ? AnyNumber() : Exactly(0);
220 
221         Mock::VerifyAndClearExpectations(mMockApi);
222         Mock::VerifyAndClearExpectations(mMockCal);
223 
224         EXPECT_CALL(*mMockApi, destructor()).Times(times);
225         EXPECT_CALL(*mMockApi, setF0(_)).Times(times);
226         EXPECT_CALL(*mMockApi, setRedc(_)).Times(times);
227         EXPECT_CALL(*mMockApi, setQ(_)).Times(times);
228         EXPECT_CALL(*mMockApi, setActivate(_)).Times(times);
229         EXPECT_CALL(*mMockApi, setDuration(_)).Times(times);
230         EXPECT_CALL(*mMockApi, getEffectCount(_)).Times(times);
231         EXPECT_CALL(*mMockApi, getEffectDuration(_)).Times(times);
232         EXPECT_CALL(*mMockApi, setEffectIndex(_)).Times(times);
233         EXPECT_CALL(*mMockApi, setEffectQueue(_)).Times(times);
234         EXPECT_CALL(*mMockApi, hasEffectScale()).Times(times);
235         EXPECT_CALL(*mMockApi, setEffectScale(_)).Times(times);
236         EXPECT_CALL(*mMockApi, setGlobalScale(_)).Times(times);
237         EXPECT_CALL(*mMockApi, setState(_)).Times(times);
238         EXPECT_CALL(*mMockApi, hasAspEnable()).Times(times);
239         EXPECT_CALL(*mMockApi, getAspEnable(_)).Times(times);
240         EXPECT_CALL(*mMockApi, setAspEnable(_)).Times(times);
241         EXPECT_CALL(*mMockApi, setGpioFallIndex(_)).Times(times);
242         EXPECT_CALL(*mMockApi, setGpioFallScale(_)).Times(times);
243         EXPECT_CALL(*mMockApi, setGpioRiseIndex(_)).Times(times);
244         EXPECT_CALL(*mMockApi, setGpioRiseScale(_)).Times(times);
245         EXPECT_CALL(*mMockApi, debug(_)).Times(times);
246 
247         EXPECT_CALL(*mMockCal, destructor()).Times(times);
248         EXPECT_CALL(*mMockCal, getF0(_)).Times(times);
249         EXPECT_CALL(*mMockCal, getRedc(_)).Times(times);
250         EXPECT_CALL(*mMockCal, getQ(_)).Times(times);
251         EXPECT_CALL(*mMockCal, getVolLevels(_)).Times(times);
252         EXPECT_CALL(*mMockCal, debug(_)).Times(times);
253     }
254 
255   protected:
256     MockApi *mMockApi;
257     MockCal *mMockCal;
258     std::shared_ptr<IVibrator> mVibrator;
259     uint32_t mEffectIndex;
260 };
261 
TEST_F(VibratorTest,Constructor)262 TEST_F(VibratorTest, Constructor) {
263     std::unique_ptr<MockApi> mockapi;
264     std::unique_ptr<MockCal> mockcal;
265     uint32_t f0Val = std::rand();
266     uint32_t redcVal = std::rand();
267     uint32_t qVal = std::rand();
268     Expectation volGet;
269     Sequence f0Seq, redcSeq, qSeq, volSeq, durSeq;
270 
271     EXPECT_CALL(*mMockApi, destructor()).WillOnce(DoDefault());
272     EXPECT_CALL(*mMockCal, destructor()).WillOnce(DoDefault());
273 
274     deleteVibrator(false);
275 
276     createMock(&mockapi, &mockcal);
277 
278     EXPECT_CALL(*mMockCal, getF0(_))
279             .InSequence(f0Seq)
280             .WillOnce(DoAll(SetArgPointee<0>(f0Val), Return(true)));
281     EXPECT_CALL(*mMockApi, setF0(f0Val)).InSequence(f0Seq).WillOnce(Return(true));
282 
283     EXPECT_CALL(*mMockCal, getRedc(_))
284             .InSequence(redcSeq)
285             .WillOnce(DoAll(SetArgPointee<0>(redcVal), Return(true)));
286     EXPECT_CALL(*mMockApi, setRedc(redcVal)).InSequence(redcSeq).WillOnce(Return(true));
287 
288     EXPECT_CALL(*mMockCal, getQ(_))
289             .InSequence(qSeq)
290             .WillOnce(DoAll(SetArgPointee<0>(qVal), Return(true)));
291     EXPECT_CALL(*mMockApi, setQ(qVal)).InSequence(qSeq).WillOnce(Return(true));
292 
293     volGet = EXPECT_CALL(*mMockCal, getVolLevels(_)).WillOnce(DoDefault());
294 
295     EXPECT_CALL(*mMockApi, setState(true)).WillOnce(Return(true));
296     EXPECT_CALL(*mMockApi, getEffectCount(_)).InSequence(durSeq).WillOnce(DoDefault());
297 
298     for (auto &d : EFFECT_DURATIONS) {
299         EXPECT_CALL(*mMockApi, setEffectIndex(&d - &EFFECT_DURATIONS[0]))
300                 .InSequence(durSeq)
301                 .WillOnce(DoDefault());
302         EXPECT_CALL(*mMockApi, getEffectDuration(_)).InSequence(durSeq).WillOnce(DoDefault());
303     }
304 
305     createVibrator(std::move(mockapi), std::move(mockcal), false);
306 }
307 
TEST_F(VibratorTest,on)308 TEST_F(VibratorTest, on) {
309     Sequence s1, s2, s3;
310     uint16_t duration = std::rand() + 1;
311 
312     EXPECT_CALL(*mMockApi, setGlobalScale(ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(Return(true));
313     EXPECT_CALL(*mMockApi, setEffectIndex(ON_EFFECT_INDEX)).InSequence(s2).WillOnce(DoDefault());
314     EXPECT_CALL(*mMockApi, setDuration(Ge(duration))).InSequence(s3).WillOnce(Return(true));
315     EXPECT_CALL(*mMockApi, setActivate(true)).InSequence(s1, s2, s3).WillOnce(Return(true));
316 
317     EXPECT_TRUE(mVibrator->on(duration, nullptr).isOk());
318 }
319 
TEST_F(VibratorTest,off)320 TEST_F(VibratorTest, off) {
321     EXPECT_CALL(*mMockApi, setActivate(false)).WillOnce(Return(true));
322     EXPECT_CALL(*mMockApi, setGlobalScale(0)).WillOnce(Return(true));
323 
324     EXPECT_TRUE(mVibrator->off().isOk());
325 }
326 
TEST_F(VibratorTest,supportsAmplitudeControl_supported)327 TEST_F(VibratorTest, supportsAmplitudeControl_supported) {
328     EXPECT_CALL(*mMockApi, hasEffectScale()).WillOnce(Return(true));
329     EXPECT_CALL(*mMockApi, hasAspEnable()).WillOnce(Return(true));
330 
331     int32_t capabilities;
332     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
333     EXPECT_GT(capabilities & IVibrator::CAP_AMPLITUDE_CONTROL, 0);
334 }
335 
TEST_F(VibratorTest,supportsAmplitudeControl_unsupported1)336 TEST_F(VibratorTest, supportsAmplitudeControl_unsupported1) {
337     EXPECT_CALL(*mMockApi, hasEffectScale()).WillOnce(Return(false));
338     EXPECT_CALL(*mMockApi, hasAspEnable()).WillOnce(Return(true));
339 
340     int32_t capabilities;
341     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
342     EXPECT_EQ(capabilities & IVibrator::CAP_AMPLITUDE_CONTROL, 0);
343 }
344 
TEST_F(VibratorTest,supportsAmplitudeControl_unsupported2)345 TEST_F(VibratorTest, supportsAmplitudeControl_unsupported2) {
346     EXPECT_CALL(*mMockApi, hasEffectScale()).WillOnce(Return(false));
347     EXPECT_CALL(*mMockApi, hasAspEnable()).WillOnce(Return(false));
348 
349     int32_t capabilities;
350     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
351     EXPECT_EQ(capabilities & IVibrator::CAP_AMPLITUDE_CONTROL, 0);
352 }
353 
TEST_F(VibratorTest,supportsExternalAmplitudeControl_unsupported)354 TEST_F(VibratorTest, supportsExternalAmplitudeControl_unsupported) {
355     EXPECT_CALL(*mMockApi, hasEffectScale()).WillOnce(Return(true));
356     EXPECT_CALL(*mMockApi, hasAspEnable()).WillOnce(Return(true));
357 
358     int32_t capabilities;
359     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
360     EXPECT_EQ(capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL, 0);
361 }
362 
TEST_F(VibratorTest,setAmplitude_supported)363 TEST_F(VibratorTest, setAmplitude_supported) {
364     Sequence s;
365     EffectAmplitude amplitude = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
366 
367     EXPECT_CALL(*mMockApi, getAspEnable(_))
368             .InSequence(s)
369             .WillOnce(DoAll(SetArgPointee<0>(false), Return(true)));
370     EXPECT_CALL(*mMockApi, setEffectScale(amplitudeToScale(amplitude)))
371             .InSequence(s)
372             .WillOnce(Return(true));
373 
374     EXPECT_TRUE(mVibrator->setAmplitude(amplitude).isOk());
375 }
376 
TEST_F(VibratorTest,setAmplitude_unsupported)377 TEST_F(VibratorTest, setAmplitude_unsupported) {
378     EXPECT_CALL(*mMockApi, getAspEnable(_)).WillOnce(DoAll(SetArgPointee<0>(true), Return(true)));
379 
380     EXPECT_EQ(EX_UNSUPPORTED_OPERATION, mVibrator->setAmplitude(1).getExceptionCode());
381 }
382 
TEST_F(VibratorTest,supportsExternalControl_supported)383 TEST_F(VibratorTest, supportsExternalControl_supported) {
384     EXPECT_CALL(*mMockApi, hasEffectScale()).WillOnce(Return(true));
385     EXPECT_CALL(*mMockApi, hasAspEnable()).WillOnce(Return(true));
386 
387     int32_t capabilities;
388     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
389     EXPECT_GT(capabilities & IVibrator::CAP_EXTERNAL_CONTROL, 0);
390 }
391 
TEST_F(VibratorTest,supportsExternalControl_unsupported)392 TEST_F(VibratorTest, supportsExternalControl_unsupported) {
393     EXPECT_CALL(*mMockApi, hasEffectScale()).WillOnce(Return(true));
394     EXPECT_CALL(*mMockApi, hasAspEnable()).WillOnce(Return(false));
395 
396     int32_t capabilities;
397     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
398     EXPECT_EQ(capabilities & IVibrator::CAP_EXTERNAL_CONTROL, 0);
399 }
400 
TEST_F(VibratorTest,setExternalControl_enable)401 TEST_F(VibratorTest, setExternalControl_enable) {
402     Sequence s;
403 
404     EXPECT_CALL(*mMockApi, setGlobalScale(ON_GLOBAL_SCALE)).InSequence(s).WillOnce(Return(true));
405     EXPECT_CALL(*mMockApi, setAspEnable(true)).InSequence(s).WillOnce(Return(true));
406 
407     EXPECT_TRUE(mVibrator->setExternalControl(true).isOk());
408 }
409 
TEST_F(VibratorTest,setExternalControl_disable)410 TEST_F(VibratorTest, setExternalControl_disable) {
411     EXPECT_CALL(*mMockApi, setAspEnable(false)).WillOnce(Return(true));
412     EXPECT_CALL(*mMockApi, setGlobalScale(0)).WillOnce(Return(true));
413 
414     EXPECT_TRUE(mVibrator->setExternalControl(false).isOk());
415 }
416 
417 class EffectsTest : public VibratorTest, public WithParamInterface<EffectTuple> {
418   public:
PrintParam(const TestParamInfo<ParamType> & info)419     static auto PrintParam(const TestParamInfo<ParamType> &info) {
420         auto param = info.param;
421         auto effect = std::get<0>(param);
422         auto strength = std::get<1>(param);
423         return toString(effect) + "_" + toString(strength);
424     }
425 };
426 
TEST_P(EffectsTest,perform)427 TEST_P(EffectsTest, perform) {
428     auto param = GetParam();
429     auto effect = std::get<0>(param);
430     auto strength = std::get<1>(param);
431     auto scale = EFFECT_SCALE.find(param);
432     auto queue = EFFECT_QUEUE.find(param);
433     EffectDuration duration;
434     auto callback = ndk::SharedRefBase::make<MockVibratorCallback>();
435     std::promise<void> promise;
436     std::future<void> future{promise.get_future()};
437     auto complete = [&promise] {
438         promise.set_value();
439         return ndk::ScopedAStatus::ok();
440     };
441 
442     ExpectationSet eSetup;
443     Expectation eActivate, ePoll;
444 
445     if (scale != EFFECT_SCALE.end()) {
446         EffectIndex index = EFFECT_INDEX.at(effect);
447         duration = EFFECT_DURATIONS[index];
448 
449         eSetup += EXPECT_CALL(*mMockApi, setEffectIndex(index)).WillOnce(DoDefault());
450         eSetup += EXPECT_CALL(*mMockApi, setEffectScale(scale->second)).WillOnce(Return(true));
451     } else if (queue != EFFECT_QUEUE.end()) {
452         duration = std::get<1>(queue->second);
453 
454         eSetup += EXPECT_CALL(*mMockApi, setEffectIndex(QUEUE_INDEX)).WillOnce(DoDefault());
455         eSetup += EXPECT_CALL(*mMockApi, setEffectQueue(std::get<0>(queue->second)))
456                           .WillOnce(Return(true));
457         eSetup += EXPECT_CALL(*mMockApi, setEffectScale(0)).WillOnce(Return(true));
458     } else {
459         duration = 0;
460     }
461 
462     if (duration) {
463         eSetup += EXPECT_CALL(*mMockApi, setDuration(Ge(duration))).WillOnce(Return(true));
464         eActivate = EXPECT_CALL(*mMockApi, setActivate(true)).After(eSetup).WillOnce(Return(true));
465         ePoll = EXPECT_CALL(*mMockApi, pollVibeState(false))
466                         .After(eActivate)
467                         .WillOnce(Return(true));
468         EXPECT_CALL(*mMockApi, setActivate(false)).After(ePoll).WillOnce(Return(true));
469         EXPECT_CALL(*callback, onComplete()).After(ePoll).WillOnce(complete);
470     }
471 
472     int32_t lengthMs;
473     ndk::ScopedAStatus status = mVibrator->perform(effect, strength, callback, &lengthMs);
474     if (status.isOk()) {
475         EXPECT_LE(duration, lengthMs);
476     } else {
477         EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
478         EXPECT_EQ(0, lengthMs);
479     }
480 
481     if (duration) {
482         EXPECT_EQ(future.wait_for(std::chrono::milliseconds(100)), std::future_status::ready);
483     }
484 }
485 
TEST_P(EffectsTest,alwaysOnEnable)486 TEST_P(EffectsTest, alwaysOnEnable) {
487     auto param = GetParam();
488     auto effect = std::get<0>(param);
489     auto strength = std::get<1>(param);
490     auto scale = EFFECT_SCALE.find(param);
491     bool supported = (scale != EFFECT_SCALE.end());
492 
493     if (supported) {
494         EXPECT_CALL(*mMockApi, setGpioRiseIndex(EFFECT_INDEX.at(effect))).WillOnce(Return(true));
495         EXPECT_CALL(*mMockApi, setGpioRiseScale(scale->second)).WillOnce(Return(true));
496     }
497 
498     ndk::ScopedAStatus status = mVibrator->alwaysOnEnable(0, effect, strength);
499     if (supported) {
500         EXPECT_EQ(EX_NONE, status.getExceptionCode());
501     } else {
502         EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
503     }
504 }
505 
506 const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
507                                    ndk::enum_range<Effect>().end()};
508 const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
509                                                    ndk::enum_range<EffectStrength>().end()};
510 
511 INSTANTIATE_TEST_CASE_P(VibratorTests, EffectsTest,
512                         Combine(ValuesIn(kEffects.begin(), kEffects.end()),
513                                 ValuesIn(kEffectStrengths.begin(), kEffectStrengths.end())),
514                         EffectsTest::PrintParam);
515 
516 struct PrimitiveParam {
517     CompositePrimitive primitive;
518     EffectIndex index;
519 };
520 
521 class PrimitiveTest : public VibratorTest, public WithParamInterface<PrimitiveParam> {
522   public:
PrintParam(const TestParamInfo<ParamType> & info)523     static auto PrintParam(const TestParamInfo<ParamType> &info) {
524         return toString(info.param.primitive);
525     }
526 };
527 
528 const std::vector<PrimitiveParam> kPrimitiveParams = {
529         {CompositePrimitive::NOOP, 0},       {CompositePrimitive::CLICK, 2},
530         {CompositePrimitive::QUICK_RISE, 6}, {CompositePrimitive::SLOW_RISE, 7},
531         {CompositePrimitive::QUICK_FALL, 8},
532 };
533 
TEST_P(PrimitiveTest,getPrimitiveDuration)534 TEST_P(PrimitiveTest, getPrimitiveDuration) {
535     auto param = GetParam();
536     auto primitive = param.primitive;
537     auto index = param.index;
538     int32_t duration;
539 
540     EXPECT_EQ(EX_NONE, mVibrator->getPrimitiveDuration(primitive, &duration).getExceptionCode());
541     EXPECT_EQ(EFFECT_DURATIONS[index], duration);
542 }
543 
544 INSTANTIATE_TEST_CASE_P(VibratorTests, PrimitiveTest,
545                         ValuesIn(kPrimitiveParams.begin(), kPrimitiveParams.end()),
546                         PrimitiveTest::PrintParam);
547 
548 struct ComposeParam {
549     std::string name;
550     std::vector<CompositeEffect> composite;
551     EffectQueue queue;
552 };
553 
554 class ComposeTest : public VibratorTest, public WithParamInterface<ComposeParam> {
555   public:
PrintParam(const TestParamInfo<ParamType> & info)556     static auto PrintParam(const TestParamInfo<ParamType> &info) { return info.param.name; }
557 };
558 
TEST_P(ComposeTest,compose)559 TEST_P(ComposeTest, compose) {
560     auto param = GetParam();
561     auto composite = param.composite;
562     auto queue = std::get<0>(param.queue);
563     ExpectationSet eSetup;
564     Expectation eActivate, ePoll;
565     auto callback = ndk::SharedRefBase::make<MockVibratorCallback>();
566     std::promise<void> promise;
567     std::future<void> future{promise.get_future()};
568     auto complete = [&promise] {
569         promise.set_value();
570         return ndk::ScopedAStatus::ok();
571     };
572 
573     eSetup += EXPECT_CALL(*mMockApi, setEffectIndex(QUEUE_INDEX)).WillOnce(DoDefault());
574     eSetup += EXPECT_CALL(*mMockApi, setEffectQueue(queue)).WillOnce(Return(true));
575     eSetup += EXPECT_CALL(*mMockApi, setEffectScale(0)).WillOnce(Return(true));
576     eSetup += EXPECT_CALL(*mMockApi, setDuration(UINT32_MAX)).WillOnce(Return(true));
577     eActivate = EXPECT_CALL(*mMockApi, setActivate(true)).After(eSetup).WillOnce(Return(true));
578     ePoll = EXPECT_CALL(*mMockApi, pollVibeState(false)).After(eActivate).WillOnce(Return(true));
579     EXPECT_CALL(*mMockApi, setActivate(false)).After(ePoll).WillOnce(Return(true));
580     EXPECT_CALL(*callback, onComplete()).After(ePoll).WillOnce(complete);
581 
582     EXPECT_EQ(EX_NONE, mVibrator->compose(composite, callback).getExceptionCode());
583 
584     EXPECT_EQ(future.wait_for(std::chrono::milliseconds(100)), std::future_status::ready);
585 }
586 
587 const std::vector<ComposeParam> kComposeParams = {
588         {"click", {{0, CompositePrimitive::CLICK, 1.0f}}, Queue(QueueEffect(2, Level(1.0f)), 0)},
589         {"quick_rise",
590          {{3, CompositePrimitive::QUICK_RISE, 0.4f}},
591          Queue(3, QueueEffect(6, Level(0.4f)), 0)},
592         {"slow_rise",
593          {{4, CompositePrimitive::SLOW_RISE, 0.0f}},
594          Queue(4, QueueEffect(7, Level(0.0f)), 0)},
595         {"quick_fall",
596          {{5, CompositePrimitive::QUICK_FALL, 1.0f}},
597          Queue(5, QueueEffect(8, Level(1.0f)), 0)},
598         {"snap",
599          {{7, CompositePrimitive::QUICK_RISE, 1.0f}, {0, CompositePrimitive::QUICK_FALL, 1.0f}},
600          Queue(7, QueueEffect(6, Level(1.0f)), QueueEffect(8, Level(1.0f)), 0)},
601 };
602 
603 INSTANTIATE_TEST_CASE_P(VibratorTests, ComposeTest,
604                         ValuesIn(kComposeParams.begin(), kComposeParams.end()),
605                         ComposeTest::PrintParam);
606 
607 class AlwaysOnTest : public VibratorTest, public WithParamInterface<int32_t> {
608   public:
PrintParam(const TestParamInfo<ParamType> & info)609     static auto PrintParam(const TestParamInfo<ParamType> &info) {
610         return std::to_string(info.param);
611     }
612 };
613 
TEST_P(AlwaysOnTest,alwaysOnEnable)614 TEST_P(AlwaysOnTest, alwaysOnEnable) {
615     auto param = GetParam();
616     auto scale = EFFECT_SCALE.begin();
617 
618     std::advance(scale, std::rand() % EFFECT_SCALE.size());
619 
620     auto effect = std::get<0>(scale->first);
621     auto strength = std::get<1>(scale->first);
622 
623     switch (param) {
624         case 0:
625             EXPECT_CALL(*mMockApi, setGpioRiseIndex(EFFECT_INDEX.at(effect)))
626                     .WillOnce(Return(true));
627             EXPECT_CALL(*mMockApi, setGpioRiseScale(scale->second)).WillOnce(Return(true));
628             break;
629         case 1:
630             EXPECT_CALL(*mMockApi, setGpioFallIndex(EFFECT_INDEX.at(effect)))
631                     .WillOnce(Return(true));
632             EXPECT_CALL(*mMockApi, setGpioFallScale(scale->second)).WillOnce(Return(true));
633             break;
634     }
635 
636     ndk::ScopedAStatus status = mVibrator->alwaysOnEnable(param, effect, strength);
637     EXPECT_EQ(EX_NONE, status.getExceptionCode());
638 }
639 
TEST_P(AlwaysOnTest,alwaysOnDisable)640 TEST_P(AlwaysOnTest, alwaysOnDisable) {
641     auto param = GetParam();
642 
643     switch (param) {
644         case 0:
645             EXPECT_CALL(*mMockApi, setGpioRiseIndex(0)).WillOnce(Return(true));
646             break;
647         case 1:
648             EXPECT_CALL(*mMockApi, setGpioFallIndex(0)).WillOnce(Return(true));
649             break;
650     }
651 
652     ndk::ScopedAStatus status = mVibrator->alwaysOnDisable(param);
653     EXPECT_EQ(EX_NONE, status.getExceptionCode());
654 }
655 
656 INSTANTIATE_TEST_CASE_P(VibratorTests, AlwaysOnTest, Range(0, 1), AlwaysOnTest::PrintParam);
657 
658 }  // namespace vibrator
659 }  // namespace hardware
660 }  // namespace android
661 }  // namespace aidl
662