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