1 /*
2 * Copyright (C) 2010 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 <attestation/HmacKeyManager.h>
18 #include <gtest/gtest.h>
19 #include <input/InputConsumer.h>
20 #include <input/InputTransport.h>
21
22 using android::base::Result;
23
24 namespace android {
25
26 namespace {
27
28 static constexpr float EPSILON = MotionEvent::ROUNDING_PRECISION;
29 static constexpr int32_t POINTER_1_DOWN =
30 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
31 static constexpr int32_t POINTER_2_DOWN =
32 AMOTION_EVENT_ACTION_POINTER_DOWN | (2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
33
34 struct Pointer {
35 int32_t id;
36 float x;
37 float y;
38 bool isResampled = false;
39 };
40
41 // A collection of arguments to be sent as publishMotionEvent(). The saved members of this struct
42 // allow to check the expectations against the event acquired from the InputReceiver. To help
43 // simplify expectation checking it carries members not present in MotionEvent, like |rawXScale|.
44 struct PublishMotionArgs {
45 const int32_t action;
46 const nsecs_t downTime;
47 const uint32_t seq;
48 const int32_t eventId;
49 const int32_t deviceId = 1;
50 const uint32_t source = AINPUT_SOURCE_TOUCHSCREEN;
51 const ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT;
52 const int32_t actionButton = 0;
53 const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
54 const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
55 const int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
56 const MotionClassification classification = MotionClassification::AMBIGUOUS_GESTURE;
57 const float xScale = 2;
58 const float yScale = 3;
59 const float xOffset = -10;
60 const float yOffset = -20;
61 const float rawXScale = 4;
62 const float rawYScale = -5;
63 const float rawXOffset = -11;
64 const float rawYOffset = 42;
65 const float xPrecision = 0.25;
66 const float yPrecision = 0.5;
67 const float xCursorPosition = 1.3;
68 const float yCursorPosition = 50.6;
69 std::array<uint8_t, 32> hmac;
70 int32_t flags;
71 ui::Transform transform;
72 ui::Transform rawTransform;
73 const nsecs_t eventTime;
74 size_t pointerCount;
75 std::vector<PointerProperties> pointerProperties;
76 std::vector<PointerCoords> pointerCoords;
77
78 PublishMotionArgs(int32_t action, nsecs_t downTime, const std::vector<Pointer>& pointers,
79 const uint32_t seq);
80 };
81
PublishMotionArgs(int32_t inAction,nsecs_t inDownTime,const std::vector<Pointer> & pointers,const uint32_t inSeq)82 PublishMotionArgs::PublishMotionArgs(int32_t inAction, nsecs_t inDownTime,
83 const std::vector<Pointer>& pointers, const uint32_t inSeq)
84 : action(inAction),
85 downTime(inDownTime),
86 seq(inSeq),
87 eventId(InputEvent::nextId()),
88 eventTime(systemTime(SYSTEM_TIME_MONOTONIC)) {
89 hmac = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
90 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
91
92 flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED |
93 AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
94 AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION;
95 if (action == AMOTION_EVENT_ACTION_CANCEL) {
96 flags |= AMOTION_EVENT_FLAG_CANCELED;
97 }
98 pointerCount = pointers.size();
99 for (size_t i = 0; i < pointerCount; i++) {
100 pointerProperties.push_back({});
101 pointerProperties[i].clear();
102 pointerProperties[i].id = pointers[i].id;
103 pointerProperties[i].toolType = ToolType::FINGER;
104
105 pointerCoords.push_back({});
106 pointerCoords[i].clear();
107 pointerCoords[i].isResampled = pointers[i].isResampled;
108 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, pointers[i].x);
109 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, pointers[i].y);
110 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i);
111 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i);
112 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i);
113 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i);
114 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i);
115 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i);
116 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
117 }
118 transform.set({xScale, 0, xOffset, 0, yScale, yOffset, 0, 0, 1});
119 rawTransform.set({rawXScale, 0, rawXOffset, 0, rawYScale, rawYOffset, 0, 0, 1});
120 }
121
122 // Checks expectations against |motionEvent| acquired from an InputConsumer. Floating point
123 // comparisons limit precision to EPSILON.
verifyArgsEqualToEvent(const PublishMotionArgs & args,const MotionEvent & motionEvent)124 void verifyArgsEqualToEvent(const PublishMotionArgs& args, const MotionEvent& motionEvent) {
125 EXPECT_EQ(args.eventId, motionEvent.getId());
126 EXPECT_EQ(args.deviceId, motionEvent.getDeviceId());
127 EXPECT_EQ(args.source, motionEvent.getSource());
128 EXPECT_EQ(args.displayId, motionEvent.getDisplayId());
129 EXPECT_EQ(args.hmac, motionEvent.getHmac());
130 EXPECT_EQ(args.action, motionEvent.getAction());
131 EXPECT_EQ(args.downTime, motionEvent.getDownTime());
132 EXPECT_EQ(args.flags, motionEvent.getFlags());
133 EXPECT_EQ(args.edgeFlags, motionEvent.getEdgeFlags());
134 EXPECT_EQ(args.metaState, motionEvent.getMetaState());
135 EXPECT_EQ(args.buttonState, motionEvent.getButtonState());
136 EXPECT_EQ(args.classification, motionEvent.getClassification());
137 EXPECT_EQ(args.transform, motionEvent.getTransform());
138 EXPECT_NEAR((-args.rawXOffset / args.rawXScale) * args.xScale + args.xOffset,
139 motionEvent.getRawXOffset(), EPSILON);
140 EXPECT_NEAR((-args.rawYOffset / args.rawYScale) * args.yScale + args.yOffset,
141 motionEvent.getRawYOffset(), EPSILON);
142 EXPECT_EQ(args.xPrecision, motionEvent.getXPrecision());
143 EXPECT_EQ(args.yPrecision, motionEvent.getYPrecision());
144 EXPECT_NEAR(args.xCursorPosition, motionEvent.getRawXCursorPosition(), EPSILON);
145 EXPECT_NEAR(args.yCursorPosition, motionEvent.getRawYCursorPosition(), EPSILON);
146 EXPECT_NEAR(args.xCursorPosition * args.xScale + args.xOffset, motionEvent.getXCursorPosition(),
147 EPSILON);
148 EXPECT_NEAR(args.yCursorPosition * args.yScale + args.yOffset, motionEvent.getYCursorPosition(),
149 EPSILON);
150 EXPECT_EQ(args.rawTransform, motionEvent.getRawTransform());
151 EXPECT_EQ(args.eventTime, motionEvent.getEventTime());
152 EXPECT_EQ(args.pointerCount, motionEvent.getPointerCount());
153 EXPECT_EQ(0U, motionEvent.getHistorySize());
154
155 for (size_t i = 0; i < args.pointerCount; i++) {
156 SCOPED_TRACE(i);
157 EXPECT_EQ(args.pointerProperties[i].id, motionEvent.getPointerId(i));
158 EXPECT_EQ(args.pointerProperties[i].toolType, motionEvent.getToolType(i));
159
160 const auto& pc = args.pointerCoords[i];
161 EXPECT_EQ(pc, motionEvent.getSamplePointerCoords()[i]);
162
163 EXPECT_NEAR(pc.getX() * args.rawXScale + args.rawXOffset, motionEvent.getRawX(i), EPSILON);
164 EXPECT_NEAR(pc.getY() * args.rawYScale + args.rawYOffset, motionEvent.getRawY(i), EPSILON);
165 EXPECT_NEAR(pc.getX() * args.xScale + args.xOffset, motionEvent.getX(i), EPSILON);
166 EXPECT_NEAR(pc.getY() * args.yScale + args.yOffset, motionEvent.getY(i), EPSILON);
167 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), motionEvent.getPressure(i));
168 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_SIZE), motionEvent.getSize(i));
169 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), motionEvent.getTouchMajor(i));
170 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), motionEvent.getTouchMinor(i));
171 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), motionEvent.getToolMajor(i));
172 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), motionEvent.getToolMinor(i));
173
174 // Calculate the orientation after scaling, keeping in mind that an orientation of 0 is
175 // "up", and the positive y direction is "down".
176 const float unscaledOrientation = pc.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
177 const float x = sinf(unscaledOrientation) * args.xScale;
178 const float y = -cosf(unscaledOrientation) * args.yScale;
179 EXPECT_EQ(atan2f(x, -y), motionEvent.getOrientation(i));
180 }
181 }
182
publishMotionEvent(InputPublisher & publisher,const PublishMotionArgs & a)183 void publishMotionEvent(InputPublisher& publisher, const PublishMotionArgs& a) {
184 status_t status =
185 publisher.publishMotionEvent(a.seq, a.eventId, a.deviceId, a.source, a.displayId,
186 a.hmac, a.action, a.actionButton, a.flags, a.edgeFlags,
187 a.metaState, a.buttonState, a.classification, a.transform,
188 a.xPrecision, a.yPrecision, a.xCursorPosition,
189 a.yCursorPosition, a.rawTransform, a.downTime, a.eventTime,
190 a.pointerCount, a.pointerProperties.data(),
191 a.pointerCoords.data());
192 ASSERT_EQ(OK, status) << "publisher publishMotionEvent should return OK";
193 }
194
sendAndVerifyFinishedSignal(InputConsumer & consumer,InputPublisher & publisher,uint32_t seq,nsecs_t publishTime)195 void sendAndVerifyFinishedSignal(InputConsumer& consumer, InputPublisher& publisher, uint32_t seq,
196 nsecs_t publishTime) {
197 status_t status = consumer.sendFinishedSignal(seq, false);
198 ASSERT_EQ(OK, status) << "consumer sendFinishedSignal should return OK";
199 Result<InputPublisher::ConsumerResponse> result = publisher.receiveConsumerResponse();
200 ASSERT_TRUE(result.ok()) << "receiveConsumerResponse should return OK";
201 ASSERT_TRUE(std::holds_alternative<InputPublisher::Finished>(*result));
202 const InputPublisher::Finished& finish = std::get<InputPublisher::Finished>(*result);
203 ASSERT_EQ(seq, finish.seq)
204 << "receiveConsumerResponse should have returned the original sequence number";
205 ASSERT_FALSE(finish.handled)
206 << "receiveConsumerResponse should have set handled to consumer's reply";
207 ASSERT_GE(finish.consumeTime, publishTime)
208 << "finished signal's consume time should be greater than publish time";
209 }
210
waitUntilInputAvailable(const InputConsumer & inputConsumer)211 void waitUntilInputAvailable(const InputConsumer& inputConsumer) {
212 bool hasInput;
213 do {
214 // The probablyHasInput() can return false positive under rare circumstances uncontrollable
215 // by the tests. Re-request the availability in this case. Returning |false| for a long
216 // time is not intended, and would cause a test timeout.
217 hasInput = inputConsumer.probablyHasInput();
218 } while (!hasInput);
219 }
220
221 } // namespace
222
223 class InputPublisherAndConsumerTest : public testing::Test {
224 protected:
225 std::unique_ptr<InputPublisher> mPublisher;
226 std::unique_ptr<InputConsumer> mConsumer;
227 PreallocatedInputEventFactory mEventFactory;
228
SetUp()229 void SetUp() override {
230 std::unique_ptr<InputChannel> serverChannel, clientChannel;
231 status_t result = InputChannel::openInputChannelPair("channel name",
232 serverChannel, clientChannel);
233 ASSERT_EQ(OK, result);
234
235 mPublisher = std::make_unique<InputPublisher>(std::move(serverChannel));
236 mConsumer = std::make_unique<InputConsumer>(std::move(clientChannel));
237 }
238
239 void publishAndConsumeKeyEvent();
240 void publishAndConsumeMotionStream();
241 void publishAndConsumeMotionDown(nsecs_t downTime);
242 void publishAndConsumeBatchedMotionMove(nsecs_t downTime);
243 void publishAndConsumeFocusEvent();
244 void publishAndConsumeCaptureEvent();
245 void publishAndConsumeDragEvent();
246 void publishAndConsumeTouchModeEvent();
247 void publishAndConsumeMotionEvent(int32_t action, nsecs_t downTime,
248 const std::vector<Pointer>& pointers);
249
250 private:
251 // The sequence number to use when publishing the next event
252 uint32_t mSeq = 1;
253 };
254
TEST_F(InputPublisherAndConsumerTest,GetChannel_ReturnsTheChannel)255 TEST_F(InputPublisherAndConsumerTest, GetChannel_ReturnsTheChannel) {
256 ASSERT_EQ(mPublisher->getChannel().getConnectionToken(),
257 mConsumer->getChannel()->getConnectionToken());
258 }
259
publishAndConsumeKeyEvent()260 void InputPublisherAndConsumerTest::publishAndConsumeKeyEvent() {
261 status_t status;
262
263 const uint32_t seq = mSeq++;
264 int32_t eventId = InputEvent::nextId();
265 constexpr int32_t deviceId = 1;
266 constexpr uint32_t source = AINPUT_SOURCE_KEYBOARD;
267 constexpr ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT;
268 constexpr std::array<uint8_t, 32> hmac = {31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21,
269 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,
270 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
271 constexpr int32_t action = AKEY_EVENT_ACTION_DOWN;
272 constexpr int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
273 constexpr int32_t keyCode = AKEYCODE_ENTER;
274 constexpr int32_t scanCode = 13;
275 constexpr int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
276 constexpr int32_t repeatCount = 1;
277 constexpr nsecs_t downTime = 3;
278 constexpr nsecs_t eventTime = 4;
279 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
280
281 status = mPublisher->publishKeyEvent(seq, eventId, deviceId, source, displayId, hmac, action,
282 flags, keyCode, scanCode, metaState, repeatCount, downTime,
283 eventTime);
284 ASSERT_EQ(OK, status)
285 << "publisher publishKeyEvent should return OK";
286
287 waitUntilInputAvailable(*mConsumer);
288 uint32_t consumeSeq;
289 InputEvent* event;
290 status = mConsumer->consume(&mEventFactory, /*consumeBatches=*/true, -1, &consumeSeq, &event);
291 ASSERT_EQ(OK, status)
292 << "consumer consume should return OK";
293 EXPECT_FALSE(mConsumer->probablyHasInput())
294 << "no events should be waiting after being consumed";
295
296 ASSERT_TRUE(event != nullptr)
297 << "consumer should have returned non-NULL event";
298 ASSERT_EQ(InputEventType::KEY, event->getType()) << "consumer should have returned a key event";
299
300 KeyEvent* keyEvent = static_cast<KeyEvent*>(event);
301 EXPECT_EQ(seq, consumeSeq);
302 EXPECT_EQ(eventId, keyEvent->getId());
303 EXPECT_EQ(deviceId, keyEvent->getDeviceId());
304 EXPECT_EQ(source, keyEvent->getSource());
305 EXPECT_EQ(displayId, keyEvent->getDisplayId());
306 EXPECT_EQ(hmac, keyEvent->getHmac());
307 EXPECT_EQ(action, keyEvent->getAction());
308 EXPECT_EQ(flags, keyEvent->getFlags());
309 EXPECT_EQ(keyCode, keyEvent->getKeyCode());
310 EXPECT_EQ(scanCode, keyEvent->getScanCode());
311 EXPECT_EQ(metaState, keyEvent->getMetaState());
312 EXPECT_EQ(repeatCount, keyEvent->getRepeatCount());
313 EXPECT_EQ(downTime, keyEvent->getDownTime());
314 EXPECT_EQ(eventTime, keyEvent->getEventTime());
315
316 status = mConsumer->sendFinishedSignal(seq, true);
317 ASSERT_EQ(OK, status)
318 << "consumer sendFinishedSignal should return OK";
319
320 Result<InputPublisher::ConsumerResponse> result = mPublisher->receiveConsumerResponse();
321 ASSERT_TRUE(result.ok()) << "receiveConsumerResponse should return OK";
322 ASSERT_TRUE(std::holds_alternative<InputPublisher::Finished>(*result));
323 const InputPublisher::Finished& finish = std::get<InputPublisher::Finished>(*result);
324 ASSERT_EQ(seq, finish.seq)
325 << "receiveConsumerResponse should have returned the original sequence number";
326 ASSERT_TRUE(finish.handled)
327 << "receiveConsumerResponse should have set handled to consumer's reply";
328 ASSERT_GE(finish.consumeTime, publishTime)
329 << "finished signal's consume time should be greater than publish time";
330 }
331
publishAndConsumeMotionStream()332 void InputPublisherAndConsumerTest::publishAndConsumeMotionStream() {
333 const nsecs_t downTime = systemTime(SYSTEM_TIME_MONOTONIC);
334
335 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_DOWN, downTime,
336 {Pointer{.id = 0, .x = 20, .y = 30}});
337
338 publishAndConsumeMotionEvent(POINTER_1_DOWN, downTime,
339 {Pointer{.id = 0, .x = 20, .y = 30},
340 Pointer{.id = 1, .x = 200, .y = 300}});
341
342 publishAndConsumeMotionEvent(POINTER_2_DOWN, downTime,
343 {Pointer{.id = 0, .x = 20, .y = 30},
344 Pointer{.id = 1, .x = 200, .y = 300},
345 Pointer{.id = 2, .x = 300, .y = 400}});
346
347 // Provide a consistent input stream - cancel the gesture that was started above
348 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_CANCEL, downTime,
349 {Pointer{.id = 0, .x = 20, .y = 30},
350 Pointer{.id = 1, .x = 200, .y = 300},
351 Pointer{.id = 2, .x = 300, .y = 400}});
352 }
353
publishAndConsumeMotionDown(nsecs_t downTime)354 void InputPublisherAndConsumerTest::publishAndConsumeMotionDown(nsecs_t downTime) {
355 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_DOWN, downTime,
356 {Pointer{.id = 0, .x = 20, .y = 30}});
357 }
358
publishAndConsumeBatchedMotionMove(nsecs_t downTime)359 void InputPublisherAndConsumerTest::publishAndConsumeBatchedMotionMove(nsecs_t downTime) {
360 uint32_t seq = mSeq++;
361 const std::vector<Pointer> pointers = {Pointer{.id = 0, .x = 20, .y = 30}};
362 PublishMotionArgs args(AMOTION_EVENT_ACTION_MOVE, downTime, pointers, seq);
363 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
364 publishMotionEvent(*mPublisher, args);
365
366 // Consume leaving a batch behind.
367 uint32_t consumeSeq;
368 InputEvent* event;
369 status_t status = mConsumer->consume(&mEventFactory,
370 /*consumeBatches=*/false, -1, &consumeSeq, &event);
371 ASSERT_EQ(WOULD_BLOCK, status)
372 << "consumer consume should return WOULD_BLOCK when a new batch is started";
373 ASSERT_TRUE(mConsumer->hasPendingBatch()) << "consume should have created a batch";
374 EXPECT_TRUE(mConsumer->probablyHasInput())
375 << "should deterministically have input because there is a batch";
376 sendAndVerifyFinishedSignal(*mConsumer, *mPublisher, seq, publishTime);
377 }
378
publishAndConsumeMotionEvent(int32_t action,nsecs_t downTime,const std::vector<Pointer> & pointers)379 void InputPublisherAndConsumerTest::publishAndConsumeMotionEvent(
380 int32_t action, nsecs_t downTime, const std::vector<Pointer>& pointers) {
381 uint32_t seq = mSeq++;
382 PublishMotionArgs args(action, downTime, pointers, seq);
383 nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
384 publishMotionEvent(*mPublisher, args);
385
386 uint32_t consumeSeq;
387 InputEvent* event;
388 status_t status =
389 mConsumer->consume(&mEventFactory, /*consumeBatches=*/true, -1, &consumeSeq, &event);
390 ASSERT_EQ(OK, status) << "consumer consume should return OK";
391 ASSERT_TRUE(event != nullptr)
392 << "consumer should have returned non-NULL event";
393 ASSERT_EQ(InputEventType::MOTION, event->getType())
394 << "consumer should have returned a motion event";
395 EXPECT_EQ(seq, consumeSeq);
396
397 verifyArgsEqualToEvent(args, static_cast<const MotionEvent&>(*event));
398 sendAndVerifyFinishedSignal(*mConsumer, *mPublisher, seq, publishTime);
399 }
400
publishAndConsumeFocusEvent()401 void InputPublisherAndConsumerTest::publishAndConsumeFocusEvent() {
402 status_t status;
403
404 constexpr uint32_t seq = 15;
405 int32_t eventId = InputEvent::nextId();
406 constexpr bool hasFocus = true;
407 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
408
409 status = mPublisher->publishFocusEvent(seq, eventId, hasFocus);
410 ASSERT_EQ(OK, status) << "publisher publishFocusEvent should return OK";
411
412 uint32_t consumeSeq;
413 InputEvent* event;
414 status = mConsumer->consume(&mEventFactory, /*consumeBatches=*/true, -1, &consumeSeq, &event);
415 ASSERT_EQ(OK, status) << "consumer consume should return OK";
416
417 ASSERT_TRUE(event != nullptr) << "consumer should have returned non-NULL event";
418 ASSERT_EQ(InputEventType::FOCUS, event->getType())
419 << "consumer should have returned a focus event";
420
421 FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
422 EXPECT_EQ(seq, consumeSeq);
423 EXPECT_EQ(eventId, focusEvent->getId());
424 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
425
426 status = mConsumer->sendFinishedSignal(seq, true);
427 ASSERT_EQ(OK, status) << "consumer sendFinishedSignal should return OK";
428
429 Result<InputPublisher::ConsumerResponse> result = mPublisher->receiveConsumerResponse();
430 ASSERT_TRUE(result.ok()) << "receiveConsumerResponse should return OK";
431 ASSERT_TRUE(std::holds_alternative<InputPublisher::Finished>(*result));
432 const InputPublisher::Finished& finish = std::get<InputPublisher::Finished>(*result);
433
434 ASSERT_EQ(seq, finish.seq)
435 << "receiveConsumerResponse should have returned the original sequence number";
436 ASSERT_TRUE(finish.handled)
437 << "receiveConsumerResponse should have set handled to consumer's reply";
438 ASSERT_GE(finish.consumeTime, publishTime)
439 << "finished signal's consume time should be greater than publish time";
440 }
441
publishAndConsumeCaptureEvent()442 void InputPublisherAndConsumerTest::publishAndConsumeCaptureEvent() {
443 status_t status;
444
445 constexpr uint32_t seq = 42;
446 int32_t eventId = InputEvent::nextId();
447 constexpr bool captureEnabled = true;
448 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
449
450 status = mPublisher->publishCaptureEvent(seq, eventId, captureEnabled);
451 ASSERT_EQ(OK, status) << "publisher publishCaptureEvent should return OK";
452
453 uint32_t consumeSeq;
454 InputEvent* event;
455 status = mConsumer->consume(&mEventFactory, /*consumeBatches=*/true, -1, &consumeSeq, &event);
456 ASSERT_EQ(OK, status) << "consumer consume should return OK";
457
458 ASSERT_TRUE(event != nullptr) << "consumer should have returned non-NULL event";
459 ASSERT_EQ(InputEventType::CAPTURE, event->getType())
460 << "consumer should have returned a capture event";
461
462 const CaptureEvent* captureEvent = static_cast<CaptureEvent*>(event);
463 EXPECT_EQ(seq, consumeSeq);
464 EXPECT_EQ(eventId, captureEvent->getId());
465 EXPECT_EQ(captureEnabled, captureEvent->getPointerCaptureEnabled());
466
467 status = mConsumer->sendFinishedSignal(seq, true);
468 ASSERT_EQ(OK, status) << "consumer sendFinishedSignal should return OK";
469
470 Result<InputPublisher::ConsumerResponse> result = mPublisher->receiveConsumerResponse();
471 ASSERT_TRUE(result.ok()) << "receiveConsumerResponse should return OK";
472 ASSERT_TRUE(std::holds_alternative<InputPublisher::Finished>(*result));
473 const InputPublisher::Finished& finish = std::get<InputPublisher::Finished>(*result);
474 ASSERT_EQ(seq, finish.seq)
475 << "receiveConsumerResponse should have returned the original sequence number";
476 ASSERT_TRUE(finish.handled)
477 << "receiveConsumerResponse should have set handled to consumer's reply";
478 ASSERT_GE(finish.consumeTime, publishTime)
479 << "finished signal's consume time should be greater than publish time";
480 }
481
publishAndConsumeDragEvent()482 void InputPublisherAndConsumerTest::publishAndConsumeDragEvent() {
483 status_t status;
484
485 constexpr uint32_t seq = 15;
486 int32_t eventId = InputEvent::nextId();
487 constexpr bool isExiting = false;
488 constexpr float x = 10;
489 constexpr float y = 15;
490 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
491
492 status = mPublisher->publishDragEvent(seq, eventId, x, y, isExiting);
493 ASSERT_EQ(OK, status) << "publisher publishDragEvent should return OK";
494
495 uint32_t consumeSeq;
496 InputEvent* event;
497 status = mConsumer->consume(&mEventFactory, /*consumeBatches=*/true, -1, &consumeSeq, &event);
498 ASSERT_EQ(OK, status) << "consumer consume should return OK";
499
500 ASSERT_TRUE(event != nullptr) << "consumer should have returned non-NULL event";
501 ASSERT_EQ(InputEventType::DRAG, event->getType())
502 << "consumer should have returned a drag event";
503
504 const DragEvent& dragEvent = static_cast<const DragEvent&>(*event);
505 EXPECT_EQ(seq, consumeSeq);
506 EXPECT_EQ(eventId, dragEvent.getId());
507 EXPECT_EQ(isExiting, dragEvent.isExiting());
508 EXPECT_EQ(x, dragEvent.getX());
509 EXPECT_EQ(y, dragEvent.getY());
510
511 status = mConsumer->sendFinishedSignal(seq, true);
512 ASSERT_EQ(OK, status) << "consumer sendFinishedSignal should return OK";
513
514 Result<InputPublisher::ConsumerResponse> result = mPublisher->receiveConsumerResponse();
515 ASSERT_TRUE(result.ok()) << "receiveConsumerResponse should return OK";
516 ASSERT_TRUE(std::holds_alternative<InputPublisher::Finished>(*result));
517 const InputPublisher::Finished& finish = std::get<InputPublisher::Finished>(*result);
518 ASSERT_EQ(seq, finish.seq)
519 << "receiveConsumerResponse should have returned the original sequence number";
520 ASSERT_TRUE(finish.handled)
521 << "receiveConsumerResponse should have set handled to consumer's reply";
522 ASSERT_GE(finish.consumeTime, publishTime)
523 << "finished signal's consume time should be greater than publish time";
524 }
525
publishAndConsumeTouchModeEvent()526 void InputPublisherAndConsumerTest::publishAndConsumeTouchModeEvent() {
527 status_t status;
528
529 constexpr uint32_t seq = 15;
530 int32_t eventId = InputEvent::nextId();
531 constexpr bool touchModeEnabled = true;
532 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
533
534 status = mPublisher->publishTouchModeEvent(seq, eventId, touchModeEnabled);
535 ASSERT_EQ(OK, status) << "publisher publishTouchModeEvent should return OK";
536
537 uint32_t consumeSeq;
538 InputEvent* event;
539 status = mConsumer->consume(&mEventFactory, /*consumeBatches=*/true, -1, &consumeSeq, &event);
540 ASSERT_EQ(OK, status) << "consumer consume should return OK";
541
542 ASSERT_TRUE(event != nullptr) << "consumer should have returned non-NULL event";
543 ASSERT_EQ(InputEventType::TOUCH_MODE, event->getType())
544 << "consumer should have returned a touch mode event";
545
546 const TouchModeEvent& touchModeEvent = static_cast<const TouchModeEvent&>(*event);
547 EXPECT_EQ(seq, consumeSeq);
548 EXPECT_EQ(eventId, touchModeEvent.getId());
549 EXPECT_EQ(touchModeEnabled, touchModeEvent.isInTouchMode());
550
551 status = mConsumer->sendFinishedSignal(seq, true);
552 ASSERT_EQ(OK, status) << "consumer sendFinishedSignal should return OK";
553
554 Result<InputPublisher::ConsumerResponse> result = mPublisher->receiveConsumerResponse();
555 ASSERT_TRUE(result.ok()) << "receiveConsumerResponse should return OK";
556 ASSERT_TRUE(std::holds_alternative<InputPublisher::Finished>(*result));
557 const InputPublisher::Finished& finish = std::get<InputPublisher::Finished>(*result);
558 ASSERT_EQ(seq, finish.seq)
559 << "receiveConsumerResponse should have returned the original sequence number";
560 ASSERT_TRUE(finish.handled)
561 << "receiveConsumerResponse should have set handled to consumer's reply";
562 ASSERT_GE(finish.consumeTime, publishTime)
563 << "finished signal's consume time should be greater than publish time";
564 }
565
TEST_F(InputPublisherAndConsumerTest,SendTimeline)566 TEST_F(InputPublisherAndConsumerTest, SendTimeline) {
567 const int32_t inputEventId = 20;
568 std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
569 graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME] = 30;
570 graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = 40;
571 status_t status = mConsumer->sendTimeline(inputEventId, graphicsTimeline);
572 ASSERT_EQ(OK, status);
573
574 Result<InputPublisher::ConsumerResponse> result = mPublisher->receiveConsumerResponse();
575 ASSERT_TRUE(result.ok()) << "receiveConsumerResponse should return OK";
576 ASSERT_TRUE(std::holds_alternative<InputPublisher::Timeline>(*result));
577 const InputPublisher::Timeline& timeline = std::get<InputPublisher::Timeline>(*result);
578 ASSERT_EQ(inputEventId, timeline.inputEventId);
579 ASSERT_EQ(graphicsTimeline, timeline.graphicsTimeline);
580 }
581
TEST_F(InputPublisherAndConsumerTest,PublishKeyEvent_EndToEnd)582 TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) {
583 ASSERT_NO_FATAL_FAILURE(publishAndConsumeKeyEvent());
584 }
585
TEST_F(InputPublisherAndConsumerTest,PublishMotionEvent_EndToEnd)586 TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_EndToEnd) {
587 ASSERT_NO_FATAL_FAILURE(publishAndConsumeMotionStream());
588 }
589
TEST_F(InputPublisherAndConsumerTest,PublishMotionMoveEvent_EndToEnd)590 TEST_F(InputPublisherAndConsumerTest, PublishMotionMoveEvent_EndToEnd) {
591 // Publish a DOWN event before MOVE to pass the InputVerifier checks.
592 const nsecs_t downTime = systemTime(SYSTEM_TIME_MONOTONIC);
593 ASSERT_NO_FATAL_FAILURE(publishAndConsumeMotionDown(downTime));
594
595 // Publish the MOVE event and check expectations.
596 ASSERT_NO_FATAL_FAILURE(publishAndConsumeBatchedMotionMove(downTime));
597 }
598
TEST_F(InputPublisherAndConsumerTest,PublishFocusEvent_EndToEnd)599 TEST_F(InputPublisherAndConsumerTest, PublishFocusEvent_EndToEnd) {
600 ASSERT_NO_FATAL_FAILURE(publishAndConsumeFocusEvent());
601 }
602
TEST_F(InputPublisherAndConsumerTest,PublishCaptureEvent_EndToEnd)603 TEST_F(InputPublisherAndConsumerTest, PublishCaptureEvent_EndToEnd) {
604 ASSERT_NO_FATAL_FAILURE(publishAndConsumeCaptureEvent());
605 }
606
TEST_F(InputPublisherAndConsumerTest,PublishDragEvent_EndToEnd)607 TEST_F(InputPublisherAndConsumerTest, PublishDragEvent_EndToEnd) {
608 ASSERT_NO_FATAL_FAILURE(publishAndConsumeDragEvent());
609 }
610
TEST_F(InputPublisherAndConsumerTest,PublishTouchModeEvent_EndToEnd)611 TEST_F(InputPublisherAndConsumerTest, PublishTouchModeEvent_EndToEnd) {
612 ASSERT_NO_FATAL_FAILURE(publishAndConsumeTouchModeEvent());
613 }
614
TEST_F(InputPublisherAndConsumerTest,PublishMotionEvent_WhenSequenceNumberIsZero_ReturnsError)615 TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenSequenceNumberIsZero_ReturnsError) {
616 status_t status;
617 const size_t pointerCount = 1;
618 PointerProperties pointerProperties[pointerCount];
619 PointerCoords pointerCoords[pointerCount];
620 for (size_t i = 0; i < pointerCount; i++) {
621 pointerProperties[i].clear();
622 pointerCoords[i].clear();
623 }
624
625 ui::Transform identityTransform;
626 status =
627 mPublisher->publishMotionEvent(0, InputEvent::nextId(), 0, 0,
628 ui::LogicalDisplayId::DEFAULT, INVALID_HMAC, 0, 0, 0, 0,
629 0, 0, MotionClassification::NONE, identityTransform, 0,
630 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
631 AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform,
632 0, 0, pointerCount, pointerProperties, pointerCoords);
633 ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE";
634 }
635
TEST_F(InputPublisherAndConsumerTest,PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError)636 TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError) {
637 status_t status;
638 const size_t pointerCount = 0;
639 PointerProperties pointerProperties[pointerCount];
640 PointerCoords pointerCoords[pointerCount];
641
642 ui::Transform identityTransform;
643 status =
644 mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0,
645 ui::LogicalDisplayId::DEFAULT, INVALID_HMAC, 0, 0, 0, 0,
646 0, 0, MotionClassification::NONE, identityTransform, 0,
647 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
648 AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform,
649 0, 0, pointerCount, pointerProperties, pointerCoords);
650 ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE";
651 }
652
TEST_F(InputPublisherAndConsumerTest,PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError)653 TEST_F(InputPublisherAndConsumerTest,
654 PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError) {
655 status_t status;
656 const size_t pointerCount = MAX_POINTERS + 1;
657 PointerProperties pointerProperties[pointerCount];
658 PointerCoords pointerCoords[pointerCount];
659 for (size_t i = 0; i < pointerCount; i++) {
660 pointerProperties[i].clear();
661 pointerCoords[i].clear();
662 }
663
664 ui::Transform identityTransform;
665 status =
666 mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0,
667 ui::LogicalDisplayId::DEFAULT, INVALID_HMAC, 0, 0, 0, 0,
668 0, 0, MotionClassification::NONE, identityTransform, 0,
669 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
670 AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform,
671 0, 0, pointerCount, pointerProperties, pointerCoords);
672 ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE";
673 }
674
TEST_F(InputPublisherAndConsumerTest,PublishMultipleEvents_EndToEnd)675 TEST_F(InputPublisherAndConsumerTest, PublishMultipleEvents_EndToEnd) {
676 const nsecs_t downTime = systemTime(SYSTEM_TIME_MONOTONIC);
677
678 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_DOWN, downTime,
679 {Pointer{.id = 0, .x = 20, .y = 30}});
680 ASSERT_NO_FATAL_FAILURE(publishAndConsumeKeyEvent());
681 publishAndConsumeMotionEvent(POINTER_1_DOWN, downTime,
682 {Pointer{.id = 0, .x = 20, .y = 30},
683 Pointer{.id = 1, .x = 200, .y = 300}});
684 ASSERT_NO_FATAL_FAILURE(publishAndConsumeFocusEvent());
685 publishAndConsumeMotionEvent(POINTER_2_DOWN, downTime,
686 {Pointer{.id = 0, .x = 20, .y = 30},
687 Pointer{.id = 1, .x = 200, .y = 300},
688 Pointer{.id = 2, .x = 200, .y = 300}});
689 ASSERT_NO_FATAL_FAILURE(publishAndConsumeKeyEvent());
690 ASSERT_NO_FATAL_FAILURE(publishAndConsumeCaptureEvent());
691 ASSERT_NO_FATAL_FAILURE(publishAndConsumeDragEvent());
692 // Provide a consistent input stream - cancel the gesture that was started above
693 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_CANCEL, downTime,
694 {Pointer{.id = 0, .x = 20, .y = 30},
695 Pointer{.id = 1, .x = 200, .y = 300},
696 Pointer{.id = 2, .x = 200, .y = 300}});
697 ASSERT_NO_FATAL_FAILURE(publishAndConsumeKeyEvent());
698 ASSERT_NO_FATAL_FAILURE(publishAndConsumeTouchModeEvent());
699 }
700
701 } // namespace android
702