blob: dd618a5bc1e2af62077caa7e6e700676e859d083 [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 }
496
497 shouldSkipWithError(state, mVibrator->off());
498 if (cb) {
499 cb->waitForComplete();
500 }
Lais Andradee29acd82020-08-07 13:21:17 +0000501});
502
503BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalControl, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000504 if (!hasCapabilities(Aidl::IVibrator::CAP_EXTERNAL_CONTROL)) {
Adrian Roos77659422024-02-09 17:20:54 +0000505 state.SkipWithMessage("external control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000506 return;
507 }
508
509 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000510 // Test
511 if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
512 return;
513 }
514
515 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000516 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000517 if (shouldSkipWithError(state, mVibrator->setExternalControl(false))) {
518 return;
519 }
520 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000521 }
522});
523
524BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalAmplitude, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000525 auto externalControl = static_cast<int32_t>(Aidl::IVibrator::CAP_EXTERNAL_CONTROL);
526 auto externalAmplitudeControl =
527 static_cast<int32_t>(Aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL);
528 if (!hasCapabilities(externalControl | externalAmplitudeControl)) {
Adrian Roos77659422024-02-09 17:20:54 +0000529 state.SkipWithMessage("external amplitude control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000530 return;
531 }
532
Lais Andrade59a5d542024-03-12 11:53:00 +0000533 if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
534 return;
Lais Andradee29acd82020-08-07 13:21:17 +0000535 }
536
Lais Andrade59a5d542024-03-12 11:53:00 +0000537 float amplitude = 1.0f;
538 for (auto _ : state) {
539 if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) {
540 return;
541 }
542 }
Lais Andradee29acd82020-08-07 13:21:17 +0000543});
544
545BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedEffects, {
546 std::vector<Aidl::Effect> supportedEffects;
547
548 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000549 if (shouldSkipWithError(state, mVibrator->getSupportedEffects(&supportedEffects))) {
550 return;
551 }
Lais Andradee29acd82020-08-07 13:21:17 +0000552 }
553});
554
555BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedAlwaysOnEffects, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000556 if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) {
557 state.SkipWithMessage("always on control unavailable");
558 return;
559 }
560
Lais Andradee29acd82020-08-07 13:21:17 +0000561 std::vector<Aidl::Effect> supportedEffects;
562
563 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000564 if (shouldSkipWithError(state, mVibrator->getSupportedAlwaysOnEffects(&supportedEffects))) {
565 return;
566 }
Lais Andradee29acd82020-08-07 13:21:17 +0000567 }
568});
569
570BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedPrimitives, {
571 std::vector<Aidl::CompositePrimitive> supportedPrimitives;
572
573 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000574 if (shouldSkipWithError(state, mVibrator->getSupportedPrimitives(&supportedPrimitives))) {
575 return;
576 }
Lais Andradee29acd82020-08-07 13:21:17 +0000577 }
578});
579
580class VibratorEffectsBench_Aidl : public VibratorBench_Aidl {
581 public:
582 static void DefaultArgs(Benchmark* b) {
583 b->ArgNames({"Effect", "Strength"});
584 for (const auto& effect : enum_range<Aidl::Effect>()) {
585 for (const auto& strength : enum_range<Aidl::EffectStrength>()) {
586 b->Args({static_cast<long>(effect), static_cast<long>(strength)});
587 }
588 }
589 }
590
591 protected:
592 auto getEffect(const State& state) const {
593 return static_cast<Aidl::Effect>(this->getOtherArg(state, 0));
594 }
595
596 auto getStrength(const State& state) const {
597 return static_cast<Aidl::EffectStrength>(this->getOtherArg(state, 1));
598 }
Lais Andrade59a5d542024-03-12 11:53:00 +0000599
600 bool isEffectSupported(const Aidl::Effect& effect) {
601 std::vector<Aidl::Effect> supported;
602 mVibrator->getSupportedEffects(&supported);
603 return std::find(supported.begin(), supported.end(), effect) != supported.end();
604 }
605
606 bool isAlwaysOnEffectSupported(const Aidl::Effect& effect) {
607 std::vector<Aidl::Effect> supported;
608 mVibrator->getSupportedAlwaysOnEffects(&supported);
609 return std::find(supported.begin(), supported.end(), effect) != supported.end();
610 }
611};
612
613class SlowVibratorEffectsBench_Aidl : public VibratorEffectsBench_Aidl {
614 public:
615 static void DefaultConfig(Benchmark* b) {
616 VibratorEffectsBench_Aidl::DefaultConfig(b);
617 SlowBenchConfig(b);
618 }
Lais Andradee29acd82020-08-07 13:21:17 +0000619};
620
621BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnEnable, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000622 if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) {
Adrian Roos77659422024-02-09 17:20:54 +0000623 state.SkipWithMessage("always on control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000624 return;
625 }
626
627 int32_t id = 1;
628 auto effect = getEffect(state);
629 auto strength = getStrength(state);
630
Lais Andrade59a5d542024-03-12 11:53:00 +0000631 if (!isAlwaysOnEffectSupported(effect)) {
632 state.SkipWithMessage("always on effect unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000633 return;
634 }
635
636 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000637 // Test
638 if (shouldSkipWithError(state, mVibrator->alwaysOnEnable(id, effect, strength))) {
639 return;
640 }
641
642 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000643 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000644 if (shouldSkipWithError(state, mVibrator->alwaysOnDisable(id))) {
645 return;
646 }
647 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000648 }
649});
650
651BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnDisable, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000652 if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) {
Adrian Roos77659422024-02-09 17:20:54 +0000653 state.SkipWithMessage("always on control unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000654 return;
655 }
656
657 int32_t id = 1;
658 auto effect = getEffect(state);
659 auto strength = getStrength(state);
660
Lais Andrade59a5d542024-03-12 11:53:00 +0000661 if (!isAlwaysOnEffectSupported(effect)) {
662 state.SkipWithMessage("always on effect unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000663 return;
664 }
665
666 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000667 // Setup
Lais Andradee29acd82020-08-07 13:21:17 +0000668 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000669 if (shouldSkipWithError(state, mVibrator->alwaysOnEnable(id, effect, strength))) {
670 return;
671 }
Lais Andradee29acd82020-08-07 13:21:17 +0000672 state.ResumeTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000673
674 // Test
675 if (shouldSkipWithError(state, mVibrator->alwaysOnDisable(id))) {
676 return;
677 }
Lais Andradee29acd82020-08-07 13:21:17 +0000678 }
679});
680
Lais Andrade59a5d542024-03-12 11:53:00 +0000681BENCHMARK_WRAPPER(SlowVibratorEffectsBench_Aidl, perform, {
Lais Andradee29acd82020-08-07 13:21:17 +0000682 auto effect = getEffect(state);
683 auto strength = getStrength(state);
Lais Andradee29acd82020-08-07 13:21:17 +0000684
Lais Andrade59a5d542024-03-12 11:53:00 +0000685 if (!isEffectSupported(effect)) {
686 state.SkipWithMessage("effect unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000687 return;
688 }
689
Lais Andrade59a5d542024-03-12 11:53:00 +0000690 int32_t lengthMs = 0;
691
Lais Andradee29acd82020-08-07 13:21:17 +0000692 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000693 auto cb = hasCapabilities(Aidl::IVibrator::CAP_PERFORM_CALLBACK) ? new HalCallback()
694 : nullptr;
695
696 // Test
697 if (shouldSkipWithError(state, mVibrator->perform(effect, strength, cb, &lengthMs))) {
698 return;
699 }
700
701 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000702 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000703 if (shouldSkipWithError(state, mVibrator->off())) {
704 return;
705 }
706 if (cb) {
707 cb->waitForComplete();
708 }
709 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000710 }
711});
712
713class VibratorPrimitivesBench_Aidl : public VibratorBench_Aidl {
714 public:
715 static void DefaultArgs(Benchmark* b) {
716 b->ArgNames({"Primitive"});
717 for (const auto& primitive : enum_range<Aidl::CompositePrimitive>()) {
718 b->Args({static_cast<long>(primitive)});
719 }
720 }
721
722 protected:
723 auto getPrimitive(const State& state) const {
724 return static_cast<Aidl::CompositePrimitive>(this->getOtherArg(state, 0));
725 }
Lais Andrade59a5d542024-03-12 11:53:00 +0000726
727 bool isPrimitiveSupported(const Aidl::CompositePrimitive& primitive) {
728 std::vector<Aidl::CompositePrimitive> supported;
729 mVibrator->getSupportedPrimitives(&supported);
730 return std::find(supported.begin(), supported.end(), primitive) != supported.end();
731 }
732};
733
734class SlowVibratorPrimitivesBench_Aidl : public VibratorPrimitivesBench_Aidl {
735 public:
736 static void DefaultConfig(Benchmark* b) {
737 VibratorPrimitivesBench_Aidl::DefaultConfig(b);
738 SlowBenchConfig(b);
739 }
Lais Andradee29acd82020-08-07 13:21:17 +0000740};
741
742BENCHMARK_WRAPPER(VibratorBench_Aidl, getCompositionDelayMax, {
743 int32_t ms = 0;
744
745 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000746 if (shouldSkipWithError(state, mVibrator->getCompositionDelayMax(&ms))) {
747 return;
748 }
Lais Andradee29acd82020-08-07 13:21:17 +0000749 }
750});
751
752BENCHMARK_WRAPPER(VibratorBench_Aidl, getCompositionSizeMax, {
753 int32_t size = 0;
754
755 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000756 if (shouldSkipWithError(state, mVibrator->getCompositionSizeMax(&size))) {
757 return;
758 }
Lais Andradee29acd82020-08-07 13:21:17 +0000759 }
760});
761
762BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, getPrimitiveDuration, {
Lais Andrade59a5d542024-03-12 11:53:00 +0000763 if (!hasCapabilities(Aidl::IVibrator::CAP_COMPOSE_EFFECTS)) {
Adrian Roos77659422024-02-09 17:20:54 +0000764 state.SkipWithMessage("compose effects unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000765 return;
766 }
767
768 auto primitive = getPrimitive(state);
769 int32_t ms = 0;
770
Lais Andrade59a5d542024-03-12 11:53:00 +0000771 if (!isPrimitiveSupported(primitive)) {
772 state.SkipWithMessage("primitive unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000773 return;
774 }
775
776 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000777 if (shouldSkipWithError(state, mVibrator->getPrimitiveDuration(primitive, &ms))) {
778 return;
779 }
Lais Andradee29acd82020-08-07 13:21:17 +0000780 }
781});
782
Lais Andrade59a5d542024-03-12 11:53:00 +0000783BENCHMARK_WRAPPER(SlowVibratorPrimitivesBench_Aidl, compose, {
784 if (!hasCapabilities(Aidl::IVibrator::CAP_COMPOSE_EFFECTS)) {
Adrian Roos77659422024-02-09 17:20:54 +0000785 state.SkipWithMessage("compose effects unavailable");
Lais Andradee29acd82020-08-07 13:21:17 +0000786 return;
787 }
788
789 Aidl::CompositeEffect effect;
790 effect.primitive = getPrimitive(state);
791 effect.scale = 1.0f;
792 effect.delayMs = 0;
793
Lais Andrade59a5d542024-03-12 11:53:00 +0000794 if (effect.primitive == Aidl::CompositePrimitive::NOOP) {
795 state.SkipWithMessage("skipping primitive NOOP");
796 return;
797 }
798 if (!isPrimitiveSupported(effect.primitive)) {
799 state.SkipWithMessage("primitive unsupported");
Lais Andradee29acd82020-08-07 13:21:17 +0000800 return;
801 }
802
Lais Andradee29acd82020-08-07 13:21:17 +0000803 std::vector<Aidl::CompositeEffect> effects;
804 effects.push_back(effect);
805
806 for (auto _ : state) {
Lais Andrade59a5d542024-03-12 11:53:00 +0000807 auto cb = new HalCallback();
808
809 // Test
810 if (shouldSkipWithError(state, mVibrator->compose(effects, cb))) {
811 return;
812 }
813
814 // Cleanup
Lais Andradee29acd82020-08-07 13:21:17 +0000815 state.PauseTiming();
Lais Andrade59a5d542024-03-12 11:53:00 +0000816 if (shouldSkipWithError(state, mVibrator->off())) {
817 return;
818 }
819 cb->waitForComplete();
820 state.ResumeTiming();
Lais Andradee29acd82020-08-07 13:21:17 +0000821 }
822});
823
824BENCHMARK_MAIN();