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