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