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
This commit is contained in:
parent
9375782730
commit
59a5d543b0
1 changed files with 363 additions and 135 deletions
|
@ -20,6 +20,8 @@
|
|||
#include <android/hardware/vibrator/BnVibratorCallback.h>
|
||||
#include <android/hardware/vibrator/IVibrator.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <future>
|
||||
|
||||
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 <typename I>
|
||||
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 <typename I>
|
||||
class VibratorBench : public BaseBench<I> {
|
||||
public:
|
||||
void SetUp(State& /*state*/) override { this->mVibrator = I::getService(); }
|
||||
void SetUp(State& state) override {
|
||||
BaseBench<I>::SetUp(state);
|
||||
this->mVibrator = I::getService();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool shouldSkipWithError(State& state, const android::hardware::Return<V1_0::Status>&& 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<I> {
|
|||
});
|
||||
|
||||
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<I> {
|
|||
using VibratorBench_V1_0 = VibratorBench<V1_0::IVibrator>;
|
||||
|
||||
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<V1_0::IVibrator, V1_0::Effect>;
|
||||
|
@ -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<V1_3::IVibrator>;
|
||||
class VibratorBench_V1_3 : public VibratorBench<V1_3::IVibrator> {
|
||||
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<V1_3::IVibrator, V1_3::Effect, V1_2::Effect>;
|
||||
|
@ -286,9 +354,42 @@ BENCHMARK_WRAPPER(VibratorEffectsBench_V1_3, perform_1_3,
|
|||
|
||||
class VibratorBench_Aidl : public BaseBench<Aidl::IVibrator> {
|
||||
public:
|
||||
void SetUp(State& /*state*/) override {
|
||||
void SetUp(State& state) override {
|
||||
BaseBench::SetUp(state);
|
||||
this->mVibrator = android::waitForVintfService<Aidl::IVibrator>();
|
||||
}
|
||||
|
||||
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<void> 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<int32_t>(Aidl::IVibrator::CAP_EXTERNAL_CONTROL);
|
||||
auto externalAmplitudeControl =
|
||||
static_cast<int32_t>(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<Aidl::Effect> 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<Aidl::Effect> 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<Aidl::CompositePrimitive> 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<Aidl::EffectStrength>(this->getOtherArg(state, 1));
|
||||
}
|
||||
|
||||
bool isEffectSupported(const Aidl::Effect& effect) {
|
||||
std::vector<Aidl::Effect> supported;
|
||||
mVibrator->getSupportedEffects(&supported);
|
||||
return std::find(supported.begin(), supported.end(), effect) != supported.end();
|
||||
}
|
||||
|
||||
bool isAlwaysOnEffectSupported(const Aidl::Effect& effect) {
|
||||
std::vector<Aidl::Effect> 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<Aidl::Effect> 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<Aidl::Effect> 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<Aidl::Effect> 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<Aidl::CompositePrimitive>(this->getOtherArg(state, 0));
|
||||
}
|
||||
|
||||
bool isPrimitiveSupported(const Aidl::CompositePrimitive& primitive) {
|
||||
std::vector<Aidl::CompositePrimitive> 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<Aidl::CompositePrimitive> 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<Aidl::CompositePrimitive> 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<Aidl::CompositeEffect> 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();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue