blob: 5bd5070488c5c3baca23b31698fc4232892e9fde [file] [log] [blame]
Cody Heiner166a5af2023-07-07 12:25:00 -07001/*
2 * Copyright 2023 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#pragma once
18
19#include <android/input.h>
20#include <attestation/HmacKeyManager.h>
Cody Heiner166a5af2023-07-07 12:25:00 -070021#include <input/Input.h>
Paul Ramirez7dfaa322024-08-21 17:44:45 +000022#include <input/InputTransport.h>
23#include <ui/LogicalDisplayId.h>
Cody Heiner166a5af2023-07-07 12:25:00 -070024#include <utils/Timers.h> // for nsecs_t, systemTime
25
26#include <vector>
27
28namespace android {
29
30// An arbitrary device id.
31static constexpr uint32_t DEFAULT_DEVICE_ID = 1;
32
33// The default policy flags to use for event injection by tests.
34static constexpr uint32_t DEFAULT_POLICY_FLAGS = POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER;
35
36class PointerBuilder {
37public:
38 PointerBuilder(int32_t id, ToolType toolType) {
39 mProperties.clear();
40 mProperties.id = id;
41 mProperties.toolType = toolType;
42 mCoords.clear();
43 }
44
45 PointerBuilder& x(float x) { return axis(AMOTION_EVENT_AXIS_X, x); }
46
47 PointerBuilder& y(float y) { return axis(AMOTION_EVENT_AXIS_Y, y); }
48
Paul Ramirez7dfaa322024-08-21 17:44:45 +000049 PointerBuilder& isResampled(bool isResampled) {
50 mCoords.isResampled = isResampled;
51 return *this;
52 }
53
Cody Heiner166a5af2023-07-07 12:25:00 -070054 PointerBuilder& axis(int32_t axis, float value) {
55 mCoords.setAxisValue(axis, value);
56 return *this;
57 }
58
59 PointerProperties buildProperties() const { return mProperties; }
60
61 PointerCoords buildCoords() const { return mCoords; }
62
63private:
64 PointerProperties mProperties;
65 PointerCoords mCoords;
66};
67
Paul Ramirez7dfaa322024-08-21 17:44:45 +000068class InputMessageBuilder {
69public:
70 InputMessageBuilder(InputMessage::Type type, uint32_t seq) : mType{type}, mSeq{seq} {}
71
72 InputMessageBuilder& eventId(int32_t eventId) {
73 mEventId = eventId;
74 return *this;
75 }
76
77 InputMessageBuilder& eventTime(nsecs_t eventTime) {
78 mEventTime = eventTime;
79 return *this;
80 }
81
82 InputMessageBuilder& deviceId(DeviceId deviceId) {
83 mDeviceId = deviceId;
84 return *this;
85 }
86
87 InputMessageBuilder& source(int32_t source) {
88 mSource = source;
89 return *this;
90 }
91
92 InputMessageBuilder& displayId(ui::LogicalDisplayId displayId) {
93 mDisplayId = displayId;
94 return *this;
95 }
96
97 InputMessageBuilder& action(int32_t action) {
98 mAction = action;
99 return *this;
100 }
101
102 InputMessageBuilder& downTime(nsecs_t downTime) {
103 mDownTime = downTime;
104 return *this;
105 }
106
107 InputMessageBuilder& pointer(PointerBuilder pointerBuilder) {
108 mPointers.push_back(pointerBuilder);
109 return *this;
110 }
111
112 InputMessage build() const {
113 InputMessage message{};
114 // Header
115 message.header.type = mType;
116 message.header.seq = mSeq;
117 // Body
118 message.body.motion.eventId = mEventId;
119 message.body.motion.pointerCount = mPointers.size();
120 message.body.motion.eventTime = mEventTime;
121 message.body.motion.deviceId = mDeviceId;
122 message.body.motion.source = mSource;
123 message.body.motion.displayId = mDisplayId.val();
124 message.body.motion.action = mAction;
125 message.body.motion.downTime = mDownTime;
126
127 for (size_t i = 0; i < mPointers.size(); ++i) {
128 message.body.motion.pointers[i].properties = mPointers[i].buildProperties();
129 message.body.motion.pointers[i].coords = mPointers[i].buildCoords();
130 }
131 return message;
132 }
133
134private:
135 const InputMessage::Type mType;
136 const uint32_t mSeq;
137
138 int32_t mEventId{InputEvent::nextId()};
139 nsecs_t mEventTime{systemTime(SYSTEM_TIME_MONOTONIC)};
140 DeviceId mDeviceId{DEFAULT_DEVICE_ID};
141 int32_t mSource{AINPUT_SOURCE_TOUCHSCREEN};
142 ui::LogicalDisplayId mDisplayId{ui::LogicalDisplayId::DEFAULT};
143 int32_t mAction{AMOTION_EVENT_ACTION_MOVE};
144 nsecs_t mDownTime{mEventTime};
145
146 std::vector<PointerBuilder> mPointers;
147};
148
Cody Heiner166a5af2023-07-07 12:25:00 -0700149class MotionEventBuilder {
150public:
151 MotionEventBuilder(int32_t action, int32_t source) {
152 mAction = action;
153 mSource = source;
154 mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
155 mDownTime = mEventTime;
156 }
157
158 MotionEventBuilder& deviceId(int32_t deviceId) {
159 mDeviceId = deviceId;
160 return *this;
161 }
162
163 MotionEventBuilder& downTime(nsecs_t downTime) {
164 mDownTime = downTime;
165 return *this;
166 }
167
168 MotionEventBuilder& eventTime(nsecs_t eventTime) {
169 mEventTime = eventTime;
170 return *this;
171 }
172
Linnan Li13bf76a2024-05-05 19:18:02 +0800173 MotionEventBuilder& displayId(ui::LogicalDisplayId displayId) {
Cody Heiner166a5af2023-07-07 12:25:00 -0700174 mDisplayId = displayId;
175 return *this;
176 }
177
178 MotionEventBuilder& actionButton(int32_t actionButton) {
179 mActionButton = actionButton;
180 return *this;
181 }
182
183 MotionEventBuilder& buttonState(int32_t buttonState) {
184 mButtonState = buttonState;
185 return *this;
186 }
187
188 MotionEventBuilder& rawXCursorPosition(float rawXCursorPosition) {
189 mRawXCursorPosition = rawXCursorPosition;
190 return *this;
191 }
192
193 MotionEventBuilder& rawYCursorPosition(float rawYCursorPosition) {
194 mRawYCursorPosition = rawYCursorPosition;
195 return *this;
196 }
197
198 MotionEventBuilder& pointer(PointerBuilder pointer) {
199 mPointers.push_back(pointer);
200 return *this;
201 }
202
203 MotionEventBuilder& addFlag(uint32_t flags) {
204 mFlags |= flags;
205 return *this;
206 }
207
Prabir Pradhanbf9b0a82024-02-29 02:23:50 +0000208 MotionEventBuilder& transform(ui::Transform t) {
209 mTransform = t;
210 return *this;
211 }
212
213 MotionEventBuilder& rawTransform(ui::Transform t) {
214 mRawTransform = t;
215 return *this;
216 }
217
Siarhei Vishniakou9d0d65e2024-08-02 12:10:05 -0700218 MotionEvent build() const {
Cody Heiner166a5af2023-07-07 12:25:00 -0700219 std::vector<PointerProperties> pointerProperties;
220 std::vector<PointerCoords> pointerCoords;
221 for (const PointerBuilder& pointer : mPointers) {
222 pointerProperties.push_back(pointer.buildProperties());
223 pointerCoords.push_back(pointer.buildCoords());
224 }
225
Siarhei Vishniakou9d0d65e2024-08-02 12:10:05 -0700226 auto [xCursorPosition, yCursorPosition] =
227 std::make_pair(mRawXCursorPosition, mRawYCursorPosition);
Cody Heiner166a5af2023-07-07 12:25:00 -0700228 // Set mouse cursor position for the most common cases to avoid boilerplate.
229 if (mSource == AINPUT_SOURCE_MOUSE &&
Siarhei Vishniakou9d0d65e2024-08-02 12:10:05 -0700230 !MotionEvent::isValidCursorPosition(xCursorPosition, yCursorPosition)) {
231 xCursorPosition = pointerCoords[0].getX();
232 yCursorPosition = pointerCoords[0].getY();
Cody Heiner166a5af2023-07-07 12:25:00 -0700233 }
234
235 MotionEvent event;
Cody Heiner166a5af2023-07-07 12:25:00 -0700236 event.initialize(InputEvent::nextId(), mDeviceId, mSource, mDisplayId, INVALID_HMAC,
237 mAction, mActionButton, mFlags, /*edgeFlags=*/0, AMETA_NONE, mButtonState,
Prabir Pradhanbf9b0a82024-02-29 02:23:50 +0000238 MotionClassification::NONE, mTransform,
Siarhei Vishniakou9d0d65e2024-08-02 12:10:05 -0700239 /*xPrecision=*/0, /*yPrecision=*/0, xCursorPosition, yCursorPosition,
240 mRawTransform, mDownTime, mEventTime, mPointers.size(),
241 pointerProperties.data(), pointerCoords.data());
Cody Heiner166a5af2023-07-07 12:25:00 -0700242 return event;
243 }
244
245private:
246 int32_t mAction;
247 int32_t mDeviceId{DEFAULT_DEVICE_ID};
248 int32_t mSource;
249 nsecs_t mDownTime;
250 nsecs_t mEventTime;
Siarhei Vishniakoucfbee532024-05-10 13:41:35 -0700251 ui::LogicalDisplayId mDisplayId{ui::LogicalDisplayId::DEFAULT};
Cody Heiner166a5af2023-07-07 12:25:00 -0700252 int32_t mActionButton{0};
253 int32_t mButtonState{0};
254 int32_t mFlags{0};
255 float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
256 float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
Prabir Pradhanbf9b0a82024-02-29 02:23:50 +0000257 ui::Transform mTransform;
258 ui::Transform mRawTransform;
Cody Heiner166a5af2023-07-07 12:25:00 -0700259
260 std::vector<PointerBuilder> mPointers;
261};
262
Prabir Pradhanb0dad3a2023-11-02 20:52:47 +0000263class KeyEventBuilder {
264public:
265 KeyEventBuilder(int32_t action, int32_t source) {
266 mAction = action;
267 mSource = source;
268 mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
269 mDownTime = mEventTime;
270 }
271
272 KeyEventBuilder(const KeyEvent& event) {
273 mAction = event.getAction();
274 mDeviceId = event.getDeviceId();
275 mSource = event.getSource();
276 mDownTime = event.getDownTime();
277 mEventTime = event.getEventTime();
278 mDisplayId = event.getDisplayId();
279 mFlags = event.getFlags();
280 mKeyCode = event.getKeyCode();
281 mScanCode = event.getScanCode();
282 mMetaState = event.getMetaState();
283 mRepeatCount = event.getRepeatCount();
284 }
285
286 KeyEventBuilder& deviceId(int32_t deviceId) {
287 mDeviceId = deviceId;
288 return *this;
289 }
290
291 KeyEventBuilder& downTime(nsecs_t downTime) {
292 mDownTime = downTime;
293 return *this;
294 }
295
296 KeyEventBuilder& eventTime(nsecs_t eventTime) {
297 mEventTime = eventTime;
298 return *this;
299 }
300
Linnan Li13bf76a2024-05-05 19:18:02 +0800301 KeyEventBuilder& displayId(ui::LogicalDisplayId displayId) {
Prabir Pradhanb0dad3a2023-11-02 20:52:47 +0000302 mDisplayId = displayId;
303 return *this;
304 }
305
306 KeyEventBuilder& policyFlags(int32_t policyFlags) {
307 mPolicyFlags = policyFlags;
308 return *this;
309 }
310
311 KeyEventBuilder& addFlag(uint32_t flags) {
312 mFlags |= flags;
313 return *this;
314 }
315
316 KeyEventBuilder& keyCode(int32_t keyCode) {
317 mKeyCode = keyCode;
318 return *this;
319 }
320
321 KeyEventBuilder& repeatCount(int32_t repeatCount) {
322 mRepeatCount = repeatCount;
323 return *this;
324 }
325
326 KeyEvent build() const {
327 KeyEvent event{};
328 event.initialize(InputEvent::nextId(), mDeviceId, mSource, mDisplayId, INVALID_HMAC,
329 mAction, mFlags, mKeyCode, mScanCode, mMetaState, mRepeatCount, mDownTime,
330 mEventTime);
331 return event;
332 }
333
334private:
335 int32_t mAction;
336 int32_t mDeviceId = DEFAULT_DEVICE_ID;
337 uint32_t mSource;
338 nsecs_t mDownTime;
339 nsecs_t mEventTime;
Siarhei Vishniakoucfbee532024-05-10 13:41:35 -0700340 ui::LogicalDisplayId mDisplayId{ui::LogicalDisplayId::DEFAULT};
Prabir Pradhanb0dad3a2023-11-02 20:52:47 +0000341 uint32_t mPolicyFlags = DEFAULT_POLICY_FLAGS;
342 int32_t mFlags{0};
343 int32_t mKeyCode{AKEYCODE_UNKNOWN};
344 int32_t mScanCode{0};
345 int32_t mMetaState{AMETA_NONE};
346 int32_t mRepeatCount{0};
347};
348
Cody Heiner166a5af2023-07-07 12:25:00 -0700349} // namespace android