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 <android-base/properties.h> 19 #include <cutils/fs.h> 20 21 #include "Hardware.h" 22 #include "Vibrator.h" 23 24 using ::android::sp; 25 using ::android::hardware::hidl_enum_range; 26 27 namespace android { 28 namespace hardware { 29 namespace vibrator { 30 namespace V1_3 { 31 namespace implementation { 32 33 using ::android::base::SetProperty; 34 using ::android::hardware::vibrator::V1_0::EffectStrength; 35 using ::android::hardware::vibrator::V1_0::Status; 36 37 class VibratorBench : public benchmark::Fixture { 38 private: 39 static constexpr const char *FILE_NAMES[]{ 40 "device/autocal", 41 "device/ol_lra_period", 42 "activate", 43 "duration", 44 "state", 45 "device/rtp_input", 46 "device/mode", 47 "device/set_sequencer", 48 "device/scale", 49 "device/ctrl_loop", 50 "device/lp_trigger_effect", 51 "device/lra_wave_shape", 52 "device/od_clamp", 53 }; 54 static constexpr char PROPERTY_PREFIX[] = "test.vibrator.hal."; 55 56 public: SetUp(::benchmark::State & state)57 void SetUp(::benchmark::State &state) override { 58 auto prefix = std::filesystem::path(mFilesDir.path) / ""; 59 60 setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true); 61 62 for (auto n : FILE_NAMES) { 63 const auto name = std::filesystem::path(n); 64 const auto path = std::filesystem::path(mFilesDir.path) / name; 65 66 fs_mkdirs(path.c_str(), S_IRWXU); 67 symlink("/dev/null", path.c_str()); 68 } 69 70 setenv("PROPERTY_PREFIX", PROPERTY_PREFIX, true); 71 72 SetProperty(std::string() + PROPERTY_PREFIX + "config.dynamic", getDynamicConfig(state)); 73 74 mVibrator = new Vibrator(HwApi::Create(), std::make_unique<HwCal>()); 75 } 76 DefaultConfig(benchmark::internal::Benchmark * b)77 static void DefaultConfig(benchmark::internal::Benchmark *b) { 78 b->Unit(benchmark::kMicrosecond); 79 } 80 DefaultArgs(benchmark::internal::Benchmark * b)81 static void DefaultArgs(benchmark::internal::Benchmark *b) { 82 b->ArgNames({"DynamicConfig"}); 83 b->Args({false}); 84 b->Args({true}); 85 } 86 87 protected: getDynamicConfig(const::benchmark::State & state) const88 std::string getDynamicConfig(const ::benchmark::State &state) const { 89 return std::to_string(state.range(0)); 90 } 91 getOtherArg(const::benchmark::State & state,std::size_t index) const92 auto getOtherArg(const ::benchmark::State &state, std::size_t index) const { 93 return state.range(index + 1); 94 } 95 96 protected: 97 TemporaryDir mFilesDir; 98 sp<IVibrator> mVibrator; 99 }; 100 101 #define BENCHMARK_WRAPPER(fixt, test, code) \ 102 BENCHMARK_DEFINE_F(fixt, test) \ 103 /* NOLINTNEXTLINE */ \ 104 (benchmark::State & state){code} BENCHMARK_REGISTER_F(fixt, test) \ 105 ->Apply(fixt::DefaultConfig) \ 106 ->Apply(fixt::DefaultArgs) 107 108 BENCHMARK_WRAPPER(VibratorBench, on, { 109 uint32_t duration = std::rand() ?: 1; 110 111 for (auto _ : state) { 112 mVibrator->on(duration); 113 } 114 }); 115 116 BENCHMARK_WRAPPER(VibratorBench, off, { 117 for (auto _ : state) { 118 mVibrator->off(); 119 } 120 }); 121 122 BENCHMARK_WRAPPER(VibratorBench, supportsAmplitudeControl, { 123 for (auto _ : state) { 124 mVibrator->supportsAmplitudeControl(); 125 } 126 }); 127 128 BENCHMARK_WRAPPER(VibratorBench, setAmplitude, { 129 uint8_t amplitude = std::rand() ?: 1; 130 131 for (auto _ : state) { 132 mVibrator->setAmplitude(amplitude); 133 } 134 }); 135 136 BENCHMARK_WRAPPER(VibratorBench, supportsExternalControl, { 137 for (auto _ : state) { 138 mVibrator->supportsExternalControl(); 139 } 140 }); 141 142 BENCHMARK_WRAPPER(VibratorBench, setExternalControl_enable, { 143 for (auto _ : state) { 144 mVibrator->setExternalControl(true); 145 } 146 }); 147 148 BENCHMARK_WRAPPER(VibratorBench, setExternalControl_disable, { 149 for (auto _ : state) { 150 mVibrator->setExternalControl(false); 151 } 152 }); 153 154 class VibratorEffectsBench : public VibratorBench { 155 public: DefaultArgs(benchmark::internal::Benchmark * b)156 static void DefaultArgs(benchmark::internal::Benchmark *b) { 157 b->ArgNames({"DynamicConfig", "Effect", "Strength"}); 158 for (const auto &dynamic : {false, true}) { 159 for (const auto &effect : hidl_enum_range<Effect>()) { 160 for (const auto &strength : hidl_enum_range<EffectStrength>()) { 161 b->Args({dynamic, static_cast<long>(effect), static_cast<long>(strength)}); 162 } 163 } 164 } 165 } 166 167 protected: getEffect(const::benchmark::State & state) const168 auto getEffect(const ::benchmark::State &state) const { 169 return static_cast<Effect>(getOtherArg(state, 0)); 170 } 171 getStrength(const::benchmark::State & state) const172 auto getStrength(const ::benchmark::State &state) const { 173 return static_cast<EffectStrength>(getOtherArg(state, 1)); 174 } 175 }; 176 177 BENCHMARK_WRAPPER(VibratorEffectsBench, perform_1_3, { 178 Effect effect = getEffect(state); 179 EffectStrength strength = getStrength(state); 180 bool supported = true; 181 __anon140e07ac0102(Status status, uint32_t ) 182 mVibrator->perform_1_3(effect, strength, [&](Status status, uint32_t /*lengthMs*/) { 183 if (status == Status::UNSUPPORTED_OPERATION) { 184 supported = false; 185 } 186 }); 187 188 if (!supported) { 189 return; 190 } 191 192 for (auto _ : state) { __anon140e07ac0202(Status , uint32_t ) 193 mVibrator->perform_1_3(effect, strength, [](Status /*status*/, uint32_t /*lengthMs*/) {}); 194 } 195 }); 196 197 } // namespace implementation 198 } // namespace V1_3 199 } // namespace vibrator 200 } // namespace hardware 201 } // namespace android 202 203 BENCHMARK_MAIN(); 204