xref: /aosp_15_r20/frameworks/native/libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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