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