blob: 2540d0b1d55b8be94461c93149a76fa688a52ac5 [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>
Lais Andrade80b18612020-10-12 18:44:40 +000021#include <android/hardware/vibrator/IVibratorManager.h>
Steven Morelandd44007e2019-10-24 18:12:46 -070022#include <binder/IServiceManager.h>
23#include <binder/ProcessState.h>
24
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +090025#include <cmath>
Steven Morelandd44007e2019-10-24 18:12:46 -070026#include <future>
27
28using android::ProcessState;
29using android::sp;
30using android::String16;
31using android::binder::Status;
32using android::hardware::vibrator::BnVibratorCallback;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090033using android::hardware::vibrator::CompositeEffect;
34using android::hardware::vibrator::CompositePrimitive;
Steven Morelandd44007e2019-10-24 18:12:46 -070035using android::hardware::vibrator::Effect;
36using android::hardware::vibrator::EffectStrength;
37using android::hardware::vibrator::IVibrator;
Lais Andrade80b18612020-10-12 18:44:40 +000038using android::hardware::vibrator::IVibratorManager;
Harpreet \"Eli\" Sanghab075a6a2020-04-10 15:11:58 +090039using std::chrono::high_resolution_clock;
Steven Morelandd44007e2019-10-24 18:12:46 -070040
Jooyung Han716648d2019-12-17 14:17:48 +000041const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
42 android::enum_range<Effect>().end()};
43const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
44 android::enum_range<EffectStrength>().end()};
Steven Morelandd44007e2019-10-24 18:12:46 -070045
46const std::vector<Effect> kInvalidEffects = {
Steven Morelandf3353882019-11-07 17:02:43 -080047 static_cast<Effect>(static_cast<int32_t>(kEffects.front()) - 1),
48 static_cast<Effect>(static_cast<int32_t>(kEffects.back()) + 1),
Steven Morelandd44007e2019-10-24 18:12:46 -070049};
50
51const std::vector<EffectStrength> kInvalidEffectStrengths = {
Steven Morelandf3353882019-11-07 17:02:43 -080052 static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.front()) - 1),
53 static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.back()) + 1),
Steven Morelandd44007e2019-10-24 18:12:46 -070054};
55
Steven Moreland1c269782020-01-09 11:16:05 -080056const std::vector<CompositePrimitive> kCompositePrimitives{
57 android::enum_range<CompositePrimitive>().begin(),
58 android::enum_range<CompositePrimitive>().end()};
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090059
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +090060const std::vector<CompositePrimitive> kOptionalPrimitives = {
61 CompositePrimitive::THUD,
62 CompositePrimitive::SPIN,
63};
64
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090065const std::vector<CompositePrimitive> kInvalidPrimitives = {
66 static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
67 static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
68};
69
Steven Morelandd44007e2019-10-24 18:12:46 -070070class CompletionCallback : public BnVibratorCallback {
71 public:
72 CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
73 Status onComplete() override {
74 mCallback();
75 return Status::ok();
76 }
77
78 private:
79 std::function<void()> mCallback;
80};
81
Lais Andrade80b18612020-10-12 18:44:40 +000082class VibratorAidl : public testing::TestWithParam<std::tuple<int32_t, int32_t>> {
Steven Morelandd44007e2019-10-24 18:12:46 -070083 public:
84 virtual void SetUp() override {
Lais Andrade80b18612020-10-12 18:44:40 +000085 int32_t managerIdx = std::get<0>(GetParam());
86 int32_t vibratorId = std::get<1>(GetParam());
87 auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
88
89 if (managerIdx < 0) {
90 // Testing a unmanaged vibrator, using vibratorId as index from registered HALs
91 auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
92 ASSERT_LT(vibratorId, vibratorAidlNames.size());
93 auto vibratorName = String16(vibratorAidlNames[vibratorId].c_str());
94 vibrator = android::waitForDeclaredService<IVibrator>(vibratorName);
95 } else {
96 // Testing a managed vibrator, using vibratorId to retrieve it from the manager
97 ASSERT_LT(managerIdx, managerAidlNames.size());
98 auto managerName = String16(managerAidlNames[managerIdx].c_str());
99 auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
100 auto vibratorResult = vibratorManager->getVibrator(vibratorId, &vibrator);
101 ASSERT_TRUE(vibratorResult.isOk());
102 }
103
Steven Morelandd44007e2019-10-24 18:12:46 -0700104 ASSERT_NE(vibrator, nullptr);
105 ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
106 }
107
108 sp<IVibrator> vibrator;
109 int32_t capabilities;
110};
111
112TEST_P(VibratorAidl, OnThenOffBeforeTimeout) {
113 EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
114 sleep(1);
115 EXPECT_TRUE(vibrator->off().isOk());
116}
117
118TEST_P(VibratorAidl, OnWithCallback) {
Fenglin Wu15b01dc2020-11-23 10:03:10 +0800119 if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) return;
Steven Morelandd44007e2019-10-24 18:12:46 -0700120
121 std::promise<void> completionPromise;
122 std::future<void> completionFuture{completionPromise.get_future()};
123 sp<CompletionCallback> callback =
124 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
125 uint32_t durationMs = 250;
126 std::chrono::milliseconds timeout{durationMs * 2};
127 EXPECT_TRUE(vibrator->on(durationMs, callback).isOk());
128 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
129 EXPECT_TRUE(vibrator->off().isOk());
130}
131
132TEST_P(VibratorAidl, OnCallbackNotSupported) {
Fenglin Wu15b01dc2020-11-23 10:03:10 +0800133 if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) {
Steven Morelandd44007e2019-10-24 18:12:46 -0700134 sp<CompletionCallback> callback = new CompletionCallback([] {});
135 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->on(250, callback).exceptionCode());
136 }
137}
138
139TEST_P(VibratorAidl, ValidateEffect) {
Steven Moreland2932b222019-11-05 14:30:17 -0800140 std::vector<Effect> supported;
141 ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
142
Steven Morelandd44007e2019-10-24 18:12:46 -0700143 for (Effect effect : kEffects) {
Steven Moreland2932b222019-11-05 14:30:17 -0800144 bool isEffectSupported =
145 std::find(supported.begin(), supported.end(), effect) != supported.end();
146
Steven Morelandd44007e2019-10-24 18:12:46 -0700147 for (EffectStrength strength : kEffectStrengths) {
148 int32_t lengthMs = 0;
149 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Steven Moreland2932b222019-11-05 14:30:17 -0800150
151 if (isEffectSupported) {
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900152 EXPECT_TRUE(status.isOk()) << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700153 EXPECT_GT(lengthMs, 0);
Steven Morelandf3353882019-11-07 17:02:43 -0800154 usleep(lengthMs * 1000);
Steven Morelandd44007e2019-10-24 18:12:46 -0700155 } else {
Steven Morelandf3353882019-11-07 17:02:43 -0800156 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900157 << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700158 }
159 }
160 }
161}
162
163TEST_P(VibratorAidl, ValidateEffectWithCallback) {
164 if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
165
Steven Moreland2932b222019-11-05 14:30:17 -0800166 std::vector<Effect> supported;
167 ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
168
Steven Morelandd44007e2019-10-24 18:12:46 -0700169 for (Effect effect : kEffects) {
Steven Moreland2932b222019-11-05 14:30:17 -0800170 bool isEffectSupported =
171 std::find(supported.begin(), supported.end(), effect) != supported.end();
172
Steven Morelandd44007e2019-10-24 18:12:46 -0700173 for (EffectStrength strength : kEffectStrengths) {
174 std::promise<void> completionPromise;
175 std::future<void> completionFuture{completionPromise.get_future()};
176 sp<CompletionCallback> callback =
177 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
Steven Moreland2932b222019-11-05 14:30:17 -0800178 int lengthMs = 0;
Steven Morelandd44007e2019-10-24 18:12:46 -0700179 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
Steven Moreland2932b222019-11-05 14:30:17 -0800180
181 if (isEffectSupported) {
182 EXPECT_TRUE(status.isOk());
183 EXPECT_GT(lengthMs, 0);
184 } else {
185 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
Steven Moreland2932b222019-11-05 14:30:17 -0800186 }
187
Steven Morelandd44007e2019-10-24 18:12:46 -0700188 if (!status.isOk()) continue;
189
190 std::chrono::milliseconds timeout{lengthMs * 2};
191 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
192 }
193 }
194}
195
196TEST_P(VibratorAidl, ValidateEffectWithCallbackNotSupported) {
197 if (capabilities & IVibrator::CAP_PERFORM_CALLBACK) return;
198
199 for (Effect effect : kEffects) {
200 for (EffectStrength strength : kEffectStrengths) {
201 sp<CompletionCallback> callback = new CompletionCallback([] {});
202 int lengthMs;
203 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
204 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700205 }
206 }
207}
208
209TEST_P(VibratorAidl, InvalidEffectsUnsupported) {
210 for (Effect effect : kInvalidEffects) {
Steven Morelandf3353882019-11-07 17:02:43 -0800211 for (EffectStrength strength : kEffectStrengths) {
212 int32_t lengthMs;
213 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
214 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900215 << toString(effect) << " " << toString(strength);
Steven Morelandf3353882019-11-07 17:02:43 -0800216 }
217 }
218 for (Effect effect : kEffects) {
Steven Morelandd44007e2019-10-24 18:12:46 -0700219 for (EffectStrength strength : kInvalidEffectStrengths) {
220 int32_t lengthMs;
221 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Steven Morelandf3353882019-11-07 17:02:43 -0800222 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900223 << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700224 }
225 }
226}
227
228TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
229 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900230 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700231 EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900232 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700233 sleep(1);
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900234 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700235 sleep(1);
236 }
237}
238
239TEST_P(VibratorAidl, AmplitudeOutsideRangeFails) {
240 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
241 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
242 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(0).exceptionCode());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900243 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(1.1).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700244 }
245}
246
247TEST_P(VibratorAidl, AmplitudeReturnsUnsupportedMatchingCapabilities) {
248 if ((capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
249 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->setAmplitude(1).exceptionCode());
250 }
251}
252
253TEST_P(VibratorAidl, ChangeVibrationExternalControl) {
254 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
255 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
256 sleep(1);
257 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
258 sleep(1);
259 }
260}
261
Steven Morelandc0b92d52019-11-05 13:31:41 -0800262TEST_P(VibratorAidl, ExternalAmplitudeControl) {
263 const bool supportsExternalAmplitudeControl =
264 (capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
265
266 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
267 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
268
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900269 Status amplitudeStatus = vibrator->setAmplitude(0.5);
Steven Morelandc0b92d52019-11-05 13:31:41 -0800270 if (supportsExternalAmplitudeControl) {
271 EXPECT_TRUE(amplitudeStatus.isOk());
272 } else {
273 EXPECT_EQ(amplitudeStatus.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
274 }
275 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
276 } else {
277 EXPECT_FALSE(supportsExternalAmplitudeControl);
278 }
279}
280
Steven Morelandd44007e2019-10-24 18:12:46 -0700281TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
282 if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
283 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
284 vibrator->setExternalControl(true).exceptionCode());
285 }
286}
287
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900288TEST_P(VibratorAidl, GetSupportedPrimitives) {
289 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
290 std::vector<CompositePrimitive> supported;
291
292 EXPECT_EQ(Status::EX_NONE, vibrator->getSupportedPrimitives(&supported).exceptionCode());
293
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900294 for (auto primitive : kCompositePrimitives) {
295 bool isPrimitiveSupported =
296 std::find(supported.begin(), supported.end(), primitive) != supported.end();
297 bool isPrimitiveOptional =
298 std::find(kOptionalPrimitives.begin(), kOptionalPrimitives.end(), primitive) !=
299 kOptionalPrimitives.end();
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900300
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900301 EXPECT_TRUE(isPrimitiveSupported || isPrimitiveOptional) << toString(primitive);
302 }
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900303 }
304}
305
306TEST_P(VibratorAidl, GetPrimitiveDuration) {
307 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900308 std::vector<CompositePrimitive> supported;
309 ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900310
311 for (auto primitive : kCompositePrimitives) {
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900312 bool isPrimitiveSupported =
313 std::find(supported.begin(), supported.end(), primitive) != supported.end();
314 int32_t duration;
315
316 Status status = vibrator->getPrimitiveDuration(primitive, &duration);
317
318 if (isPrimitiveSupported) {
319 EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
320 } else {
321 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode());
322 }
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900323 }
324 }
325}
326
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900327TEST_P(VibratorAidl, ComposeValidPrimitives) {
328 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900329 std::vector<CompositePrimitive> supported;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900330 int32_t maxDelay, maxSize;
331
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900332 ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900333 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
334 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
335
336 std::vector<CompositeEffect> composite;
337
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900338 for (auto primitive : supported) {
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900339 CompositeEffect effect;
340
341 effect.delayMs = std::rand() % (maxDelay + 1);
342 effect.primitive = primitive;
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900343 effect.scale = static_cast<float>(std::rand()) / RAND_MAX;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900344 composite.emplace_back(effect);
345
346 if (composite.size() == maxSize) {
347 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
348 composite.clear();
349 vibrator->off();
350 }
351 }
352
353 if (composite.size() != 0) {
354 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
355 vibrator->off();
356 }
357 }
358}
359
360TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
361 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900362 auto unsupported = kInvalidPrimitives;
363 std::vector<CompositePrimitive> supported;
364
365 ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
366
367 for (auto primitive : kCompositePrimitives) {
368 bool isPrimitiveSupported =
369 std::find(supported.begin(), supported.end(), primitive) != supported.end();
370
371 if (!isPrimitiveSupported) {
372 unsupported.push_back(primitive);
373 }
374 }
375
376 for (auto primitive : unsupported) {
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900377 std::vector<CompositeEffect> composite(1);
378
379 for (auto& effect : composite) {
380 effect.delayMs = 0;
381 effect.primitive = primitive;
382 effect.scale = 1.0f;
383 }
384 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
385 vibrator->compose(composite, nullptr).exceptionCode());
386 vibrator->off();
387 }
388 }
389}
390
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900391TEST_P(VibratorAidl, ComposeScaleBoundary) {
392 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
393 std::vector<CompositeEffect> composite(1);
394 CompositeEffect& effect = composite[0];
395
396 effect.delayMs = 0;
397 effect.primitive = CompositePrimitive::CLICK;
398
399 effect.scale = std::nextafter(0.0f, -1.0f);
400 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
401 vibrator->compose(composite, nullptr).exceptionCode());
402
403 effect.scale = 0.0f;
404 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
405
406 effect.scale = 1.0f;
407 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
408
409 effect.scale = std::nextafter(1.0f, 2.0f);
410 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
411 vibrator->compose(composite, nullptr).exceptionCode());
412
413 vibrator->off();
414 }
415}
416
417TEST_P(VibratorAidl, ComposeDelayBoundary) {
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900418 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
419 int32_t maxDelay;
420
421 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
422
423 std::vector<CompositeEffect> composite(1);
424 CompositeEffect effect;
425
426 effect.delayMs = 1;
427 effect.primitive = CompositePrimitive::CLICK;
428 effect.scale = 1.0f;
429
430 std::fill(composite.begin(), composite.end(), effect);
431 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
432
433 effect.delayMs = maxDelay + 1;
434
435 std::fill(composite.begin(), composite.end(), effect);
436 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
437 vibrator->compose(composite, nullptr).exceptionCode());
438 vibrator->off();
439 }
440}
441
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900442TEST_P(VibratorAidl, ComposeSizeBoundary) {
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900443 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
444 int32_t maxSize;
445
446 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
447
448 std::vector<CompositeEffect> composite(maxSize);
449 CompositeEffect effect;
450
451 effect.delayMs = 1;
452 effect.primitive = CompositePrimitive::CLICK;
453 effect.scale = 1.0f;
454
455 std::fill(composite.begin(), composite.end(), effect);
456 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
457
458 composite.emplace_back(effect);
459 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
460 vibrator->compose(composite, nullptr).exceptionCode());
461 vibrator->off();
462 }
463}
464
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900465TEST_P(VibratorAidl, ComposeCallback) {
Harpreet \"Eli\" Sanghab075a6a2020-04-10 15:11:58 +0900466 constexpr std::chrono::milliseconds allowedLatency{10};
467
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900468 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
Harpreet \"Eli\" Sanghab075a6a2020-04-10 15:11:58 +0900469 std::vector<CompositePrimitive> supported;
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900470
Harpreet \"Eli\" Sanghab075a6a2020-04-10 15:11:58 +0900471 ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900472
Harpreet \"Eli\" Sanghab075a6a2020-04-10 15:11:58 +0900473 for (auto primitive : supported) {
474 if (primitive == CompositePrimitive::NOOP) {
475 continue;
476 }
477
478 std::promise<void> completionPromise;
479 std::future<void> completionFuture{completionPromise.get_future()};
480 sp<CompletionCallback> callback =
481 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
482 CompositeEffect effect;
483 std::vector<CompositeEffect> composite;
484 int32_t durationMs;
485 std::chrono::milliseconds duration;
486 std::chrono::time_point<high_resolution_clock> start, end;
487 std::chrono::milliseconds elapsed;
488
489 effect.delayMs = 0;
490 effect.primitive = primitive;
491 effect.scale = 1.0f;
492 composite.emplace_back(effect);
493
494 EXPECT_EQ(Status::EX_NONE,
495 vibrator->getPrimitiveDuration(primitive, &durationMs).exceptionCode())
496 << toString(primitive);
497 duration = std::chrono::milliseconds(durationMs);
498
499 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
500 << toString(primitive);
501 start = high_resolution_clock::now();
502
503 EXPECT_EQ(completionFuture.wait_for(duration + allowedLatency),
504 std::future_status::ready)
505 << toString(primitive);
506 end = high_resolution_clock::now();
507
508 elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
509 EXPECT_LE(elapsed.count(), (duration + allowedLatency).count()) << toString(primitive);
510 EXPECT_GE(elapsed.count(), (duration - allowedLatency).count()) << toString(primitive);
511 }
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900512 }
513}
514
Harpreet \"Eli\" Sangha63624092019-09-09 11:04:54 +0900515TEST_P(VibratorAidl, AlwaysOn) {
516 if (capabilities & IVibrator::CAP_ALWAYS_ON_CONTROL) {
517 std::vector<Effect> supported;
518 ASSERT_TRUE(vibrator->getSupportedAlwaysOnEffects(&supported).isOk());
519
520 for (Effect effect : kEffects) {
521 bool isEffectSupported =
522 std::find(supported.begin(), supported.end(), effect) != supported.end();
523
524 for (EffectStrength strength : kEffectStrengths) {
525 Status status = vibrator->alwaysOnEnable(0, effect, strength);
526
527 if (isEffectSupported) {
528 EXPECT_EQ(Status::EX_NONE, status.exceptionCode())
529 << toString(effect) << " " << toString(strength);
530 } else {
531 EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode())
532 << toString(effect) << " " << toString(strength);
533 }
534 }
535 }
536
537 EXPECT_EQ(Status::EX_NONE, vibrator->alwaysOnDisable(0).exceptionCode());
538 }
539}
540
Vince Leung4bae4f92021-02-03 06:21:58 +0000541TEST_P(VibratorAidl, GetResonantFrequency) {
542 float resonantFrequency;
543 Status status = vibrator->getResonantFrequency(&resonantFrequency);
544 if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) {
545 ASSERT_NE(resonantFrequency, 0);
546 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
547 } else {
548 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
549 }
550}
551
552TEST_P(VibratorAidl, GetQFactor) {
553 float qFactor;
554 Status status = vibrator->getQFactor(&qFactor);
555 if (capabilities & IVibrator::CAP_GET_Q_FACTOR) {
556 ASSERT_NE(qFactor, 0);
557 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
558 } else {
559 EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
560 }
561}
562
Lais Andrade80b18612020-10-12 18:44:40 +0000563std::vector<std::tuple<int32_t, int32_t>> GenerateVibratorMapping() {
564 std::vector<std::tuple<int32_t, int32_t>> tuples;
565 auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
566 std::vector<int32_t> vibratorIds;
567
568 for (int i = 0; i < managerAidlNames.size(); i++) {
569 auto managerName = String16(managerAidlNames[i].c_str());
570 auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
571 if (vibratorManager->getVibratorIds(&vibratorIds).isOk()) {
572 for (auto& vibratorId : vibratorIds) {
573 tuples.push_back(std::make_tuple(i, vibratorId));
574 }
575 }
576 }
577
578 auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
579 for (int i = 0; i < vibratorAidlNames.size(); i++) {
580 tuples.push_back(std::make_tuple(-1, i));
581 }
582
583 return tuples;
584}
585
586std::string PrintGeneratedTest(const testing::TestParamInfo<VibratorAidl::ParamType>& info) {
587 const auto& [managerIdx, vibratorId] = info.param;
588 if (managerIdx < 0) {
589 return std::string("TOP_LEVEL_VIBRATOR_") + std::to_string(vibratorId);
590 }
591 return std::string("MANAGER_") + std::to_string(managerIdx) + "_VIBRATOR_ID_" +
592 std::to_string(vibratorId);
593}
594
Dan Shiba4d5322020-07-28 13:09:30 -0700595GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
Lais Andrade80b18612020-10-12 18:44:40 +0000596INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(GenerateVibratorMapping()),
597 PrintGeneratedTest);
Steven Morelandd44007e2019-10-24 18:12:46 -0700598
599int main(int argc, char** argv) {
600 ::testing::InitGoogleTest(&argc, argv);
601 ProcessState::self()->setThreadPoolMaxThreadCount(1);
602 ProcessState::self()->startThreadPool();
603 return RUN_ALL_TESTS();
604}