blob: db474d69202d49541d7645c517b0b233bd0ae154 [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>
Steven Morelandd44007e2019-10-24 18:12:46 -070018#include <android/hardware/vibrator/BnVibratorCallback.h>
19#include <android/hardware/vibrator/IVibrator.h>
Lais Andrade80b18612020-10-12 18:44:40 +000020#include <android/hardware/vibrator/IVibratorManager.h>
Steven Morelandd44007e2019-10-24 18:12:46 -070021#include <binder/IServiceManager.h>
22#include <binder/ProcessState.h>
23
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +090024#include <cmath>
Steven Morelandd44007e2019-10-24 18:12:46 -070025#include <future>
26
27using android::ProcessState;
28using android::sp;
29using android::String16;
30using android::binder::Status;
Vince Leung823cf5f2021-02-11 02:21:57 +000031using android::hardware::vibrator::ActivePwle;
Steven Morelandd44007e2019-10-24 18:12:46 -070032using android::hardware::vibrator::BnVibratorCallback;
Vince Leung823cf5f2021-02-11 02:21:57 +000033using android::hardware::vibrator::Braking;
34using android::hardware::vibrator::BrakingPwle;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090035using android::hardware::vibrator::CompositeEffect;
36using android::hardware::vibrator::CompositePrimitive;
Steven Morelandd44007e2019-10-24 18:12:46 -070037using android::hardware::vibrator::Effect;
38using android::hardware::vibrator::EffectStrength;
39using android::hardware::vibrator::IVibrator;
Lais Andrade80b18612020-10-12 18:44:40 +000040using android::hardware::vibrator::IVibratorManager;
Vince Leung823cf5f2021-02-11 02:21:57 +000041using android::hardware::vibrator::PrimitivePwle;
Harpreet \"Eli\" Sanghab075a6a2020-04-10 15:11:58 +090042using std::chrono::high_resolution_clock;
Steven Morelandd44007e2019-10-24 18:12:46 -070043
Lais Andradec689ba52024-04-10 11:07:11 +010044using namespace ::std::chrono_literals;
45
Jooyung Han716648d2019-12-17 14:17:48 +000046const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
47 android::enum_range<Effect>().end()};
48const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
49 android::enum_range<EffectStrength>().end()};
Steven Morelandd44007e2019-10-24 18:12:46 -070050
51const std::vector<Effect> kInvalidEffects = {
Vince Leung823cf5f2021-02-11 02:21:57 +000052 static_cast<Effect>(static_cast<int32_t>(kEffects.front()) - 1),
53 static_cast<Effect>(static_cast<int32_t>(kEffects.back()) + 1),
Steven Morelandd44007e2019-10-24 18:12:46 -070054};
55
56const std::vector<EffectStrength> kInvalidEffectStrengths = {
Vince Leung823cf5f2021-02-11 02:21:57 +000057 static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.front()) - 1),
58 static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.back()) + 1),
Steven Morelandd44007e2019-10-24 18:12:46 -070059};
60
Steven Moreland1c269782020-01-09 11:16:05 -080061const std::vector<CompositePrimitive> kCompositePrimitives{
Vince Leung823cf5f2021-02-11 02:21:57 +000062 android::enum_range<CompositePrimitive>().begin(),
63 android::enum_range<CompositePrimitive>().end()};
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090064
Lais Andrade7e643772021-07-09 14:59:44 +010065const std::vector<CompositePrimitive> kRequiredPrimitives = {
66 CompositePrimitive::CLICK, CompositePrimitive::LIGHT_TICK,
67 CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
68 CompositePrimitive::QUICK_FALL,
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +090069};
70
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090071const std::vector<CompositePrimitive> kInvalidPrimitives = {
Vince Leung823cf5f2021-02-11 02:21:57 +000072 static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.front()) - 1),
73 static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +090074};
75
Lais Andradec689ba52024-04-10 11:07:11 +010076// Timeout to wait for vibration callback completion.
77static constexpr auto VIBRATION_CALLBACK_TIMEOUT = 100ms;
78
Steven Morelandd44007e2019-10-24 18:12:46 -070079class CompletionCallback : public BnVibratorCallback {
80 public:
Vince Leung823cf5f2021-02-11 02:21:57 +000081 CompletionCallback(const std::function<void()> &callback) : mCallback(callback) {}
Steven Morelandd44007e2019-10-24 18:12:46 -070082 Status onComplete() override {
83 mCallback();
84 return Status::ok();
85 }
86
87 private:
88 std::function<void()> mCallback;
89};
90
Lais Andrade80b18612020-10-12 18:44:40 +000091class VibratorAidl : public testing::TestWithParam<std::tuple<int32_t, int32_t>> {
Steven Morelandd44007e2019-10-24 18:12:46 -070092 public:
93 virtual void SetUp() override {
Lais Andrade80b18612020-10-12 18:44:40 +000094 int32_t managerIdx = std::get<0>(GetParam());
95 int32_t vibratorId = std::get<1>(GetParam());
96 auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
97
98 if (managerIdx < 0) {
99 // Testing a unmanaged vibrator, using vibratorId as index from registered HALs
100 auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
101 ASSERT_LT(vibratorId, vibratorAidlNames.size());
102 auto vibratorName = String16(vibratorAidlNames[vibratorId].c_str());
103 vibrator = android::waitForDeclaredService<IVibrator>(vibratorName);
104 } else {
105 // Testing a managed vibrator, using vibratorId to retrieve it from the manager
106 ASSERT_LT(managerIdx, managerAidlNames.size());
107 auto managerName = String16(managerAidlNames[managerIdx].c_str());
108 auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
109 auto vibratorResult = vibratorManager->getVibrator(vibratorId, &vibrator);
110 ASSERT_TRUE(vibratorResult.isOk());
111 }
112
Steven Morelandd44007e2019-10-24 18:12:46 -0700113 ASSERT_NE(vibrator, nullptr);
114 ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk());
115 }
116
Lais Andrade38d054e2024-02-09 12:42:09 +0000117 virtual void TearDown() override {
118 // Reset vibrator state between tests.
119 EXPECT_TRUE(vibrator->off().isOk());
120 }
121
Steven Morelandd44007e2019-10-24 18:12:46 -0700122 sp<IVibrator> vibrator;
123 int32_t capabilities;
124};
125
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100126inline bool isUnknownOrUnsupported(Status status) {
127 return status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
128 status.transactionError() == android::UNKNOWN_TRANSACTION;
129}
130
Vince Leung823cf5f2021-02-11 02:21:57 +0000131static float getResonantFrequencyHz(sp<IVibrator> vibrator, int32_t capabilities) {
132 float resonantFrequencyHz;
133 Status status = vibrator->getResonantFrequency(&resonantFrequencyHz);
134 if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) {
135 EXPECT_GT(resonantFrequencyHz, 0);
136 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
137 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100138 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Vince Leung823cf5f2021-02-11 02:21:57 +0000139 }
140 return resonantFrequencyHz;
141}
142
143static float getFrequencyResolutionHz(sp<IVibrator> vibrator, int32_t capabilities) {
144 float freqResolutionHz;
145 Status status = vibrator->getFrequencyResolution(&freqResolutionHz);
146 if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
147 EXPECT_GT(freqResolutionHz, 0);
148 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
149 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100150 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Vince Leung823cf5f2021-02-11 02:21:57 +0000151 }
152 return freqResolutionHz;
153}
154
155static float getFrequencyMinimumHz(sp<IVibrator> vibrator, int32_t capabilities) {
156 float freqMinimumHz;
157 Status status = vibrator->getFrequencyMinimum(&freqMinimumHz);
158 if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
159 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
160
161 float resonantFrequencyHz = getResonantFrequencyHz(vibrator, capabilities);
162
163 EXPECT_GT(freqMinimumHz, 0);
164 EXPECT_LE(freqMinimumHz, resonantFrequencyHz);
165 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100166 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Vince Leung823cf5f2021-02-11 02:21:57 +0000167 }
168 return freqMinimumHz;
169}
170
171static float getFrequencyMaximumHz(sp<IVibrator> vibrator, int32_t capabilities) {
172 std::vector<float> bandwidthAmplitudeMap;
173 Status status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
174 if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
175 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
176 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100177 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Vince Leung823cf5f2021-02-11 02:21:57 +0000178 }
179
chasewu70da3cc2022-03-15 15:16:04 +0800180 float freqMaximumHz = ((bandwidthAmplitudeMap.size() - 1) *
181 getFrequencyResolutionHz(vibrator, capabilities)) +
182 getFrequencyMinimumHz(vibrator, capabilities);
Vince Leung823cf5f2021-02-11 02:21:57 +0000183 return freqMaximumHz;
184}
185
186static float getAmplitudeMin() {
187 return 0.0;
188}
189
190static float getAmplitudeMax() {
191 return 1.0;
192}
193
194static ActivePwle composeValidActivePwle(sp<IVibrator> vibrator, int32_t capabilities) {
195 float frequencyHz;
196 if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) {
197 frequencyHz = getResonantFrequencyHz(vibrator, capabilities);
198 } else if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
199 frequencyHz = getFrequencyMinimumHz(vibrator, capabilities);
200 } else {
201 frequencyHz = 150.0; // default value commonly used
202 }
203
204 ActivePwle active;
205 active.startAmplitude = (getAmplitudeMin() + getAmplitudeMax()) / 2;
206 active.startFrequency = frequencyHz;
207 active.endAmplitude = (getAmplitudeMin() + getAmplitudeMax()) / 2;
208 active.endFrequency = frequencyHz;
chasewu22cb9012022-03-31 23:23:27 +0800209 vibrator->getPwlePrimitiveDurationMax(&(active.duration));
Vince Leung823cf5f2021-02-11 02:21:57 +0000210
211 return active;
212}
213
Steven Morelandd44007e2019-10-24 18:12:46 -0700214TEST_P(VibratorAidl, OnThenOffBeforeTimeout) {
215 EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
216 sleep(1);
217 EXPECT_TRUE(vibrator->off().isOk());
218}
219
220TEST_P(VibratorAidl, OnWithCallback) {
Vince Leung823cf5f2021-02-11 02:21:57 +0000221 if (!(capabilities & IVibrator::CAP_ON_CALLBACK))
222 return;
Steven Morelandd44007e2019-10-24 18:12:46 -0700223
224 std::promise<void> completionPromise;
225 std::future<void> completionFuture{completionPromise.get_future()};
226 sp<CompletionCallback> callback =
Vince Leung823cf5f2021-02-11 02:21:57 +0000227 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
Steven Morelandd44007e2019-10-24 18:12:46 -0700228 uint32_t durationMs = 250;
Lais Andradec689ba52024-04-10 11:07:11 +0100229 auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
Steven Morelandd44007e2019-10-24 18:12:46 -0700230 EXPECT_TRUE(vibrator->on(durationMs, callback).isOk());
231 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
232 EXPECT_TRUE(vibrator->off().isOk());
233}
234
235TEST_P(VibratorAidl, OnCallbackNotSupported) {
Fenglin Wu15b01dc2020-11-23 10:03:10 +0800236 if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) {
Steven Morelandd44007e2019-10-24 18:12:46 -0700237 sp<CompletionCallback> callback = new CompletionCallback([] {});
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100238 Status status = vibrator->on(250, callback);
239 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Steven Morelandd44007e2019-10-24 18:12:46 -0700240 }
241}
242
243TEST_P(VibratorAidl, ValidateEffect) {
Steven Moreland2932b222019-11-05 14:30:17 -0800244 std::vector<Effect> supported;
245 ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
246
Steven Morelandd44007e2019-10-24 18:12:46 -0700247 for (Effect effect : kEffects) {
Steven Moreland2932b222019-11-05 14:30:17 -0800248 bool isEffectSupported =
Vince Leung823cf5f2021-02-11 02:21:57 +0000249 std::find(supported.begin(), supported.end(), effect) != supported.end();
Steven Moreland2932b222019-11-05 14:30:17 -0800250
Steven Morelandd44007e2019-10-24 18:12:46 -0700251 for (EffectStrength strength : kEffectStrengths) {
252 int32_t lengthMs = 0;
253 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Steven Moreland2932b222019-11-05 14:30:17 -0800254
255 if (isEffectSupported) {
Harpreet \"Eli\" Sanghae1723a42019-12-06 14:09:33 +0900256 EXPECT_TRUE(status.isOk()) << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700257 EXPECT_GT(lengthMs, 0);
Steven Morelandf3353882019-11-07 17:02:43 -0800258 usleep(lengthMs * 1000);
Steven Morelandd44007e2019-10-24 18:12:46 -0700259 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100260 EXPECT_TRUE(isUnknownOrUnsupported(status))
261 << status << " " << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700262 }
263 }
264 }
265}
266
267TEST_P(VibratorAidl, ValidateEffectWithCallback) {
Vince Leung823cf5f2021-02-11 02:21:57 +0000268 if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK))
269 return;
Steven Morelandd44007e2019-10-24 18:12:46 -0700270
Steven Moreland2932b222019-11-05 14:30:17 -0800271 std::vector<Effect> supported;
272 ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
273
Steven Morelandd44007e2019-10-24 18:12:46 -0700274 for (Effect effect : kEffects) {
Steven Moreland2932b222019-11-05 14:30:17 -0800275 bool isEffectSupported =
Vince Leung823cf5f2021-02-11 02:21:57 +0000276 std::find(supported.begin(), supported.end(), effect) != supported.end();
Steven Moreland2932b222019-11-05 14:30:17 -0800277
Steven Morelandd44007e2019-10-24 18:12:46 -0700278 for (EffectStrength strength : kEffectStrengths) {
279 std::promise<void> completionPromise;
280 std::future<void> completionFuture{completionPromise.get_future()};
281 sp<CompletionCallback> callback =
Vince Leung823cf5f2021-02-11 02:21:57 +0000282 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
Steven Moreland2932b222019-11-05 14:30:17 -0800283 int lengthMs = 0;
Steven Morelandd44007e2019-10-24 18:12:46 -0700284 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
Steven Moreland2932b222019-11-05 14:30:17 -0800285
286 if (isEffectSupported) {
287 EXPECT_TRUE(status.isOk());
288 EXPECT_GT(lengthMs, 0);
289 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100290 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Steven Moreland2932b222019-11-05 14:30:17 -0800291 }
292
Vince Leung823cf5f2021-02-11 02:21:57 +0000293 if (!status.isOk())
294 continue;
Steven Morelandd44007e2019-10-24 18:12:46 -0700295
Lais Andradec689ba52024-04-10 11:07:11 +0100296 auto timeout = std::chrono::milliseconds(lengthMs) + VIBRATION_CALLBACK_TIMEOUT;
Steven Morelandd44007e2019-10-24 18:12:46 -0700297 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
Lais Andradec689ba52024-04-10 11:07:11 +0100298
299 EXPECT_TRUE(vibrator->off().isOk());
Steven Morelandd44007e2019-10-24 18:12:46 -0700300 }
301 }
302}
303
304TEST_P(VibratorAidl, ValidateEffectWithCallbackNotSupported) {
Vince Leung823cf5f2021-02-11 02:21:57 +0000305 if (capabilities & IVibrator::CAP_PERFORM_CALLBACK)
306 return;
Steven Morelandd44007e2019-10-24 18:12:46 -0700307
308 for (Effect effect : kEffects) {
309 for (EffectStrength strength : kEffectStrengths) {
310 sp<CompletionCallback> callback = new CompletionCallback([] {});
311 int lengthMs;
312 Status status = vibrator->perform(effect, strength, callback, &lengthMs);
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100313 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Steven Morelandd44007e2019-10-24 18:12:46 -0700314 }
315 }
316}
317
318TEST_P(VibratorAidl, InvalidEffectsUnsupported) {
319 for (Effect effect : kInvalidEffects) {
Steven Morelandf3353882019-11-07 17:02:43 -0800320 for (EffectStrength strength : kEffectStrengths) {
321 int32_t lengthMs;
322 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Lais Andrade14932002021-06-16 13:37:37 +0100323 EXPECT_TRUE(isUnknownOrUnsupported(status))
324 << status << toString(effect) << " " << toString(strength);
Steven Morelandf3353882019-11-07 17:02:43 -0800325 }
326 }
327 for (Effect effect : kEffects) {
Steven Morelandd44007e2019-10-24 18:12:46 -0700328 for (EffectStrength strength : kInvalidEffectStrengths) {
329 int32_t lengthMs;
330 Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100331 EXPECT_TRUE(isUnknownOrUnsupported(status))
332 << status << " " << toString(effect) << " " << toString(strength);
Steven Morelandd44007e2019-10-24 18:12:46 -0700333 }
334 }
335}
336
337TEST_P(VibratorAidl, ChangeVibrationAmplitude) {
338 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900339 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.1f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700340 EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900341 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(0.5f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700342 sleep(1);
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900343 EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700344 sleep(1);
Fenglin Wua464fb42022-05-12 10:25:58 +0800345 EXPECT_TRUE(vibrator->off().isOk());
Steven Morelandd44007e2019-10-24 18:12:46 -0700346 }
347}
348
349TEST_P(VibratorAidl, AmplitudeOutsideRangeFails) {
350 if (capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) {
351 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(-1).exceptionCode());
352 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(0).exceptionCode());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900353 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->setAmplitude(1.1).exceptionCode());
Steven Morelandd44007e2019-10-24 18:12:46 -0700354 }
355}
356
357TEST_P(VibratorAidl, AmplitudeReturnsUnsupportedMatchingCapabilities) {
358 if ((capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100359 Status status = vibrator->setAmplitude(1);
360 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Steven Morelandd44007e2019-10-24 18:12:46 -0700361 }
362}
363
364TEST_P(VibratorAidl, ChangeVibrationExternalControl) {
365 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
366 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
367 sleep(1);
368 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
369 sleep(1);
370 }
371}
372
Steven Morelandc0b92d52019-11-05 13:31:41 -0800373TEST_P(VibratorAidl, ExternalAmplitudeControl) {
374 const bool supportsExternalAmplitudeControl =
Vince Leung823cf5f2021-02-11 02:21:57 +0000375 (capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
Steven Morelandc0b92d52019-11-05 13:31:41 -0800376
377 if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
378 EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
379
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900380 Status amplitudeStatus = vibrator->setAmplitude(0.5);
Steven Morelandc0b92d52019-11-05 13:31:41 -0800381 if (supportsExternalAmplitudeControl) {
382 EXPECT_TRUE(amplitudeStatus.isOk());
383 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100384 EXPECT_TRUE(isUnknownOrUnsupported(amplitudeStatus)) << amplitudeStatus;
Steven Morelandc0b92d52019-11-05 13:31:41 -0800385 }
386 EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
387 } else {
388 EXPECT_FALSE(supportsExternalAmplitudeControl);
389 }
390}
391
Steven Morelandd44007e2019-10-24 18:12:46 -0700392TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
393 if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100394 Status status = vibrator->setExternalControl(true);
395 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Steven Morelandd44007e2019-10-24 18:12:46 -0700396 }
397}
398
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900399TEST_P(VibratorAidl, GetSupportedPrimitives) {
400 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
401 std::vector<CompositePrimitive> supported;
402
403 EXPECT_EQ(Status::EX_NONE, vibrator->getSupportedPrimitives(&supported).exceptionCode());
404
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900405 for (auto primitive : kCompositePrimitives) {
406 bool isPrimitiveSupported =
Vince Leung823cf5f2021-02-11 02:21:57 +0000407 std::find(supported.begin(), supported.end(), primitive) != supported.end();
Lais Andrade7e643772021-07-09 14:59:44 +0100408 bool isPrimitiveRequired =
409 std::find(kRequiredPrimitives.begin(), kRequiredPrimitives.end(), primitive) !=
410 kRequiredPrimitives.end();
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900411
Lais Andrade7e643772021-07-09 14:59:44 +0100412 EXPECT_TRUE(isPrimitiveSupported || !isPrimitiveRequired) << toString(primitive);
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900413 }
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900414 }
415}
416
417TEST_P(VibratorAidl, GetPrimitiveDuration) {
418 if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) {
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900419 std::vector<CompositePrimitive> supported;
420 ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900421
422 for (auto primitive : kCompositePrimitives) {
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900423 bool isPrimitiveSupported =
Vince Leung823cf5f2021-02-11 02:21:57 +0000424 std::find(supported.begin(), supported.end(), primitive) != supported.end();
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900425 int32_t duration;
426
427 Status status = vibrator->getPrimitiveDuration(primitive, &duration);
428
429 if (isPrimitiveSupported) {
430 EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
Lais Andradef1b4dd32021-11-03 16:47:32 +0000431 if (primitive != CompositePrimitive::NOOP) {
432 ASSERT_GT(duration, 0) << toString(primitive) << " " << duration;
433 }
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900434 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100435 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900436 }
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900437 }
438 }
439}
440
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900441TEST_P(VibratorAidl, ComposeValidPrimitives) {
Lais Andrade38d054e2024-02-09 12:42:09 +0000442 if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
443 GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
444 }
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900445
Lais Andrade38d054e2024-02-09 12:42:09 +0000446 std::vector<CompositePrimitive> supported;
447 int32_t maxDelay, maxSize;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900448
Lais Andrade38d054e2024-02-09 12:42:09 +0000449 ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
450 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
451 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900452
Lais Andrade38d054e2024-02-09 12:42:09 +0000453 std::vector<CompositeEffect> composite;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900454
Lais Andrade661481e2024-02-12 10:33:09 +0000455 for (int i = 0; i < supported.size(); i++) {
456 auto primitive = supported[i];
457 float t = static_cast<float>(i + 1) / supported.size();
Lais Andrade38d054e2024-02-09 12:42:09 +0000458 CompositeEffect effect;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900459
Lais Andrade661481e2024-02-12 10:33:09 +0000460 effect.delayMs = maxDelay * t;
Lais Andrade38d054e2024-02-09 12:42:09 +0000461 effect.primitive = primitive;
Lais Andrade661481e2024-02-12 10:33:09 +0000462 effect.scale = t;
Lais Andrade38d054e2024-02-09 12:42:09 +0000463
464 if (composite.size() == maxSize) {
465 break;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900466 }
Lais Andrade38d054e2024-02-09 12:42:09 +0000467 }
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900468
Lais Andrade38d054e2024-02-09 12:42:09 +0000469 if (composite.size() != 0) {
470 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
471 EXPECT_TRUE(vibrator->off().isOk());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900472 }
473}
474
475TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) {
Lais Andrade38d054e2024-02-09 12:42:09 +0000476 if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
477 GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
478 }
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900479
Lais Andrade38d054e2024-02-09 12:42:09 +0000480 auto unsupported = kInvalidPrimitives;
481 std::vector<CompositePrimitive> supported;
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900482
Lais Andrade38d054e2024-02-09 12:42:09 +0000483 ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
484
485 for (auto primitive : kCompositePrimitives) {
486 bool isPrimitiveSupported =
Vince Leung823cf5f2021-02-11 02:21:57 +0000487 std::find(supported.begin(), supported.end(), primitive) != supported.end();
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900488
Lais Andrade38d054e2024-02-09 12:42:09 +0000489 if (!isPrimitiveSupported) {
490 unsupported.push_back(primitive);
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900491 }
Lais Andrade38d054e2024-02-09 12:42:09 +0000492 }
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900493
Lais Andrade38d054e2024-02-09 12:42:09 +0000494 for (auto primitive : unsupported) {
495 std::vector<CompositeEffect> composite(1);
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900496
Lais Andrade38d054e2024-02-09 12:42:09 +0000497 for (auto& effect : composite) {
498 effect.delayMs = 0;
499 effect.primitive = primitive;
500 effect.scale = 1.0f;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900501 }
Lais Andrade38d054e2024-02-09 12:42:09 +0000502 Status status = vibrator->compose(composite, nullptr);
503 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900504 }
505}
506
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900507TEST_P(VibratorAidl, ComposeScaleBoundary) {
Lais Andrade38d054e2024-02-09 12:42:09 +0000508 if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
509 GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900510 }
Lais Andrade38d054e2024-02-09 12:42:09 +0000511
512 std::vector<CompositeEffect> composite(1);
513 CompositeEffect& effect = composite[0];
514
515 effect.delayMs = 0;
516 effect.primitive = CompositePrimitive::CLICK;
517
518 effect.scale = std::nextafter(0.0f, -1.0f);
519 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
520
521 effect.scale = 0.0f;
522 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
523 EXPECT_TRUE(vibrator->off().isOk());
524
525 effect.scale = 1.0f;
526 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
527 EXPECT_TRUE(vibrator->off().isOk());
528
529 effect.scale = std::nextafter(1.0f, 2.0f);
530 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900531}
532
533TEST_P(VibratorAidl, ComposeDelayBoundary) {
Lais Andrade38d054e2024-02-09 12:42:09 +0000534 if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
535 GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900536 }
Lais Andrade38d054e2024-02-09 12:42:09 +0000537
538 int32_t maxDelay;
539
540 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionDelayMax(&maxDelay).exceptionCode());
541
542 std::vector<CompositeEffect> composite(1);
Lais Andrade661481e2024-02-12 10:33:09 +0000543 CompositeEffect& effect = composite[0];
Lais Andrade38d054e2024-02-09 12:42:09 +0000544
Lais Andrade38d054e2024-02-09 12:42:09 +0000545 effect.primitive = CompositePrimitive::CLICK;
546 effect.scale = 1.0f;
547
Lais Andrade661481e2024-02-12 10:33:09 +0000548 effect.delayMs = 0;
549 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
550 EXPECT_TRUE(vibrator->off().isOk());
551
552 effect.delayMs = 1;
553 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
554 EXPECT_TRUE(vibrator->off().isOk());
555
556 effect.delayMs = maxDelay;
Lais Andrade38d054e2024-02-09 12:42:09 +0000557 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
558 EXPECT_TRUE(vibrator->off().isOk());
559
560 effect.delayMs = maxDelay + 1;
Lais Andrade38d054e2024-02-09 12:42:09 +0000561 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900562}
563
Harpreet \"Eli\" Sangha7aec5022020-03-11 06:00:55 +0900564TEST_P(VibratorAidl, ComposeSizeBoundary) {
Lais Andrade38d054e2024-02-09 12:42:09 +0000565 if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
566 GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900567 }
Lais Andrade38d054e2024-02-09 12:42:09 +0000568
569 int32_t maxSize;
570
571 EXPECT_EQ(Status::EX_NONE, vibrator->getCompositionSizeMax(&maxSize).exceptionCode());
572
573 std::vector<CompositeEffect> composite(maxSize);
574 CompositeEffect effect;
575
576 effect.delayMs = 1;
577 effect.primitive = CompositePrimitive::CLICK;
578 effect.scale = 1.0f;
579
580 std::fill(composite.begin(), composite.end(), effect);
581 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, nullptr).exceptionCode());
582 EXPECT_TRUE(vibrator->off().isOk());
583
584 composite.emplace_back(effect);
585 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->compose(composite, nullptr).exceptionCode());
Harpreet \"Eli\" Sanghaf4de5b02019-10-23 09:25:52 +0900586}
587
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900588TEST_P(VibratorAidl, ComposeCallback) {
Lais Andrade38d054e2024-02-09 12:42:09 +0000589 if (!(capabilities & IVibrator::CAP_COMPOSE_EFFECTS)) {
590 GTEST_SKIP() << "CAP_COMPOSE_EFFECTS not supported";
591 }
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900592
Lais Andrade38d054e2024-02-09 12:42:09 +0000593 std::vector<CompositePrimitive> supported;
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900594
Lais Andrade38d054e2024-02-09 12:42:09 +0000595 ASSERT_TRUE(vibrator->getSupportedPrimitives(&supported).isOk());
Harpreet \"Eli\" Sanghab075a6a2020-04-10 15:11:58 +0900596
Lais Andrade38d054e2024-02-09 12:42:09 +0000597 for (auto primitive : supported) {
598 if (primitive == CompositePrimitive::NOOP) {
599 continue;
Harpreet \"Eli\" Sanghab075a6a2020-04-10 15:11:58 +0900600 }
Lais Andrade38d054e2024-02-09 12:42:09 +0000601
602 std::promise<void> completionPromise;
603 std::future<void> completionFuture{completionPromise.get_future()};
604 sp<CompletionCallback> callback =
605 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
606 CompositeEffect effect;
607 std::vector<CompositeEffect> composite;
608 int32_t durationMs;
609 std::chrono::milliseconds duration;
610 std::chrono::time_point<high_resolution_clock> start, end;
611 std::chrono::milliseconds elapsed;
612
613 effect.delayMs = 0;
614 effect.primitive = primitive;
615 effect.scale = 1.0f;
616 composite.emplace_back(effect);
617
618 EXPECT_EQ(Status::EX_NONE,
619 vibrator->getPrimitiveDuration(primitive, &durationMs).exceptionCode())
620 << toString(primitive);
621 duration = std::chrono::milliseconds(durationMs);
622
623 start = high_resolution_clock::now();
624 EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
625 << toString(primitive);
626
Lais Andradec689ba52024-04-10 11:07:11 +0100627 EXPECT_EQ(completionFuture.wait_for(duration + VIBRATION_CALLBACK_TIMEOUT),
Lais Andrade38d054e2024-02-09 12:42:09 +0000628 std::future_status::ready)
629 << toString(primitive);
630 end = high_resolution_clock::now();
631
632 elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
633 EXPECT_GE(elapsed.count(), duration.count()) << toString(primitive);
634
635 EXPECT_TRUE(vibrator->off().isOk());
Harpreet \"Eli\" Sanghaafa86362020-01-21 16:15:42 +0900636 }
637}
638
Harpreet \"Eli\" Sangha63624092019-09-09 11:04:54 +0900639TEST_P(VibratorAidl, AlwaysOn) {
640 if (capabilities & IVibrator::CAP_ALWAYS_ON_CONTROL) {
641 std::vector<Effect> supported;
642 ASSERT_TRUE(vibrator->getSupportedAlwaysOnEffects(&supported).isOk());
643
644 for (Effect effect : kEffects) {
645 bool isEffectSupported =
Vince Leung823cf5f2021-02-11 02:21:57 +0000646 std::find(supported.begin(), supported.end(), effect) != supported.end();
Harpreet \"Eli\" Sangha63624092019-09-09 11:04:54 +0900647
648 for (EffectStrength strength : kEffectStrengths) {
649 Status status = vibrator->alwaysOnEnable(0, effect, strength);
650
651 if (isEffectSupported) {
652 EXPECT_EQ(Status::EX_NONE, status.exceptionCode())
Vince Leung823cf5f2021-02-11 02:21:57 +0000653 << toString(effect) << " " << toString(strength);
Harpreet \"Eli\" Sangha63624092019-09-09 11:04:54 +0900654 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100655 EXPECT_TRUE(isUnknownOrUnsupported(status))
656 << status << " " << toString(effect) << " " << toString(strength);
Harpreet \"Eli\" Sangha63624092019-09-09 11:04:54 +0900657 }
658 }
659 }
660
661 EXPECT_EQ(Status::EX_NONE, vibrator->alwaysOnDisable(0).exceptionCode());
662 }
663}
664
Vince Leung4bae4f92021-02-03 06:21:58 +0000665TEST_P(VibratorAidl, GetResonantFrequency) {
Vince Leung823cf5f2021-02-11 02:21:57 +0000666 getResonantFrequencyHz(vibrator, capabilities);
Vince Leung4bae4f92021-02-03 06:21:58 +0000667}
668
669TEST_P(VibratorAidl, GetQFactor) {
670 float qFactor;
671 Status status = vibrator->getQFactor(&qFactor);
672 if (capabilities & IVibrator::CAP_GET_Q_FACTOR) {
Vince Leung823cf5f2021-02-11 02:21:57 +0000673 ASSERT_GT(qFactor, 0);
Vince Leung4bae4f92021-02-03 06:21:58 +0000674 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
675 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100676 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Vince Leung4bae4f92021-02-03 06:21:58 +0000677 }
678}
679
Vince Leung823cf5f2021-02-11 02:21:57 +0000680TEST_P(VibratorAidl, GetFrequencyResolution) {
681 getFrequencyResolutionHz(vibrator, capabilities);
682}
683
684TEST_P(VibratorAidl, GetFrequencyMinimum) {
685 getFrequencyMinimumHz(vibrator, capabilities);
686}
687
688TEST_P(VibratorAidl, GetBandwidthAmplitudeMap) {
689 std::vector<float> bandwidthAmplitudeMap;
690 Status status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
691 if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
692 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
693 ASSERT_FALSE(bandwidthAmplitudeMap.empty());
694
695 int minMapSize = (getResonantFrequencyHz(vibrator, capabilities) -
696 getFrequencyMinimumHz(vibrator, capabilities)) /
697 getFrequencyResolutionHz(vibrator, capabilities);
698 ASSERT_GT(bandwidthAmplitudeMap.size(), minMapSize);
699
700 for (float e : bandwidthAmplitudeMap) {
701 ASSERT_GE(e, 0.0);
702 ASSERT_LE(e, 1.0);
703 }
704 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100705 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Vince Leung823cf5f2021-02-11 02:21:57 +0000706 }
707}
708
709TEST_P(VibratorAidl, GetPwlePrimitiveDurationMax) {
710 int32_t durationMs;
711 Status status = vibrator->getPwlePrimitiveDurationMax(&durationMs);
712 if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
713 ASSERT_NE(durationMs, 0);
714 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
715 } else {
Lais Andrade14932002021-06-16 13:37:37 +0100716 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Vince Leung823cf5f2021-02-11 02:21:57 +0000717 }
718}
719
720TEST_P(VibratorAidl, GetPwleCompositionSizeMax) {
721 int32_t maxSize;
722 Status status = vibrator->getPwleCompositionSizeMax(&maxSize);
723 if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
724 ASSERT_NE(maxSize, 0);
725 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
726 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100727 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Vince Leung823cf5f2021-02-11 02:21:57 +0000728 }
729}
730
731TEST_P(VibratorAidl, GetSupportedBraking) {
732 std::vector<Braking> supported;
733 Status status = vibrator->getSupportedBraking(&supported);
734 if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
735 bool isDefaultNoneSupported =
736 std::find(supported.begin(), supported.end(), Braking::NONE) != supported.end();
737 ASSERT_TRUE(isDefaultNoneSupported);
738 EXPECT_EQ(status.exceptionCode(), Status::EX_NONE);
739 } else {
Lais Andrade4b54b1f2021-06-10 16:38:34 +0100740 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
Vince Leung823cf5f2021-02-11 02:21:57 +0000741 }
742}
743
744TEST_P(VibratorAidl, ComposeValidPwle) {
745 if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
Lais Andrade22754c52021-09-14 12:21:59 +0000746 ActivePwle firstActive = composeValidActivePwle(vibrator, capabilities);
Vince Leung823cf5f2021-02-11 02:21:57 +0000747
748 std::vector<Braking> supported;
749 ASSERT_TRUE(vibrator->getSupportedBraking(&supported).isOk());
750 bool isClabSupported =
751 std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end();
Lais Andrade22754c52021-09-14 12:21:59 +0000752 BrakingPwle firstBraking;
753 firstBraking.braking = isClabSupported ? Braking::CLAB : Braking::NONE;
754 firstBraking.duration = 100;
Vince Leung823cf5f2021-02-11 02:21:57 +0000755
Lais Andrade22754c52021-09-14 12:21:59 +0000756 ActivePwle secondActive = composeValidActivePwle(vibrator, capabilities);
757 if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
758 float minFrequencyHz = getFrequencyMinimumHz(vibrator, capabilities);
759 float maxFrequencyHz = getFrequencyMaximumHz(vibrator, capabilities);
760 float freqResolutionHz = getFrequencyResolutionHz(vibrator, capabilities);
761 secondActive.startFrequency = minFrequencyHz + (freqResolutionHz / 2.0f);
762 secondActive.endFrequency = maxFrequencyHz - (freqResolutionHz / 3.0f);
763 }
764 BrakingPwle secondBraking;
765 secondBraking.braking = Braking::NONE;
766 secondBraking.duration = 10;
767
768 auto pwleQueue =
769 std::vector<PrimitivePwle>{firstActive, firstBraking, secondActive, secondBraking};
Vince Leung823cf5f2021-02-11 02:21:57 +0000770
771 EXPECT_EQ(Status::EX_NONE, vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
Lais Andrade22754c52021-09-14 12:21:59 +0000772 EXPECT_TRUE(vibrator->off().isOk());
Vince Leung823cf5f2021-02-11 02:21:57 +0000773 }
774}
775
776TEST_P(VibratorAidl, ComposeValidPwleWithCallback) {
777 if (!((capabilities & IVibrator::CAP_ON_CALLBACK) &&
778 (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS)))
779 return;
780
781 std::promise<void> completionPromise;
782 std::future<void> completionFuture{completionPromise.get_future()};
783 sp<CompletionCallback> callback =
784 new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
chasewu22cb9012022-03-31 23:23:27 +0800785 int32_t segmentDurationMaxMs;
786 vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
787 uint32_t durationMs = segmentDurationMaxMs * 2 + 100; // Sum of 2 active and 1 braking below
Lais Andradec689ba52024-04-10 11:07:11 +0100788 auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
Vince Leung823cf5f2021-02-11 02:21:57 +0000789
790 ActivePwle active = composeValidActivePwle(vibrator, capabilities);
791
792 std::vector<Braking> supported;
793 ASSERT_TRUE(vibrator->getSupportedBraking(&supported).isOk());
794 bool isClabSupported =
795 std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end();
796 BrakingPwle braking;
797 braking.braking = isClabSupported ? Braking::CLAB : Braking::NONE;
798 braking.duration = 100;
799
Lais Andrade22754c52021-09-14 12:21:59 +0000800 auto pwleQueue = std::vector<PrimitivePwle>{active, braking, active};
Vince Leung823cf5f2021-02-11 02:21:57 +0000801
802 EXPECT_TRUE(vibrator->composePwle(pwleQueue, callback).isOk());
803 EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
804 EXPECT_TRUE(vibrator->off().isOk());
805}
806
807TEST_P(VibratorAidl, ComposePwleSegmentBoundary) {
808 if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
809 std::vector<PrimitivePwle> pwleQueue;
810 // test empty queue
811 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
812 vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
Lais Andrade22754c52021-09-14 12:21:59 +0000813 EXPECT_TRUE(vibrator->off().isOk());
Vince Leung823cf5f2021-02-11 02:21:57 +0000814
815 ActivePwle active = composeValidActivePwle(vibrator, capabilities);
816
817 PrimitivePwle pwle;
818 pwle = active;
819 int segmentCountMax;
820 vibrator->getPwleCompositionSizeMax(&segmentCountMax);
821
822 // Create PWLE queue with more segments than allowed
823 for (int i = 0; i < segmentCountMax + 10; i++) {
824 pwleQueue.emplace_back(std::move(pwle));
825 }
826
827 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
828 vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
Lais Andrade22754c52021-09-14 12:21:59 +0000829 EXPECT_TRUE(vibrator->off().isOk());
Vince Leung823cf5f2021-02-11 02:21:57 +0000830 }
831}
832
833TEST_P(VibratorAidl, ComposePwleAmplitudeParameterBoundary) {
834 if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
835 ActivePwle active = composeValidActivePwle(vibrator, capabilities);
836 active.startAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed
837 active.endAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed
838
Lais Andrade22754c52021-09-14 12:21:59 +0000839 auto pwleQueueGreater = std::vector<PrimitivePwle>{active};
Vince Leung823cf5f2021-02-11 02:21:57 +0000840
841 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
842 vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode());
Lais Andrade22754c52021-09-14 12:21:59 +0000843 EXPECT_TRUE(vibrator->off().isOk());
Vince Leung823cf5f2021-02-11 02:21:57 +0000844
845 active.startAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed
846 active.endAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed
847
Lais Andrade22754c52021-09-14 12:21:59 +0000848 auto pwleQueueLess = std::vector<PrimitivePwle>{active};
Vince Leung823cf5f2021-02-11 02:21:57 +0000849
850 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
851 vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode());
Lais Andrade22754c52021-09-14 12:21:59 +0000852 EXPECT_TRUE(vibrator->off().isOk());
Vince Leung823cf5f2021-02-11 02:21:57 +0000853 }
854}
855
856TEST_P(VibratorAidl, ComposePwleFrequencyParameterBoundary) {
857 if ((capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) &&
858 (capabilities & IVibrator::CAP_FREQUENCY_CONTROL)) {
859 float freqMinimumHz = getFrequencyMinimumHz(vibrator, capabilities);
860 float freqMaximumHz = getFrequencyMaximumHz(vibrator, capabilities);
861 float freqResolutionHz = getFrequencyResolutionHz(vibrator, capabilities);
862
863 ActivePwle active = composeValidActivePwle(vibrator, capabilities);
864 active.startFrequency =
865 freqMaximumHz + freqResolutionHz; // Frequency greater than allowed
866 active.endFrequency = freqMaximumHz + freqResolutionHz; // Frequency greater than allowed
867
Lais Andrade22754c52021-09-14 12:21:59 +0000868 auto pwleQueueGreater = std::vector<PrimitivePwle>{active};
Vince Leung823cf5f2021-02-11 02:21:57 +0000869
870 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
871 vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode());
Lais Andrade22754c52021-09-14 12:21:59 +0000872 EXPECT_TRUE(vibrator->off().isOk());
Vince Leung823cf5f2021-02-11 02:21:57 +0000873
874 active.startFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed
875 active.endFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed
876
Lais Andrade22754c52021-09-14 12:21:59 +0000877 auto pwleQueueLess = std::vector<PrimitivePwle>{active};
Vince Leung823cf5f2021-02-11 02:21:57 +0000878
879 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
880 vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode());
Lais Andrade22754c52021-09-14 12:21:59 +0000881 EXPECT_TRUE(vibrator->off().isOk());
Vince Leung823cf5f2021-02-11 02:21:57 +0000882 }
883}
884
885TEST_P(VibratorAidl, ComposePwleSegmentDurationBoundary) {
886 if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
887 ActivePwle active = composeValidActivePwle(vibrator, capabilities);
888
chasewu22cb9012022-03-31 23:23:27 +0800889 int32_t segmentDurationMaxMs;
Vince Leung823cf5f2021-02-11 02:21:57 +0000890 vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
891 active.duration = segmentDurationMaxMs + 10; // Segment duration greater than allowed
892
Lais Andrade22754c52021-09-14 12:21:59 +0000893 auto pwleQueue = std::vector<PrimitivePwle>{active};
Vince Leung823cf5f2021-02-11 02:21:57 +0000894
895 EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT,
896 vibrator->composePwle(pwleQueue, nullptr).exceptionCode());
Lais Andrade22754c52021-09-14 12:21:59 +0000897 EXPECT_TRUE(vibrator->off().isOk());
Vince Leung823cf5f2021-02-11 02:21:57 +0000898 }
899}
900
Lais Andrade80b18612020-10-12 18:44:40 +0000901std::vector<std::tuple<int32_t, int32_t>> GenerateVibratorMapping() {
902 std::vector<std::tuple<int32_t, int32_t>> tuples;
903 auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor);
904 std::vector<int32_t> vibratorIds;
905
906 for (int i = 0; i < managerAidlNames.size(); i++) {
907 auto managerName = String16(managerAidlNames[i].c_str());
908 auto vibratorManager = android::waitForDeclaredService<IVibratorManager>(managerName);
909 if (vibratorManager->getVibratorIds(&vibratorIds).isOk()) {
Vince Leung823cf5f2021-02-11 02:21:57 +0000910 for (auto &vibratorId : vibratorIds) {
Lais Andrade80b18612020-10-12 18:44:40 +0000911 tuples.push_back(std::make_tuple(i, vibratorId));
912 }
913 }
914 }
915
916 auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor);
917 for (int i = 0; i < vibratorAidlNames.size(); i++) {
918 tuples.push_back(std::make_tuple(-1, i));
919 }
920
921 return tuples;
922}
923
Vince Leung823cf5f2021-02-11 02:21:57 +0000924std::string PrintGeneratedTest(const testing::TestParamInfo<VibratorAidl::ParamType> &info) {
925 const auto &[managerIdx, vibratorId] = info.param;
Lais Andrade80b18612020-10-12 18:44:40 +0000926 if (managerIdx < 0) {
927 return std::string("TOP_LEVEL_VIBRATOR_") + std::to_string(vibratorId);
928 }
929 return std::string("MANAGER_") + std::to_string(managerIdx) + "_VIBRATOR_ID_" +
930 std::to_string(vibratorId);
931}
932
Dan Shiba4d5322020-07-28 13:09:30 -0700933GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl);
Lais Andrade80b18612020-10-12 18:44:40 +0000934INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(GenerateVibratorMapping()),
935 PrintGeneratedTest);
Steven Morelandd44007e2019-10-24 18:12:46 -0700936
Vince Leung823cf5f2021-02-11 02:21:57 +0000937int main(int argc, char **argv) {
Steven Morelandd44007e2019-10-24 18:12:46 -0700938 ::testing::InitGoogleTest(&argc, argv);
939 ProcessState::self()->setThreadPoolMaxThreadCount(1);
940 ProcessState::self()->startThreadPool();
941 return RUN_ALL_TESTS();
942}