From 59a5d543b02165762c3ad54ef62d0a9a558966d7 Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Tue, 12 Mar 2024 11:53:00 +0000 Subject: [PATCH] Fix binder transaction errors on vibrator benchmark tests Setup binder process thread pool for vibrator HAL benchmark tests to fix binder transaction errors of the type: E Vibrator: Failed completion callback: -129 This change also adds checks for HAL results, which will cause them to fail earlier with a useful error message when the device reaches a bad state. This should avoid timeout failures for the whole test suite. Other fixes: - Fix vibrator.on(ms) tests to use a valid max duration value (previously failing with illegal argument); - Use a smaller fixed # of iterations on tests that iterate on vibrate calls, and add wait for vibration to be complete to measure the HAL in a more stable state; - Skip getSupportedAlwaysOnEffects on devices without capability; Fix: 329239120 Bug: 329899022 Bug: 329203383 Test: atest VibratorHalIntegrationBenchmark Change-Id: Id541a62745320a601934fd3f176f8ba42b5a7b2d --- vibrator/bench/benchmark.cpp | 498 +++++++++++++++++++++++++---------- 1 file changed, 363 insertions(+), 135 deletions(-) diff --git a/vibrator/bench/benchmark.cpp b/vibrator/bench/benchmark.cpp index b96e06da5b..dd618a5bc1 100644 --- a/vibrator/bench/benchmark.cpp +++ b/vibrator/bench/benchmark.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include using ::android::enum_range; using ::android::sp; @@ -31,9 +33,8 @@ using ::benchmark::Fixture; using ::benchmark::kMicrosecond; using ::benchmark::State; using ::benchmark::internal::Benchmark; -using ::std::chrono::duration; -using ::std::chrono::duration_cast; -using ::std::chrono::high_resolution_clock; + +using namespace ::std::chrono_literals; namespace Aidl = ::android::hardware::vibrator; namespace V1_0 = ::android::hardware::vibrator::V1_0; @@ -41,14 +42,28 @@ namespace V1_1 = ::android::hardware::vibrator::V1_1; namespace V1_2 = ::android::hardware::vibrator::V1_2; namespace V1_3 = ::android::hardware::vibrator::V1_3; +// Fixed number of iterations for benchmarks that trigger a vibration on the loop. +// They require slow cleanup to ensure a stable state on each run and less noisy metrics. +static constexpr auto VIBRATION_ITERATIONS = 500; + +// Timeout to wait for vibration callback completion. +static constexpr auto VIBRATION_CALLBACK_TIMEOUT = 100ms; + +// Max duration the vibrator can be turned on, in milliseconds. +static constexpr uint32_t MAX_ON_DURATION_MS = UINT16_MAX; + template class BaseBench : public Fixture { public: + void SetUp(State& /*state*/) override { + android::ProcessState::self()->setThreadPoolMaxThreadCount(1); + android::ProcessState::self()->startThreadPool(); + } + void TearDown(State& /*state*/) override { - if (!mVibrator) { - return; + if (mVibrator) { + mVibrator->off(); } - mVibrator->off(); } static void DefaultConfig(Benchmark* b) { b->Unit(kMicrosecond); } @@ -66,7 +81,19 @@ class BaseBench : public Fixture { template class VibratorBench : public BaseBench { public: - void SetUp(State& /*state*/) override { this->mVibrator = I::getService(); } + void SetUp(State& state) override { + BaseBench::SetUp(state); + this->mVibrator = I::getService(); + } + + protected: + bool shouldSkipWithError(State& state, const android::hardware::Return&& ret) { + if (!ret.isOk()) { + state.SkipWithError(ret.description()); + return true; + } + return false; + } }; enum class EmptyEnum : uint32_t; @@ -118,16 +145,25 @@ class VibratorEffectsBench : public VibratorBench { }); if (!supported) { - state->SkipWithMessage("performApi returned UNSUPPORTED_OPERATION"); + state->SkipWithMessage("effect unsupported"); return; } for (auto _ : *state) { - state->ResumeTiming(); - (*this->mVibrator.*performApi)(effect, strength, - [](Status /*status*/, uint32_t /*lengthMs*/) {}); + // Test + auto ret = (*this->mVibrator.*performApi)( + effect, strength, [](Status /*status*/, uint32_t /*lengthMs*/) {}); + + // Cleanup state->PauseTiming(); - this->mVibrator->off(); + if (!ret.isOk()) { + state->SkipWithError(ret.description()); + return; + } + if (this->shouldSkipWithError(*state, this->mVibrator->off())) { + return; + } + state->ResumeTiming(); } } @@ -157,24 +193,38 @@ class VibratorEffectsBench : public VibratorBench { using VibratorBench_V1_0 = VibratorBench; BENCHMARK_WRAPPER(VibratorBench_V1_0, on, { - uint32_t ms = UINT32_MAX; + auto ms = MAX_ON_DURATION_MS; for (auto _ : state) { - state.ResumeTiming(); - mVibrator->on(ms); + // Test + if (shouldSkipWithError(state, mVibrator->on(ms))) { + return; + } + + // Cleanup state.PauseTiming(); - mVibrator->off(); + if (shouldSkipWithError(state, mVibrator->off())) { + return; + } + state.ResumeTiming(); } }); BENCHMARK_WRAPPER(VibratorBench_V1_0, off, { - uint32_t ms = UINT32_MAX; + auto ms = MAX_ON_DURATION_MS; for (auto _ : state) { + // Setup state.PauseTiming(); - mVibrator->on(ms); + if (shouldSkipWithError(state, mVibrator->on(ms))) { + return; + } state.ResumeTiming(); - mVibrator->off(); + + // Test + if (shouldSkipWithError(state, mVibrator->off())) { + return; + } } }); @@ -185,20 +235,23 @@ BENCHMARK_WRAPPER(VibratorBench_V1_0, supportsAmplitudeControl, { }); BENCHMARK_WRAPPER(VibratorBench_V1_0, setAmplitude, { + auto ms = MAX_ON_DURATION_MS; uint8_t amplitude = UINT8_MAX; if (!mVibrator->supportsAmplitudeControl()) { - state.SkipWithMessage("Amplitude control unavailable"); + state.SkipWithMessage("amplitude control unavailable"); return; } - mVibrator->on(UINT32_MAX); - - for (auto _ : state) { - mVibrator->setAmplitude(amplitude); + if (shouldSkipWithError(state, mVibrator->on(ms))) { + return; } - mVibrator->off(); + for (auto _ : state) { + if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) { + return; + } + } }); using VibratorEffectsBench_V1_0 = VibratorEffectsBench; @@ -218,7 +271,15 @@ using VibratorEffectsBench_V1_2 = BENCHMARK_WRAPPER(VibratorEffectsBench_V1_2, perform_1_2, { performBench(&state, &V1_2::IVibrator::perform_1_2); }); -using VibratorBench_V1_3 = VibratorBench; +class VibratorBench_V1_3 : public VibratorBench { + public: + void TearDown(State& state) override { + VibratorBench::TearDown(state); + if (mVibrator) { + mVibrator->setExternalControl(false); + } + } +}; BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalControl, { for (auto _ : state) { @@ -227,18 +288,23 @@ BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalControl, { }); BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalControl, { - bool enable = true; - if (!mVibrator->supportsExternalControl()) { state.SkipWithMessage("external control unavailable"); return; } for (auto _ : state) { - state.ResumeTiming(); - mVibrator->setExternalControl(enable); + // Test + if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) { + return; + } + + // Cleanup state.PauseTiming(); - mVibrator->setExternalControl(false); + if (shouldSkipWithError(state, mVibrator->setExternalControl(false))) { + return; + } + state.ResumeTiming(); } }); @@ -248,13 +314,13 @@ BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalAmplitudeControl, { return; } - mVibrator->setExternalControl(true); + if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) { + return; + } for (auto _ : state) { mVibrator->supportsAmplitudeControl(); } - - mVibrator->setExternalControl(false); }); BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalAmplitude, { @@ -265,7 +331,9 @@ BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalAmplitude, { return; } - mVibrator->setExternalControl(true); + if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) { + return; + } if (!mVibrator->supportsAmplitudeControl()) { state.SkipWithMessage("amplitude control unavailable"); @@ -273,10 +341,10 @@ BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalAmplitude, { } for (auto _ : state) { - mVibrator->setAmplitude(amplitude); + if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) { + return; + } } - - mVibrator->setExternalControl(false); }); using VibratorEffectsBench_V1_3 = VibratorEffectsBench; @@ -286,9 +354,42 @@ BENCHMARK_WRAPPER(VibratorEffectsBench_V1_3, perform_1_3, class VibratorBench_Aidl : public BaseBench { public: - void SetUp(State& /*state*/) override { + void SetUp(State& state) override { + BaseBench::SetUp(state); this->mVibrator = android::waitForVintfService(); } + + void TearDown(State& state) override { + BaseBench::TearDown(state); + if (mVibrator) { + mVibrator->setExternalControl(false); + } + } + + protected: + int32_t hasCapabilities(int32_t capabilities) { + int32_t deviceCapabilities = 0; + this->mVibrator->getCapabilities(&deviceCapabilities); + return (deviceCapabilities & capabilities) == capabilities; + } + + bool shouldSkipWithError(State& state, const android::binder::Status&& status) { + if (!status.isOk()) { + state.SkipWithError(status.toString8().c_str()); + return true; + } + return false; + } + + static void SlowBenchConfig(Benchmark* b) { b->Iterations(VIBRATION_ITERATIONS); } +}; + +class SlowVibratorBench_Aidl : public VibratorBench_Aidl { + public: + static void DefaultConfig(Benchmark* b) { + VibratorBench_Aidl::DefaultConfig(b); + SlowBenchConfig(b); + } }; class HalCallback : public Aidl::BnVibratorCallback { @@ -296,30 +397,70 @@ class HalCallback : public Aidl::BnVibratorCallback { HalCallback() = default; ~HalCallback() = default; - android::binder::Status onComplete() override { return android::binder::Status::ok(); } + android::binder::Status onComplete() override { + mPromise.set_value(); + return android::binder::Status::ok(); + } + + void waitForComplete() { + // Wait until the HAL has finished processing previous vibration before starting a new one, + // so the HAL state is consistent on each run and metrics are less noisy. Some of the newest + // HAL implementations are waiting on previous vibration cleanup and might be significantly + // slower, so make sure we measure vibrations on a clean slate. + mPromise.get_future().wait_for(VIBRATION_CALLBACK_TIMEOUT); + } + + private: + std::promise mPromise; }; -BENCHMARK_WRAPPER(VibratorBench_Aidl, on, { - int32_t capabilities = 0; - mVibrator->getCapabilities(&capabilities); - - int32_t ms = INT32_MAX; - auto cb = (capabilities & Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr; +BENCHMARK_WRAPPER(SlowVibratorBench_Aidl, on, { + auto ms = MAX_ON_DURATION_MS; for (auto _ : state) { - state.ResumeTiming(); - mVibrator->on(ms, cb); + auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr; + + // Test + if (shouldSkipWithError(state, mVibrator->on(ms, cb))) { + return; + } + + // Cleanup state.PauseTiming(); - mVibrator->off(); + if (shouldSkipWithError(state, mVibrator->off())) { + return; + } + if (cb) { + cb->waitForComplete(); + } + state.ResumeTiming(); } }); -BENCHMARK_WRAPPER(VibratorBench_Aidl, off, { +BENCHMARK_WRAPPER(SlowVibratorBench_Aidl, off, { + auto ms = MAX_ON_DURATION_MS; + for (auto _ : state) { + auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr; + + // Setup state.PauseTiming(); - mVibrator->on(INT32_MAX, nullptr); + if (shouldSkipWithError(state, mVibrator->on(ms, cb))) { + return; + } + state.ResumeTiming(); + + // Test + if (shouldSkipWithError(state, mVibrator->off())) { + return; + } + + // Cleanup + state.PauseTiming(); + if (cb) { + cb->waitForComplete(); + } state.ResumeTiming(); - mVibrator->off(); } }); @@ -327,76 +468,102 @@ BENCHMARK_WRAPPER(VibratorBench_Aidl, getCapabilities, { int32_t capabilities = 0; for (auto _ : state) { - mVibrator->getCapabilities(&capabilities); + if (shouldSkipWithError(state, mVibrator->getCapabilities(&capabilities))) { + return; + } } }); BENCHMARK_WRAPPER(VibratorBench_Aidl, setAmplitude, { - int32_t capabilities = 0; - mVibrator->getCapabilities(&capabilities); - if ((capabilities & Aidl::IVibrator::CAP_AMPLITUDE_CONTROL) == 0) { + auto ms = MAX_ON_DURATION_MS; + float amplitude = 1.0f; + + if (!hasCapabilities(Aidl::IVibrator::CAP_AMPLITUDE_CONTROL)) { state.SkipWithMessage("amplitude control unavailable"); return; } - float amplitude = 1.0f; - mVibrator->on(INT32_MAX, nullptr); - - for (auto _ : state) { - mVibrator->setAmplitude(amplitude); + auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr; + if (shouldSkipWithError(state, mVibrator->on(ms, cb))) { + return; } - mVibrator->off(); + for (auto _ : state) { + if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) { + return; + } + } + + shouldSkipWithError(state, mVibrator->off()); + if (cb) { + cb->waitForComplete(); + } }); BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalControl, { - int32_t capabilities = 0; - mVibrator->getCapabilities(&capabilities); - if ((capabilities & Aidl::IVibrator::CAP_EXTERNAL_CONTROL) == 0) { + if (!hasCapabilities(Aidl::IVibrator::CAP_EXTERNAL_CONTROL)) { state.SkipWithMessage("external control unavailable"); return; } for (auto _ : state) { - state.ResumeTiming(); - mVibrator->setExternalControl(true); + // Test + if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) { + return; + } + + // Cleanup state.PauseTiming(); - mVibrator->setExternalControl(false); + if (shouldSkipWithError(state, mVibrator->setExternalControl(false))) { + return; + } + state.ResumeTiming(); } }); BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalAmplitude, { - int32_t capabilities = 0; - mVibrator->getCapabilities(&capabilities); - if ((capabilities & Aidl::IVibrator::CAP_EXTERNAL_CONTROL) == 0 || - (capabilities & Aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) == 0) { + auto externalControl = static_cast(Aidl::IVibrator::CAP_EXTERNAL_CONTROL); + auto externalAmplitudeControl = + static_cast(Aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL); + if (!hasCapabilities(externalControl | externalAmplitudeControl)) { state.SkipWithMessage("external amplitude control unavailable"); return; } - float amplitude = 1.0f; - mVibrator->setExternalControl(true); - - for (auto _ : state) { - mVibrator->setAmplitude(amplitude); + if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) { + return; } - mVibrator->setExternalControl(false); + float amplitude = 1.0f; + for (auto _ : state) { + if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) { + return; + } + } }); BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedEffects, { std::vector supportedEffects; for (auto _ : state) { - mVibrator->getSupportedEffects(&supportedEffects); + if (shouldSkipWithError(state, mVibrator->getSupportedEffects(&supportedEffects))) { + return; + } } }); BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedAlwaysOnEffects, { + if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) { + state.SkipWithMessage("always on control unavailable"); + return; + } + std::vector supportedEffects; for (auto _ : state) { - mVibrator->getSupportedAlwaysOnEffects(&supportedEffects); + if (shouldSkipWithError(state, mVibrator->getSupportedAlwaysOnEffects(&supportedEffects))) { + return; + } } }); @@ -404,7 +571,9 @@ BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedPrimitives, { std::vector supportedPrimitives; for (auto _ : state) { - mVibrator->getSupportedPrimitives(&supportedPrimitives); + if (shouldSkipWithError(state, mVibrator->getSupportedPrimitives(&supportedPrimitives))) { + return; + } } }); @@ -427,12 +596,30 @@ class VibratorEffectsBench_Aidl : public VibratorBench_Aidl { auto getStrength(const State& state) const { return static_cast(this->getOtherArg(state, 1)); } + + bool isEffectSupported(const Aidl::Effect& effect) { + std::vector supported; + mVibrator->getSupportedEffects(&supported); + return std::find(supported.begin(), supported.end(), effect) != supported.end(); + } + + bool isAlwaysOnEffectSupported(const Aidl::Effect& effect) { + std::vector supported; + mVibrator->getSupportedAlwaysOnEffects(&supported); + return std::find(supported.begin(), supported.end(), effect) != supported.end(); + } +}; + +class SlowVibratorEffectsBench_Aidl : public VibratorEffectsBench_Aidl { + public: + static void DefaultConfig(Benchmark* b) { + VibratorEffectsBench_Aidl::DefaultConfig(b); + SlowBenchConfig(b); + } }; BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnEnable, { - int32_t capabilities = 0; - mVibrator->getCapabilities(&capabilities); - if ((capabilities & Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL) == 0) { + if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) { state.SkipWithMessage("always on control unavailable"); return; } @@ -441,25 +628,28 @@ BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnEnable, { auto effect = getEffect(state); auto strength = getStrength(state); - std::vector supported; - mVibrator->getSupportedAlwaysOnEffects(&supported); - if (std::find(supported.begin(), supported.end(), effect) == supported.end()) { - state.SkipWithMessage("always on effects unavailable"); + if (!isAlwaysOnEffectSupported(effect)) { + state.SkipWithMessage("always on effect unsupported"); return; } for (auto _ : state) { - state.ResumeTiming(); - mVibrator->alwaysOnEnable(id, effect, strength); + // Test + if (shouldSkipWithError(state, mVibrator->alwaysOnEnable(id, effect, strength))) { + return; + } + + // Cleanup state.PauseTiming(); - mVibrator->alwaysOnDisable(id); + if (shouldSkipWithError(state, mVibrator->alwaysOnDisable(id))) { + return; + } + state.ResumeTiming(); } }); BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnDisable, { - int32_t capabilities = 0; - mVibrator->getCapabilities(&capabilities); - if ((capabilities & Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL) == 0) { + if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) { state.SkipWithMessage("always on control unavailable"); return; } @@ -468,42 +658,55 @@ BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnDisable, { auto effect = getEffect(state); auto strength = getStrength(state); - std::vector supported; - mVibrator->getSupportedAlwaysOnEffects(&supported); - if (std::find(supported.begin(), supported.end(), effect) == supported.end()) { - state.SkipWithMessage("always on effects unavailable"); + if (!isAlwaysOnEffectSupported(effect)) { + state.SkipWithMessage("always on effect unsupported"); return; } for (auto _ : state) { + // Setup state.PauseTiming(); - mVibrator->alwaysOnEnable(id, effect, strength); + if (shouldSkipWithError(state, mVibrator->alwaysOnEnable(id, effect, strength))) { + return; + } state.ResumeTiming(); - mVibrator->alwaysOnDisable(id); + + // Test + if (shouldSkipWithError(state, mVibrator->alwaysOnDisable(id))) { + return; + } } }); -BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, perform, { - int32_t capabilities = 0; - mVibrator->getCapabilities(&capabilities); - +BENCHMARK_WRAPPER(SlowVibratorEffectsBench_Aidl, perform, { auto effect = getEffect(state); auto strength = getStrength(state); - auto cb = (capabilities & Aidl::IVibrator::CAP_PERFORM_CALLBACK) ? new HalCallback() : nullptr; - int32_t lengthMs = 0; - std::vector supported; - mVibrator->getSupportedEffects(&supported); - if (std::find(supported.begin(), supported.end(), effect) == supported.end()) { - state.SkipWithMessage("effects unavailable"); + if (!isEffectSupported(effect)) { + state.SkipWithMessage("effect unsupported"); return; } + int32_t lengthMs = 0; + for (auto _ : state) { - state.ResumeTiming(); - mVibrator->perform(effect, strength, cb, &lengthMs); + auto cb = hasCapabilities(Aidl::IVibrator::CAP_PERFORM_CALLBACK) ? new HalCallback() + : nullptr; + + // Test + if (shouldSkipWithError(state, mVibrator->perform(effect, strength, cb, &lengthMs))) { + return; + } + + // Cleanup state.PauseTiming(); - mVibrator->off(); + if (shouldSkipWithError(state, mVibrator->off())) { + return; + } + if (cb) { + cb->waitForComplete(); + } + state.ResumeTiming(); } }); @@ -520,13 +723,29 @@ class VibratorPrimitivesBench_Aidl : public VibratorBench_Aidl { auto getPrimitive(const State& state) const { return static_cast(this->getOtherArg(state, 0)); } + + bool isPrimitiveSupported(const Aidl::CompositePrimitive& primitive) { + std::vector supported; + mVibrator->getSupportedPrimitives(&supported); + return std::find(supported.begin(), supported.end(), primitive) != supported.end(); + } +}; + +class SlowVibratorPrimitivesBench_Aidl : public VibratorPrimitivesBench_Aidl { + public: + static void DefaultConfig(Benchmark* b) { + VibratorPrimitivesBench_Aidl::DefaultConfig(b); + SlowBenchConfig(b); + } }; BENCHMARK_WRAPPER(VibratorBench_Aidl, getCompositionDelayMax, { int32_t ms = 0; for (auto _ : state) { - mVibrator->getCompositionDelayMax(&ms); + if (shouldSkipWithError(state, mVibrator->getCompositionDelayMax(&ms))) { + return; + } } }); @@ -534,14 +753,14 @@ BENCHMARK_WRAPPER(VibratorBench_Aidl, getCompositionSizeMax, { int32_t size = 0; for (auto _ : state) { - mVibrator->getCompositionSizeMax(&size); + if (shouldSkipWithError(state, mVibrator->getCompositionSizeMax(&size))) { + return; + } } }); BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, getPrimitiveDuration, { - int32_t capabilities = 0; - mVibrator->getCapabilities(&capabilities); - if ((capabilities & Aidl::IVibrator::CAP_COMPOSE_EFFECTS) == 0) { + if (!hasCapabilities(Aidl::IVibrator::CAP_COMPOSE_EFFECTS)) { state.SkipWithMessage("compose effects unavailable"); return; } @@ -549,22 +768,20 @@ BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, getPrimitiveDuration, { auto primitive = getPrimitive(state); int32_t ms = 0; - std::vector supported; - mVibrator->getSupportedPrimitives(&supported); - if (std::find(supported.begin(), supported.end(), primitive) == supported.end()) { - state.SkipWithMessage("supported primitives unavailable"); + if (!isPrimitiveSupported(primitive)) { + state.SkipWithMessage("primitive unsupported"); return; } for (auto _ : state) { - mVibrator->getPrimitiveDuration(primitive, &ms); + if (shouldSkipWithError(state, mVibrator->getPrimitiveDuration(primitive, &ms))) { + return; + } } }); -BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, compose, { - int32_t capabilities = 0; - mVibrator->getCapabilities(&capabilities); - if ((capabilities & Aidl::IVibrator::CAP_COMPOSE_EFFECTS) == 0) { +BENCHMARK_WRAPPER(SlowVibratorPrimitivesBench_Aidl, compose, { + if (!hasCapabilities(Aidl::IVibrator::CAP_COMPOSE_EFFECTS)) { state.SkipWithMessage("compose effects unavailable"); return; } @@ -574,22 +791,33 @@ BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, compose, { effect.scale = 1.0f; effect.delayMs = 0; - std::vector supported; - mVibrator->getSupportedPrimitives(&supported); - if (std::find(supported.begin(), supported.end(), effect.primitive) == supported.end()) { - state.SkipWithMessage("supported primitives unavailable"); + if (effect.primitive == Aidl::CompositePrimitive::NOOP) { + state.SkipWithMessage("skipping primitive NOOP"); + return; + } + if (!isPrimitiveSupported(effect.primitive)) { + state.SkipWithMessage("primitive unsupported"); return; } - auto cb = new HalCallback(); std::vector effects; effects.push_back(effect); for (auto _ : state) { - state.ResumeTiming(); - mVibrator->compose(effects, cb); + auto cb = new HalCallback(); + + // Test + if (shouldSkipWithError(state, mVibrator->compose(effects, cb))) { + return; + } + + // Cleanup state.PauseTiming(); - mVibrator->off(); + if (shouldSkipWithError(state, mVibrator->off())) { + return; + } + cb->waitForComplete(); + state.ResumeTiming(); } });