xref: /aosp_15_r20/frameworks/native/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <benchmark/benchmark.h>
18 
19 #include <android/os/IInputConstants.h>
20 #include <binder/Binder.h>
21 #include "../dispatcher/InputDispatcher.h"
22 #include "../tests/FakeApplicationHandle.h"
23 #include "../tests/FakeInputDispatcherPolicy.h"
24 #include "../tests/FakeWindows.h"
25 
26 using android::base::Result;
27 using android::gui::WindowInfo;
28 using android::os::IInputConstants;
29 using android::os::InputEventInjectionResult;
30 using android::os::InputEventInjectionSync;
31 
32 namespace android::inputdispatcher {
33 
34 namespace {
35 
36 // An arbitrary device id.
37 constexpr DeviceId DEVICE_ID = 1;
38 
39 // An arbitrary display id
40 constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
41 
42 static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 5s;
43 
now()44 static nsecs_t now() {
45     return systemTime(SYSTEM_TIME_MONOTONIC);
46 }
47 
generateMotionEvent()48 static MotionEvent generateMotionEvent() {
49     PointerProperties pointerProperties[1];
50     PointerCoords pointerCoords[1];
51 
52     pointerProperties[0].clear();
53     pointerProperties[0].id = 0;
54     pointerProperties[0].toolType = ToolType::FINGER;
55 
56     pointerCoords[0].clear();
57     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
58     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 100);
59 
60     const nsecs_t currentTime = now();
61 
62     ui::Transform identityTransform;
63     MotionEvent event;
64     event.initialize(IInputConstants::INVALID_INPUT_EVENT_ID, DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
65                      ui::LogicalDisplayId::DEFAULT, INVALID_HMAC, AMOTION_EVENT_ACTION_DOWN,
66                      /* actionButton */ 0, /* flags */ 0,
67                      /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
68                      identityTransform, /* xPrecision */ 0,
69                      /* yPrecision */ 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
70                      AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, currentTime,
71                      currentTime,
72                      /*pointerCount*/ 1, pointerProperties, pointerCoords);
73     return event;
74 }
75 
generateMotionArgs()76 static NotifyMotionArgs generateMotionArgs() {
77     PointerProperties pointerProperties[1];
78     PointerCoords pointerCoords[1];
79 
80     pointerProperties[0].clear();
81     pointerProperties[0].id = 0;
82     pointerProperties[0].toolType = ToolType::FINGER;
83 
84     pointerCoords[0].clear();
85     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
86     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 100);
87 
88     const nsecs_t currentTime = now();
89     // Define a valid motion event.
90     NotifyMotionArgs args(IInputConstants::INVALID_INPUT_EVENT_ID, currentTime, currentTime,
91                           DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
92                           POLICY_FLAG_PASS_TO_USER, AMOTION_EVENT_ACTION_DOWN,
93                           /* actionButton */ 0, /* flags */ 0, AMETA_NONE, /* buttonState */ 0,
94                           MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, 1,
95                           pointerProperties, pointerCoords,
96                           /* xPrecision */ 0, /* yPrecision */ 0,
97                           AMOTION_EVENT_INVALID_CURSOR_POSITION,
98                           AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
99 
100     return args;
101 }
102 
benchmarkNotifyMotion(benchmark::State & state)103 static void benchmarkNotifyMotion(benchmark::State& state) {
104     // Create dispatcher
105     FakeInputDispatcherPolicy fakePolicy;
106     auto dispatcher = std::make_unique<InputDispatcher>(fakePolicy);
107     dispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
108     dispatcher->start();
109 
110     // Create a window that will receive motion events
111     std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
112     sp<FakeWindowHandle> window =
113             sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window", DISPLAY_ID);
114 
115     dispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
116 
117     NotifyMotionArgs motionArgs = generateMotionArgs();
118 
119     for (auto _ : state) {
120         // Send ACTION_DOWN
121         motionArgs.action = AMOTION_EVENT_ACTION_DOWN;
122         motionArgs.downTime = now();
123         motionArgs.eventTime = motionArgs.downTime;
124         dispatcher->notifyMotion(motionArgs);
125 
126         // Send ACTION_UP
127         motionArgs.action = AMOTION_EVENT_ACTION_UP;
128         motionArgs.eventTime = now();
129         dispatcher->notifyMotion(motionArgs);
130 
131         window->consumeMotionEvent();
132         window->consumeMotionEvent();
133     }
134 
135     dispatcher->stop();
136 }
137 
benchmarkInjectMotion(benchmark::State & state)138 static void benchmarkInjectMotion(benchmark::State& state) {
139     // Create dispatcher
140     FakeInputDispatcherPolicy fakePolicy;
141     auto dispatcher = std::make_unique<InputDispatcher>(fakePolicy);
142     dispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
143     dispatcher->start();
144 
145     // Create a window that will receive motion events
146     std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
147     sp<FakeWindowHandle> window =
148             sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window", DISPLAY_ID);
149 
150     dispatcher->onWindowInfosChanged({{*window->getInfo()}, {}, 0, 0});
151 
152     for (auto _ : state) {
153         MotionEvent event = generateMotionEvent();
154         // Send ACTION_DOWN
155         dispatcher->injectInputEvent(&event, /*targetUid=*/{}, InputEventInjectionSync::NONE,
156                                      INJECT_EVENT_TIMEOUT,
157                                      POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
158 
159         // Send ACTION_UP
160         event.setAction(AMOTION_EVENT_ACTION_UP);
161         dispatcher->injectInputEvent(&event, /*targetUid=*/{}, InputEventInjectionSync::NONE,
162                                      INJECT_EVENT_TIMEOUT,
163                                      POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
164 
165         window->consumeMotionEvent();
166         window->consumeMotionEvent();
167     }
168 
169     dispatcher->stop();
170 }
171 
benchmarkOnWindowInfosChanged(benchmark::State & state)172 static void benchmarkOnWindowInfosChanged(benchmark::State& state) {
173     // Create dispatcher
174     FakeInputDispatcherPolicy fakePolicy;
175     auto dispatcher = std::make_unique<InputDispatcher>(fakePolicy);
176     dispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
177     dispatcher->start();
178 
179     // Create a window
180     std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
181     sp<FakeWindowHandle> window =
182             sp<FakeWindowHandle>::make(application, dispatcher, "Fake Window", DISPLAY_ID);
183 
184     std::vector<gui::WindowInfo> windowInfos{*window->getInfo()};
185     gui::DisplayInfo info;
186     info.displayId = window->getInfo()->displayId;
187     std::vector<gui::DisplayInfo> displayInfos{info};
188 
189     for (auto _ : state) {
190         dispatcher->onWindowInfosChanged(
191                 {windowInfos, displayInfos, /*vsyncId=*/0, /*timestamp=*/0});
192         dispatcher->onWindowInfosChanged(
193                 {/*windowInfos=*/{}, /*displayInfos=*/{}, /*vsyncId=*/{}, /*timestamp=*/0});
194     }
195     dispatcher->stop();
196 }
197 
198 } // namespace
199 
200 BENCHMARK(benchmarkNotifyMotion);
201 BENCHMARK(benchmarkInjectMotion);
202 BENCHMARK(benchmarkOnWindowInfosChanged);
203 
204 } // namespace android::inputdispatcher
205 
206 BENCHMARK_MAIN();
207