blob: 5c6120b6f560345e628ce46f45fbcdfa22c8f073 [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
Steven Moreland2932b222019-11-05 14:30:17 -080037// TODO(b/143992652): autogenerate
Steven Morelandd44007e2019-10-24 18:12:46 -070038const 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
Steven Moreland2932b222019-11-05 14:30:17 -080046// TODO(b/143992652): autogenerate
Steven Morelandd44007e2019-10-24 18:12:46 -070047const std::vector<EffectStrength> kEffectStrengths = {EffectStrength::LIGHT, EffectStrength::MEDIUM,
48 EffectStrength::STRONG};
49
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) {
Steven Morelandf3353882019-11-07 17:02:43 -0800138 EXPECT_TRUE(status.isOk())
139 << static_cast<int>(effect) << " " << static_cast<int>(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700140 EXPECT_GT(lengthMs, 0);
Steven Morelandf3353882019-11-07 17:02:43 -0800141 usleep(lengthMs * 1000);
Steven Morelandd44007e2019-10-24 18:12:46 -0700142 } else {
Steven Morelandf3353882019-11-07 17:02:43 -0800143 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
144 << static_cast<int>(effect) << " " << static_cast<int>(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700145 EXPECT_EQ(lengthMs, 0);
146 }
147 }
148 }
149}
150
151TEST_P(VibratorAidl, ValidateEffectWithCallback) {
152 if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
153
Steven Moreland2932b222019-11-05 14:30:17 -0800154 std::vector<Effect> supported;
155 ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
156
Steven Morelandd44007e2019-10-24 18:12:46 -0700157 for (Effect effect : kEffects) {
Steven Moreland2932b222019-11-05 14:30:17 -0800158 bool isEffectSupported =
159 std::find(supported.begin(), supported.end(), effect) != supported.end();
160
Steven Morelandd44007e2019-10-24 18:12:46 -0700161 for (EffectStrength strength : kEffectStrengths) {
162 std::promise<void> completionPromise;
163 std::future<void> completionFuture{completionPromise.get_future()};
164 sp<CompletionCallback> callback =
165 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
Steven Moreland2932b222019-11-05 14:30:17 -0800166 int lengthMs = 0;
Steven Morelandd44007e2019-10-24 18:12:46 -0700167 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
Steven Moreland2932b222019-11-05 14:30:17 -0800168
169 if (isEffectSupported) {
170 EXPECT_TRUE(status.isOk());
171 EXPECT_GT(lengthMs, 0);
172 } else {
173 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
174 EXPECT_EQ(lengthMs, 0);
175 }
176
Steven Morelandd44007e2019-10-24 18:12:46 -0700177 if (!status.isOk()) continue;
178
179 std::chrono::milliseconds timeout{lengthMs * 2};
180 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
181 }
182 }
183}
184
185TEST_P(VibratorAidl, ValidateEffectWithCallbackNotSupported) {
186 if (capabilities & IVibrator::CAP_PERFORM_CALLBACK) return;
187
188 for (Effect effect : kEffects) {
189 for (EffectStrength strength : kEffectStrengths) {
190 sp<CompletionCallback> callback = new CompletionCallback([] {});
191 int lengthMs;
192 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
193 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
194 EXPECT_EQ(lengthMs, 0);
195 }
196 }
197}
198
199TEST_P(VibratorAidl, InvalidEffectsUnsupported) {
200 for (Effect effect : kInvalidEffects) {
Steven Morelandf3353882019-11-07 17:02:43 -0800201 for (EffectStrength strength : kEffectStrengths) {
202 int32_t lengthMs;
203 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
204 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
205 << static_cast<int>(effect) << " " << static_cast<int>(strength);
206 }
207 }
208 for (Effect effect : kEffects) {
Steven Morelandd44007e2019-10-24 18:12:46 -0700209 for (EffectStrength strength : kInvalidEffectStrengths) {
210 int32_t lengthMs;
211 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Steven Morelandf3353882019-11-07 17:02:43 -0800212 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
213 << static_cast<int>(effect) << " " << static_cast<int>(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700214 }
215 }
216}
217
218TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
219 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900220 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700221 EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900222 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700223 sleep(1);
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900224 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700225 sleep(1);
226 }
227}
228
229TEST_P(VibratorAidl, AmplitudeOutsideRangeFails) {
230 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
231 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
232 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(0).exceptionCode());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900233 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(1.1).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700234 }
235}
236
237TEST_P(VibratorAidl, AmplitudeReturnsUnsupportedMatchingCapabilities) {
238 if ((capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
239 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->setAmplitude(1).exceptionCode());
240 }
241}
242
243TEST_P(VibratorAidl, ChangeVibrationExternalControl) {
244 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
245 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
246 sleep(1);
247 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
248 sleep(1);
249 }
250}
251
Steven Morelandc0b92d52019-11-05 13:31:41 -0800252TEST_P(VibratorAidl, ExternalAmplitudeControl) {
253 const bool supportsExternalAmplitudeControl =
254 (capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
255
256 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
257 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
258
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900259 Status amplitudeStatus = vibrator->setAmplitude(0.5);
Steven Morelandc0b92d52019-11-05 13:31:41 -0800260 if (supportsExternalAmplitudeControl) {
261 EXPECT_TRUE(amplitudeStatus.isOk());
262 } else {
263 EXPECT_EQ(amplitudeStatus.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
264 }
265 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
266 } else {
267 EXPECT_FALSE(supportsExternalAmplitudeControl);
268 }
269}
270
Steven Morelandd44007e2019-10-24 18:12:46 -0700271TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
272 if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
273 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
274 vibrator->setExternalControl(true).exceptionCode());
275 }
276}
277
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900278TEST_P(VibratorAidl, ComposeValidPrimitives) {
279 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
280 int32_t maxDelay, maxSize;
281
282 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
283 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
284
285 std::vector<CompositeEffect> composite;
286
287 for (auto primitive : kCompositePrimitives) {
288 CompositeEffect effect;
289
290 effect.delayMs = std::rand() % (maxDelay + 1);
291 effect.primitive = primitive;
292 effect.scale = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;
293 composite.emplace_back(effect);
294
295 if (composite.size() == maxSize) {
296 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
297 composite.clear();
298 vibrator->off();
299 }
300 }
301
302 if (composite.size() != 0) {
303 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
304 vibrator->off();
305 }
306 }
307}
308
309TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
310 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
311 for (auto primitive : kInvalidPrimitives) {
312 std::vector<CompositeEffect> composite(1);
313
314 for (auto& effect : composite) {
315 effect.delayMs = 0;
316 effect.primitive = primitive;
317 effect.scale = 1.0f;
318 }
319 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
320 vibrator->compose(composite, nullptr).exceptionCode());
321 vibrator->off();
322 }
323 }
324}
325
326TEST_P(VibratorAidl, CompseDelayBoundary) {
327 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
328 int32_t maxDelay;
329
330 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
331
332 std::vector<CompositeEffect> composite(1);
333 CompositeEffect effect;
334
335 effect.delayMs = 1;
336 effect.primitive = CompositePrimitive::CLICK;
337 effect.scale = 1.0f;
338
339 std::fill(composite.begin(), composite.end(), effect);
340 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
341
342 effect.delayMs = maxDelay + 1;
343
344 std::fill(composite.begin(), composite.end(), effect);
345 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
346 vibrator->compose(composite, nullptr).exceptionCode());
347 vibrator->off();
348 }
349}
350
351TEST_P(VibratorAidl, CompseSizeBoundary) {
352 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
353 int32_t maxSize;
354
355 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
356
357 std::vector<CompositeEffect> composite(maxSize);
358 CompositeEffect effect;
359
360 effect.delayMs = 1;
361 effect.primitive = CompositePrimitive::CLICK;
362 effect.scale = 1.0f;
363
364 std::fill(composite.begin(), composite.end(), effect);
365 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
366
367 composite.emplace_back(effect);
368 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
369 vibrator->compose(composite, nullptr).exceptionCode());
370 vibrator->off();
371 }
372}
373
Haibo Huang83b4c1e2019-11-08 11:59:40 -0800374INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
Steven Morelandd44007e2019-10-24 18:12:46 -0700375 testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
376 android::PrintInstanceNameToString);
377
378int main(int argc, char** argv) {
379 ::testing::InitGoogleTest(&argc, argv);
380 ProcessState::self()->setThreadPoolMaxThreadCount(1);
381 ProcessState::self()->startThreadPool();
382 return RUN_ALL_TESTS();
383}