• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "../InputDispatcher.h"
18 
19 #include <binder/Binder.h>
20 
21 #include <gtest/gtest.h>
22 #include <linux/input.h>
23 
24 namespace android {
25 
26 // An arbitrary time value.
27 static const nsecs_t ARBITRARY_TIME = 1234;
28 
29 // An arbitrary device id.
30 static const int32_t DEVICE_ID = 1;
31 
32 // An arbitrary display id.
33 static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
34 
35 // An arbitrary injector pid / uid pair that has permission to inject events.
36 static const int32_t INJECTOR_PID = 999;
37 static const int32_t INJECTOR_UID = 1001;
38 
39 
40 // --- FakeInputDispatcherPolicy ---
41 
42 class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
43     InputDispatcherConfiguration mConfig;
44 
45 protected:
~FakeInputDispatcherPolicy()46     virtual ~FakeInputDispatcherPolicy() {
47     }
48 
49 public:
FakeInputDispatcherPolicy()50     FakeInputDispatcherPolicy() {
51         mInputEventFiltered = false;
52         mTime = -1;
53         mAction = -1;
54         mDisplayId = -1;
55         mOnPointerDownToken.clear();
56     }
57 
assertFilterInputEventWasCalledWithExpectedArgs(const NotifyMotionArgs * args)58     void assertFilterInputEventWasCalledWithExpectedArgs(const NotifyMotionArgs* args) {
59         ASSERT_TRUE(mInputEventFiltered)
60                 << "Expected filterInputEvent() to have been called.";
61 
62         ASSERT_EQ(mTime, args->eventTime)
63                 << "Expected time of filtered event was not matched";
64         ASSERT_EQ(mAction, args->action)
65                 << "Expected action of filtered event was not matched";
66         ASSERT_EQ(mDisplayId, args->displayId)
67                 << "Expected displayId of filtered event was not matched";
68 
69         reset();
70     }
71 
assertFilterInputEventWasCalledWithExpectedArgs(const NotifyKeyArgs * args)72     void assertFilterInputEventWasCalledWithExpectedArgs(const NotifyKeyArgs* args) {
73         ASSERT_TRUE(mInputEventFiltered)
74                 << "Expected filterInputEvent() to have been called.";
75 
76         ASSERT_EQ(mTime, args->eventTime)
77                 << "Expected time of filtered event was not matched";
78         ASSERT_EQ(mAction, args->action)
79                 << "Expected action of filtered event was not matched";
80         ASSERT_EQ(mDisplayId, args->displayId)
81                 << "Expected displayId of filtered event was not matched";
82 
83         reset();
84     }
85 
assertFilterInputEventWasNotCalled()86     void assertFilterInputEventWasNotCalled() {
87         ASSERT_FALSE(mInputEventFiltered)
88                 << "Expected filterInputEvent() to not have been called.";
89     }
90 
assertOnPointerDownEquals(const sp<IBinder> & touchedToken)91     void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
92         ASSERT_EQ(mOnPointerDownToken, touchedToken)
93                 << "Expected token from onPointerDownOutsideFocus was not matched";
94         reset();
95     }
96 
97 private:
98     bool mInputEventFiltered;
99     nsecs_t mTime;
100     int32_t mAction;
101     int32_t mDisplayId;
102     sp<IBinder> mOnPointerDownToken;
103 
notifyConfigurationChanged(nsecs_t)104     virtual void notifyConfigurationChanged(nsecs_t) {
105     }
106 
notifyANR(const sp<InputApplicationHandle> &,const sp<IBinder> &,const std::string &)107     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&,
108             const sp<IBinder>&,
109             const std::string&) {
110         return 0;
111     }
112 
notifyInputChannelBroken(const sp<IBinder> &)113     virtual void notifyInputChannelBroken(const sp<IBinder>&) {
114     }
115 
notifyFocusChanged(const sp<IBinder> &,const sp<IBinder> &)116     virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) {
117     }
118 
getDispatcherConfiguration(InputDispatcherConfiguration * outConfig)119     virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
120         *outConfig = mConfig;
121     }
122 
filterInputEvent(const InputEvent * inputEvent,uint32_t policyFlags)123     virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
124         switch (inputEvent->getType()) {
125             case AINPUT_EVENT_TYPE_KEY: {
126                 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
127                 mTime = keyEvent->getEventTime();
128                 mAction = keyEvent->getAction();
129                 mDisplayId = keyEvent->getDisplayId();
130                 break;
131             }
132 
133             case AINPUT_EVENT_TYPE_MOTION: {
134                 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
135                 mTime = motionEvent->getEventTime();
136                 mAction = motionEvent->getAction();
137                 mDisplayId = motionEvent->getDisplayId();
138                 break;
139             }
140         }
141 
142         mInputEventFiltered = true;
143         return true;
144     }
145 
interceptKeyBeforeQueueing(const KeyEvent *,uint32_t &)146     virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
147     }
148 
interceptMotionBeforeQueueing(int32_t,nsecs_t,uint32_t &)149     virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
150     }
151 
interceptKeyBeforeDispatching(const sp<IBinder> &,const KeyEvent *,uint32_t)152     virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
153             const KeyEvent*, uint32_t) {
154         return 0;
155     }
156 
dispatchUnhandledKey(const sp<IBinder> &,const KeyEvent *,uint32_t,KeyEvent *)157     virtual bool dispatchUnhandledKey(const sp<IBinder>&,
158             const KeyEvent*, uint32_t, KeyEvent*) {
159         return false;
160     }
161 
notifySwitch(nsecs_t,uint32_t,uint32_t,uint32_t)162     virtual void notifySwitch(nsecs_t, uint32_t, uint32_t, uint32_t) {
163     }
164 
pokeUserActivity(nsecs_t,int32_t)165     virtual void pokeUserActivity(nsecs_t, int32_t) {
166     }
167 
checkInjectEventsPermissionNonReentrant(int32_t,int32_t)168     virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) {
169         return false;
170     }
171 
onPointerDownOutsideFocus(const sp<IBinder> & newToken)172     virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) {
173         mOnPointerDownToken = newToken;
174     }
175 
reset()176     void reset() {
177         mInputEventFiltered = false;
178         mTime = -1;
179         mAction = -1;
180         mDisplayId = -1;
181         mOnPointerDownToken.clear();
182     }
183 };
184 
185 
186 // --- InputDispatcherTest ---
187 
188 class InputDispatcherTest : public testing::Test {
189 protected:
190     sp<FakeInputDispatcherPolicy> mFakePolicy;
191     sp<InputDispatcher> mDispatcher;
192     sp<InputDispatcherThread> mDispatcherThread;
193 
SetUp()194     virtual void SetUp() {
195         mFakePolicy = new FakeInputDispatcherPolicy();
196         mDispatcher = new InputDispatcher(mFakePolicy);
197         mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
198         //Start InputDispatcher thread
199         mDispatcherThread = new InputDispatcherThread(mDispatcher);
200         mDispatcherThread->run("InputDispatcherTest", PRIORITY_URGENT_DISPLAY);
201     }
202 
TearDown()203     virtual void TearDown() {
204         mDispatcherThread->requestExit();
205         mDispatcherThread.clear();
206         mFakePolicy.clear();
207         mDispatcher.clear();
208     }
209 };
210 
211 
TEST_F(InputDispatcherTest,InjectInputEvent_ValidatesKeyEvents)212 TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
213     KeyEvent event;
214 
215     // Rejects undefined key actions.
216     event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
217             /*action*/ -1, 0,
218             AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
219     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
220             &event,
221             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
222             << "Should reject key events with undefined action.";
223 
224     // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
225     event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
226             AKEY_EVENT_ACTION_MULTIPLE, 0,
227             AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
228     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
229             &event,
230             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
231             << "Should reject key events with ACTION_MULTIPLE.";
232 }
233 
TEST_F(InputDispatcherTest,InjectInputEvent_ValidatesMotionEvents)234 TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
235     MotionEvent event;
236     PointerProperties pointerProperties[MAX_POINTERS + 1];
237     PointerCoords pointerCoords[MAX_POINTERS + 1];
238     for (int i = 0; i <= MAX_POINTERS; i++) {
239         pointerProperties[i].clear();
240         pointerProperties[i].id = i;
241         pointerCoords[i].clear();
242     }
243 
244     // Some constants commonly used below
245     constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
246     constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
247     constexpr int32_t metaState = AMETA_NONE;
248     constexpr MotionClassification classification = MotionClassification::NONE;
249 
250     // Rejects undefined motion actions.
251     event.initialize(DEVICE_ID, source, DISPLAY_ID,
252             /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
253             ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
254     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
255             &event,
256             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
257             << "Should reject motion events with undefined action.";
258 
259     // Rejects pointer down with invalid index.
260     event.initialize(DEVICE_ID, source, DISPLAY_ID,
261             AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
262             0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
263             ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
264     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
265             &event,
266             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
267             << "Should reject motion events with pointer down index too large.";
268 
269     event.initialize(DEVICE_ID, source, DISPLAY_ID,
270             AMOTION_EVENT_ACTION_POINTER_DOWN | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
271             0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
272             ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
273     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
274             &event,
275             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
276             << "Should reject motion events with pointer down index too small.";
277 
278     // Rejects pointer up with invalid index.
279     event.initialize(DEVICE_ID, source, DISPLAY_ID,
280             AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
281             0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
282             ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
283     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
284             &event,
285             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
286             << "Should reject motion events with pointer up index too large.";
287 
288     event.initialize(DEVICE_ID, source, DISPLAY_ID,
289             AMOTION_EVENT_ACTION_POINTER_UP | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
290             0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
291             ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
292     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
293             &event,
294             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
295             << "Should reject motion events with pointer up index too small.";
296 
297     // Rejects motion events with invalid number of pointers.
298     event.initialize(DEVICE_ID, source, DISPLAY_ID,
299             AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
300             ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 0, pointerProperties, pointerCoords);
301     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
302             &event,
303             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
304             << "Should reject motion events with 0 pointers.";
305 
306     event.initialize(DEVICE_ID, source, DISPLAY_ID,
307             AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
308             ARBITRARY_TIME, ARBITRARY_TIME,
309             /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
310     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
311             &event,
312             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
313             << "Should reject motion events with more than MAX_POINTERS pointers.";
314 
315     // Rejects motion events with invalid pointer ids.
316     pointerProperties[0].id = -1;
317     event.initialize(DEVICE_ID, source, DISPLAY_ID,
318             AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
319             ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
320     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
321             &event,
322             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
323             << "Should reject motion events with pointer ids less than 0.";
324 
325     pointerProperties[0].id = MAX_POINTER_ID + 1;
326     event.initialize(DEVICE_ID, source, DISPLAY_ID,
327             AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
328             ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
329     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
330             &event,
331             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
332             << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
333 
334     // Rejects motion events with duplicate pointer ids.
335     pointerProperties[0].id = 1;
336     pointerProperties[1].id = 1;
337     event.initialize(DEVICE_ID, source, DISPLAY_ID,
338             AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
339             ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 2, pointerProperties, pointerCoords);
340     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
341             &event,
342             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
343             << "Should reject motion events with duplicate pointer ids.";
344 }
345 
346 // --- InputDispatcherTest SetInputWindowTest ---
347 static const int32_t INJECT_EVENT_TIMEOUT = 500;
348 static const int32_t DISPATCHING_TIMEOUT = 100;
349 
350 class FakeApplicationHandle : public InputApplicationHandle {
351 public:
FakeApplicationHandle()352     FakeApplicationHandle() {}
~FakeApplicationHandle()353     virtual ~FakeApplicationHandle() {}
354 
updateInfo()355     virtual bool updateInfo() {
356         mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
357         return true;
358     }
359 };
360 
361 class FakeInputReceiver {
362 public:
consumeEvent(int32_t expectedEventType,int32_t expectedDisplayId,int32_t expectedFlags=0)363     void consumeEvent(int32_t expectedEventType, int32_t expectedDisplayId,
364             int32_t expectedFlags = 0) {
365         uint32_t consumeSeq;
366         InputEvent* event;
367         status_t status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1,
368             &consumeSeq, &event);
369 
370         ASSERT_EQ(OK, status)
371                 << mName.c_str() << ": consumer consume should return OK.";
372         ASSERT_TRUE(event != nullptr)
373                 << mName.c_str() << ": consumer should have returned non-NULL event.";
374         ASSERT_EQ(expectedEventType, event->getType())
375                 << mName.c_str() << ": event type should match.";
376 
377         ASSERT_EQ(expectedDisplayId, event->getDisplayId())
378                 << mName.c_str() << ": event displayId should be the same as expected.";
379 
380         int32_t flags;
381         switch (expectedEventType) {
382             case AINPUT_EVENT_TYPE_KEY: {
383                 KeyEvent* typedEvent = static_cast<KeyEvent*>(event);
384                 flags = typedEvent->getFlags();
385                 break;
386             }
387             case AINPUT_EVENT_TYPE_MOTION: {
388                 MotionEvent* typedEvent = static_cast<MotionEvent*>(event);
389                 flags = typedEvent->getFlags();
390                 break;
391             }
392             default: {
393                 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
394             }
395         }
396         ASSERT_EQ(expectedFlags, flags)
397                 << mName.c_str() << ": event flags should be the same as expected.";
398 
399         status = mConsumer->sendFinishedSignal(consumeSeq, handled());
400         ASSERT_EQ(OK, status)
401                 << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
402     }
403 
assertNoEvents()404     void assertNoEvents() {
405         uint32_t consumeSeq;
406         InputEvent* event;
407         status_t status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1,
408             &consumeSeq, &event);
409         ASSERT_NE(OK, status)
410                 << mName.c_str()
411                 << ": should not have received any events, so consume(..) should not return OK.";
412     }
413 
414 protected:
FakeInputReceiver(const sp<InputDispatcher> & dispatcher,const std::string name,int32_t displayId)415         explicit FakeInputReceiver(const sp<InputDispatcher>& dispatcher,
416             const std::string name, int32_t displayId) :
417                 mDispatcher(dispatcher), mName(name), mDisplayId(displayId) {
418             InputChannel::openInputChannelPair(name, mServerChannel, mClientChannel);
419             mConsumer = new InputConsumer(mClientChannel);
420         }
421 
~FakeInputReceiver()422         virtual ~FakeInputReceiver() {
423         }
424 
425         // return true if the event has been handled.
handled()426         virtual bool handled() {
427             return false;
428         }
429 
430         sp<InputDispatcher> mDispatcher;
431         sp<InputChannel> mServerChannel, mClientChannel;
432         InputConsumer *mConsumer;
433         PreallocatedInputEventFactory mEventFactory;
434 
435         std::string mName;
436         int32_t mDisplayId;
437 };
438 
439 class FakeWindowHandle : public InputWindowHandle, public FakeInputReceiver {
440 public:
441     static const int32_t WIDTH = 600;
442     static const int32_t HEIGHT = 800;
443 
FakeWindowHandle(const sp<InputApplicationHandle> & inputApplicationHandle,const sp<InputDispatcher> & dispatcher,const std::string name,int32_t displayId)444     FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
445         const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) :
446             FakeInputReceiver(dispatcher, name, displayId),
447             mFocused(false), mFrame(Rect(0, 0, WIDTH, HEIGHT)), mLayoutParamFlags(0) {
448             mServerChannel->setToken(new BBinder());
449             mDispatcher->registerInputChannel(mServerChannel, displayId);
450 
451             inputApplicationHandle->updateInfo();
452             mInfo.applicationInfo = *inputApplicationHandle->getInfo();
453     }
454 
updateInfo()455     virtual bool updateInfo() {
456         mInfo.token = mServerChannel ? mServerChannel->getToken() : nullptr;
457         mInfo.name = mName;
458         mInfo.layoutParamsFlags = mLayoutParamFlags;
459         mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
460         mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
461         mInfo.frameLeft = mFrame.left;
462         mInfo.frameTop = mFrame.top;
463         mInfo.frameRight = mFrame.right;
464         mInfo.frameBottom = mFrame.bottom;
465         mInfo.globalScaleFactor = 1.0;
466         mInfo.addTouchableRegion(mFrame);
467         mInfo.visible = true;
468         mInfo.canReceiveKeys = true;
469         mInfo.hasFocus = mFocused;
470         mInfo.hasWallpaper = false;
471         mInfo.paused = false;
472         mInfo.layer = 0;
473         mInfo.ownerPid = INJECTOR_PID;
474         mInfo.ownerUid = INJECTOR_UID;
475         mInfo.inputFeatures = 0;
476         mInfo.displayId = mDisplayId;
477 
478         return true;
479     }
480 
setFocus()481     void setFocus() {
482         mFocused = true;
483     }
484 
setFrame(const Rect & frame)485     void setFrame(const Rect& frame) {
486         mFrame.set(frame);
487     }
488 
setLayoutParamFlags(int32_t flags)489     void setLayoutParamFlags(int32_t flags) {
490         mLayoutParamFlags = flags;
491     }
492 
releaseChannel()493     void releaseChannel() {
494         mServerChannel.clear();
495         InputWindowHandle::releaseChannel();
496     }
497 protected:
handled()498     virtual bool handled() {
499         return true;
500     }
501 
502     bool mFocused;
503     Rect mFrame;
504     int32_t mLayoutParamFlags;
505 };
506 
injectKeyDown(const sp<InputDispatcher> & dispatcher,int32_t displayId=ADISPLAY_ID_NONE)507 static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
508         int32_t displayId = ADISPLAY_ID_NONE) {
509     KeyEvent event;
510     nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
511 
512     // Define a valid key down event.
513     event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
514             AKEY_EVENT_ACTION_DOWN, /* flags */ 0,
515             AKEYCODE_A, KEY_A, AMETA_NONE, /* repeatCount */ 0, currentTime, currentTime);
516 
517     // Inject event until dispatch out.
518     return dispatcher->injectInputEvent(
519             &event,
520             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
521             INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
522 }
523 
injectMotionDown(const sp<InputDispatcher> & dispatcher,int32_t source,int32_t displayId,int32_t x=100,int32_t y=200)524 static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
525         int32_t displayId, int32_t x = 100, int32_t y = 200) {
526     MotionEvent event;
527     PointerProperties pointerProperties[1];
528     PointerCoords pointerCoords[1];
529 
530     pointerProperties[0].clear();
531     pointerProperties[0].id = 0;
532     pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
533 
534     pointerCoords[0].clear();
535     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
536     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
537 
538     nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
539     // Define a valid motion down event.
540     event.initialize(DEVICE_ID, source, displayId,
541             AMOTION_EVENT_ACTION_DOWN, /* actionButton */ 0, /* flags */ 0, /* edgeFlags */ 0,
542             AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
543             /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
544             /* yPrecision */ 0, currentTime, currentTime, /*pointerCount*/ 1, pointerProperties,
545             pointerCoords);
546 
547     // Inject event until dispatch out.
548     return dispatcher->injectInputEvent(
549             &event,
550             INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
551             INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
552 }
553 
generateKeyArgs(int32_t action,int32_t displayId=ADISPLAY_ID_NONE)554 static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
555     nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
556     // Define a valid key event.
557     NotifyKeyArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
558             displayId, POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0,
559             AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);
560 
561     return args;
562 }
563 
generateMotionArgs(int32_t action,int32_t source,int32_t displayId)564 static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
565     PointerProperties pointerProperties[1];
566     PointerCoords pointerCoords[1];
567 
568     pointerProperties[0].clear();
569     pointerProperties[0].id = 0;
570     pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
571 
572     pointerCoords[0].clear();
573     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
574     pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
575 
576     nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
577     // Define a valid motion event.
578     NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
579             POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
580             AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
581             AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1, pointerProperties,
582             pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0, currentTime,
583             /* videoFrames */ {});
584 
585     return args;
586 }
587 
TEST_F(InputDispatcherTest,SetInputWindow_SingleWindowTouch)588 TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
589     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
590     sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
591             ADISPLAY_ID_DEFAULT);
592 
593     std::vector<sp<InputWindowHandle>> inputWindowHandles;
594     inputWindowHandles.push_back(window);
595 
596     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
597     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
598             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
599             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
600 
601     // Window should receive motion event.
602     window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
603 }
604 
605 // The foreground window should receive the first touch down event.
TEST_F(InputDispatcherTest,SetInputWindow_MultiWindowsTouch)606 TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
607     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
608     sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
609             ADISPLAY_ID_DEFAULT);
610     sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
611             ADISPLAY_ID_DEFAULT);
612 
613     std::vector<sp<InputWindowHandle>> inputWindowHandles;
614     inputWindowHandles.push_back(windowTop);
615     inputWindowHandles.push_back(windowSecond);
616 
617     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
618     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
619             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
620             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
621 
622     // Top window should receive the touch down event. Second window should not receive anything.
623     windowTop->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
624     windowSecond->assertNoEvents();
625 }
626 
TEST_F(InputDispatcherTest,SetInputWindow_FocusedWindow)627 TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
628     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
629     sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
630             ADISPLAY_ID_DEFAULT);
631     sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
632             ADISPLAY_ID_DEFAULT);
633 
634     // Set focused application.
635     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
636 
637     // Expect one focus window exist in display.
638     windowSecond->setFocus();
639     std::vector<sp<InputWindowHandle>> inputWindowHandles;
640     inputWindowHandles.push_back(windowTop);
641     inputWindowHandles.push_back(windowSecond);
642 
643     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
644     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
645             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
646 
647     // Focused window should receive event.
648     windowTop->assertNoEvents();
649     windowSecond->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
650 }
651 
TEST_F(InputDispatcherTest,SetInputWindow_FocusPriority)652 TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
653     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
654     sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
655             ADISPLAY_ID_DEFAULT);
656     sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
657             ADISPLAY_ID_DEFAULT);
658 
659     // Set focused application.
660     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
661 
662     // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
663     windowTop->setFocus();
664     windowSecond->setFocus();
665     std::vector<sp<InputWindowHandle>> inputWindowHandles;
666     inputWindowHandles.push_back(windowTop);
667     inputWindowHandles.push_back(windowSecond);
668 
669     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
670     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
671             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
672 
673     // Top focused window should receive event.
674     windowTop->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
675     windowSecond->assertNoEvents();
676 }
677 
TEST_F(InputDispatcherTest,SetInputWindow_InputWindowInfo)678 TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
679     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
680 
681     sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
682             ADISPLAY_ID_DEFAULT);
683     sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
684             ADISPLAY_ID_DEFAULT);
685 
686     // Set focused application.
687     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
688 
689     windowTop->setFocus();
690     windowSecond->setFocus();
691     std::vector<sp<InputWindowHandle>> inputWindowHandles;
692     inputWindowHandles.push_back(windowTop);
693     inputWindowHandles.push_back(windowSecond);
694     // Release channel for window is no longer valid.
695     windowTop->releaseChannel();
696     mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
697 
698     // Test inject a key down, should dispatch to a valid window.
699     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
700             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
701 
702     // Top window is invalid, so it should not receive any input event.
703     windowTop->assertNoEvents();
704     windowSecond->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
705 }
706 
707 /* Test InputDispatcher for MultiDisplay */
708 class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
709 public:
710     static constexpr int32_t SECOND_DISPLAY_ID = 1;
SetUp()711     virtual void SetUp() {
712         InputDispatcherTest::SetUp();
713 
714         application1 = new FakeApplicationHandle();
715         windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
716                 ADISPLAY_ID_DEFAULT);
717         std::vector<sp<InputWindowHandle>> inputWindowHandles;
718         inputWindowHandles.push_back(windowInPrimary);
719         // Set focus window for primary display, but focused display would be second one.
720         mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
721         windowInPrimary->setFocus();
722         mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
723 
724         application2 = new FakeApplicationHandle();
725         windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
726                 SECOND_DISPLAY_ID);
727         // Set focus to second display window.
728         std::vector<sp<InputWindowHandle>> inputWindowHandles_Second;
729         inputWindowHandles_Second.push_back(windowInSecondary);
730         // Set focus display to second one.
731         mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
732         // Set focus window for second display.
733         mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
734         windowInSecondary->setFocus();
735         mDispatcher->setInputWindows(inputWindowHandles_Second, SECOND_DISPLAY_ID);
736     }
737 
TearDown()738     virtual void TearDown() {
739         InputDispatcherTest::TearDown();
740 
741         application1.clear();
742         windowInPrimary.clear();
743         application2.clear();
744         windowInSecondary.clear();
745     }
746 
747 protected:
748     sp<FakeApplicationHandle> application1;
749     sp<FakeWindowHandle> windowInPrimary;
750     sp<FakeApplicationHandle> application2;
751     sp<FakeWindowHandle> windowInSecondary;
752 };
753 
TEST_F(InputDispatcherFocusOnTwoDisplaysTest,SetInputWindow_MultiDisplayTouch)754 TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
755     // Test touch down on primary display.
756     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
757             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
758             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
759     windowInPrimary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
760     windowInSecondary->assertNoEvents();
761 
762     // Test touch down on second display.
763     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
764             AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
765             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
766     windowInPrimary->assertNoEvents();
767     windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, SECOND_DISPLAY_ID);
768 }
769 
TEST_F(InputDispatcherFocusOnTwoDisplaysTest,SetInputWindow_MultiDisplayFocus)770 TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
771     // Test inject a key down with display id specified.
772     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
773             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
774     windowInPrimary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_DEFAULT);
775     windowInSecondary->assertNoEvents();
776 
777     // Test inject a key down without display id specified.
778     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
779             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
780     windowInPrimary->assertNoEvents();
781     windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
782 
783     // Remove secondary display.
784     std::vector<sp<InputWindowHandle>> noWindows;
785     mDispatcher->setInputWindows(noWindows, SECOND_DISPLAY_ID);
786 
787     // Expect old focus should receive a cancel event.
788     windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE,
789             AKEY_EVENT_FLAG_CANCELED);
790 
791     // Test inject a key down, should timeout because of no target window.
792     ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
793             << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
794     windowInPrimary->assertNoEvents();
795     windowInSecondary->assertNoEvents();
796 }
797 
798 class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
799 public:
FakeMonitorReceiver(const sp<InputDispatcher> & dispatcher,const std::string name,int32_t displayId,bool isGestureMonitor=false)800     FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
801             int32_t displayId, bool isGestureMonitor = false)
802             : FakeInputReceiver(dispatcher, name, displayId) {
803         mServerChannel->setToken(new BBinder());
804         mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
805     }
806 };
807 
808 // Test per-display input monitors for motion event.
TEST_F(InputDispatcherFocusOnTwoDisplaysTest,MonitorMotionEvent_MultiDisplay)809 TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
810     sp<FakeMonitorReceiver> monitorInPrimary =
811             new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
812     sp<FakeMonitorReceiver> monitorInSecondary =
813             new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
814 
815     // Test touch down on primary display.
816     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
817             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
818             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
819     windowInPrimary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
820     monitorInPrimary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
821     windowInSecondary->assertNoEvents();
822     monitorInSecondary->assertNoEvents();
823 
824     // Test touch down on second display.
825     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
826             AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
827             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
828     windowInPrimary->assertNoEvents();
829     monitorInPrimary->assertNoEvents();
830     windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, SECOND_DISPLAY_ID);
831     monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, SECOND_DISPLAY_ID);
832 
833     // Test inject a non-pointer motion event.
834     // If specific a display, it will dispatch to the focused window of particular display,
835     // or it will dispatch to the focused window of focused display.
836     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
837         AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
838             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
839     windowInPrimary->assertNoEvents();
840     monitorInPrimary->assertNoEvents();
841     windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_NONE);
842     monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_NONE);
843 }
844 
845 // Test per-display input monitors for key event.
TEST_F(InputDispatcherFocusOnTwoDisplaysTest,MonitorKeyEvent_MultiDisplay)846 TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
847     //Input monitor per display.
848     sp<FakeMonitorReceiver> monitorInPrimary =
849             new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
850     sp<FakeMonitorReceiver> monitorInSecondary =
851             new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
852 
853     // Test inject a key down.
854     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
855             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
856     windowInPrimary->assertNoEvents();
857     monitorInPrimary->assertNoEvents();
858     windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
859     monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
860 }
861 
862 class InputFilterTest : public InputDispatcherTest {
863 protected:
864     static constexpr int32_t SECOND_DISPLAY_ID = 1;
865 
testNotifyMotion(int32_t displayId,bool expectToBeFiltered)866     void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
867         NotifyMotionArgs motionArgs;
868 
869         motionArgs = generateMotionArgs(
870                 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
871         mDispatcher->notifyMotion(&motionArgs);
872         motionArgs = generateMotionArgs(
873                 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
874         mDispatcher->notifyMotion(&motionArgs);
875 
876         if (expectToBeFiltered) {
877             mFakePolicy->assertFilterInputEventWasCalledWithExpectedArgs(&motionArgs);
878         } else {
879             mFakePolicy->assertFilterInputEventWasNotCalled();
880         }
881     }
882 
testNotifyKey(bool expectToBeFiltered)883     void testNotifyKey(bool expectToBeFiltered) {
884         NotifyKeyArgs keyArgs;
885 
886         keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
887         mDispatcher->notifyKey(&keyArgs);
888         keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
889         mDispatcher->notifyKey(&keyArgs);
890 
891         if (expectToBeFiltered) {
892             mFakePolicy->assertFilterInputEventWasCalledWithExpectedArgs(&keyArgs);
893         } else {
894             mFakePolicy->assertFilterInputEventWasNotCalled();
895         }
896     }
897 };
898 
899 // Test InputFilter for MotionEvent
TEST_F(InputFilterTest,MotionEvent_InputFilter)900 TEST_F(InputFilterTest, MotionEvent_InputFilter) {
901     // Since the InputFilter is disabled by default, check if touch events aren't filtered.
902     testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
903     testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
904 
905     // Enable InputFilter
906     mDispatcher->setInputFilterEnabled(true);
907     // Test touch on both primary and second display, and check if both events are filtered.
908     testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
909     testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
910 
911     // Disable InputFilter
912     mDispatcher->setInputFilterEnabled(false);
913     // Test touch on both primary and second display, and check if both events aren't filtered.
914     testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
915     testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
916 }
917 
918 // Test InputFilter for KeyEvent
TEST_F(InputFilterTest,KeyEvent_InputFilter)919 TEST_F(InputFilterTest, KeyEvent_InputFilter) {
920     // Since the InputFilter is disabled by default, check if key event aren't filtered.
921     testNotifyKey(/*expectToBeFiltered*/ false);
922 
923     // Enable InputFilter
924     mDispatcher->setInputFilterEnabled(true);
925     // Send a key event, and check if it is filtered.
926     testNotifyKey(/*expectToBeFiltered*/ true);
927 
928     // Disable InputFilter
929     mDispatcher->setInputFilterEnabled(false);
930     // Send a key event, and check if it isn't filtered.
931     testNotifyKey(/*expectToBeFiltered*/ false);
932 }
933 
934 class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
SetUp()935     virtual void SetUp() {
936         InputDispatcherTest::SetUp();
937 
938         sp<FakeApplicationHandle> application = new FakeApplicationHandle();
939         mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
940                 ADISPLAY_ID_DEFAULT);
941         mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
942         // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
943         // window.
944         mUnfocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
945 
946         mWindowFocused = new FakeWindowHandle(application, mDispatcher, "Second",
947                 ADISPLAY_ID_DEFAULT);
948         mWindowFocused->setFrame(Rect(50, 50, 100, 100));
949         mWindowFocused->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
950         mWindowFocusedTouchPoint = 60;
951 
952         // Set focused application.
953         mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
954         mWindowFocused->setFocus();
955 
956         // Expect one focus window exist in display.
957         std::vector<sp<InputWindowHandle>> inputWindowHandles;
958         inputWindowHandles.push_back(mUnfocusedWindow);
959         inputWindowHandles.push_back(mWindowFocused);
960         mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
961     }
962 
TearDown()963     virtual void TearDown() {
964         InputDispatcherTest::TearDown();
965 
966         mUnfocusedWindow.clear();
967         mWindowFocused.clear();
968     }
969 
970 protected:
971     sp<FakeWindowHandle> mUnfocusedWindow;
972     sp<FakeWindowHandle> mWindowFocused;
973     int32_t mWindowFocusedTouchPoint;
974 };
975 
976 // Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
977 // DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
978 // the onPointerDownOutsideFocus callback.
TEST_F(InputDispatcherOnPointerDownOutsideFocus,OnPointerDownOutsideFocus_Success)979 TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
980     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
981             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20))
982             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
983     // Call monitor to wait for the command queue to get flushed.
984     mDispatcher->monitor();
985 
986     mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
987 }
988 
989 // Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
990 // DOWN on the window that doesn't have focus. Ensure no window received the
991 // onPointerDownOutsideFocus callback.
TEST_F(InputDispatcherOnPointerDownOutsideFocus,OnPointerDownOutsideFocus_NonPointerSource)992 TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
993     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
994             AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20))
995             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
996     // Call monitor to wait for the command queue to get flushed.
997     mDispatcher->monitor();
998 
999     mFakePolicy->assertOnPointerDownEquals(nullptr);
1000 }
1001 
1002 // Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
1003 // have focus. Ensure no window received the onPointerDownOutsideFocus callback.
TEST_F(InputDispatcherOnPointerDownOutsideFocus,OnPointerDownOutsideFocus_NonMotionFailure)1004 TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
1005     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1006             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1007     // Call monitor to wait for the command queue to get flushed.
1008     mDispatcher->monitor();
1009 
1010     mFakePolicy->assertOnPointerDownEquals(nullptr);
1011 }
1012 
1013 // Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1014 // DOWN on the window that already has focus. Ensure no window received the
1015 // onPointerDownOutsideFocus callback.
TEST_F(InputDispatcherOnPointerDownOutsideFocus,OnPointerDownOutsideFocus_OnAlreadyFocusedWindow)1016 TEST_F(InputDispatcherOnPointerDownOutsideFocus,
1017         OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
1018     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1019             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, mWindowFocusedTouchPoint,
1020             mWindowFocusedTouchPoint))
1021             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1022     // Call monitor to wait for the command queue to get flushed.
1023     mDispatcher->monitor();
1024 
1025     mFakePolicy->assertOnPointerDownEquals(nullptr);
1026 }
1027 
1028 } // namespace android
1029