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