blob: deaa6f2c5579e8d95c19b58fc1c2d83940c3e0ef [file] [log] [blame]
Lais Andradee29acd82020-08-07 13:21:17 +00001/*
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
17#include "benchmark/benchmark.h"
18
19#include <android/hardware/vibrator/1.3/IVibrator.h>
20#include <android/hardware/vibrator/BnVibratorCallback.h>
21#include <android/hardware/vibrator/IVibrator.h>
22#include <binder/IServiceManager.h>
Lais Andrade59a5d542024-03-12 11:53:00 +000023#include <binder/ProcessState.h>
24#include <future>
Lais Andradee29acd82020-08-07 13:21:17 +000025
26using ::android::enum_range;
27using ::android::sp;
28using ::android::hardware::hidl_enum_range;
29using ::android::hardware::Return;
30using ::android::hardware::details::hidl_enum_values;
31using ::benchmark::Counter;
32using ::benchmark::Fixture;
33using ::benchmark::kMicrosecond;
34using ::benchmark::State;
35using ::benchmark::internal::Benchmark;
Lais Andrade59a5d542024-03-12 11:53:00 +000036
37using namespace ::std::chrono_literals;
Lais Andradee29acd82020-08-07 13:21:17 +000038
39namespace Aidl = ::android::hardware::vibrator;
40namespace V1_0 = ::android::hardware::vibrator::V1_0;
41namespace V1_1 = ::android::hardware::vibrator::V1_1;
42namespace V1_2 = ::android::hardware::vibrator::V1_2;
43namespace V1_3 = ::android::hardware::vibrator::V1_3;
44
Lais Andrade59a5d542024-03-12 11:53:00 +000045// Fixed number of iterations for benchmarks that trigger a vibration on the loop.
46// They require slow cleanup to ensure a stable state on each run and less noisy metrics.
47static constexpr auto VIBRATION_ITERATIONS = 500;
48
49// Timeout to wait for vibration callback completion.
50static constexpr auto VIBRATION_CALLBACK_TIMEOUT = 100ms;
51
52// Max duration the vibrator can be turned on, in milliseconds.
53static constexpr uint32_t MAX_ON_DURATION_MS = UINT16_MAX;
54
Lais Andradee29acd82020-08-07 13:21:17 +000055template <typename I>
56class BaseBench : public Fixture {
57 public:
Lais Andrade59a5d542024-03-12 11:53:00 +000058 void SetUp(State& /*state*/) override {
59 android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
60 android::ProcessState::self()->startThreadPool();
61 }
62
Lais Andradee29acd82020-08-07 13:21:17 +000063 void TearDown(State& /*state*/) override {
Lais Andrade59a5d542024-03-12 11:53:00 +000064 if (mVibrator) {
65 mVibrator->off();
Lais Andradee29acd82020-08-07 13:21:17 +000066 }
Lais Andradee29acd82020-08-07 13:21:17 +000067 }
68
69 static void DefaultConfig(Benchmark* b) { b->Unit(kMicrosecond); }
70
71 static void DefaultArgs(Benchmark* /*b*/) { /* none */
72 }
73
74 protected:
75 auto getOtherArg(const State& state, std::size_t index) const { return state.range(index + 0); }
76
77 protected:
78 sp<I> mVibrator;
79};
80
81template <typename I>
82class VibratorBench : public BaseBench<I> {
83 public:
Lais Andrade59a5d542024-03-12 11:53:00 +000084 void SetUp(State& state) override {
85 BaseBench<I>::SetUp(state);
86 this->mVibrator = I::getService();
87 }
88
89 protected:
90 bool shouldSkipWithError(State& state, const android::hardware::Return<V1_0::Status>&& ret) {
91 if (!ret.isOk()) {
92 state.SkipWithError(ret.description());
93 return true;
94 }
95 return false;
96 }
Lais Andradee29acd82020-08-07 13:21:17 +000097};
98
99enum class EmptyEnum : uint32_t;
100template <>
101inline constexpr std::array<EmptyEnum, 0> hidl_enum_values<EmptyEnum> = {};
102
103template <typename T, typename U>
104std::set<T> difference(const hidl_enum_range<T>& t, const hidl_enum_range<U>& u) {
105 class Compare {
106 public:
107 bool operator()(const T& a, const U& b) { return a < static_cast<T>(b); }
108 bool operator()(const U& a, const T& b) { return static_cast<T>(a) < b; }
109 };
110 std::set<T> ret;
111
112 std::set_difference(t.begin(), t.end(), u.begin(), u.end(),
113 std::insert_iterator<decltype(ret)>(ret, ret.begin()), Compare());
114
115 return ret;
116}
117
118template <typename I, typename E1, typename E2 = EmptyEnum>
119class VibratorEffectsBench : public VibratorBench<I> {
120 public:
121 using Effect = E1;
122 using EffectStrength = V1_0::EffectStrength;
123 using Status = V1_0::Status;
124
125 public:
126 static void DefaultArgs(Benchmark* b) {
127 b->ArgNames({"Effect", "Strength"});
128 for (const auto& effect : difference(hidl_enum_range<E1>(), hidl_enum_range<E2>())) {
129 for (const auto& strength : hidl_enum_range<EffectStrength>()) {
130 b->Args({static_cast<long>(effect), static_cast<long>(strength)});
131 }
132 }
133 }
134
135 void performBench(State* state, Return<void> (I::*performApi)(Effect, EffectStrength,
136 typename I::perform_cb)) {
137 auto effect = getEffect(*state);
138 auto strength = getStrength(*state);
139 bool supported = true;
140
141 (*this->mVibrator.*performApi)(effect, strength, [&](Status status, uint32_t /*lengthMs*/) {
142 if (status == Status::UNSUPPORTED_OPERATION) {
143 supported = false;
144 }
145 });
146
147 if (!supported) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000148 state->SkipWithMessage("effect unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000149 return;
150 }
151
152 for (auto _ : *state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000153 // Test
154 auto ret = (*this->mVibrator.*performApi)(
155 effect, strength, [](Status /*status*/, uint32_t /*lengthMs*/) {});
156
157 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000158 state->PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000159 if (!ret.isOk()) {
160 state->SkipWithError(ret.description());
161 return;
162 }
163 if (this->shouldSkipWithError(*state, this->mVibrator->off())) {
164 return;
165 }
166 state->ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000167 }
168 }
169
170 protected:
171 auto getEffect(const State& state) const {
172 return static_cast<Effect>(this->getOtherArg(state, 0));
173 }
174
175 auto getStrength(const State& state) const {
176 return static_cast<EffectStrength>(this->getOtherArg(state, 1));
177 }
178};
179
Adrian Roos77659422024-02-09 17:20:54 +0000180#define BENCHMARK_WRAPPER(fixt, test, code) \
181 BENCHMARK_DEFINE_F(fixt, test) \
182 /* NOLINTNEXTLINE */ \
183 (State & state) { \
184 if (!mVibrator) { \
185 state.SkipWithMessage("HAL unavailable"); \
186 return; \
187 } \
188 \
189 code \
190 } \
Lais Andradee29acd82020-08-07 13:21:17 +0000191 BENCHMARK_REGISTER_F(fixt, test)->Apply(fixt::DefaultConfig)->Apply(fixt::DefaultArgs)
192
193using VibratorBench_V1_0 = VibratorBench<V1_0::IVibrator>;
194
195BENCHMARK_WRAPPER(VibratorBench_V1_0, on, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000196 auto ms = MAX_ON_DURATION_MS;
Lais Andradee29acd82020-08-07 13:21:17 +0000197
198 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000199 // Test
200 if (shouldSkipWithError(state, mVibrator->on(ms))) {
201 return;
202 }
203
204 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000205 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000206 if (shouldSkipWithError(state, mVibrator->off())) {
207 return;
208 }
209 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000210 }
211});
212
213BENCHMARK_WRAPPER(VibratorBench_V1_0, off, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000214 auto ms = MAX_ON_DURATION_MS;
Lais Andradee29acd82020-08-07 13:21:17 +0000215
216 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000217 // Setup
Lais Andradee29acd82020-08-07 13:21:17 +0000218 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000219 if (shouldSkipWithError(state, mVibrator->on(ms))) {
220 return;
221 }
Lais Andradee29acd82020-08-07 13:21:17 +0000222 state.ResumeTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000223
224 // Test
225 if (shouldSkipWithError(state, mVibrator->off())) {
226 return;
227 }
Lais Andradee29acd82020-08-07 13:21:17 +0000228 }
229});
230
231BENCHMARK_WRAPPER(VibratorBench_V1_0, supportsAmplitudeControl, {
232 for (auto _ : state) {
233 mVibrator->supportsAmplitudeControl();
234 }
235});
236
237BENCHMARK_WRAPPER(VibratorBench_V1_0, setAmplitude, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000238 auto ms = MAX_ON_DURATION_MS;
Lais Andradee29acd82020-08-07 13:21:17 +0000239 uint8_t amplitude = UINT8_MAX;
240
241 if (!mVibrator->supportsAmplitudeControl()) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000242 state.SkipWithMessage("amplitude control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000243 return;
244 }
245
Lais Andrade59a5d542024-03-12 11:53:00 +0000246 if (shouldSkipWithError(state, mVibrator->on(ms))) {
247 return;
Lais Andradee29acd82020-08-07 13:21:17 +0000248 }
249
Lais Andrade59a5d542024-03-12 11:53:00 +0000250 for (auto _ : state) {
251 if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) {
252 return;
253 }
254 }
Lais Andradee29acd82020-08-07 13:21:17 +0000255});
256
257using VibratorEffectsBench_V1_0 = VibratorEffectsBench<V1_0::IVibrator, V1_0::Effect>;
258
259BENCHMARK_WRAPPER(VibratorEffectsBench_V1_0, perform,
260 { performBench(&state, &V1_0::IVibrator::perform); });
261
262using VibratorEffectsBench_V1_1 =
263 VibratorEffectsBench<V1_1::IVibrator, V1_1::Effect_1_1, V1_0::Effect>;
264
265BENCHMARK_WRAPPER(VibratorEffectsBench_V1_1, perform_1_1,
266 { performBench(&state, &V1_1::IVibrator::perform_1_1); });
267
268using VibratorEffectsBench_V1_2 =
269 VibratorEffectsBench<V1_2::IVibrator, V1_2::Effect, V1_1::Effect_1_1>;
270
271BENCHMARK_WRAPPER(VibratorEffectsBench_V1_2, perform_1_2,
272 { performBench(&state, &V1_2::IVibrator::perform_1_2); });
273
Lais Andrade59a5d542024-03-12 11:53:00 +0000274class VibratorBench_V1_3 : public VibratorBench<V1_3::IVibrator> {
275 public:
276 void TearDown(State& state) override {
277 VibratorBench::TearDown(state);
278 if (mVibrator) {
279 mVibrator->setExternalControl(false);
280 }
281 }
282};
Lais Andradee29acd82020-08-07 13:21:17 +0000283
284BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalControl, {
285 for (auto _ : state) {
286 mVibrator->supportsExternalControl();
287 }
288});
289
290BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalControl, {
Lais Andradee29acd82020-08-07 13:21:17 +0000291 if (!mVibrator->supportsExternalControl()) {
Adrian Roos77659422024-02-09 17:20:54 +0000292 state.SkipWithMessage("external control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000293 return;
294 }
295
296 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000297 // Test
298 if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
299 return;
300 }
301
302 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000303 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000304 if (shouldSkipWithError(state, mVibrator->setExternalControl(false))) {
305 return;
306 }
307 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000308 }
309});
310
311BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalAmplitudeControl, {
312 if (!mVibrator->supportsExternalControl()) {
Adrian Roos77659422024-02-09 17:20:54 +0000313 state.SkipWithMessage("external control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000314 return;
315 }
316
Lais Andrade59a5d542024-03-12 11:53:00 +0000317 if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
318 return;
319 }
Lais Andradee29acd82020-08-07 13:21:17 +0000320
321 for (auto _ : state) {
322 mVibrator->supportsAmplitudeControl();
323 }
Lais Andradee29acd82020-08-07 13:21:17 +0000324});
325
326BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalAmplitude, {
327 uint8_t amplitude = UINT8_MAX;
328
329 if (!mVibrator->supportsExternalControl()) {
Adrian Roos77659422024-02-09 17:20:54 +0000330 state.SkipWithMessage("external control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000331 return;
332 }
333
Lais Andrade59a5d542024-03-12 11:53:00 +0000334 if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
335 return;
336 }
Lais Andradee29acd82020-08-07 13:21:17 +0000337
338 if (!mVibrator->supportsAmplitudeControl()) {
Adrian Roos77659422024-02-09 17:20:54 +0000339 state.SkipWithMessage("amplitude control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000340 return;
341 }
342
343 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000344 if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) {
345 return;
346 }
Lais Andradee29acd82020-08-07 13:21:17 +0000347 }
Lais Andradee29acd82020-08-07 13:21:17 +0000348});
349
350using VibratorEffectsBench_V1_3 = VibratorEffectsBench<V1_3::IVibrator, V1_3::Effect, V1_2::Effect>;
351
352BENCHMARK_WRAPPER(VibratorEffectsBench_V1_3, perform_1_3,
353 { performBench(&state, &V1_3::IVibrator::perform_1_3); });
354
355class VibratorBench_Aidl : public BaseBench<Aidl::IVibrator> {
356 public:
Lais Andrade59a5d542024-03-12 11:53:00 +0000357 void SetUp(State& state) override {
358 BaseBench::SetUp(state);
Lais Andradee29acd82020-08-07 13:21:17 +0000359 this->mVibrator = android::waitForVintfService<Aidl::IVibrator>();
360 }
Lais Andrade59a5d542024-03-12 11:53:00 +0000361
362 void TearDown(State& state) override {
363 BaseBench::TearDown(state);
364 if (mVibrator) {
365 mVibrator->setExternalControl(false);
366 }
367 }
368
369 protected:
370 int32_t hasCapabilities(int32_t capabilities) {
371 int32_t deviceCapabilities = 0;
372 this->mVibrator->getCapabilities(&deviceCapabilities);
373 return (deviceCapabilities & capabilities) == capabilities;
374 }
375
376 bool shouldSkipWithError(State& state, const android::binder::Status&& status) {
377 if (!status.isOk()) {
378 state.SkipWithError(status.toString8().c_str());
379 return true;
380 }
381 return false;
382 }
383
384 static void SlowBenchConfig(Benchmark* b) { b->Iterations(VIBRATION_ITERATIONS); }
385};
386
387class SlowVibratorBench_Aidl : public VibratorBench_Aidl {
388 public:
389 static void DefaultConfig(Benchmark* b) {
390 VibratorBench_Aidl::DefaultConfig(b);
391 SlowBenchConfig(b);
392 }
Lais Andradee29acd82020-08-07 13:21:17 +0000393};
394
395class HalCallback : public Aidl::BnVibratorCallback {
396 public:
397 HalCallback() = default;
398 ~HalCallback() = default;
399
Lais Andrade59a5d542024-03-12 11:53:00 +0000400 android::binder::Status onComplete() override {
401 mPromise.set_value();
402 return android::binder::Status::ok();
403 }
404
405 void waitForComplete() {
406 // Wait until the HAL has finished processing previous vibration before starting a new one,
407 // so the HAL state is consistent on each run and metrics are less noisy. Some of the newest
408 // HAL implementations are waiting on previous vibration cleanup and might be significantly
409 // slower, so make sure we measure vibrations on a clean slate.
410 mPromise.get_future().wait_for(VIBRATION_CALLBACK_TIMEOUT);
411 }
412
413 private:
414 std::promise<void> mPromise;
Lais Andradee29acd82020-08-07 13:21:17 +0000415};
416
Lais Andrade59a5d542024-03-12 11:53:00 +0000417BENCHMARK_WRAPPER(SlowVibratorBench_Aidl, on, {
418 auto ms = MAX_ON_DURATION_MS;
Lais Andradee29acd82020-08-07 13:21:17 +0000419
420 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000421 auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
422
423 // Test
424 if (shouldSkipWithError(state, mVibrator->on(ms, cb))) {
425 return;
426 }
427
428 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000429 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000430 if (shouldSkipWithError(state, mVibrator->off())) {
431 return;
432 }
433 if (cb) {
434 cb->waitForComplete();
435 }
436 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000437 }
438});
439
Lais Andrade59a5d542024-03-12 11:53:00 +0000440BENCHMARK_WRAPPER(SlowVibratorBench_Aidl, off, {
441 auto ms = MAX_ON_DURATION_MS;
442
Lais Andradee29acd82020-08-07 13:21:17 +0000443 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000444 auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
445
446 // Setup
Lais Andradee29acd82020-08-07 13:21:17 +0000447 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000448 if (shouldSkipWithError(state, mVibrator->on(ms, cb))) {
449 return;
450 }
Lais Andradee29acd82020-08-07 13:21:17 +0000451 state.ResumeTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000452
453 // Test
454 if (shouldSkipWithError(state, mVibrator->off())) {
455 return;
456 }
457
458 // Cleanup
459 state.PauseTiming();
460 if (cb) {
461 cb->waitForComplete();
462 }
463 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000464 }
465});
466
467BENCHMARK_WRAPPER(VibratorBench_Aidl, getCapabilities, {
468 int32_t capabilities = 0;
469
470 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000471 if (shouldSkipWithError(state, mVibrator->getCapabilities(&capabilities))) {
472 return;
473 }
Lais Andradee29acd82020-08-07 13:21:17 +0000474 }
475});
476
477BENCHMARK_WRAPPER(VibratorBench_Aidl, setAmplitude, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000478 auto ms = MAX_ON_DURATION_MS;
479 float amplitude = 1.0f;
480
481 if (!hasCapabilities(Aidl::IVibrator::CAP_AMPLITUDE_CONTROL)) {
Adrian Roos77659422024-02-09 17:20:54 +0000482 state.SkipWithMessage("amplitude control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000483 return;
484 }
485
Lais Andrade59a5d542024-03-12 11:53:00 +0000486 auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
487 if (shouldSkipWithError(state, mVibrator->on(ms, cb))) {
488 return;
Lais Andradee29acd82020-08-07 13:21:17 +0000489 }
490
Lais Andrade59a5d542024-03-12 11:53:00 +0000491 for (auto _ : state) {
492 if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) {
493 return;
494 }
495 }
Lais Andradee29acd82020-08-07 13:21:17 +0000496});
497
498BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalControl, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000499 if (!hasCapabilities(Aidl::IVibrator::CAP_EXTERNAL_CONTROL)) {
Adrian Roos77659422024-02-09 17:20:54 +0000500 state.SkipWithMessage("external control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000501 return;
502 }
503
504 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000505 // Test
506 if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
507 return;
508 }
509
510 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000511 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000512 if (shouldSkipWithError(state, mVibrator->setExternalControl(false))) {
513 return;
514 }
515 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000516 }
517});
518
519BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalAmplitude, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000520 auto externalControl = static_cast<int32_t>(Aidl::IVibrator::CAP_EXTERNAL_CONTROL);
521 auto externalAmplitudeControl =
522 static_cast<int32_t>(Aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL);
523 if (!hasCapabilities(externalControl | externalAmplitudeControl)) {
Adrian Roos77659422024-02-09 17:20:54 +0000524 state.SkipWithMessage("external amplitude control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000525 return;
526 }
527
Lais Andrade59a5d542024-03-12 11:53:00 +0000528 if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
529 return;
Lais Andradee29acd82020-08-07 13:21:17 +0000530 }
531
Lais Andrade59a5d542024-03-12 11:53:00 +0000532 float amplitude = 1.0f;
533 for (auto _ : state) {
534 if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) {
535 return;
536 }
537 }
Lais Andradee29acd82020-08-07 13:21:17 +0000538});
539
540BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedEffects, {
541 std::vector<Aidl::Effect> supportedEffects;
542
543 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000544 if (shouldSkipWithError(state, mVibrator->getSupportedEffects(&supportedEffects))) {
545 return;
546 }
Lais Andradee29acd82020-08-07 13:21:17 +0000547 }
548});
549
550BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedAlwaysOnEffects, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000551 if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) {
552 state.SkipWithMessage("always on control unavailable");
553 return;
554 }
555
Lais Andradee29acd82020-08-07 13:21:17 +0000556 std::vector<Aidl::Effect> supportedEffects;
557
558 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000559 if (shouldSkipWithError(state, mVibrator->getSupportedAlwaysOnEffects(&supportedEffects))) {
560 return;
561 }
Lais Andradee29acd82020-08-07 13:21:17 +0000562 }
563});
564
565BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedPrimitives, {
566 std::vector<Aidl::CompositePrimitive> supportedPrimitives;
567
568 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000569 if (shouldSkipWithError(state, mVibrator->getSupportedPrimitives(&supportedPrimitives))) {
570 return;
571 }
Lais Andradee29acd82020-08-07 13:21:17 +0000572 }
573});
574
575class VibratorEffectsBench_Aidl : public VibratorBench_Aidl {
576 public:
577 static void DefaultArgs(Benchmark* b) {
578 b->ArgNames({"Effect", "Strength"});
579 for (const auto& effect : enum_range<Aidl::Effect>()) {
580 for (const auto& strength : enum_range<Aidl::EffectStrength>()) {
581 b->Args({static_cast<long>(effect), static_cast<long>(strength)});
582 }
583 }
584 }
585
586 protected:
587 auto getEffect(const State& state) const {
588 return static_cast<Aidl::Effect>(this->getOtherArg(state, 0));
589 }
590
591 auto getStrength(const State& state) const {
592 return static_cast<Aidl::EffectStrength>(this->getOtherArg(state, 1));
593 }
Lais Andrade59a5d542024-03-12 11:53:00 +0000594
595 bool isEffectSupported(const Aidl::Effect& effect) {
596 std::vector<Aidl::Effect> supported;
597 mVibrator->getSupportedEffects(&supported);
598 return std::find(supported.begin(), supported.end(), effect) != supported.end();
599 }
600
601 bool isAlwaysOnEffectSupported(const Aidl::Effect& effect) {
602 std::vector<Aidl::Effect> supported;
603 mVibrator->getSupportedAlwaysOnEffects(&supported);
604 return std::find(supported.begin(), supported.end(), effect) != supported.end();
605 }
606};
607
608class SlowVibratorEffectsBench_Aidl : public VibratorEffectsBench_Aidl {
609 public:
610 static void DefaultConfig(Benchmark* b) {
611 VibratorEffectsBench_Aidl::DefaultConfig(b);
612 SlowBenchConfig(b);
613 }
Lais Andradee29acd82020-08-07 13:21:17 +0000614};
615
616BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnEnable, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000617 if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) {
Adrian Roos77659422024-02-09 17:20:54 +0000618 state.SkipWithMessage("always on control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000619 return;
620 }
621
622 int32_t id = 1;
623 auto effect = getEffect(state);
624 auto strength = getStrength(state);
625
Lais Andrade59a5d542024-03-12 11:53:00 +0000626 if (!isAlwaysOnEffectSupported(effect)) {
627 state.SkipWithMessage("always on effect unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000628 return;
629 }
630
631 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000632 // Test
633 if (shouldSkipWithError(state, mVibrator->alwaysOnEnable(id, effect, strength))) {
634 return;
635 }
636
637 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000638 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000639 if (shouldSkipWithError(state, mVibrator->alwaysOnDisable(id))) {
640 return;
641 }
642 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000643 }
644});
645
646BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnDisable, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000647 if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) {
Adrian Roos77659422024-02-09 17:20:54 +0000648 state.SkipWithMessage("always on control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000649 return;
650 }
651
652 int32_t id = 1;
653 auto effect = getEffect(state);
654 auto strength = getStrength(state);
655
Lais Andrade59a5d542024-03-12 11:53:00 +0000656 if (!isAlwaysOnEffectSupported(effect)) {
657 state.SkipWithMessage("always on effect unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000658 return;
659 }
660
661 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000662 // Setup
Lais Andradee29acd82020-08-07 13:21:17 +0000663 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000664 if (shouldSkipWithError(state, mVibrator->alwaysOnEnable(id, effect, strength))) {
665 return;
666 }
Lais Andradee29acd82020-08-07 13:21:17 +0000667 state.ResumeTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000668
669 // Test
670 if (shouldSkipWithError(state, mVibrator->alwaysOnDisable(id))) {
671 return;
672 }
Lais Andradee29acd82020-08-07 13:21:17 +0000673 }
674});
675
Lais Andrade59a5d542024-03-12 11:53:00 +0000676BENCHMARK_WRAPPER(SlowVibratorEffectsBench_Aidl, perform, {
Lais Andradee29acd82020-08-07 13:21:17 +0000677 auto effect = getEffect(state);
678 auto strength = getStrength(state);
Lais Andradee29acd82020-08-07 13:21:17 +0000679
Lais Andrade59a5d542024-03-12 11:53:00 +0000680 if (!isEffectSupported(effect)) {
681 state.SkipWithMessage("effect unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000682 return;
683 }
684
Lais Andrade59a5d542024-03-12 11:53:00 +0000685 int32_t lengthMs = 0;
686
Lais Andradee29acd82020-08-07 13:21:17 +0000687 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000688 auto cb = hasCapabilities(Aidl::IVibrator::CAP_PERFORM_CALLBACK) ? new HalCallback()
689 : nullptr;
690
691 // Test
692 if (shouldSkipWithError(state, mVibrator->perform(effect, strength, cb, &lengthMs))) {
693 return;
694 }
695
696 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000697 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000698 if (shouldSkipWithError(state, mVibrator->off())) {
699 return;
700 }
701 if (cb) {
702 cb->waitForComplete();
703 }
704 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000705 }
706});
707
708class VibratorPrimitivesBench_Aidl : public VibratorBench_Aidl {
709 public:
710 static void DefaultArgs(Benchmark* b) {
711 b->ArgNames({"Primitive"});
712 for (const auto& primitive : enum_range<Aidl::CompositePrimitive>()) {
713 b->Args({static_cast<long>(primitive)});
714 }
715 }
716
717 protected:
718 auto getPrimitive(const State& state) const {
719 return static_cast<Aidl::CompositePrimitive>(this->getOtherArg(state, 0));
720 }
Lais Andrade59a5d542024-03-12 11:53:00 +0000721
722 bool isPrimitiveSupported(const Aidl::CompositePrimitive& primitive) {
723 std::vector<Aidl::CompositePrimitive> supported;
724 mVibrator->getSupportedPrimitives(&supported);
725 return std::find(supported.begin(), supported.end(), primitive) != supported.end();
726 }
727};
728
729class SlowVibratorPrimitivesBench_Aidl : public VibratorPrimitivesBench_Aidl {
730 public:
731 static void DefaultConfig(Benchmark* b) {
732 VibratorPrimitivesBench_Aidl::DefaultConfig(b);
733 SlowBenchConfig(b);
734 }
Lais Andradee29acd82020-08-07 13:21:17 +0000735};
736
737BENCHMARK_WRAPPER(VibratorBench_Aidl, getCompositionDelayMax, {
738 int32_t ms = 0;
739
740 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000741 if (shouldSkipWithError(state, mVibrator->getCompositionDelayMax(&ms))) {
742 return;
743 }
Lais Andradee29acd82020-08-07 13:21:17 +0000744 }
745});
746
747BENCHMARK_WRAPPER(VibratorBench_Aidl, getCompositionSizeMax, {
748 int32_t size = 0;
749
750 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000751 if (shouldSkipWithError(state, mVibrator->getCompositionSizeMax(&size))) {
752 return;
753 }
Lais Andradee29acd82020-08-07 13:21:17 +0000754 }
755});
756
757BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, getPrimitiveDuration, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000758 if (!hasCapabilities(Aidl::IVibrator::CAP_COMPOSE_EFFECTS)) {
Adrian Roos77659422024-02-09 17:20:54 +0000759 state.SkipWithMessage("compose effects unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000760 return;
761 }
762
763 auto primitive = getPrimitive(state);
764 int32_t ms = 0;
765
Lais Andrade59a5d542024-03-12 11:53:00 +0000766 if (!isPrimitiveSupported(primitive)) {
767 state.SkipWithMessage("primitive unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000768 return;
769 }
770
771 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000772 if (shouldSkipWithError(state, mVibrator->getPrimitiveDuration(primitive, &ms))) {
773 return;
774 }
Lais Andradee29acd82020-08-07 13:21:17 +0000775 }
776});
777
Lais Andrade59a5d542024-03-12 11:53:00 +0000778BENCHMARK_WRAPPER(SlowVibratorPrimitivesBench_Aidl, compose, {
779 if (!hasCapabilities(Aidl::IVibrator::CAP_COMPOSE_EFFECTS)) {
Adrian Roos77659422024-02-09 17:20:54 +0000780 state.SkipWithMessage("compose effects unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000781 return;
782 }
783
784 Aidl::CompositeEffect effect;
785 effect.primitive = getPrimitive(state);
786 effect.scale = 1.0f;
787 effect.delayMs = 0;
788
Lais Andrade59a5d542024-03-12 11:53:00 +0000789 if (effect.primitive == Aidl::CompositePrimitive::NOOP) {
790 state.SkipWithMessage("skipping primitive NOOP");
791 return;
792 }
793 if (!isPrimitiveSupported(effect.primitive)) {
794 state.SkipWithMessage("primitive unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000795 return;
796 }
797
Lais Andradee29acd82020-08-07 13:21:17 +0000798 std::vector<Aidl::CompositeEffect> effects;
799 effects.push_back(effect);
800
801 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000802 auto cb = new HalCallback();
803
804 // Test
805 if (shouldSkipWithError(state, mVibrator->compose(effects, cb))) {
806 return;
807 }
808
809 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000810 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000811 if (shouldSkipWithError(state, mVibrator->off())) {
812 return;
813 }
814 cb->waitForComplete();
815 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000816 }
817});
818
819BENCHMARK_MAIN();