1 /*
2 * Copyright 2024 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 <android-base/logging.h>
18 #include <attestation/HmacKeyManager.h>
19 #include <ftl/enum.h>
20 #include <gtest/gtest.h>
21 #include <input/BlockingQueue.h>
22 #include <input/InputConsumerNoResampling.h>
23 #include <input/InputTransport.h>
24
25 using android::base::Result;
26
27 namespace android {
28
29 namespace {
30
31 static constexpr float EPSILON = MotionEvent::ROUNDING_PRECISION;
32 static constexpr int32_t ACTION_MOVE = AMOTION_EVENT_ACTION_MOVE;
33 static constexpr int32_t POINTER_1_DOWN =
34 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
35 static constexpr int32_t POINTER_2_DOWN =
36 AMOTION_EVENT_ACTION_POINTER_DOWN | (2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
37
38 static auto constexpr TIMEOUT = 5s;
39
40 struct Pointer {
41 int32_t id;
42 float x;
43 float y;
44 bool isResampled = false;
45 };
46
47 // A collection of arguments to be sent as publishMotionEvent(). The saved members of this struct
48 // allow to check the expectations against the event acquired from the InputConsumerCallbacks. To
49 // help simplify expectation checking it carries members not present in MotionEvent, like
50 // |rawXScale|.
51 struct PublishMotionArgs {
52 const int32_t action;
53 const nsecs_t downTime;
54 const uint32_t seq;
55 const int32_t eventId;
56 const int32_t deviceId = 1;
57 const uint32_t source = AINPUT_SOURCE_TOUCHSCREEN;
58 const ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT;
59 const int32_t actionButton = 0;
60 const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
61 const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
62 const int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
63 const MotionClassification classification = MotionClassification::AMBIGUOUS_GESTURE;
64 const float xScale = 2;
65 const float yScale = 3;
66 const float xOffset = -10;
67 const float yOffset = -20;
68 const float rawXScale = 4;
69 const float rawYScale = -5;
70 const float rawXOffset = -11;
71 const float rawYOffset = 42;
72 const float xPrecision = 0.25;
73 const float yPrecision = 0.5;
74 const float xCursorPosition = 1.3;
75 const float yCursorPosition = 50.6;
76 std::array<uint8_t, 32> hmac;
77 int32_t flags;
78 ui::Transform transform;
79 ui::Transform rawTransform;
80 const nsecs_t eventTime;
81 size_t pointerCount;
82 std::vector<PointerProperties> pointerProperties;
83 std::vector<PointerCoords> pointerCoords;
84
85 PublishMotionArgs(int32_t action, nsecs_t downTime, const std::vector<Pointer>& pointers,
86 const uint32_t seq);
87 };
88
PublishMotionArgs(int32_t inAction,nsecs_t inDownTime,const std::vector<Pointer> & pointers,const uint32_t inSeq)89 PublishMotionArgs::PublishMotionArgs(int32_t inAction, nsecs_t inDownTime,
90 const std::vector<Pointer>& pointers, const uint32_t inSeq)
91 : action(inAction),
92 downTime(inDownTime),
93 seq(inSeq),
94 eventId(InputEvent::nextId()),
95 eventTime(systemTime(SYSTEM_TIME_MONOTONIC)) {
96 hmac = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
97 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
98
99 flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED |
100 AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
101 AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION;
102 if (action == AMOTION_EVENT_ACTION_CANCEL) {
103 flags |= AMOTION_EVENT_FLAG_CANCELED;
104 }
105 pointerCount = pointers.size();
106 for (size_t i = 0; i < pointerCount; i++) {
107 pointerProperties.push_back({});
108 pointerProperties[i].clear();
109 pointerProperties[i].id = pointers[i].id;
110 pointerProperties[i].toolType = ToolType::FINGER;
111
112 pointerCoords.push_back({});
113 pointerCoords[i].clear();
114 pointerCoords[i].isResampled = pointers[i].isResampled;
115 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, pointers[i].x);
116 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, pointers[i].y);
117 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i);
118 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i);
119 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i);
120 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i);
121 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i);
122 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i);
123 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
124 }
125 transform.set({xScale, 0, xOffset, 0, yScale, yOffset, 0, 0, 1});
126 rawTransform.set({rawXScale, 0, rawXOffset, 0, rawYScale, rawYOffset, 0, 0, 1});
127 }
128
129 // Checks expectations against |motionEvent| acquired from an InputConsumer. Floating point
130 // comparisons limit precision to EPSILON.
verifyArgsEqualToEvent(const PublishMotionArgs & args,const MotionEvent & motionEvent)131 void verifyArgsEqualToEvent(const PublishMotionArgs& args, const MotionEvent& motionEvent) {
132 EXPECT_EQ(args.eventId, motionEvent.getId());
133 EXPECT_EQ(args.deviceId, motionEvent.getDeviceId());
134 EXPECT_EQ(args.source, motionEvent.getSource());
135 EXPECT_EQ(args.displayId, motionEvent.getDisplayId());
136 EXPECT_EQ(args.hmac, motionEvent.getHmac());
137 EXPECT_EQ(args.action, motionEvent.getAction());
138 EXPECT_EQ(args.downTime, motionEvent.getDownTime());
139 EXPECT_EQ(args.flags, motionEvent.getFlags());
140 EXPECT_EQ(args.edgeFlags, motionEvent.getEdgeFlags());
141 EXPECT_EQ(args.metaState, motionEvent.getMetaState());
142 EXPECT_EQ(args.buttonState, motionEvent.getButtonState());
143 EXPECT_EQ(args.classification, motionEvent.getClassification());
144 EXPECT_EQ(args.transform, motionEvent.getTransform());
145 EXPECT_NEAR((-args.rawXOffset / args.rawXScale) * args.xScale + args.xOffset,
146 motionEvent.getRawXOffset(), EPSILON);
147 EXPECT_NEAR((-args.rawYOffset / args.rawYScale) * args.yScale + args.yOffset,
148 motionEvent.getRawYOffset(), EPSILON);
149 EXPECT_EQ(args.xPrecision, motionEvent.getXPrecision());
150 EXPECT_EQ(args.yPrecision, motionEvent.getYPrecision());
151 EXPECT_NEAR(args.xCursorPosition, motionEvent.getRawXCursorPosition(), EPSILON);
152 EXPECT_NEAR(args.yCursorPosition, motionEvent.getRawYCursorPosition(), EPSILON);
153 EXPECT_NEAR(args.xCursorPosition * args.xScale + args.xOffset, motionEvent.getXCursorPosition(),
154 EPSILON);
155 EXPECT_NEAR(args.yCursorPosition * args.yScale + args.yOffset, motionEvent.getYCursorPosition(),
156 EPSILON);
157 EXPECT_EQ(args.rawTransform, motionEvent.getRawTransform());
158 EXPECT_EQ(args.eventTime, motionEvent.getEventTime());
159 EXPECT_EQ(args.pointerCount, motionEvent.getPointerCount());
160 EXPECT_EQ(0U, motionEvent.getHistorySize());
161
162 for (size_t i = 0; i < args.pointerCount; i++) {
163 SCOPED_TRACE(i);
164 EXPECT_EQ(args.pointerProperties[i].id, motionEvent.getPointerId(i));
165 EXPECT_EQ(args.pointerProperties[i].toolType, motionEvent.getToolType(i));
166
167 const auto& pc = args.pointerCoords[i];
168 EXPECT_EQ(pc, motionEvent.getSamplePointerCoords()[i]);
169
170 EXPECT_NEAR(pc.getX() * args.rawXScale + args.rawXOffset, motionEvent.getRawX(i), EPSILON);
171 EXPECT_NEAR(pc.getY() * args.rawYScale + args.rawYOffset, motionEvent.getRawY(i), EPSILON);
172 EXPECT_NEAR(pc.getX() * args.xScale + args.xOffset, motionEvent.getX(i), EPSILON);
173 EXPECT_NEAR(pc.getY() * args.yScale + args.yOffset, motionEvent.getY(i), EPSILON);
174 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), motionEvent.getPressure(i));
175 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_SIZE), motionEvent.getSize(i));
176 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), motionEvent.getTouchMajor(i));
177 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), motionEvent.getTouchMinor(i));
178 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), motionEvent.getToolMajor(i));
179 EXPECT_EQ(pc.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), motionEvent.getToolMinor(i));
180
181 // Calculate the orientation after scaling, keeping in mind that an orientation of 0 is
182 // "up", and the positive y direction is "down".
183 const float unscaledOrientation = pc.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
184 const float x = sinf(unscaledOrientation) * args.xScale;
185 const float y = -cosf(unscaledOrientation) * args.yScale;
186 EXPECT_EQ(atan2f(x, -y), motionEvent.getOrientation(i));
187 }
188 }
189
publishMotionEvent(InputPublisher & publisher,const PublishMotionArgs & a)190 void publishMotionEvent(InputPublisher& publisher, const PublishMotionArgs& a) {
191 status_t status =
192 publisher.publishMotionEvent(a.seq, a.eventId, a.deviceId, a.source, a.displayId,
193 a.hmac, a.action, a.actionButton, a.flags, a.edgeFlags,
194 a.metaState, a.buttonState, a.classification, a.transform,
195 a.xPrecision, a.yPrecision, a.xCursorPosition,
196 a.yCursorPosition, a.rawTransform, a.downTime, a.eventTime,
197 a.pointerCount, a.pointerProperties.data(),
198 a.pointerCoords.data());
199 ASSERT_EQ(OK, status) << "publisher publishMotionEvent should return OK";
200 }
201
receiveConsumerResponse(InputPublisher & publisher,std::chrono::milliseconds timeout)202 Result<InputPublisher::ConsumerResponse> receiveConsumerResponse(
203 InputPublisher& publisher, std::chrono::milliseconds timeout) {
204 const std::chrono::time_point start = std::chrono::steady_clock::now();
205
206 while (true) {
207 Result<InputPublisher::ConsumerResponse> result = publisher.receiveConsumerResponse();
208 if (result.ok()) {
209 return result;
210 }
211 const std::chrono::duration waited = std::chrono::steady_clock::now() - start;
212 if (waited > timeout) {
213 return result;
214 }
215 }
216 }
217
verifyFinishedSignal(InputPublisher & publisher,uint32_t seq,nsecs_t publishTime)218 void verifyFinishedSignal(InputPublisher& publisher, uint32_t seq, nsecs_t publishTime) {
219 Result<InputPublisher::ConsumerResponse> result = receiveConsumerResponse(publisher, TIMEOUT);
220 ASSERT_TRUE(result.ok()) << "receiveConsumerResponse returned " << result.error().message();
221 ASSERT_TRUE(std::holds_alternative<InputPublisher::Finished>(*result));
222 const InputPublisher::Finished& finish = std::get<InputPublisher::Finished>(*result);
223 ASSERT_EQ(seq, finish.seq)
224 << "receiveConsumerResponse should have returned the original sequence number";
225 ASSERT_TRUE(finish.handled)
226 << "receiveConsumerResponse should have set handled to consumer's reply";
227 ASSERT_GE(finish.consumeTime, publishTime)
228 << "finished signal's consume time should be greater than publish time";
229 }
230
231 } // namespace
232
233 class InputConsumerMessageHandler : public MessageHandler {
234 public:
InputConsumerMessageHandler(std::function<void (const Message &)> function)235 InputConsumerMessageHandler(std::function<void(const Message&)> function)
236 : mFunction(function) {}
237
238 private:
handleMessage(const Message & message)239 void handleMessage(const Message& message) override { mFunction(message); }
240
241 std::function<void(const Message&)> mFunction;
242 };
243
244 class InputPublisherAndConsumerNoResamplingTest : public testing::Test,
245 public InputConsumerCallbacks {
246 protected:
247 std::unique_ptr<InputChannel> mClientChannel;
248 std::unique_ptr<InputPublisher> mPublisher;
249 std::unique_ptr<InputConsumerNoResampling> mConsumer;
250
251 std::thread mLooperThread;
252 sp<Looper> mLooper = sp<Looper>::make(/*allowNonCallbacks=*/false);
253
254 // LOOPER CONTROL
255 // Set to false when you want the looper to exit
256 std::atomic<bool> mExitLooper = false;
257 std::mutex mLock;
258
259 // Used by test to notify looper that the value of "mLooperMayProceed" has changed
260 std::condition_variable mNotifyLooperMayProceed;
GUARDED_BY(mLock)261 bool mLooperMayProceed GUARDED_BY(mLock){true};
262 // Used by looper to notify the test that it's about to block on "mLooperMayProceed" -> true
263 std::condition_variable mNotifyLooperWaiting;
GUARDED_BY(mLock)264 bool mLooperIsBlocked GUARDED_BY(mLock){false};
265
266 std::condition_variable mNotifyConsumerDestroyed;
GUARDED_BY(mLock)267 bool mConsumerDestroyed GUARDED_BY(mLock){false};
268
runLooper()269 void runLooper() {
270 static constexpr int LOOP_INDEFINITELY = -1;
271 Looper::setForThread(mLooper);
272 // Loop forever -- this thread is dedicated to servicing the looper callbacks.
273 while (!mExitLooper) {
274 mLooper->pollOnce(/*timeoutMillis=*/LOOP_INDEFINITELY);
275 }
276 }
277
SetUp()278 void SetUp() override {
279 std::unique_ptr<InputChannel> serverChannel;
280 status_t result =
281 InputChannel::openInputChannelPair("channel name", serverChannel, mClientChannel);
282 ASSERT_EQ(OK, result);
283
284 mPublisher = std::make_unique<InputPublisher>(std::move(serverChannel));
285 mMessageHandler = sp<InputConsumerMessageHandler>::make(
286 [this](const Message& message) { handleMessage(message); });
287 mLooperThread = std::thread([this] { runLooper(); });
288 sendMessage(LooperMessage::CREATE_CONSUMER);
289 }
290
291 void publishAndConsumeKeyEvent();
292 void publishAndConsumeMotionStream();
293 void publishAndConsumeMotionDown(nsecs_t downTime);
294 void publishAndConsumeBatchedMotionMove(nsecs_t downTime);
295 void publishAndConsumeFocusEvent();
296 void publishAndConsumeCaptureEvent();
297 void publishAndConsumeDragEvent();
298 void publishAndConsumeTouchModeEvent();
299 void publishAndConsumeMotionEvent(int32_t action, nsecs_t downTime,
300 const std::vector<Pointer>& pointers);
TearDown()301 void TearDown() override {
302 // Destroy the consumer, flushing any of the pending ack's.
303 sendMessage(LooperMessage::DESTROY_CONSUMER);
304 {
305 std::unique_lock lock(mLock);
306 base::ScopedLockAssertion assumeLocked(mLock);
307 mNotifyConsumerDestroyed.wait(lock, [this] { return mConsumerDestroyed; });
308 }
309 // Stop the looper thread so that we can destroy the object.
310 mExitLooper = true;
311 mLooper->wake();
312 mLooperThread.join();
313 }
314
315 protected:
316 // Interaction with the looper thread
317 enum class LooperMessage : int {
318 CALL_PROBABLY_HAS_INPUT,
319 CREATE_CONSUMER,
320 DESTROY_CONSUMER,
321 CALL_REPORT_TIMELINE,
322 BLOCK_LOOPER,
323 };
324 void sendMessage(LooperMessage message);
325 struct ReportTimelineArgs {
326 int32_t inputEventId;
327 nsecs_t gpuCompletedTime;
328 nsecs_t presentTime;
329 };
330 // The input to the function "InputConsumer::reportTimeline". Populated on the test thread and
331 // accessed on the looper thread.
332 BlockingQueue<ReportTimelineArgs> mReportTimelineArgs;
333 // The output of calling "InputConsumer::probablyHasInput()". Populated on the looper thread and
334 // accessed on the test thread.
335 BlockingQueue<bool> mProbablyHasInputResponses;
336
337 private:
338 sp<MessageHandler> mMessageHandler;
339 void handleMessage(const Message& message);
340
341 static auto constexpr NO_EVENT_TIMEOUT = 10ms;
342 // The sequence number to use when publishing the next event
343 uint32_t mSeq = 1;
344
345 BlockingQueue<std::unique_ptr<KeyEvent>> mKeyEvents;
346 BlockingQueue<std::unique_ptr<MotionEvent>> mMotionEvents;
347 BlockingQueue<std::unique_ptr<FocusEvent>> mFocusEvents;
348 BlockingQueue<std::unique_ptr<CaptureEvent>> mCaptureEvents;
349 BlockingQueue<std::unique_ptr<DragEvent>> mDragEvents;
350 BlockingQueue<std::unique_ptr<TouchModeEvent>> mTouchModeEvents;
351
352 // InputConsumerCallbacks interface
onKeyEvent(std::unique_ptr<KeyEvent> event,uint32_t seq)353 void onKeyEvent(std::unique_ptr<KeyEvent> event, uint32_t seq) override {
354 mKeyEvents.push(std::move(event));
355 mConsumer->finishInputEvent(seq, true);
356 }
onMotionEvent(std::unique_ptr<MotionEvent> event,uint32_t seq)357 void onMotionEvent(std::unique_ptr<MotionEvent> event, uint32_t seq) override {
358 mMotionEvents.push(std::move(event));
359 mConsumer->finishInputEvent(seq, true);
360 }
onBatchedInputEventPending(int32_t pendingBatchSource)361 void onBatchedInputEventPending(int32_t pendingBatchSource) override {
362 if (!mConsumer->probablyHasInput()) {
363 ADD_FAILURE() << "should deterministically have input because there is a batch";
364 }
365 mConsumer->consumeBatchedInputEvents(std::nullopt);
366 };
onFocusEvent(std::unique_ptr<FocusEvent> event,uint32_t seq)367 void onFocusEvent(std::unique_ptr<FocusEvent> event, uint32_t seq) override {
368 mFocusEvents.push(std::move(event));
369 mConsumer->finishInputEvent(seq, true);
370 };
onCaptureEvent(std::unique_ptr<CaptureEvent> event,uint32_t seq)371 void onCaptureEvent(std::unique_ptr<CaptureEvent> event, uint32_t seq) override {
372 mCaptureEvents.push(std::move(event));
373 mConsumer->finishInputEvent(seq, true);
374 };
onDragEvent(std::unique_ptr<DragEvent> event,uint32_t seq)375 void onDragEvent(std::unique_ptr<DragEvent> event, uint32_t seq) override {
376 mDragEvents.push(std::move(event));
377 mConsumer->finishInputEvent(seq, true);
378 }
onTouchModeEvent(std::unique_ptr<TouchModeEvent> event,uint32_t seq)379 void onTouchModeEvent(std::unique_ptr<TouchModeEvent> event, uint32_t seq) override {
380 mTouchModeEvents.push(std::move(event));
381 mConsumer->finishInputEvent(seq, true);
382 };
383 };
384
sendMessage(LooperMessage message)385 void InputPublisherAndConsumerNoResamplingTest::sendMessage(LooperMessage message) {
386 Message msg{ftl::to_underlying(message)};
387 mLooper->sendMessage(mMessageHandler, msg);
388 }
389
handleMessage(const Message & message)390 void InputPublisherAndConsumerNoResamplingTest::handleMessage(const Message& message) {
391 switch (static_cast<LooperMessage>(message.what)) {
392 case LooperMessage::CALL_PROBABLY_HAS_INPUT: {
393 mProbablyHasInputResponses.push(mConsumer->probablyHasInput());
394 break;
395 }
396 case LooperMessage::CREATE_CONSUMER: {
397 mConsumer = std::make_unique<InputConsumerNoResampling>(std::move(mClientChannel),
398 mLooper, *this);
399 break;
400 }
401 case LooperMessage::DESTROY_CONSUMER: {
402 mConsumer = nullptr;
403 {
404 std::unique_lock lock(mLock);
405 mConsumerDestroyed = true;
406 }
407 mNotifyConsumerDestroyed.notify_all();
408 break;
409 }
410 case LooperMessage::CALL_REPORT_TIMELINE: {
411 std::optional<ReportTimelineArgs> args = mReportTimelineArgs.pop();
412 if (!args.has_value()) {
413 ADD_FAILURE() << "Couldn't get the 'reportTimeline' args in time";
414 return;
415 }
416 mConsumer->reportTimeline(args->inputEventId, args->gpuCompletedTime,
417 args->presentTime);
418 break;
419 }
420 case LooperMessage::BLOCK_LOOPER: {
421 {
422 std::unique_lock lock(mLock);
423 mLooperIsBlocked = true;
424 }
425 mNotifyLooperWaiting.notify_all();
426
427 {
428 std::unique_lock lock(mLock);
429 base::ScopedLockAssertion assumeLocked(mLock);
430 mNotifyLooperMayProceed.wait(lock, [this] { return mLooperMayProceed; });
431 }
432
433 {
434 std::unique_lock lock(mLock);
435 mLooperIsBlocked = false;
436 }
437 mNotifyLooperWaiting.notify_all();
438 break;
439 }
440 }
441 }
442
publishAndConsumeKeyEvent()443 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeKeyEvent() {
444 status_t status;
445
446 const uint32_t seq = mSeq++;
447 int32_t eventId = InputEvent::nextId();
448 constexpr int32_t deviceId = 1;
449 constexpr uint32_t source = AINPUT_SOURCE_KEYBOARD;
450 constexpr ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT;
451 constexpr std::array<uint8_t, 32> hmac = {31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21,
452 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,
453 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
454 constexpr int32_t action = AKEY_EVENT_ACTION_DOWN;
455 constexpr int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
456 constexpr int32_t keyCode = AKEYCODE_ENTER;
457 constexpr int32_t scanCode = 13;
458 constexpr int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
459 constexpr int32_t repeatCount = 1;
460 constexpr nsecs_t downTime = 3;
461 constexpr nsecs_t eventTime = 4;
462 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
463
464 status = mPublisher->publishKeyEvent(seq, eventId, deviceId, source, displayId, hmac, action,
465 flags, keyCode, scanCode, metaState, repeatCount, downTime,
466 eventTime);
467 ASSERT_EQ(OK, status) << "publisher publishKeyEvent should return OK";
468
469 std::optional<std::unique_ptr<KeyEvent>> optKeyEvent = mKeyEvents.popWithTimeout(TIMEOUT);
470 ASSERT_TRUE(optKeyEvent.has_value()) << "consumer should have returned non-NULL event";
471 std::unique_ptr<KeyEvent> keyEvent = std::move(*optKeyEvent);
472
473 sendMessage(LooperMessage::CALL_PROBABLY_HAS_INPUT);
474 std::optional<bool> probablyHasInput = mProbablyHasInputResponses.popWithTimeout(TIMEOUT);
475 ASSERT_TRUE(probablyHasInput.has_value());
476 ASSERT_FALSE(probablyHasInput.value()) << "no events should be waiting after being consumed";
477
478 EXPECT_EQ(eventId, keyEvent->getId());
479 EXPECT_EQ(deviceId, keyEvent->getDeviceId());
480 EXPECT_EQ(source, keyEvent->getSource());
481 EXPECT_EQ(displayId, keyEvent->getDisplayId());
482 EXPECT_EQ(hmac, keyEvent->getHmac());
483 EXPECT_EQ(action, keyEvent->getAction());
484 EXPECT_EQ(flags, keyEvent->getFlags());
485 EXPECT_EQ(keyCode, keyEvent->getKeyCode());
486 EXPECT_EQ(scanCode, keyEvent->getScanCode());
487 EXPECT_EQ(metaState, keyEvent->getMetaState());
488 EXPECT_EQ(repeatCount, keyEvent->getRepeatCount());
489 EXPECT_EQ(downTime, keyEvent->getDownTime());
490 EXPECT_EQ(eventTime, keyEvent->getEventTime());
491
492 verifyFinishedSignal(*mPublisher, seq, publishTime);
493 }
494
publishAndConsumeMotionStream()495 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeMotionStream() {
496 const nsecs_t downTime = systemTime(SYSTEM_TIME_MONOTONIC);
497
498 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_DOWN, downTime,
499 {Pointer{.id = 0, .x = 20, .y = 30}});
500
501 publishAndConsumeMotionEvent(POINTER_1_DOWN, downTime,
502 {Pointer{.id = 0, .x = 20, .y = 30},
503 Pointer{.id = 1, .x = 200, .y = 300}});
504
505 publishAndConsumeMotionEvent(POINTER_2_DOWN, downTime,
506 {Pointer{.id = 0, .x = 20, .y = 30},
507 Pointer{.id = 1, .x = 200, .y = 300},
508 Pointer{.id = 2, .x = 300, .y = 400}});
509
510 // Provide a consistent input stream - cancel the gesture that was started above
511 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_CANCEL, downTime,
512 {Pointer{.id = 0, .x = 20, .y = 30},
513 Pointer{.id = 1, .x = 200, .y = 300},
514 Pointer{.id = 2, .x = 300, .y = 400}});
515 }
516
publishAndConsumeMotionDown(nsecs_t downTime)517 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeMotionDown(nsecs_t downTime) {
518 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_DOWN, downTime,
519 {Pointer{.id = 0, .x = 20, .y = 30}});
520 }
521
publishAndConsumeBatchedMotionMove(nsecs_t downTime)522 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeBatchedMotionMove(
523 nsecs_t downTime) {
524 uint32_t seq = mSeq++;
525 const std::vector<Pointer> pointers = {Pointer{.id = 0, .x = 20, .y = 30}};
526 PublishMotionArgs args(AMOTION_EVENT_ACTION_MOVE, downTime, pointers, seq);
527 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
528
529 // Block the looper thread, preventing it from being able to service any of the fd callbacks.
530
531 {
532 std::scoped_lock lock(mLock);
533 mLooperMayProceed = false;
534 }
535 sendMessage(LooperMessage::BLOCK_LOOPER);
536 {
537 std::unique_lock lock(mLock);
538 mNotifyLooperWaiting.wait(lock, [this] { return mLooperIsBlocked; });
539 }
540
541 publishMotionEvent(*mPublisher, args);
542
543 // Ensure no event arrives because the UI thread is blocked
544 std::optional<std::unique_ptr<MotionEvent>> noEvent =
545 mMotionEvents.popWithTimeout(NO_EVENT_TIMEOUT);
546 ASSERT_FALSE(noEvent.has_value()) << "Got unexpected event: " << *noEvent;
547
548 Result<InputPublisher::ConsumerResponse> result = mPublisher->receiveConsumerResponse();
549 ASSERT_FALSE(result.ok());
550 ASSERT_EQ(WOULD_BLOCK, result.error().code());
551
552 // We shouldn't be calling mConsumer on the UI thread, but in this situation, the looper
553 // thread is locked, so this should be safe to do.
554 ASSERT_TRUE(mConsumer->probablyHasInput())
555 << "should deterministically have input because there is a batch";
556
557 // Now, unblock the looper thread, so that the event can arrive.
558 {
559 std::scoped_lock lock(mLock);
560 mLooperMayProceed = true;
561 }
562 mNotifyLooperMayProceed.notify_all();
563
564 std::optional<std::unique_ptr<MotionEvent>> optMotion = mMotionEvents.popWithTimeout(TIMEOUT);
565 ASSERT_TRUE(optMotion.has_value());
566 std::unique_ptr<MotionEvent> motion = std::move(*optMotion);
567 ASSERT_EQ(ACTION_MOVE, motion->getAction());
568
569 verifyFinishedSignal(*mPublisher, seq, publishTime);
570 }
571
publishAndConsumeMotionEvent(int32_t action,nsecs_t downTime,const std::vector<Pointer> & pointers)572 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeMotionEvent(
573 int32_t action, nsecs_t downTime, const std::vector<Pointer>& pointers) {
574 uint32_t seq = mSeq++;
575 PublishMotionArgs args(action, downTime, pointers, seq);
576 nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
577 publishMotionEvent(*mPublisher, args);
578
579 std::optional<std::unique_ptr<MotionEvent>> optMotion = mMotionEvents.popWithTimeout(TIMEOUT);
580 ASSERT_TRUE(optMotion.has_value());
581 std::unique_ptr<MotionEvent> event = std::move(*optMotion);
582
583 verifyArgsEqualToEvent(args, *event);
584
585 verifyFinishedSignal(*mPublisher, seq, publishTime);
586 }
587
publishAndConsumeFocusEvent()588 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeFocusEvent() {
589 status_t status;
590
591 constexpr uint32_t seq = 15;
592 int32_t eventId = InputEvent::nextId();
593 constexpr bool hasFocus = true;
594 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
595
596 status = mPublisher->publishFocusEvent(seq, eventId, hasFocus);
597 ASSERT_EQ(OK, status) << "publisher publishFocusEvent should return OK";
598
599 std::optional<std::unique_ptr<FocusEvent>> optFocusEvent = mFocusEvents.popWithTimeout(TIMEOUT);
600 ASSERT_TRUE(optFocusEvent.has_value()) << "consumer should have returned non-NULL event";
601 std::unique_ptr<FocusEvent> focusEvent = std::move(*optFocusEvent);
602 EXPECT_EQ(eventId, focusEvent->getId());
603 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
604
605 verifyFinishedSignal(*mPublisher, seq, publishTime);
606 }
607
publishAndConsumeCaptureEvent()608 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeCaptureEvent() {
609 status_t status;
610
611 constexpr uint32_t seq = 42;
612 int32_t eventId = InputEvent::nextId();
613 constexpr bool captureEnabled = true;
614 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
615
616 status = mPublisher->publishCaptureEvent(seq, eventId, captureEnabled);
617 ASSERT_EQ(OK, status) << "publisher publishCaptureEvent should return OK";
618
619 std::optional<std::unique_ptr<CaptureEvent>> optEvent = mCaptureEvents.popWithTimeout(TIMEOUT);
620 ASSERT_TRUE(optEvent.has_value()) << "consumer should have returned non-NULL event";
621 std::unique_ptr<CaptureEvent> event = std::move(*optEvent);
622
623 const CaptureEvent& captureEvent = *event;
624 EXPECT_EQ(eventId, captureEvent.getId());
625 EXPECT_EQ(captureEnabled, captureEvent.getPointerCaptureEnabled());
626
627 verifyFinishedSignal(*mPublisher, seq, publishTime);
628 }
629
publishAndConsumeDragEvent()630 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeDragEvent() {
631 status_t status;
632
633 constexpr uint32_t seq = 15;
634 int32_t eventId = InputEvent::nextId();
635 constexpr bool isExiting = false;
636 constexpr float x = 10;
637 constexpr float y = 15;
638 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
639
640 status = mPublisher->publishDragEvent(seq, eventId, x, y, isExiting);
641 ASSERT_EQ(OK, status) << "publisher publishDragEvent should return OK";
642
643 std::optional<std::unique_ptr<DragEvent>> optEvent = mDragEvents.popWithTimeout(TIMEOUT);
644 ASSERT_TRUE(optEvent.has_value()) << "consumer should have returned non-NULL event";
645 std::unique_ptr<DragEvent> event = std::move(*optEvent);
646
647 const DragEvent& dragEvent = *event;
648 EXPECT_EQ(eventId, dragEvent.getId());
649 EXPECT_EQ(isExiting, dragEvent.isExiting());
650 EXPECT_EQ(x, dragEvent.getX());
651 EXPECT_EQ(y, dragEvent.getY());
652
653 verifyFinishedSignal(*mPublisher, seq, publishTime);
654 }
655
publishAndConsumeTouchModeEvent()656 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeTouchModeEvent() {
657 status_t status;
658
659 constexpr uint32_t seq = 15;
660 int32_t eventId = InputEvent::nextId();
661 constexpr bool touchModeEnabled = true;
662 const nsecs_t publishTime = systemTime(SYSTEM_TIME_MONOTONIC);
663
664 status = mPublisher->publishTouchModeEvent(seq, eventId, touchModeEnabled);
665 ASSERT_EQ(OK, status) << "publisher publishTouchModeEvent should return OK";
666
667 std::optional<std::unique_ptr<TouchModeEvent>> optEvent =
668 mTouchModeEvents.popWithTimeout(TIMEOUT);
669 ASSERT_TRUE(optEvent.has_value());
670 std::unique_ptr<TouchModeEvent> event = std::move(*optEvent);
671
672 const TouchModeEvent& touchModeEvent = *event;
673 EXPECT_EQ(eventId, touchModeEvent.getId());
674 EXPECT_EQ(touchModeEnabled, touchModeEvent.isInTouchMode());
675
676 verifyFinishedSignal(*mPublisher, seq, publishTime);
677 }
678
TEST_F(InputPublisherAndConsumerNoResamplingTest,SendTimeline)679 TEST_F(InputPublisherAndConsumerNoResamplingTest, SendTimeline) {
680 const int32_t inputEventId = 20;
681 const nsecs_t gpuCompletedTime = 30;
682 const nsecs_t presentTime = 40;
683
684 mReportTimelineArgs.emplace(inputEventId, gpuCompletedTime, presentTime);
685 sendMessage(LooperMessage::CALL_REPORT_TIMELINE);
686
687 Result<InputPublisher::ConsumerResponse> result = receiveConsumerResponse(*mPublisher, TIMEOUT);
688 ASSERT_TRUE(result.ok()) << "receiveConsumerResponse should return OK";
689 ASSERT_TRUE(std::holds_alternative<InputPublisher::Timeline>(*result));
690 const InputPublisher::Timeline& timeline = std::get<InputPublisher::Timeline>(*result);
691 ASSERT_EQ(inputEventId, timeline.inputEventId);
692 ASSERT_EQ(gpuCompletedTime, timeline.graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME]);
693 ASSERT_EQ(presentTime, timeline.graphicsTimeline[GraphicsTimeline::PRESENT_TIME]);
694 }
695
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishKeyEvent_EndToEnd)696 TEST_F(InputPublisherAndConsumerNoResamplingTest, PublishKeyEvent_EndToEnd) {
697 ASSERT_NO_FATAL_FAILURE(publishAndConsumeKeyEvent());
698 }
699
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishMotionEvent_EndToEnd)700 TEST_F(InputPublisherAndConsumerNoResamplingTest, PublishMotionEvent_EndToEnd) {
701 ASSERT_NO_FATAL_FAILURE(publishAndConsumeMotionStream());
702 }
703
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishMotionMoveEvent_EndToEnd)704 TEST_F(InputPublisherAndConsumerNoResamplingTest, PublishMotionMoveEvent_EndToEnd) {
705 // Publish a DOWN event before MOVE to pass the InputVerifier checks.
706 const nsecs_t downTime = systemTime(SYSTEM_TIME_MONOTONIC);
707 ASSERT_NO_FATAL_FAILURE(publishAndConsumeMotionDown(downTime));
708
709 // Publish the MOVE event and check expectations.
710 ASSERT_NO_FATAL_FAILURE(publishAndConsumeBatchedMotionMove(downTime));
711 }
712
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishFocusEvent_EndToEnd)713 TEST_F(InputPublisherAndConsumerNoResamplingTest, PublishFocusEvent_EndToEnd) {
714 ASSERT_NO_FATAL_FAILURE(publishAndConsumeFocusEvent());
715 }
716
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishCaptureEvent_EndToEnd)717 TEST_F(InputPublisherAndConsumerNoResamplingTest, PublishCaptureEvent_EndToEnd) {
718 ASSERT_NO_FATAL_FAILURE(publishAndConsumeCaptureEvent());
719 }
720
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishDragEvent_EndToEnd)721 TEST_F(InputPublisherAndConsumerNoResamplingTest, PublishDragEvent_EndToEnd) {
722 ASSERT_NO_FATAL_FAILURE(publishAndConsumeDragEvent());
723 }
724
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishTouchModeEvent_EndToEnd)725 TEST_F(InputPublisherAndConsumerNoResamplingTest, PublishTouchModeEvent_EndToEnd) {
726 ASSERT_NO_FATAL_FAILURE(publishAndConsumeTouchModeEvent());
727 }
728
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishMotionEvent_WhenSequenceNumberIsZero_ReturnsError)729 TEST_F(InputPublisherAndConsumerNoResamplingTest,
730 PublishMotionEvent_WhenSequenceNumberIsZero_ReturnsError) {
731 status_t status;
732 const size_t pointerCount = 1;
733 PointerProperties pointerProperties[pointerCount];
734 PointerCoords pointerCoords[pointerCount];
735 for (size_t i = 0; i < pointerCount; i++) {
736 pointerProperties[i].clear();
737 pointerCoords[i].clear();
738 }
739
740 ui::Transform identityTransform;
741 status =
742 mPublisher->publishMotionEvent(0, InputEvent::nextId(), 0, 0,
743 ui::LogicalDisplayId::DEFAULT, INVALID_HMAC, 0, 0, 0, 0,
744 0, 0, MotionClassification::NONE, identityTransform, 0,
745 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
746 AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform,
747 0, 0, pointerCount, pointerProperties, pointerCoords);
748 ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE";
749 }
750
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError)751 TEST_F(InputPublisherAndConsumerNoResamplingTest,
752 PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError) {
753 status_t status;
754 const size_t pointerCount = 0;
755 PointerProperties pointerProperties[pointerCount];
756 PointerCoords pointerCoords[pointerCount];
757
758 ui::Transform identityTransform;
759 status =
760 mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0,
761 ui::LogicalDisplayId::DEFAULT, INVALID_HMAC, 0, 0, 0, 0,
762 0, 0, MotionClassification::NONE, identityTransform, 0,
763 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
764 AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform,
765 0, 0, pointerCount, pointerProperties, pointerCoords);
766 ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE";
767 }
768
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError)769 TEST_F(InputPublisherAndConsumerNoResamplingTest,
770 PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError) {
771 status_t status;
772 const size_t pointerCount = MAX_POINTERS + 1;
773 PointerProperties pointerProperties[pointerCount];
774 PointerCoords pointerCoords[pointerCount];
775 for (size_t i = 0; i < pointerCount; i++) {
776 pointerProperties[i].clear();
777 pointerCoords[i].clear();
778 }
779
780 ui::Transform identityTransform;
781 status =
782 mPublisher->publishMotionEvent(1, InputEvent::nextId(), 0, 0,
783 ui::LogicalDisplayId::DEFAULT, INVALID_HMAC, 0, 0, 0, 0,
784 0, 0, MotionClassification::NONE, identityTransform, 0,
785 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
786 AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform,
787 0, 0, pointerCount, pointerProperties, pointerCoords);
788 ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE";
789 }
790
TEST_F(InputPublisherAndConsumerNoResamplingTest,PublishMultipleEvents_EndToEnd)791 TEST_F(InputPublisherAndConsumerNoResamplingTest, PublishMultipleEvents_EndToEnd) {
792 const nsecs_t downTime = systemTime(SYSTEM_TIME_MONOTONIC);
793
794 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_DOWN, downTime,
795 {Pointer{.id = 0, .x = 20, .y = 30}});
796 ASSERT_NO_FATAL_FAILURE(publishAndConsumeKeyEvent());
797 publishAndConsumeMotionEvent(POINTER_1_DOWN, downTime,
798 {Pointer{.id = 0, .x = 20, .y = 30},
799 Pointer{.id = 1, .x = 200, .y = 300}});
800 ASSERT_NO_FATAL_FAILURE(publishAndConsumeFocusEvent());
801 publishAndConsumeMotionEvent(POINTER_2_DOWN, downTime,
802 {Pointer{.id = 0, .x = 20, .y = 30},
803 Pointer{.id = 1, .x = 200, .y = 300},
804 Pointer{.id = 2, .x = 200, .y = 300}});
805 ASSERT_NO_FATAL_FAILURE(publishAndConsumeKeyEvent());
806 ASSERT_NO_FATAL_FAILURE(publishAndConsumeCaptureEvent());
807 ASSERT_NO_FATAL_FAILURE(publishAndConsumeDragEvent());
808 // Provide a consistent input stream - cancel the gesture that was started above
809 publishAndConsumeMotionEvent(AMOTION_EVENT_ACTION_CANCEL, downTime,
810 {Pointer{.id = 0, .x = 20, .y = 30},
811 Pointer{.id = 1, .x = 200, .y = 300},
812 Pointer{.id = 2, .x = 200, .y = 300}});
813 ASSERT_NO_FATAL_FAILURE(publishAndConsumeKeyEvent());
814 ASSERT_NO_FATAL_FAILURE(publishAndConsumeTouchModeEvent());
815 }
816
817 } // namespace android
818