• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 namespace aidl {
25 namespace android {
26 namespace hardware {
27 namespace vibrator {
28 
29 using ::android::base::SetProperty;
30 
31 class VibratorBench : public benchmark::Fixture {
32   private:
33     static constexpr const char *FILE_NAMES[]{
34         "device/autocal",
35         "device/ol_lra_period",
36         "activate",
37         "duration",
38         "state",
39         "device/rtp_input",
40         "device/mode",
41         "device/set_sequencer",
42         "device/scale",
43         "device/ctrl_loop",
44         "device/lp_trigger_effect",
45         "device/lra_wave_shape",
46         "device/od_clamp",
47     };
48     static constexpr char PROPERTY_PREFIX[] = "test.vibrator.hal.";
49 
50   public:
SetUp(::benchmark::State & state)51     void SetUp(::benchmark::State &state) override {
52         auto prefix = std::filesystem::path(mFilesDir.path) / "";
53 
54         setenv("HWAPI_PATH_PREFIX", prefix.c_str(), true);
55 
56         for (auto n : FILE_NAMES) {
57             const auto name = std::filesystem::path(n);
58             const auto path = std::filesystem::path(mFilesDir.path) / name;
59 
60             fs_mkdirs(path.c_str(), S_IRWXU);
61             symlink("/dev/null", path.c_str());
62         }
63 
64         setenv("PROPERTY_PREFIX", PROPERTY_PREFIX, true);
65 
66         SetProperty(std::string() + PROPERTY_PREFIX + "config.dynamic", getDynamicConfig(state));
67 
68         mVibrator = ndk::SharedRefBase::make<Vibrator>(HwApi::Create(), std::make_unique<HwCal>());
69     }
70 
DefaultConfig(benchmark::internal::Benchmark * b)71     static void DefaultConfig(benchmark::internal::Benchmark *b) {
72         b->Unit(benchmark::kMicrosecond);
73     }
74 
DefaultArgs(benchmark::internal::Benchmark * b)75     static void DefaultArgs(benchmark::internal::Benchmark *b) {
76         b->ArgNames({"DynamicConfig"});
77         b->Args({false});
78         b->Args({true});
79     }
80 
81   protected:
getDynamicConfig(const::benchmark::State & state) const82     std::string getDynamicConfig(const ::benchmark::State &state) const {
83         return std::to_string(state.range(0));
84     }
85 
getOtherArg(const::benchmark::State & state,std::size_t index) const86     auto getOtherArg(const ::benchmark::State &state, std::size_t index) const {
87         return state.range(index + 1);
88     }
89 
90   protected:
91     TemporaryDir mFilesDir;
92     std::shared_ptr<IVibrator> mVibrator;
93 };
94 
95 #define BENCHMARK_WRAPPER(fixt, test, code)                           \
96     BENCHMARK_DEFINE_F(fixt, test)                                    \
97     /* NOLINTNEXTLINE */                                              \
98     (benchmark::State & state){code} BENCHMARK_REGISTER_F(fixt, test) \
99         ->Apply(fixt::DefaultConfig)                                  \
100         ->Apply(fixt::DefaultArgs)
101 
102 BENCHMARK_WRAPPER(VibratorBench, on, {
103     uint32_t duration = std::rand() ?: 1;
104 
105     for (auto _ : state) {
106         mVibrator->on(duration, nullptr);
107     }
108 });
109 
110 BENCHMARK_WRAPPER(VibratorBench, off, {
111     for (auto _ : state) {
112         mVibrator->off();
113     }
114 });
115 
116 BENCHMARK_WRAPPER(VibratorBench, setAmplitude, {
117     uint8_t amplitude = std::rand() ?: 1;
118 
119     for (auto _ : state) {
120         mVibrator->setAmplitude(amplitude);
121     }
122 });
123 
124 BENCHMARK_WRAPPER(VibratorBench, setExternalControl_enable, {
125     for (auto _ : state) {
126         mVibrator->setExternalControl(true);
127     }
128 });
129 
130 BENCHMARK_WRAPPER(VibratorBench, setExternalControl_disable, {
131     for (auto _ : state) {
132         mVibrator->setExternalControl(false);
133     }
134 });
135 
136 BENCHMARK_WRAPPER(VibratorBench, getCapabilities, {
137     int32_t capabilities;
138 
139     for (auto _ : state) {
140         mVibrator->getCapabilities(&capabilities);
141     }
142 });
143 
144 class VibratorEffectsBench : public VibratorBench {
145   public:
DefaultArgs(benchmark::internal::Benchmark * b)146     static void DefaultArgs(benchmark::internal::Benchmark *b) {
147         b->ArgNames({"DynamicConfig", "Effect", "Strength"});
148         for (const auto &dynamic : {false, true}) {
149             for (const auto &effect : ndk::enum_range<Effect>()) {
150                 for (const auto &strength : ndk::enum_range<EffectStrength>()) {
151                     b->Args({dynamic, static_cast<long>(effect), static_cast<long>(strength)});
152                 }
153             }
154         }
155     }
156 
157   protected:
getEffect(const::benchmark::State & state) const158     auto getEffect(const ::benchmark::State &state) const {
159         return static_cast<Effect>(getOtherArg(state, 0));
160     }
161 
getStrength(const::benchmark::State & state) const162     auto getStrength(const ::benchmark::State &state) const {
163         return static_cast<EffectStrength>(getOtherArg(state, 1));
164     }
165 };
166 
167 BENCHMARK_WRAPPER(VibratorEffectsBench, perform, {
168     Effect effect = getEffect(state);
169     EffectStrength strength = getStrength(state);
170     int32_t lengthMs;
171 
172     ndk::ScopedAStatus status = mVibrator->perform(effect, strength, nullptr, &lengthMs);
173 
174     if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
175         return;
176     }
177 
178     for (auto _ : state) {
179         mVibrator->perform(effect, strength, nullptr, &lengthMs);
180     }
181 });
182 
183 }  // namespace vibrator
184 }  // namespace hardware
185 }  // namespace android
186 }  // namespace aidl
187 
188 BENCHMARK_MAIN();
189