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