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