blob: 6f9ba1a96ecc551edc80dc95486872e572e78987 [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 Han61d357e2019-12-17 08:36:07 +000037// TODO(b/143992652): autogenerate
38const std::vector<Effect> kEffects = {
39 Effect::CLICK, Effect::DOUBLE_CLICK, Effect::TICK, Effect::THUD,
40 Effect::POP, Effect::HEAVY_CLICK, Effect::RINGTONE_1, Effect::RINGTONE_2,
41 Effect::RINGTONE_3, Effect::RINGTONE_4, Effect::RINGTONE_5, Effect::RINGTONE_6,
42 Effect::RINGTONE_7, Effect::RINGTONE_8, Effect::RINGTONE_9, Effect::RINGTONE_10,
43 Effect::RINGTONE_11, Effect::RINGTONE_12, Effect::RINGTONE_13, Effect::RINGTONE_14,
44 Effect::RINGTONE_15, Effect::TEXTURE_TICK};
45
46// TODO(b/143992652): autogenerate
47const std::vector<EffectStrength> kEffectStrengths = {EffectStrength::LIGHT, EffectStrength::MEDIUM,
48 EffectStrength::STRONG};
Steven Morelandd44007e2019-10-24 18:12:46 -070049
50const std::vector<Effect> kInvalidEffects = {
Steven Morelandf3353882019-11-07 17:02:43 -080051 static_cast<Effect>(static_cast<int32_t>(kEffects.front()) - 1),
52 static_cast<Effect>(static_cast<int32_t>(kEffects.back()) + 1),
Steven Morelandd44007e2019-10-24 18:12:46 -070053};
54
55const std::vector<EffectStrength> kInvalidEffectStrengths = {
Steven Morelandf3353882019-11-07 17:02:43 -080056 static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.front()) - 1),
57 static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.back()) + 1),
Steven Morelandd44007e2019-10-24 18:12:46 -070058};
59
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090060// TODO(b/143992652): autogenerate
61const std::vector<CompositePrimitive> kCompositePrimitives = {
62 CompositePrimitive::NOOP, CompositePrimitive::CLICK,
63 CompositePrimitive::THUD, CompositePrimitive::SPIN,
64 CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
65 CompositePrimitive::QUICK_FALL,
66};
67// TODO(b/143992652): autogenerate
68
69const std::vector<CompositePrimitive> kInvalidPrimitives = {
70 static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
71 static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
72};
73
Steven Morelandd44007e2019-10-24 18:12:46 -070074class CompletionCallback : public BnVibratorCallback {
75 public:
76 CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
77 Status onComplete() override {
78 mCallback();
79 return Status::ok();
80 }
81
82 private:
83 std::function<void()> mCallback;
84};
85
86class VibratorAidl : public testing::TestWithParam<std::string> {
87 public:
88 virtual void SetUp() override {
89 vibrator = android::waitForDeclaredService<IVibrator>(String16(GetParam().c_str()));
90 ASSERT_NE(vibrator, nullptr);
91 ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
92 }
93
94 sp<IVibrator> vibrator;
95 int32_t capabilities;
96};
97
98TEST_P(VibratorAidl, OnThenOffBeforeTimeout) {
99 EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
100 sleep(1);
101 EXPECT_TRUE(vibrator->off().isOk());
102}
103
104TEST_P(VibratorAidl, OnWithCallback) {
105 if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
106
107 std::promise<void> completionPromise;
108 std::future<void> completionFuture{completionPromise.get_future()};
109 sp<CompletionCallback> callback =
110 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
111 uint32_t durationMs = 250;
112 std::chrono::milliseconds timeout{durationMs * 2};
113 EXPECT_TRUE(vibrator->on(durationMs, callback).isOk());
114 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
115 EXPECT_TRUE(vibrator->off().isOk());
116}
117
118TEST_P(VibratorAidl, OnCallbackNotSupported) {
119 if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) {
120 sp<CompletionCallback> callback = new CompletionCallback([] {});
121 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->on(250, callback).exceptionCode());
122 }
123}
124
125TEST_P(VibratorAidl, ValidateEffect) {
Steven Moreland2932b222019-11-05 14:30:17 -0800126 std::vector<Effect> supported;
127 ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
128
Steven Morelandd44007e2019-10-24 18:12:46 -0700129 for (Effect effect : kEffects) {
Steven Moreland2932b222019-11-05 14:30:17 -0800130 bool isEffectSupported =
131 std::find(supported.begin(), supported.end(), effect) != supported.end();
132
Steven Morelandd44007e2019-10-24 18:12:46 -0700133 for (EffectStrength strength : kEffectStrengths) {
134 int32_t lengthMs = 0;
135 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Steven Moreland2932b222019-11-05 14:30:17 -0800136
137 if (isEffectSupported) {
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900138 EXPECT_TRUE(status.isOk()) << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700139 EXPECT_GT(lengthMs, 0);
Steven Morelandf3353882019-11-07 17:02:43 -0800140 usleep(lengthMs * 1000);
Steven Morelandd44007e2019-10-24 18:12:46 -0700141 } else {
Steven Morelandf3353882019-11-07 17:02:43 -0800142 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900143 << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700144 EXPECT_EQ(lengthMs, 0);
145 }
146 }
147 }
148}
149
150TEST_P(VibratorAidl, ValidateEffectWithCallback) {
151 if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
152
Steven Moreland2932b222019-11-05 14:30:17 -0800153 std::vector<Effect> supported;
154 ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
155
Steven Morelandd44007e2019-10-24 18:12:46 -0700156 for (Effect effect : kEffects) {
Steven Moreland2932b222019-11-05 14:30:17 -0800157 bool isEffectSupported =
158 std::find(supported.begin(), supported.end(), effect) != supported.end();
159
Steven Morelandd44007e2019-10-24 18:12:46 -0700160 for (EffectStrength strength : kEffectStrengths) {
161 std::promise<void> completionPromise;
162 std::future<void> completionFuture{completionPromise.get_future()};
163 sp<CompletionCallback> callback =
164 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
Steven Moreland2932b222019-11-05 14:30:17 -0800165 int lengthMs = 0;
Steven Morelandd44007e2019-10-24 18:12:46 -0700166 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
Steven Moreland2932b222019-11-05 14:30:17 -0800167
168 if (isEffectSupported) {
169 EXPECT_TRUE(status.isOk());
170 EXPECT_GT(lengthMs, 0);
171 } else {
172 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
173 EXPECT_EQ(lengthMs, 0);
174 }
175
Steven Morelandd44007e2019-10-24 18:12:46 -0700176 if (!status.isOk()) continue;
177
178 std::chrono::milliseconds timeout{lengthMs * 2};
179 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
180 }
181 }
182}
183
184TEST_P(VibratorAidl, ValidateEffectWithCallbackNotSupported) {
185 if (capabilities & IVibrator::CAP_PERFORM_CALLBACK) return;
186
187 for (Effect effect : kEffects) {
188 for (EffectStrength strength : kEffectStrengths) {
189 sp<CompletionCallback> callback = new CompletionCallback([] {});
190 int lengthMs;
191 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
192 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
193 EXPECT_EQ(lengthMs, 0);
194 }
195 }
196}
197
198TEST_P(VibratorAidl, InvalidEffectsUnsupported) {
199 for (Effect effect : kInvalidEffects) {
Steven Morelandf3353882019-11-07 17:02:43 -0800200 for (EffectStrength strength : kEffectStrengths) {
201 int32_t lengthMs;
202 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
203 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900204 << toString(effect) << " " << toString(strength);
Steven Morelandf3353882019-11-07 17:02:43 -0800205 }
206 }
207 for (Effect effect : kEffects) {
Steven Morelandd44007e2019-10-24 18:12:46 -0700208 for (EffectStrength strength : kInvalidEffectStrengths) {
209 int32_t lengthMs;
210 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Steven Morelandf3353882019-11-07 17:02:43 -0800211 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900212 << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700213 }
214 }
215}
216
217TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
218 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900219 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700220 EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900221 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700222 sleep(1);
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900223 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700224 sleep(1);
225 }
226}
227
228TEST_P(VibratorAidl, AmplitudeOutsideRangeFails) {
229 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
230 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
231 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(0).exceptionCode());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900232 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(1.1).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700233 }
234}
235
236TEST_P(VibratorAidl, AmplitudeReturnsUnsupportedMatchingCapabilities) {
237 if ((capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
238 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->setAmplitude(1).exceptionCode());
239 }
240}
241
242TEST_P(VibratorAidl, ChangeVibrationExternalControl) {
243 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
244 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
245 sleep(1);
246 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
247 sleep(1);
248 }
249}
250
Steven Morelandc0b92d52019-11-05 13:31:41 -0800251TEST_P(VibratorAidl, ExternalAmplitudeControl) {
252 const bool supportsExternalAmplitudeControl =
253 (capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
254
255 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
256 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
257
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900258 Status amplitudeStatus = vibrator->setAmplitude(0.5);
Steven Morelandc0b92d52019-11-05 13:31:41 -0800259 if (supportsExternalAmplitudeControl) {
260 EXPECT_TRUE(amplitudeStatus.isOk());
261 } else {
262 EXPECT_EQ(amplitudeStatus.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
263 }
264 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
265 } else {
266 EXPECT_FALSE(supportsExternalAmplitudeControl);
267 }
268}
269
Steven Morelandd44007e2019-10-24 18:12:46 -0700270TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
271 if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
272 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
273 vibrator->setExternalControl(true).exceptionCode());
274 }
275}
276
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900277TEST_P(VibratorAidl, ComposeValidPrimitives) {
278 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
279 int32_t maxDelay, maxSize;
280
281 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
282 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
283
284 std::vector<CompositeEffect> composite;
285
286 for (auto primitive : kCompositePrimitives) {
287 CompositeEffect effect;
288
289 effect.delayMs = std::rand() % (maxDelay + 1);
290 effect.primitive = primitive;
291 effect.scale = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
292 composite.emplace_back(effect);
293
294 if (composite.size() == maxSize) {
295 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
296 composite.clear();
297 vibrator->off();
298 }
299 }
300
301 if (composite.size() != 0) {
302 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
303 vibrator->off();
304 }
305 }
306}
307
308TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
309 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
310 for (auto primitive : kInvalidPrimitives) {
311 std::vector<CompositeEffect> composite(1);
312
313 for (auto& effect : composite) {
314 effect.delayMs = 0;
315 effect.primitive = primitive;
316 effect.scale = 1.0f;
317 }
318 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
319 vibrator->compose(composite, nullptr).exceptionCode());
320 vibrator->off();
321 }
322 }
323}
324
325TEST_P(VibratorAidl, CompseDelayBoundary) {
326 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
327 int32_t maxDelay;
328
329 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
330
331 std::vector<CompositeEffect> composite(1);
332 CompositeEffect effect;
333
334 effect.delayMs = 1;
335 effect.primitive = CompositePrimitive::CLICK;
336 effect.scale = 1.0f;
337
338 std::fill(composite.begin(), composite.end(), effect);
339 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
340
341 effect.delayMs = maxDelay + 1;
342
343 std::fill(composite.begin(), composite.end(), effect);
344 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
345 vibrator->compose(composite, nullptr).exceptionCode());
346 vibrator->off();
347 }
348}
349
350TEST_P(VibratorAidl, CompseSizeBoundary) {
351 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
352 int32_t maxSize;
353
354 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
355
356 std::vector<CompositeEffect> composite(maxSize);
357 CompositeEffect effect;
358
359 effect.delayMs = 1;
360 effect.primitive = CompositePrimitive::CLICK;
361 effect.scale = 1.0f;
362
363 std::fill(composite.begin(), composite.end(), effect);
364 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
365
366 composite.emplace_back(effect);
367 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
368 vibrator->compose(composite, nullptr).exceptionCode());
369 vibrator->off();
370 }
371}
372
Haibo Huang83b4c1e2019-11-08 11:59:40 -0800373INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
Steven Morelandd44007e2019-10-24 18:12:46 -0700374 testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
375 android::PrintInstanceNameToString);
376
377int main(int argc, char** argv) {
378 ::testing::InitGoogleTest(&argc, argv);
379 ProcessState::self()->setThreadPoolMaxThreadCount(1);
380 ProcessState::self()->startThreadPool();
381 return RUN_ALL_TESTS();
382}