• 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 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