1 /* * Copyright (C) 2019 The Android Open Source Project * 2 * Licensed under the Apache License, Version 2.0 (the "License"); 3 * you may not use this file except in compliance with the License. 4 * You may obtain a copy of the License at 5 * 6 * http://www.apache.org/licenses/LICENSE-2.0 7 * 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 #include "benchmark/benchmark.h" 16 17 #include <android-base/file.h> 18 #include <cutils/fs.h> 19 20 #include "Hardware.h" 21 #include "Vibrator.h" 22 23 namespace aidl { 24 namespace android { 25 namespace hardware { 26 namespace vibrator { 27 28 class VibratorBench : public benchmark::Fixture { 29 private: 30 static constexpr const char *FILE_NAMES[]{ 31 "device/f0_stored", 32 "device/redc_stored", 33 "device/q_stored", 34 "activate", 35 "duration", 36 "state", 37 "device/cp_trigger_duration", 38 "device/cp_trigger_index", 39 "device/cp_trigger_queue", 40 "device/cp_dig_scale", 41 "device/dig_scale", 42 "device/asp_enable", 43 "device/gpio1_fall_index", 44 "device/gpio1_fall_dig_scale", 45 "device/gpio1_rise_index", 46 "device/gpio1_rise_dig_scale", 47 "device/vibe_state", 48 "device/num_waves", 49 }; 50 51 public: SetUp(::benchmark::State &)52 void SetUp(::benchmark::State & /*state*/) override { 53 auto prefix = std::filesystem::path(mFilesDir.path) / ""; 54 const std::map<const std::string, const std::string> content{ 55 {"duration", std::to_string((uint32_t)std::rand() ?: 1)}, 56 {"device/asp_enable", std::to_string(0)}, 57 {"device/cp_trigger_duration", std::to_string(0)}, 58 {"device/num_waves", std::to_string(10)}, 59 {"device/vibe_state", std::to_string(0)}, 60 }; 61 62 setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true); 63 64 for (auto n : FILE_NAMES) { 65 const auto it = content.find(n); 66 const auto name = std::filesystem::path(n); 67 const auto path = std::filesystem::path(mFilesDir.path) / name; 68 69 fs_mkdirs(path.c_str(), S_IRWXU); 70 71 if (it != content.end()) { 72 std::ofstream{path} << it->second << std::endl; 73 } else { 74 symlink("/dev/null", path.c_str()); 75 } 76 } 77 78 mVibrator = ndk::SharedRefBase::make<Vibrator>(std::make_unique<HwApi>(), 79 std::make_unique<HwCal>()); 80 } 81 DefaultArgs(benchmark::internal::Benchmark * b)82 static void DefaultArgs(benchmark::internal::Benchmark *b) { b->Unit(benchmark::kMicrosecond); } 83 SupportedEffectArgs(benchmark::internal::Benchmark * b)84 static void SupportedEffectArgs(benchmark::internal::Benchmark *b) { 85 b->ArgNames({"Effect", "Strength"}); 86 for (Effect effect : ndk::enum_range<Effect>()) { 87 for (EffectStrength strength : ndk::enum_range<EffectStrength>()) { 88 b->Args({static_cast<long>(effect), static_cast<long>(strength)}); 89 } 90 } 91 } 92 93 protected: 94 TemporaryDir mFilesDir; 95 std::shared_ptr<IVibrator> mVibrator; 96 }; 97 98 #define BENCHMARK_WRAPPER(fixt, test, code) \ 99 BENCHMARK_DEFINE_F(fixt, test) \ 100 /* NOLINTNEXTLINE */ \ 101 (benchmark::State & state){code} BENCHMARK_REGISTER_F(fixt, test)->Apply(fixt::DefaultArgs) 102 103 BENCHMARK_WRAPPER(VibratorBench, on, { 104 uint32_t duration = std::rand() ?: 1; 105 106 for (auto _ : state) { 107 mVibrator->on(duration, nullptr); 108 } 109 }); 110 111 BENCHMARK_WRAPPER(VibratorBench, off, { 112 for (auto _ : state) { 113 mVibrator->off(); 114 } 115 }); 116 117 BENCHMARK_WRAPPER(VibratorBench, setAmplitude, { 118 uint8_t amplitude = std::rand() ?: 1; 119 120 for (auto _ : state) { 121 mVibrator->setAmplitude(amplitude); 122 } 123 }); 124 125 BENCHMARK_WRAPPER(VibratorBench, setExternalControl_enable, { 126 for (auto _ : state) { 127 mVibrator->setExternalControl(true); 128 } 129 }); 130 131 BENCHMARK_WRAPPER(VibratorBench, setExternalControl_disable, { 132 for (auto _ : state) { 133 mVibrator->setExternalControl(false); 134 } 135 }); 136 137 BENCHMARK_WRAPPER(VibratorBench, getCapabilities, { 138 int32_t capabilities; 139 140 for (auto _ : state) { 141 mVibrator->getCapabilities(&capabilities); 142 } 143 }); 144 145 BENCHMARK_WRAPPER(VibratorBench, perform, { 146 Effect effect = Effect(state.range(0)); 147 EffectStrength strength = EffectStrength(state.range(1)); 148 int32_t lengthMs; 149 150 ndk::ScopedAStatus status = mVibrator->perform(effect, strength, nullptr, &lengthMs); 151 152 if (!status.isOk()) { 153 return; 154 } 155 156 for (auto _ : state) { 157 mVibrator->perform(effect, strength, nullptr, &lengthMs); 158 } 159 })->Apply(VibratorBench::SupportedEffectArgs); 160 161 } // namespace vibrator 162 } // namespace hardware 163 } // namespace android 164 } // namespace aidl 165 166 BENCHMARK_MAIN(); 167