• 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, 130, 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, enableDbc()).Times(times);
307 
308         EXPECT_CALL(*mMockApi, debug(_)).Times(times);
309 
310         EXPECT_CALL(*mMockCal, destructor()).Times(times);
311         EXPECT_CALL(*mMockCal, getF0(_)).Times(times);
312         EXPECT_CALL(*mMockCal, getRedc(_)).Times(times);
313         EXPECT_CALL(*mMockCal, getQ(_)).Times(times);
314         EXPECT_CALL(*mMockCal, getTickVolLevels(_)).Times(times);
315         EXPECT_CALL(*mMockCal, getClickVolLevels(_)).Times(times);
316         EXPECT_CALL(*mMockCal, getLongVolLevels(_)).Times(times);
317         EXPECT_CALL(*mMockCal, isChirpEnabled()).Times(times);
318         EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).Times(times);
319         EXPECT_CALL(*mMockCal, isF0CompEnabled()).Times(times);
320         EXPECT_CALL(*mMockCal, isRedcCompEnabled()).Times(times);
321         EXPECT_CALL(*mMockCal, debug(_)).Times(times);
322 
323         EXPECT_CALL(*mMockStats, destructor()).Times(times);
324         EXPECT_CALL(*mMockStats, logPrimitive(_)).Times(times);
325         EXPECT_CALL(*mMockStats, logWaveform(_, _)).Times(times);
326         EXPECT_CALL(*mMockStats, logLatencyStart(_)).Times(times);
327         EXPECT_CALL(*mMockStats, logLatencyEnd()).Times(times);
328     }
329 
330   protected:
331     MockApi *mMockApi;
332     MockCal *mMockCal;
333     MockStats *mMockStats;
334     std::shared_ptr<IVibrator> mVibrator;
335     uint32_t mEffectIndex;
336 };
337 
TEST_F(VibratorTest,Constructor)338 TEST_F(VibratorTest, Constructor) {
339     std::unique_ptr<MockApi> mockapi;
340     std::unique_ptr<MockCal> mockcal;
341     std::unique_ptr<MockStats> mockstats;
342     std::string f0Val = std::to_string(std::rand());
343     std::string redcVal = std::to_string(std::rand());
344     std::string qVal = std::to_string(std::rand());
345     uint32_t calVer;
346     uint32_t supportedPrimitivesBits = 0x0;
347     Expectation volGet;
348     Sequence f0Seq, redcSeq, qSeq, supportedPrimitivesSeq;
349 
350     EXPECT_CALL(*mMockApi, destructor()).WillOnce(DoDefault());
351     EXPECT_CALL(*mMockCal, destructor()).WillOnce(DoDefault());
352     EXPECT_CALL(*mMockStats, destructor()).WillOnce(DoDefault());
353 
354     deleteVibrator(false);
355 
356     createMock(&mockapi, &mockcal, &mockstats);
357 
358     EXPECT_CALL(*mMockCal, getF0(_))
359             .InSequence(f0Seq)
360             .WillOnce(DoAll(SetArgReferee<0>(f0Val), Return(true)));
361     EXPECT_CALL(*mMockApi, setF0(f0Val)).InSequence(f0Seq).WillOnce(Return(true));
362 
363     EXPECT_CALL(*mMockCal, getRedc(_))
364             .InSequence(redcSeq)
365             .WillOnce(DoAll(SetArgReferee<0>(redcVal), Return(true)));
366     EXPECT_CALL(*mMockApi, setRedc(redcVal)).InSequence(redcSeq).WillOnce(Return(true));
367 
368     EXPECT_CALL(*mMockCal, getQ(_))
369             .InSequence(qSeq)
370             .WillOnce(DoAll(SetArgReferee<0>(qVal), Return(true)));
371     EXPECT_CALL(*mMockApi, setQ(qVal)).InSequence(qSeq).WillOnce(Return(true));
372 
373     EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).WillOnce(Return(true));
374 
375     mMockCal->getVersion(&calVer);
376     if (calVer == 2) {
377         volGet = EXPECT_CALL(*mMockCal, getTickVolLevels(_)).WillOnce(DoDefault());
378         volGet = EXPECT_CALL(*mMockCal, getClickVolLevels(_)).WillOnce(DoDefault());
379         volGet = EXPECT_CALL(*mMockCal, getLongVolLevels(_)).WillOnce(DoDefault());
380     }
381 
382     EXPECT_CALL(*mMockCal, isF0CompEnabled()).WillOnce(Return(true));
383     EXPECT_CALL(*mMockApi, setF0CompEnable(true)).WillOnce(Return(true));
384     EXPECT_CALL(*mMockCal, isRedcCompEnabled()).WillOnce(Return(true));
385     EXPECT_CALL(*mMockApi, setRedcCompEnable(true)).WillOnce(Return(true));
386 
387     EXPECT_CALL(*mMockCal, isChirpEnabled()).WillOnce(Return(true));
388     EXPECT_CALL(*mMockCal, getSupportedPrimitives(_))
389             .InSequence(supportedPrimitivesSeq)
390             .WillOnce(DoAll(SetArgPointee<0>(supportedPrimitivesBits), Return(true)));
391 
392     EXPECT_CALL(*mMockApi, setMinOnOffInterval(MIN_ON_OFF_INTERVAL_US)).WillOnce(Return(true));
393     EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
394     EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));
395     EXPECT_CALL(*mMockApi, getContextScale()).WillRepeatedly(Return(0));
396     EXPECT_CALL(*mMockApi, getContextEnable()).WillRepeatedly(Return(false));
397     EXPECT_CALL(*mMockApi, getContextSettlingTime()).WillRepeatedly(Return(0));
398     EXPECT_CALL(*mMockApi, getContextCooldownTime()).WillRepeatedly(Return(0));
399     EXPECT_CALL(*mMockApi, getContextFadeEnable()).WillRepeatedly(Return(false));
400     EXPECT_CALL(*mMockApi, enableDbc()).WillOnce(Return(true));
401     createVibrator(std::move(mockapi), std::move(mockcal), std::move(mockstats), false);
402 }
403 
TEST_F(VibratorTest,on)404 TEST_F(VibratorTest, on) {
405     Sequence s1, s2;
406     uint16_t duration = std::rand() + 1;
407 
408     EXPECT_CALL(*mMockStats, logLatencyStart(kWaveformEffectLatency))
409             .InSequence(s1, s2)
410             .WillOnce(DoDefault());
411     EXPECT_CALL(*mMockApi, setFFGain(ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
412     EXPECT_CALL(*mMockStats, logWaveform(_, _)).InSequence(s1).WillOnce(DoDefault());
413     EXPECT_CALL(*mMockApi, setFFEffect(_, duration + MAX_COLD_START_LATENCY_MS))
414             .InSequence(s2)
415             .WillOnce(DoDefault());
416     EXPECT_CALL(*mMockStats, logLatencyEnd()).InSequence(s1, s2).WillOnce(DoDefault());
417     EXPECT_CALL(*mMockApi, setFFPlay(ON_EFFECT_INDEX, true))
418             .InSequence(s1, s2)
419             .WillOnce(DoDefault());
420     EXPECT_TRUE(mVibrator->on(duration, nullptr).isOk());
421 }
422 
TEST_F(VibratorTest,off)423 TEST_F(VibratorTest, off) {
424     Sequence s1;
425     EXPECT_CALL(*mMockApi, setFFGain(ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
426     EXPECT_TRUE(mVibrator->off().isOk());
427 }
428 
TEST_F(VibratorTest,supportsAmplitudeControl_supported)429 TEST_F(VibratorTest, supportsAmplitudeControl_supported) {
430     int32_t capabilities;
431     EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
432     EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));
433 
434     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
435     EXPECT_GT(capabilities & IVibrator::CAP_AMPLITUDE_CONTROL, 0);
436 }
437 
TEST_F(VibratorTest,supportsExternalAmplitudeControl_unsupported)438 TEST_F(VibratorTest, supportsExternalAmplitudeControl_unsupported) {
439     int32_t capabilities;
440     EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
441     EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));
442 
443     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
444     EXPECT_EQ(capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL, 0);
445 }
446 
TEST_F(VibratorTest,setAmplitude_supported)447 TEST_F(VibratorTest, setAmplitude_supported) {
448     EffectAmplitude amplitude = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
449 
450     EXPECT_CALL(*mMockApi, setFFGain(amplitudeToScale(amplitude))).WillOnce(Return(true));
451 
452     EXPECT_TRUE(mVibrator->setAmplitude(amplitude).isOk());
453 }
454 
TEST_F(VibratorTest,supportsExternalControl_supported)455 TEST_F(VibratorTest, supportsExternalControl_supported) {
456     int32_t capabilities;
457     EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
458     EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));
459 
460     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
461     EXPECT_GT(capabilities & IVibrator::CAP_EXTERNAL_CONTROL, 0);
462 }
463 
TEST_F(VibratorTest,supportsExternalControl_unsupported)464 TEST_F(VibratorTest, supportsExternalControl_unsupported) {
465     int32_t capabilities;
466     EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
467     EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(false));
468 
469     EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
470     EXPECT_EQ(capabilities & IVibrator::CAP_EXTERNAL_CONTROL, 0);
471 }
472 
TEST_F(VibratorTest,setExternalControl_enable)473 TEST_F(VibratorTest, setExternalControl_enable) {
474     Sequence s1, s2;
475     EXPECT_CALL(*mMockApi, setFFGain(ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
476     EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).InSequence(s2).WillOnce(Return(true));
477     EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, true, _, _))
478             .InSequence(s1, s2)
479             .WillOnce(Return(true));
480 
481     EXPECT_TRUE(mVibrator->setExternalControl(true).isOk());
482 }
483 
TEST_F(VibratorTest,setExternalControl_disable)484 TEST_F(VibratorTest, setExternalControl_disable) {
485     Sequence s1, s2, s3, s4;
486 
487     // The default mIsUnderExternalControl is false, so it needs to turn on the External Control
488     // to make mIsUnderExternalControl become true.
489     EXPECT_CALL(*mMockApi, setFFGain(ON_GLOBAL_SCALE))
490             .InSequence(s1)
491             .InSequence(s1)
492             .WillOnce(DoDefault());
493     EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).InSequence(s2).WillOnce(Return(true));
494     EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, true, _, _)).InSequence(s3).WillOnce(Return(true));
495 
496     EXPECT_TRUE(mVibrator->setExternalControl(true).isOk());
497 
498     EXPECT_CALL(*mMockApi, setFFGain(levelToScale(VOLTAGE_SCALE_MAX)))
499             .InSequence(s4)
500             .WillOnce(DoDefault());
501     EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, false, _, _))
502             .InSequence(s1, s2, s3, s4)
503             .WillOnce(Return(true));
504 
505     EXPECT_TRUE(mVibrator->setExternalControl(false).isOk());
506 }
507 
508 class EffectsTest : public VibratorTest, public WithParamInterface<EffectTuple> {
509   public:
PrintParam(const TestParamInfo<ParamType> & info)510     static auto PrintParam(const TestParamInfo<ParamType> &info) {
511         auto param = info.param;
512         auto effect = std::get<0>(param);
513         auto strength = std::get<1>(param);
514         return toString(effect) + "_" + toString(strength);
515     }
516 };
517 
TEST_P(EffectsTest,perform)518 TEST_P(EffectsTest, perform) {
519     auto param = GetParam();
520     auto effect = std::get<0>(param);
521     auto strength = std::get<1>(param);
522     auto scale = EFFECT_SCALE.find(param);
523     auto queue = EFFECT_QUEUE.find(param);
524     EffectDuration duration;
525     auto callback = ndk::SharedRefBase::make<MockVibratorCallback>();
526     std::promise<void> promise;
527     std::future<void> future{promise.get_future()};
528     auto complete = [&promise] {
529         promise.set_value();
530         return ndk::ScopedAStatus::ok();
531     };
532     bool composeEffect;
533 
534     ExpectationSet eSetup;
535     Expectation eActivate, ePollHaptics, ePollStop, eEraseDone;
536 
537     eSetup +=
538             EXPECT_CALL(*mMockStats, logLatencyStart(kPrebakedEffectLatency)).WillOnce(DoDefault());
539 
540     if (scale != EFFECT_SCALE.end()) {
541         EffectIndex index = EFFECT_INDEX.at(effect);
542         duration = EFFECT_DURATIONS[index];
543 
544         eSetup += EXPECT_CALL(*mMockApi, setFFGain(levelToScale(scale->second)))
545                           .WillOnce(DoDefault());
546         eSetup += EXPECT_CALL(*mMockStats, logLatencyEnd()).WillOnce(DoDefault());
547         eActivate =
548                 EXPECT_CALL(*mMockApi, setFFPlay(index, true)).After(eSetup).WillOnce(DoDefault());
549     } else if (queue != EFFECT_QUEUE.end()) {
550         duration = std::get<1>(queue->second);
551         eSetup += EXPECT_CALL(*mMockApi, setFFGain(ON_GLOBAL_SCALE))
552                           .After(eSetup)
553                           .WillOnce(DoDefault());
554         eSetup += EXPECT_CALL(*mMockApi, getOwtFreeSpace(_)).WillOnce(DoDefault());
555         eSetup += EXPECT_CALL(*mMockApi, uploadOwtEffect(_, _, _, _, _))
556                           .After(eSetup)
557                           .WillOnce(DoDefault());
558         eSetup += EXPECT_CALL(*mMockStats, logLatencyEnd()).After(eSetup).WillOnce(DoDefault());
559         eActivate = EXPECT_CALL(*mMockApi, setFFPlay(WAVEFORM_COMPOSE, true))
560                             .After(eSetup)
561                             .WillOnce(DoDefault());
562         composeEffect = true;
563     } else {
564         duration = 0;
565     }
566 
567     if (duration) {
568         ePollHaptics = EXPECT_CALL(*mMockApi, pollVibeState(1, POLLING_TIMEOUT))
569                                .After(eActivate)
570                                .WillOnce(DoDefault());
571         ePollStop = EXPECT_CALL(*mMockApi, pollVibeState(0, -1))
572                             .After(ePollHaptics)
573                             .WillOnce(DoDefault());
574         if (composeEffect) {
575             eEraseDone = EXPECT_CALL(*mMockApi, eraseOwtEffect(_, _))
576                                  .After(ePollStop)
577                                  .WillOnce(DoDefault());
578             EXPECT_CALL(*callback, onComplete()).After(eEraseDone).WillOnce(complete);
579         } else {
580             EXPECT_CALL(*callback, onComplete()).After(ePollStop).WillOnce(complete);
581         }
582     }
583 
584     int32_t lengthMs;
585     ndk::ScopedAStatus status = mVibrator->perform(effect, strength, callback, &lengthMs);
586     if (status.isOk()) {
587         EXPECT_LE(duration, lengthMs);
588     } else {
589         EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
590         EXPECT_EQ(0, lengthMs);
591     }
592 
593     if (duration) {
594         EXPECT_EQ(future.wait_for(std::chrono::milliseconds(100)), std::future_status::ready);
595     }
596 }
597 
598 const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
599                                    ndk::enum_range<Effect>().end()};
600 const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
601                                                    ndk::enum_range<EffectStrength>().end()};
602 
603 INSTANTIATE_TEST_CASE_P(VibratorTests, EffectsTest,
604                         Combine(ValuesIn(kEffects.begin(), kEffects.end()),
605                                 ValuesIn(kEffectStrengths.begin(), kEffectStrengths.end())),
606                         EffectsTest::PrintParam);
607 
608 struct PrimitiveParam {
609     CompositePrimitive primitive;
610     EffectIndex index;
611 };
612 
613 class PrimitiveTest : public VibratorTest, public WithParamInterface<PrimitiveParam> {
614   public:
PrintParam(const TestParamInfo<ParamType> & info)615     static auto PrintParam(const TestParamInfo<ParamType> &info) {
616         return toString(info.param.primitive);
617     }
618 };
619 
620 const std::vector<PrimitiveParam> kPrimitiveParams = {
621         {CompositePrimitive::CLICK, 2},      {CompositePrimitive::THUD, 4},
622         {CompositePrimitive::SPIN, 5},       {CompositePrimitive::QUICK_RISE, 6},
623         {CompositePrimitive::SLOW_RISE, 7},  {CompositePrimitive::QUICK_FALL, 8},
624         {CompositePrimitive::LIGHT_TICK, 9}, {CompositePrimitive::LOW_TICK, 10},
625 };
626 
TEST_P(PrimitiveTest,getPrimitiveDuration)627 TEST_P(PrimitiveTest, getPrimitiveDuration) {
628     auto param = GetParam();
629     auto primitive = param.primitive;
630     auto index = param.index;
631     int32_t duration;
632 
633     EXPECT_EQ(EX_NONE, mVibrator->getPrimitiveDuration(primitive, &duration).getExceptionCode());
634     EXPECT_EQ(EFFECT_DURATIONS[index], duration);
635 }
636 
637 INSTANTIATE_TEST_CASE_P(VibratorTests, PrimitiveTest,
638                         ValuesIn(kPrimitiveParams.begin(), kPrimitiveParams.end()),
639                         PrimitiveTest::PrintParam);
640 
641 struct ComposeParam {
642     std::string name;
643     std::vector<CompositeEffect> composite;
644     EffectQueue queue;
645 };
646 
647 class ComposeTest : public VibratorTest, public WithParamInterface<ComposeParam> {
648   public:
PrintParam(const TestParamInfo<ParamType> & info)649     static auto PrintParam(const TestParamInfo<ParamType> &info) { return info.param.name; }
650 };
651 
TEST_P(ComposeTest,compose)652 TEST_P(ComposeTest, compose) {
653     auto param = GetParam();
654     auto composite = param.composite;
655     auto queue = std::get<0>(param.queue);
656     ExpectationSet eSetup;
657     Expectation eActivate, ePollHaptics, ePollStop, eEraseDone;
658     auto callback = ndk::SharedRefBase::make<MockVibratorCallback>();
659     std::promise<void> promise;
660     std::future<void> future{promise.get_future()};
661     auto complete = [&promise] {
662         promise.set_value();
663         return ndk::ScopedAStatus::ok();
664     };
665 
666     eSetup += EXPECT_CALL(*mMockStats, logLatencyStart(kCompositionEffectLatency))
667                       .WillOnce(DoDefault());
668     for (auto &primitive : composite) {
669         eSetup += EXPECT_CALL(*mMockStats, logPrimitive(_)).After(eSetup).WillOnce(DoDefault());
670     }
671     eSetup +=
672             EXPECT_CALL(*mMockApi, setFFGain(ON_GLOBAL_SCALE)).After(eSetup).WillOnce(DoDefault());
673     eSetup += EXPECT_CALL(*mMockApi, getOwtFreeSpace(_)).WillOnce(DoDefault());
674     eSetup += EXPECT_CALL(*mMockApi, uploadOwtEffect(_, _, _, _, _))
675                       .After(eSetup)
676                       .WillOnce(DoDefault());
677     eSetup += EXPECT_CALL(*mMockStats, logLatencyEnd()).WillOnce(DoDefault());
678     eActivate = EXPECT_CALL(*mMockApi, setFFPlay(WAVEFORM_COMPOSE, true))
679                         .After(eSetup)
680                         .WillOnce(DoDefault());
681 
682     ePollHaptics = EXPECT_CALL(*mMockApi, pollVibeState(1, POLLING_TIMEOUT))
683                            .After(eActivate)
684                            .WillOnce(DoDefault());
685     ePollStop =
686             EXPECT_CALL(*mMockApi, pollVibeState(0, -1)).After(ePollHaptics).WillOnce(DoDefault());
687     eEraseDone =
688             EXPECT_CALL(*mMockApi, eraseOwtEffect(_, _)).After(ePollStop).WillOnce(DoDefault());
689     EXPECT_CALL(*callback, onComplete()).After(eEraseDone).WillOnce(complete);
690 
691     EXPECT_EQ(EX_NONE, mVibrator->compose(composite, callback).getExceptionCode());
692 
693     EXPECT_EQ(future.wait_for(std::chrono::milliseconds(100)), std::future_status::ready);
694 }
695 
696 const std::vector<ComposeParam> kComposeParams = {
697         {"click",
698          {{0, CompositePrimitive::CLICK, 1.0f}},
699          Queue(QueueEffect(2, Level(1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
700         {"thud",
701          {{1, CompositePrimitive::THUD, 0.8f}},
702          Queue(1, QueueEffect(4, Level(0.8f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
703         {"spin",
704          {{2, CompositePrimitive::SPIN, 0.6f}},
705          Queue(2, QueueEffect(5, Level(0.6f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
706         {"quick_rise",
707          {{3, CompositePrimitive::QUICK_RISE, 0.4f}},
708          Queue(3, QueueEffect(6, Level(0.4f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])), 0)},
709         {"slow_rise",
710          {{4, CompositePrimitive::SLOW_RISE, 0.0f}},
711          Queue(4, QueueEffect(7, Level(0.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
712         {"quick_fall",
713          {{5, CompositePrimitive::QUICK_FALL, 1.0f}},
714          Queue(5, QueueEffect(8, Level(1.0f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])), 0)},
715         {"pop",
716          {{6, CompositePrimitive::SLOW_RISE, 1.0f}, {50, CompositePrimitive::THUD, 1.0f}},
717          Queue(6, QueueEffect(7, Level(1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 50,
718                QueueEffect(4, Level(1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
719         {"snap",
720          {{7, CompositePrimitive::QUICK_RISE, 1.0f}, {0, CompositePrimitive::QUICK_FALL, 1.0f}},
721          Queue(7, QueueEffect(6, Level(1.0f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])),
722                QueueEffect(8, Level(1.0f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])), 0)},
723 };
724 
725 INSTANTIATE_TEST_CASE_P(VibratorTests, ComposeTest,
726                         ValuesIn(kComposeParams.begin(), kComposeParams.end()),
727                         ComposeTest::PrintParam);
728 }  // namespace vibrator
729 }  // namespace hardware
730 }  // namespace android
731 }  // namespace aidl
732