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 "Stats.h" 22 #include "Vibrator.h" 23 24 namespace aidl { 25 namespace android { 26 namespace hardware { 27 namespace vibrator { 28 29 class VibratorBench : public benchmark::Fixture { 30 private: 31 static constexpr const char *FILE_NAMES[]{ 32 "device/f0_stored", 33 "device/redc_stored", 34 "device/q_stored", 35 "activate", 36 "duration", 37 "state", 38 "device/cp_trigger_duration", 39 "device/cp_trigger_index", 40 "device/cp_trigger_queue", 41 "device/cp_dig_scale", 42 "device/dig_scale", 43 "device/asp_enable", 44 "device/gpio1_fall_index", 45 "device/gpio1_fall_dig_scale", 46 "device/gpio1_rise_index", 47 "device/gpio1_rise_dig_scale", 48 "device/vibe_state", 49 "device/num_waves", 50 }; 51 52 public: SetUp(::benchmark::State &)53 void SetUp(::benchmark::State & /*state*/) override { 54 auto prefix = std::filesystem::path(mFilesDir.path) / ""; 55 const std::map<const std::string, const std::string> content{ 56 {"duration", std::to_string((uint32_t)std::rand() ?: 1)}, 57 {"device/asp_enable", std::to_string(0)}, 58 {"device/cp_trigger_duration", std::to_string(0)}, 59 {"device/num_waves", std::to_string(10)}, 60 {"device/vibe_state", std::to_string(0)}, 61 }; 62 63 setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true); 64 65 for (auto n : FILE_NAMES) { 66 const auto it = content.find(n); 67 const auto name = std::filesystem::path(n); 68 const auto path = std::filesystem::path(mFilesDir.path) / name; 69 70 fs_mkdirs(path.c_str(), S_IRWXU); 71 72 if (it != content.end()) { 73 std::ofstream{path} << it->second << std::endl; 74 } else { 75 symlink("/dev/null", path.c_str()); 76 } 77 } 78 79 mVibrator = ndk::SharedRefBase::make<Vibrator>( 80 std::make_unique<HwApi>(), std::make_unique<HwCal>(), std::make_unique<StatsApi>()); 81 } 82 DefaultArgs(benchmark::internal::Benchmark * b)83 static void DefaultArgs(benchmark::internal::Benchmark *b) { b->Unit(benchmark::kMicrosecond); } 84 SupportedEffectArgs(benchmark::internal::Benchmark * b)85 static void SupportedEffectArgs(benchmark::internal::Benchmark *b) { 86 b->ArgNames({"Effect", "Strength"}); 87 for (Effect effect : ndk::enum_range<Effect>()) { 88 for (EffectStrength strength : ndk::enum_range<EffectStrength>()) { 89 b->Args({static_cast<long>(effect), static_cast<long>(strength)}); 90 } 91 } 92 } 93 94 protected: 95 TemporaryDir mFilesDir; 96 std::shared_ptr<IVibrator> mVibrator; 97 }; 98 99 #define BENCHMARK_WRAPPER(fixt, test, code) \ 100 BENCHMARK_DEFINE_F(fixt, test) \ 101 /* NOLINTNEXTLINE */ \ 102 (benchmark::State & state){code} BENCHMARK_REGISTER_F(fixt, test)->Apply(fixt::DefaultArgs) 103 104 BENCHMARK_WRAPPER(VibratorBench, on, { 105 uint32_t duration = std::rand() ?: 1; 106 107 for (auto _ : state) { 108 mVibrator->on(duration, nullptr); 109 } 110 }); 111 112 BENCHMARK_WRAPPER(VibratorBench, off, { 113 for (auto _ : state) { 114 mVibrator->off(); 115 } 116 }); 117 118 BENCHMARK_WRAPPER(VibratorBench, setAmplitude, { 119 uint8_t amplitude = std::rand() ?: 1; 120 121 for (auto _ : state) { 122 mVibrator->setAmplitude(amplitude); 123 } 124 }); 125 126 BENCHMARK_WRAPPER(VibratorBench, setExternalControl_enable, { 127 for (auto _ : state) { 128 mVibrator->setExternalControl(true); 129 } 130 }); 131 132 BENCHMARK_WRAPPER(VibratorBench, setExternalControl_disable, { 133 for (auto _ : state) { 134 mVibrator->setExternalControl(false); 135 } 136 }); 137 138 BENCHMARK_WRAPPER(VibratorBench, getCapabilities, { 139 int32_t capabilities; 140 141 for (auto _ : state) { 142 mVibrator->getCapabilities(&capabilities); 143 } 144 }); 145 146 BENCHMARK_WRAPPER(VibratorBench, perform, { 147 Effect effect = Effect(state.range(0)); 148 EffectStrength strength = EffectStrength(state.range(1)); 149 int32_t lengthMs; 150 151 ndk::ScopedAStatus status = mVibrator->perform(effect, strength, nullptr, &lengthMs); 152 153 if (!status.isOk()) { 154 return; 155 } 156 157 for (auto _ : state) { 158 mVibrator->perform(effect, strength, nullptr, &lengthMs); 159 } 160 })->Apply(VibratorBench::SupportedEffectArgs); 161 162 } // namespace vibrator 163 } // namespace hardware 164 } // namespace android 165 } // namespace aidl 166 167 BENCHMARK_MAIN(); 168