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