1 /*
2 * Copyright 2025 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 "../dispatcher/trace/AndroidInputEventProtoConverter.h"
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 namespace android::inputdispatcher::trace {
23
24 namespace {
25
26 using testing::Return, testing::_;
27
28 class MockProtoAxisValue {
29 public:
30 MOCK_METHOD(void, set_axis, (int32_t));
31 MOCK_METHOD(void, set_value, (float));
32 };
33
34 class MockProtoPointer {
35 public:
36 MOCK_METHOD(void, set_pointer_id, (uint32_t));
37 MOCK_METHOD(void, set_tool_type, (int32_t));
38 MOCK_METHOD(MockProtoAxisValue*, add_axis_value, ());
39 };
40
41 class MockProtoMotion {
42 public:
43 MOCK_METHOD(void, set_event_id, (uint32_t));
44 MOCK_METHOD(void, set_event_time_nanos, (int64_t));
45 MOCK_METHOD(void, set_down_time_nanos, (int64_t));
46 MOCK_METHOD(void, set_source, (uint32_t));
47 MOCK_METHOD(void, set_action, (int32_t));
48 MOCK_METHOD(void, set_device_id, (uint32_t));
49 MOCK_METHOD(void, set_display_id, (uint32_t));
50 MOCK_METHOD(void, set_classification, (int32_t));
51 MOCK_METHOD(void, set_flags, (uint32_t));
52 MOCK_METHOD(void, set_policy_flags, (uint32_t));
53 MOCK_METHOD(void, set_button_state, (uint32_t));
54 MOCK_METHOD(void, set_action_button, (uint32_t));
55 MOCK_METHOD(void, set_cursor_position_x, (float));
56 MOCK_METHOD(void, set_cursor_position_y, (float));
57 MOCK_METHOD(void, set_meta_state, (uint32_t));
58 MOCK_METHOD(void, set_precision_x, (float));
59 MOCK_METHOD(void, set_precision_y, (float));
60 MOCK_METHOD(MockProtoPointer*, add_pointer, ());
61 };
62
63 class MockProtoKey {
64 public:
65 MOCK_METHOD(void, set_event_id, (uint32_t));
66 MOCK_METHOD(void, set_event_time_nanos, (int64_t));
67 MOCK_METHOD(void, set_down_time_nanos, (int64_t));
68 MOCK_METHOD(void, set_source, (uint32_t));
69 MOCK_METHOD(void, set_action, (int32_t));
70 MOCK_METHOD(void, set_device_id, (uint32_t));
71 MOCK_METHOD(void, set_display_id, (uint32_t));
72 MOCK_METHOD(void, set_repeat_count, (uint32_t));
73 MOCK_METHOD(void, set_flags, (uint32_t));
74 MOCK_METHOD(void, set_policy_flags, (uint32_t));
75 MOCK_METHOD(void, set_key_code, (uint32_t));
76 MOCK_METHOD(void, set_scan_code, (uint32_t));
77 MOCK_METHOD(void, set_meta_state, (uint32_t));
78 };
79
80 class MockProtoDispatchPointer {
81 public:
82 MOCK_METHOD(void, set_pointer_id, (uint32_t));
83 MOCK_METHOD(void, set_x_in_display, (float));
84 MOCK_METHOD(void, set_y_in_display, (float));
85 MOCK_METHOD(MockProtoAxisValue*, add_axis_value_in_window, ());
86 };
87
88 class MockProtoDispatch {
89 public:
90 MOCK_METHOD(void, set_event_id, (uint32_t));
91 MOCK_METHOD(void, set_vsync_id, (uint32_t));
92 MOCK_METHOD(void, set_window_id, (uint32_t));
93 MOCK_METHOD(void, set_resolved_flags, (uint32_t));
94 MOCK_METHOD(MockProtoDispatchPointer*, add_dispatched_pointer, ());
95 };
96
97 using TestProtoConverter =
98 AndroidInputEventProtoConverter<MockProtoMotion, MockProtoKey, MockProtoDispatch,
99 proto::AndroidInputEventConfig::Decoder>;
100
TEST(AndroidInputEventProtoConverterTest,ToProtoMotionEvent)101 TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent) {
102 TracedMotionEvent event{};
103 event.id = 1;
104 event.eventTime = 2;
105 event.downTime = 3;
106 event.source = AINPUT_SOURCE_MOUSE;
107 event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS;
108 event.deviceId = 4;
109 event.displayId = ui::LogicalDisplayId(5);
110 event.classification = MotionClassification::PINCH;
111 event.flags = 6;
112 event.policyFlags = 7;
113 event.buttonState = 8;
114 event.actionButton = 9;
115 event.xCursorPosition = 10.0f;
116 event.yCursorPosition = 11.0f;
117 event.metaState = 12;
118 event.xPrecision = 13.0f;
119 event.yPrecision = 14.0f;
120 event.pointerProperties.emplace_back(PointerProperties{
121 .id = 15,
122 .toolType = ToolType::MOUSE,
123 });
124 event.pointerProperties.emplace_back(PointerProperties{
125 .id = 16,
126 .toolType = ToolType::FINGER,
127 });
128 event.pointerCoords.emplace_back();
129 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 17.0f);
130 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 18.0f);
131 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 19.0f);
132 event.pointerCoords.emplace_back();
133 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 20.0f);
134 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 21.0f);
135 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22.0f);
136
137 testing::StrictMock<MockProtoMotion> proto;
138 testing::StrictMock<MockProtoPointer> pointer1;
139 testing::StrictMock<MockProtoPointer> pointer2;
140 testing::StrictMock<MockProtoAxisValue> axisValue1;
141 testing::StrictMock<MockProtoAxisValue> axisValue2;
142 testing::StrictMock<MockProtoAxisValue> axisValue3;
143 testing::StrictMock<MockProtoAxisValue> axisValue4;
144 testing::StrictMock<MockProtoAxisValue> axisValue5;
145 testing::StrictMock<MockProtoAxisValue> axisValue6;
146
147 EXPECT_CALL(proto, set_event_id(1));
148 EXPECT_CALL(proto, set_event_time_nanos(2));
149 EXPECT_CALL(proto, set_down_time_nanos(3));
150 EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE));
151 EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS));
152 EXPECT_CALL(proto, set_device_id(4));
153 EXPECT_CALL(proto, set_display_id(5));
154 EXPECT_CALL(proto, set_classification(AMOTION_EVENT_CLASSIFICATION_PINCH));
155 EXPECT_CALL(proto, set_flags(6));
156 EXPECT_CALL(proto, set_policy_flags(7));
157 EXPECT_CALL(proto, set_button_state(8));
158 EXPECT_CALL(proto, set_action_button(9));
159 EXPECT_CALL(proto, set_cursor_position_x(10.0f));
160 EXPECT_CALL(proto, set_cursor_position_y(11.0f));
161 EXPECT_CALL(proto, set_meta_state(12));
162 EXPECT_CALL(proto, set_precision_x(13.0f));
163 EXPECT_CALL(proto, set_precision_y(14.0f));
164
165 EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2));
166
167 EXPECT_CALL(pointer1, set_pointer_id(15));
168 EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE));
169 EXPECT_CALL(pointer1, add_axis_value())
170 .WillOnce(Return(&axisValue1))
171 .WillOnce(Return(&axisValue2))
172 .WillOnce(Return(&axisValue3));
173 EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X));
174 EXPECT_CALL(axisValue1, set_value(17.0f));
175 EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y));
176 EXPECT_CALL(axisValue2, set_value(18.0f));
177 EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_PRESSURE));
178 EXPECT_CALL(axisValue3, set_value(19.0f));
179
180 EXPECT_CALL(pointer2, set_pointer_id(16));
181 EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER));
182 EXPECT_CALL(pointer2, add_axis_value())
183 .WillOnce(Return(&axisValue4))
184 .WillOnce(Return(&axisValue5))
185 .WillOnce(Return(&axisValue6));
186 EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_X));
187 EXPECT_CALL(axisValue4, set_value(20.0f));
188 EXPECT_CALL(axisValue5, set_axis(AMOTION_EVENT_AXIS_Y));
189 EXPECT_CALL(axisValue5, set_value(21.0f));
190 EXPECT_CALL(axisValue6, set_axis(AMOTION_EVENT_AXIS_PRESSURE));
191 EXPECT_CALL(axisValue6, set_value(22.0f));
192
193 TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/false);
194 }
195
TEST(AndroidInputEventProtoConverterTest,ToProtoMotionEvent_Redacted)196 TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent_Redacted) {
197 TracedMotionEvent event{};
198 event.id = 1;
199 event.eventTime = 2;
200 event.downTime = 3;
201 event.source = AINPUT_SOURCE_MOUSE;
202 event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS;
203 event.deviceId = 4;
204 event.displayId = ui::LogicalDisplayId(5);
205 event.classification = MotionClassification::PINCH;
206 event.flags = 6;
207 event.policyFlags = 7;
208 event.buttonState = 8;
209 event.actionButton = 9;
210 event.xCursorPosition = 10.0f;
211 event.yCursorPosition = 11.0f;
212 event.metaState = 12;
213 event.xPrecision = 13.0f;
214 event.yPrecision = 14.0f;
215 event.pointerProperties.emplace_back(PointerProperties{
216 .id = 15,
217 .toolType = ToolType::MOUSE,
218 });
219 event.pointerProperties.emplace_back(PointerProperties{
220 .id = 16,
221 .toolType = ToolType::FINGER,
222 });
223 event.pointerCoords.emplace_back();
224 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 17.0f);
225 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 18.0f);
226 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 19.0f);
227 event.pointerCoords.emplace_back();
228 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 20.0f);
229 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 21.0f);
230 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22.0f);
231
232 testing::StrictMock<MockProtoMotion> proto;
233 testing::StrictMock<MockProtoPointer> pointer1;
234 testing::StrictMock<MockProtoPointer> pointer2;
235 testing::StrictMock<MockProtoAxisValue> axisValue1;
236 testing::StrictMock<MockProtoAxisValue> axisValue2;
237 testing::StrictMock<MockProtoAxisValue> axisValue3;
238 testing::StrictMock<MockProtoAxisValue> axisValue4;
239 testing::StrictMock<MockProtoAxisValue> axisValue5;
240 testing::StrictMock<MockProtoAxisValue> axisValue6;
241
242 EXPECT_CALL(proto, set_event_id(1));
243 EXPECT_CALL(proto, set_event_time_nanos(2));
244 EXPECT_CALL(proto, set_down_time_nanos(3));
245 EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE));
246 EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS));
247 EXPECT_CALL(proto, set_device_id(4));
248 EXPECT_CALL(proto, set_display_id(5));
249 EXPECT_CALL(proto, set_classification(AMOTION_EVENT_CLASSIFICATION_PINCH));
250 EXPECT_CALL(proto, set_flags(6));
251 EXPECT_CALL(proto, set_policy_flags(7));
252 EXPECT_CALL(proto, set_button_state(8));
253 EXPECT_CALL(proto, set_action_button(9));
254
255 EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2));
256
257 EXPECT_CALL(pointer1, set_pointer_id(15));
258 EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE));
259 EXPECT_CALL(pointer1, add_axis_value())
260 .WillOnce(Return(&axisValue1))
261 .WillOnce(Return(&axisValue2))
262 .WillOnce(Return(&axisValue3));
263 EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X));
264 EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y));
265 EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_PRESSURE));
266
267 EXPECT_CALL(pointer2, set_pointer_id(16));
268 EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER));
269 EXPECT_CALL(pointer2, add_axis_value())
270 .WillOnce(Return(&axisValue4))
271 .WillOnce(Return(&axisValue5))
272 .WillOnce(Return(&axisValue6));
273 EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_X));
274 EXPECT_CALL(axisValue5, set_axis(AMOTION_EVENT_AXIS_Y));
275 EXPECT_CALL(axisValue6, set_axis(AMOTION_EVENT_AXIS_PRESSURE));
276
277 // Redacted fields
278 EXPECT_CALL(proto, set_meta_state(_)).Times(0);
279 EXPECT_CALL(proto, set_cursor_position_x(_)).Times(0);
280 EXPECT_CALL(proto, set_cursor_position_y(_)).Times(0);
281 EXPECT_CALL(proto, set_precision_x(_)).Times(0);
282 EXPECT_CALL(proto, set_precision_y(_)).Times(0);
283 EXPECT_CALL(axisValue1, set_value(_)).Times(0);
284 EXPECT_CALL(axisValue2, set_value(_)).Times(0);
285 EXPECT_CALL(axisValue3, set_value(_)).Times(0);
286 EXPECT_CALL(axisValue4, set_value(_)).Times(0);
287 EXPECT_CALL(axisValue5, set_value(_)).Times(0);
288 EXPECT_CALL(axisValue6, set_value(_)).Times(0);
289
290 TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/true);
291 }
292
293 // Test any special handling for zero values for pointer events.
TEST(AndroidInputEventProtoConverterTest,ToProtoMotionEvent_ZeroValues)294 TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent_ZeroValues) {
295 TracedMotionEvent event{};
296 event.id = 0;
297 event.eventTime = 0;
298 event.downTime = 0;
299 event.source = AINPUT_SOURCE_MOUSE;
300 event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS;
301 event.deviceId = 0;
302 event.displayId = ui::LogicalDisplayId(0);
303 event.classification = {};
304 event.flags = 0;
305 event.policyFlags = 0;
306 event.buttonState = 0;
307 event.actionButton = 0;
308 event.xCursorPosition = 0.0f;
309 event.yCursorPosition = 0.0f;
310 event.metaState = 0;
311 event.xPrecision = 0.0f;
312 event.yPrecision = 0.0f;
313 event.pointerProperties.emplace_back(PointerProperties{
314 .id = 0,
315 .toolType = ToolType::MOUSE,
316 });
317 event.pointerProperties.emplace_back(PointerProperties{
318 .id = 1,
319 .toolType = ToolType::FINGER,
320 });
321 // Zero values for x and y axes are always traced for pointer events.
322 // However, zero values for other axes may not necessarily be traced.
323 event.pointerCoords.emplace_back();
324 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 0.0f);
325 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 1.0f);
326 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f);
327 event.pointerCoords.emplace_back();
328 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 0.0f);
329 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 0.0f);
330 event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f);
331
332 testing::StrictMock<MockProtoMotion> proto;
333 testing::StrictMock<MockProtoPointer> pointer1;
334 testing::StrictMock<MockProtoPointer> pointer2;
335 testing::StrictMock<MockProtoAxisValue> axisValue1;
336 testing::StrictMock<MockProtoAxisValue> axisValue2;
337 testing::StrictMock<MockProtoAxisValue> axisValue3;
338 testing::StrictMock<MockProtoAxisValue> axisValue4;
339
340 EXPECT_CALL(proto, set_event_id(0));
341 EXPECT_CALL(proto, set_event_time_nanos(0));
342 EXPECT_CALL(proto, set_down_time_nanos(0));
343 EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE));
344 EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS));
345 EXPECT_CALL(proto, set_device_id(0));
346 EXPECT_CALL(proto, set_display_id(0));
347 EXPECT_CALL(proto, set_classification(0));
348 EXPECT_CALL(proto, set_flags(0));
349 EXPECT_CALL(proto, set_policy_flags(0));
350 EXPECT_CALL(proto, set_button_state(0));
351 EXPECT_CALL(proto, set_action_button(0));
352 EXPECT_CALL(proto, set_cursor_position_x(0.0f));
353 EXPECT_CALL(proto, set_cursor_position_y(0.0f));
354 EXPECT_CALL(proto, set_meta_state(0));
355 EXPECT_CALL(proto, set_precision_x(0.0f));
356 EXPECT_CALL(proto, set_precision_y(0.0f));
357
358 EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2));
359
360 EXPECT_CALL(pointer1, set_pointer_id(0));
361 EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE));
362 EXPECT_CALL(pointer1, add_axis_value())
363 .WillOnce(Return(&axisValue1))
364 .WillOnce(Return(&axisValue2));
365 EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X));
366 EXPECT_CALL(axisValue1, set_value(0.0f));
367 EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y));
368 EXPECT_CALL(axisValue2, set_value(1.0f));
369
370 EXPECT_CALL(pointer2, set_pointer_id(1));
371 EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER));
372 EXPECT_CALL(pointer2, add_axis_value())
373 .WillOnce(Return(&axisValue3))
374 .WillOnce(Return(&axisValue4));
375 EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_X));
376 EXPECT_CALL(axisValue3, set_value(0.0f));
377 EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_Y));
378 EXPECT_CALL(axisValue4, set_value(0.0f));
379
380 TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/false);
381 }
382
TEST(AndroidInputEventProtoConverterTest,ToProtoKeyEvent)383 TEST(AndroidInputEventProtoConverterTest, ToProtoKeyEvent) {
384 TracedKeyEvent event{};
385 event.id = 1;
386 event.eventTime = 2;
387 event.downTime = 3;
388 event.source = AINPUT_SOURCE_KEYBOARD;
389 event.action = AKEY_EVENT_ACTION_DOWN;
390 event.deviceId = 4;
391 event.displayId = ui::LogicalDisplayId(5);
392 event.repeatCount = 6;
393 event.flags = 7;
394 event.policyFlags = 8;
395 event.keyCode = 9;
396 event.scanCode = 10;
397 event.metaState = 11;
398
399 testing::StrictMock<MockProtoKey> proto;
400
401 EXPECT_CALL(proto, set_event_id(1));
402 EXPECT_CALL(proto, set_event_time_nanos(2));
403 EXPECT_CALL(proto, set_down_time_nanos(3));
404 EXPECT_CALL(proto, set_source(AINPUT_SOURCE_KEYBOARD));
405 EXPECT_CALL(proto, set_action(AKEY_EVENT_ACTION_DOWN));
406 EXPECT_CALL(proto, set_device_id(4));
407 EXPECT_CALL(proto, set_display_id(5));
408 EXPECT_CALL(proto, set_repeat_count(6));
409 EXPECT_CALL(proto, set_flags(7));
410 EXPECT_CALL(proto, set_policy_flags(8));
411 EXPECT_CALL(proto, set_key_code(9));
412 EXPECT_CALL(proto, set_scan_code(10));
413 EXPECT_CALL(proto, set_meta_state(11));
414
415 TestProtoConverter::toProtoKeyEvent(event, proto, /*isRedacted=*/false);
416 }
417
TEST(AndroidInputEventProtoConverterTest,ToProtoKeyEvent_Redacted)418 TEST(AndroidInputEventProtoConverterTest, ToProtoKeyEvent_Redacted) {
419 TracedKeyEvent event{};
420 event.id = 1;
421 event.eventTime = 2;
422 event.downTime = 3;
423 event.source = AINPUT_SOURCE_KEYBOARD;
424 event.action = AKEY_EVENT_ACTION_DOWN;
425 event.deviceId = 4;
426 event.displayId = ui::LogicalDisplayId(5);
427 event.repeatCount = 6;
428 event.flags = 7;
429 event.policyFlags = 8;
430 event.keyCode = 9;
431 event.scanCode = 10;
432 event.metaState = 11;
433
434 testing::StrictMock<MockProtoKey> proto;
435
436 EXPECT_CALL(proto, set_event_id(1));
437 EXPECT_CALL(proto, set_event_time_nanos(2));
438 EXPECT_CALL(proto, set_down_time_nanos(3));
439 EXPECT_CALL(proto, set_source(AINPUT_SOURCE_KEYBOARD));
440 EXPECT_CALL(proto, set_action(AKEY_EVENT_ACTION_DOWN));
441 EXPECT_CALL(proto, set_device_id(4));
442 EXPECT_CALL(proto, set_display_id(5));
443 EXPECT_CALL(proto, set_repeat_count(6));
444 EXPECT_CALL(proto, set_flags(7));
445 EXPECT_CALL(proto, set_policy_flags(8));
446
447 // Redacted fields
448 EXPECT_CALL(proto, set_key_code(_)).Times(0);
449 EXPECT_CALL(proto, set_scan_code(_)).Times(0);
450 EXPECT_CALL(proto, set_meta_state(_)).Times(0);
451
452 TestProtoConverter::toProtoKeyEvent(event, proto, /*isRedacted=*/true);
453 }
454
TEST(AndroidInputEventProtoConverterTest,ToProtoWindowDispatchEvent_Motion_IdentityTransform)455 TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Motion_IdentityTransform) {
456 TracedMotionEvent motion{};
457 motion.pointerProperties.emplace_back(PointerProperties{
458 .id = 4,
459 .toolType = ToolType::MOUSE,
460 });
461 motion.pointerCoords.emplace_back();
462 motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 5.0f);
463 motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 6.0f);
464
465 WindowDispatchArgs args{};
466 args.eventEntry = motion;
467 args.vsyncId = 1;
468 args.windowId = 2;
469 args.resolvedFlags = 3;
470 args.rawTransform = ui::Transform{};
471 args.transform = ui::Transform{};
472
473 testing::StrictMock<MockProtoDispatch> proto;
474 testing::StrictMock<MockProtoDispatchPointer> pointer;
475
476 EXPECT_CALL(proto, set_event_id(0));
477 EXPECT_CALL(proto, set_vsync_id(1));
478 EXPECT_CALL(proto, set_window_id(2));
479 EXPECT_CALL(proto, set_resolved_flags(3));
480 EXPECT_CALL(proto, add_dispatched_pointer()).WillOnce(Return(&pointer));
481 EXPECT_CALL(pointer, set_pointer_id(4));
482
483 // Since we are using identity transforms, the axis values will be identical to those in the
484 // traced event, so they should not be traced here.
485 EXPECT_CALL(pointer, add_axis_value_in_window()).Times(0);
486 EXPECT_CALL(pointer, set_x_in_display(_)).Times(0);
487 EXPECT_CALL(pointer, set_y_in_display(_)).Times(0);
488
489 TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/false);
490 }
491
TEST(AndroidInputEventProtoConverterTest,ToProtoWindowDispatchEvent_Motion_CustomTransform)492 TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Motion_CustomTransform) {
493 TracedMotionEvent motion{};
494 motion.pointerProperties.emplace_back(PointerProperties{
495 .id = 4,
496 .toolType = ToolType::MOUSE,
497 });
498 motion.pointerCoords.emplace_back();
499 motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 8.0f);
500 motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 6.0f);
501
502 WindowDispatchArgs args{};
503 args.eventEntry = motion;
504 args.vsyncId = 1;
505 args.windowId = 2;
506 args.resolvedFlags = 3;
507 args.rawTransform.set(2, 0, 0, 0.5);
508 args.transform.set(1.0, 0, 0, 0.5);
509
510 testing::StrictMock<MockProtoDispatch> proto;
511 testing::StrictMock<MockProtoDispatchPointer> pointer;
512 testing::StrictMock<MockProtoAxisValue> axisValue1;
513
514 EXPECT_CALL(proto, set_event_id(0));
515 EXPECT_CALL(proto, set_vsync_id(1));
516 EXPECT_CALL(proto, set_window_id(2));
517 EXPECT_CALL(proto, set_resolved_flags(3));
518 EXPECT_CALL(proto, add_dispatched_pointer()).WillOnce(Return(&pointer));
519 EXPECT_CALL(pointer, set_pointer_id(4));
520
521 // Only the transformed axis-values that differ from the traced event will be traced.
522 EXPECT_CALL(pointer, add_axis_value_in_window()).WillOnce(Return(&axisValue1));
523 EXPECT_CALL(pointer, set_x_in_display(16.0f)); // MotionEvent::getRawX
524 EXPECT_CALL(pointer, set_y_in_display(3.0f)); // MotionEvent::getRawY
525
526 EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_Y));
527 EXPECT_CALL(axisValue1, set_value(3.0f));
528
529 TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/false);
530 }
531
TEST(AndroidInputEventProtoConverterTest,ToProtoWindowDispatchEvent_Motion_Redacted)532 TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Motion_Redacted) {
533 TracedMotionEvent motion{};
534 motion.pointerProperties.emplace_back(PointerProperties{
535 .id = 4,
536 .toolType = ToolType::MOUSE,
537 });
538 motion.pointerCoords.emplace_back();
539 motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 5.0f);
540 motion.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 6.0f);
541
542 WindowDispatchArgs args{};
543 args.eventEntry = motion;
544 args.vsyncId = 1;
545 args.windowId = 2;
546 args.resolvedFlags = 3;
547 args.rawTransform = ui::Transform{};
548 args.transform = ui::Transform{};
549
550 testing::StrictMock<MockProtoDispatch> proto;
551
552 EXPECT_CALL(proto, set_event_id(0));
553 EXPECT_CALL(proto, set_vsync_id(1));
554 EXPECT_CALL(proto, set_window_id(2));
555 EXPECT_CALL(proto, set_resolved_flags(3));
556
557 // Redacted fields
558 EXPECT_CALL(proto, add_dispatched_pointer()).Times(0);
559
560 TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/true);
561 }
562
TEST(AndroidInputEventProtoConverterTest,ToProtoWindowDispatchEvent_Key)563 TEST(AndroidInputEventProtoConverterTest, ToProtoWindowDispatchEvent_Key) {
564 TracedKeyEvent key{};
565
566 WindowDispatchArgs args{};
567 args.eventEntry = key;
568 args.vsyncId = 1;
569 args.windowId = 2;
570 args.resolvedFlags = 3;
571 args.rawTransform = ui::Transform{};
572 args.transform = ui::Transform{};
573
574 testing::StrictMock<MockProtoDispatch> proto;
575
576 EXPECT_CALL(proto, set_event_id(0));
577 EXPECT_CALL(proto, set_vsync_id(1));
578 EXPECT_CALL(proto, set_window_id(2));
579 EXPECT_CALL(proto, set_resolved_flags(3));
580
581 TestProtoConverter::toProtoWindowDispatchEvent(args, proto, /*isRedacted=*/true);
582 }
583
584 } // namespace
585
586 } // namespace android::inputdispatcher::trace
587