blob: 0e2b3e1e0e3bacefca73ae29f3fa1f36ba2cb7d9 [file] [log] [blame]
Steven Morelandd44007e2019-10-24 18:12:46 -07001/*
2 * Copyright (C) 2019 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#include <aidl/Gtest.h>
17#include <aidl/Vintf.h>
18
19#include <android/hardware/vibrator/BnVibratorCallback.h>
20#include <android/hardware/vibrator/IVibrator.h>
21#include <binder/IServiceManager.h>
22#include <binder/ProcessState.h>
23
24#include <future>
25
26using android::ProcessState;
27using android::sp;
28using android::String16;
29using android::binder::Status;
30using android::hardware::vibrator::BnVibratorCallback;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090031using android::hardware::vibrator::CompositeEffect;
32using android::hardware::vibrator::CompositePrimitive;
Steven Morelandd44007e2019-10-24 18:12:46 -070033using android::hardware::vibrator::Effect;
34using android::hardware::vibrator::EffectStrength;
35using android::hardware::vibrator::IVibrator;
36
Jooyung Han716648d2019-12-17 14:17:48 +000037const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
38 android::enum_range<Effect>().end()};
39const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
40 android::enum_range<EffectStrength>().end()};
Steven Morelandd44007e2019-10-24 18:12:46 -070041
42const std::vector<Effect> kInvalidEffects = {
Steven Morelandf3353882019-11-07 17:02:43 -080043 static_cast<Effect>(static_cast<int32_t>(kEffects.front()) - 1),
44 static_cast<Effect>(static_cast<int32_t>(kEffects.back()) + 1),
Steven Morelandd44007e2019-10-24 18:12:46 -070045};
46
47const std::vector<EffectStrength> kInvalidEffectStrengths = {
Steven Morelandf3353882019-11-07 17:02:43 -080048 static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.front()) - 1),
49 static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.back()) + 1),
Steven Morelandd44007e2019-10-24 18:12:46 -070050};
51
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090052// TODO(b/143992652): autogenerate
53const std::vector<CompositePrimitive> kCompositePrimitives = {
54 CompositePrimitive::NOOP, CompositePrimitive::CLICK,
55 CompositePrimitive::THUD, CompositePrimitive::SPIN,
56 CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
57 CompositePrimitive::QUICK_FALL,
58};
59// TODO(b/143992652): autogenerate
60
61const std::vector<CompositePrimitive> kInvalidPrimitives = {
62 static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
63 static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
64};
65
Steven Morelandd44007e2019-10-24 18:12:46 -070066class CompletionCallback : public BnVibratorCallback {
67 public:
68 CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
69 Status onComplete() override {
70 mCallback();
71 return Status::ok();
72 }
73
74 private:
75 std::function<void()> mCallback;
76};
77
78class VibratorAidl : public testing::TestWithParam<std::string> {
79 public:
80 virtual void SetUp() override {
81 vibrator = android::waitForDeclaredService<IVibrator>(String16(GetParam().c_str()));
82 ASSERT_NE(vibrator, nullptr);
83 ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
84 }
85
86 sp<IVibrator> vibrator;
87 int32_t capabilities;
88};
89
90TEST_P(VibratorAidl, OnThenOffBeforeTimeout) {
91 EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
92 sleep(1);
93 EXPECT_TRUE(vibrator->off().isOk());
94}
95
96TEST_P(VibratorAidl, OnWithCallback) {
97 if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
98
99 std::promise<void> completionPromise;
100 std::future<void> completionFuture{completionPromise.get_future()};
101 sp<CompletionCallback> callback =
102 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
103 uint32_t durationMs = 250;
104 std::chrono::milliseconds timeout{durationMs * 2};
105 EXPECT_TRUE(vibrator->on(durationMs, callback).isOk());
106 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
107 EXPECT_TRUE(vibrator->off().isOk());
108}
109
110TEST_P(VibratorAidl, OnCallbackNotSupported) {
111 if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) {
112 sp<CompletionCallback> callback = new CompletionCallback([] {});
113 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->on(250, callback).exceptionCode());
114 }
115}
116
117TEST_P(VibratorAidl, ValidateEffect) {
Steven Moreland2932b222019-11-05 14:30:17 -0800118 std::vector<Effect> supported;
119 ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
120
Steven Morelandd44007e2019-10-24 18:12:46 -0700121 for (Effect effect : kEffects) {
Steven Moreland2932b222019-11-05 14:30:17 -0800122 bool isEffectSupported =
123 std::find(supported.begin(), supported.end(), effect) != supported.end();
124
Steven Morelandd44007e2019-10-24 18:12:46 -0700125 for (EffectStrength strength : kEffectStrengths) {
126 int32_t lengthMs = 0;
127 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Steven Moreland2932b222019-11-05 14:30:17 -0800128
129 if (isEffectSupported) {
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900130 EXPECT_TRUE(status.isOk()) << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700131 EXPECT_GT(lengthMs, 0);
Steven Morelandf3353882019-11-07 17:02:43 -0800132 usleep(lengthMs * 1000);
Steven Morelandd44007e2019-10-24 18:12:46 -0700133 } else {
Steven Morelandf3353882019-11-07 17:02:43 -0800134 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900135 << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700136 EXPECT_EQ(lengthMs, 0);
137 }
138 }
139 }
140}
141
142TEST_P(VibratorAidl, ValidateEffectWithCallback) {
143 if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
144
Steven Moreland2932b222019-11-05 14:30:17 -0800145 std::vector<Effect> supported;
146 ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
147
Steven Morelandd44007e2019-10-24 18:12:46 -0700148 for (Effect effect : kEffects) {
Steven Moreland2932b222019-11-05 14:30:17 -0800149 bool isEffectSupported =
150 std::find(supported.begin(), supported.end(), effect) != supported.end();
151
Steven Morelandd44007e2019-10-24 18:12:46 -0700152 for (EffectStrength strength : kEffectStrengths) {
153 std::promise<void> completionPromise;
154 std::future<void> completionFuture{completionPromise.get_future()};
155 sp<CompletionCallback> callback =
156 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
Steven Moreland2932b222019-11-05 14:30:17 -0800157 int lengthMs = 0;
Steven Morelandd44007e2019-10-24 18:12:46 -0700158 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
Steven Moreland2932b222019-11-05 14:30:17 -0800159
160 if (isEffectSupported) {
161 EXPECT_TRUE(status.isOk());
162 EXPECT_GT(lengthMs, 0);
163 } else {
164 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
165 EXPECT_EQ(lengthMs, 0);
166 }
167
Steven Morelandd44007e2019-10-24 18:12:46 -0700168 if (!status.isOk()) continue;
169
170 std::chrono::milliseconds timeout{lengthMs * 2};
171 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
172 }
173 }
174}
175
176TEST_P(VibratorAidl, ValidateEffectWithCallbackNotSupported) {
177 if (capabilities & IVibrator::CAP_PERFORM_CALLBACK) return;
178
179 for (Effect effect : kEffects) {
180 for (EffectStrength strength : kEffectStrengths) {
181 sp<CompletionCallback> callback = new CompletionCallback([] {});
182 int lengthMs;
183 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
184 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
185 EXPECT_EQ(lengthMs, 0);
186 }
187 }
188}
189
190TEST_P(VibratorAidl, InvalidEffectsUnsupported) {
191 for (Effect effect : kInvalidEffects) {
Steven Morelandf3353882019-11-07 17:02:43 -0800192 for (EffectStrength strength : kEffectStrengths) {
193 int32_t lengthMs;
194 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
195 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900196 << toString(effect) << " " << toString(strength);
Steven Morelandf3353882019-11-07 17:02:43 -0800197 }
198 }
199 for (Effect effect : kEffects) {
Steven Morelandd44007e2019-10-24 18:12:46 -0700200 for (EffectStrength strength : kInvalidEffectStrengths) {
201 int32_t lengthMs;
202 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Steven Morelandf3353882019-11-07 17:02:43 -0800203 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900204 << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700205 }
206 }
207}
208
209TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
210 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900211 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700212 EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900213 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700214 sleep(1);
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900215 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700216 sleep(1);
217 }
218}
219
220TEST_P(VibratorAidl, AmplitudeOutsideRangeFails) {
221 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
222 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
223 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(0).exceptionCode());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900224 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(1.1).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700225 }
226}
227
228TEST_P(VibratorAidl, AmplitudeReturnsUnsupportedMatchingCapabilities) {
229 if ((capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
230 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->setAmplitude(1).exceptionCode());
231 }
232}
233
234TEST_P(VibratorAidl, ChangeVibrationExternalControl) {
235 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
236 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
237 sleep(1);
238 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
239 sleep(1);
240 }
241}
242
Steven Morelandc0b92d52019-11-05 13:31:41 -0800243TEST_P(VibratorAidl, ExternalAmplitudeControl) {
244 const bool supportsExternalAmplitudeControl =
245 (capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
246
247 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
248 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
249
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900250 Status amplitudeStatus = vibrator->setAmplitude(0.5);
Steven Morelandc0b92d52019-11-05 13:31:41 -0800251 if (supportsExternalAmplitudeControl) {
252 EXPECT_TRUE(amplitudeStatus.isOk());
253 } else {
254 EXPECT_EQ(amplitudeStatus.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
255 }
256 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
257 } else {
258 EXPECT_FALSE(supportsExternalAmplitudeControl);
259 }
260}
261
Steven Morelandd44007e2019-10-24 18:12:46 -0700262TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
263 if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
264 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
265 vibrator->setExternalControl(true).exceptionCode());
266 }
267}
268
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900269TEST_P(VibratorAidl, ComposeValidPrimitives) {
270 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
271 int32_t maxDelay, maxSize;
272
273 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
274 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
275
276 std::vector<CompositeEffect> composite;
277
278 for (auto primitive : kCompositePrimitives) {
279 CompositeEffect effect;
280
281 effect.delayMs = std::rand() % (maxDelay + 1);
282 effect.primitive = primitive;
283 effect.scale = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
284 composite.emplace_back(effect);
285
286 if (composite.size() == maxSize) {
287 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
288 composite.clear();
289 vibrator->off();
290 }
291 }
292
293 if (composite.size() != 0) {
294 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
295 vibrator->off();
296 }
297 }
298}
299
300TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
301 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
302 for (auto primitive : kInvalidPrimitives) {
303 std::vector<CompositeEffect> composite(1);
304
305 for (auto& effect : composite) {
306 effect.delayMs = 0;
307 effect.primitive = primitive;
308 effect.scale = 1.0f;
309 }
310 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
311 vibrator->compose(composite, nullptr).exceptionCode());
312 vibrator->off();
313 }
314 }
315}
316
317TEST_P(VibratorAidl, CompseDelayBoundary) {
318 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
319 int32_t maxDelay;
320
321 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
322
323 std::vector<CompositeEffect> composite(1);
324 CompositeEffect effect;
325
326 effect.delayMs = 1;
327 effect.primitive = CompositePrimitive::CLICK;
328 effect.scale = 1.0f;
329
330 std::fill(composite.begin(), composite.end(), effect);
331 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
332
333 effect.delayMs = maxDelay + 1;
334
335 std::fill(composite.begin(), composite.end(), effect);
336 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
337 vibrator->compose(composite, nullptr).exceptionCode());
338 vibrator->off();
339 }
340}
341
342TEST_P(VibratorAidl, CompseSizeBoundary) {
343 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
344 int32_t maxSize;
345
346 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
347
348 std::vector<CompositeEffect> composite(maxSize);
349 CompositeEffect effect;
350
351 effect.delayMs = 1;
352 effect.primitive = CompositePrimitive::CLICK;
353 effect.scale = 1.0f;
354
355 std::fill(composite.begin(), composite.end(), effect);
356 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
357
358 composite.emplace_back(effect);
359 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
360 vibrator->compose(composite, nullptr).exceptionCode());
361 vibrator->off();
362 }
363}
364
Harpreet \"Eli\" Sangha63624092019-09-09 11:04:54 +0900365TEST_P(VibratorAidl, AlwaysOn) {
366 if (capabilities & IVibrator::CAP_ALWAYS_ON_CONTROL) {
367 std::vector<Effect> supported;
368 ASSERT_TRUE(vibrator->getSupportedAlwaysOnEffects(&supported).isOk());
369
370 for (Effect effect : kEffects) {
371 bool isEffectSupported =
372 std::find(supported.begin(), supported.end(), effect) != supported.end();
373
374 for (EffectStrength strength : kEffectStrengths) {
375 Status status = vibrator->alwaysOnEnable(0, effect, strength);
376
377 if (isEffectSupported) {
378 EXPECT_EQ(Status::EX_NONE, status.exceptionCode())
379 << toString(effect) << " " << toString(strength);
380 } else {
381 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode())
382 << toString(effect) << " " << toString(strength);
383 }
384 }
385 }
386
387 EXPECT_EQ(Status::EX_NONE, vibrator->alwaysOnDisable(0).exceptionCode());
388 }
389}
390
Haibo Huang83b4c1e2019-11-08 11:59:40 -0800391INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
Steven Morelandd44007e2019-10-24 18:12:46 -0700392 testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
393 android::PrintInstanceNameToString);
394
395int main(int argc, char** argv) {
396 ::testing::InitGoogleTest(&argc, argv);
397 ProcessState::self()->setThreadPoolMaxThreadCount(1);
398 ProcessState::self()->startThreadPool();
399 return RUN_ALL_TESTS();
400}