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