blob: 745fac0b1f5d421eb38dd49dddfd034215aed2ef [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
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
Robert Carr803535b2018-08-02 16:38:15 -070019#include <binder/Binder.h>
20
Michael Wrightd02c5b62014-02-10 15:10:22 -080021#include <gtest/gtest.h>
22#include <linux/input.h>
23
24namespace android {
25
26// An arbitrary time value.
27static const nsecs_t ARBITRARY_TIME = 1234;
28
29// An arbitrary device id.
30static const int32_t DEVICE_ID = 1;
31
Jeff Brownf086ddb2014-02-11 14:28:48 -080032// An arbitrary display id.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -080033static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
Jeff Brownf086ddb2014-02-11 14:28:48 -080034
Michael Wrightd02c5b62014-02-10 15:10:22 -080035// An arbitrary injector pid / uid pair that has permission to inject events.
36static const int32_t INJECTOR_PID = 999;
37static const int32_t INJECTOR_UID = 1001;
38
39
40// --- FakeInputDispatcherPolicy ---
41
42class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
43 InputDispatcherConfiguration mConfig;
44
45protected:
46 virtual ~FakeInputDispatcherPolicy() {
47 }
48
49public:
50 FakeInputDispatcherPolicy() {
Jackal Guof9696682018-10-05 12:23:23 +080051 mInputEventFiltered = false;
52 mTime = -1;
53 mAction = -1;
54 mDisplayId = -1;
55 }
56
57 void assertFilterInputEventWasCalledWithExpectedArgs(const NotifyMotionArgs* args) {
58 ASSERT_TRUE(mInputEventFiltered)
59 << "Expected filterInputEvent() to have been called.";
60
61 ASSERT_EQ(mTime, args->eventTime)
62 << "Expected time of filtered event was not matched";
63 ASSERT_EQ(mAction, args->action)
64 << "Expected action of filtered event was not matched";
65 ASSERT_EQ(mDisplayId, args->displayId)
66 << "Expected displayId of filtered event was not matched";
67
68 reset();
69 }
70
71 void assertFilterInputEventWasCalledWithExpectedArgs(const NotifyKeyArgs* args) {
72 ASSERT_TRUE(mInputEventFiltered)
73 << "Expected filterInputEvent() to have been called.";
74
75 ASSERT_EQ(mTime, args->eventTime)
76 << "Expected time of filtered event was not matched";
77 ASSERT_EQ(mAction, args->action)
78 << "Expected action of filtered event was not matched";
79 ASSERT_EQ(mDisplayId, args->displayId)
80 << "Expected displayId of filtered event was not matched";
81
82 reset();
83 }
84
85 void assertFilterInputEventWasNotCalled() {
86 ASSERT_FALSE(mInputEventFiltered)
87 << "Expected filterInputEvent() to not have been called.";
Michael Wrightd02c5b62014-02-10 15:10:22 -080088 }
89
90private:
Jackal Guof9696682018-10-05 12:23:23 +080091 bool mInputEventFiltered;
92 nsecs_t mTime;
93 int32_t mAction;
94 int32_t mDisplayId;
95
Narayan Kamath39efe3e2014-10-17 10:37:08 +010096 virtual void notifyConfigurationChanged(nsecs_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080097 }
98
Narayan Kamath39efe3e2014-10-17 10:37:08 +010099 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&,
Robert Carr803535b2018-08-02 16:38:15 -0700100 const sp<IBinder>&,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800101 const std::string&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800102 return 0;
103 }
104
Robert Carr803535b2018-08-02 16:38:15 -0700105 virtual void notifyInputChannelBroken(const sp<IBinder>&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800106 }
107
chaviw0c06c6e2019-01-09 13:27:07 -0800108 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) {
Robert Carr740167f2018-10-11 19:03:41 -0700109 }
110
Michael Wrightd02c5b62014-02-10 15:10:22 -0800111 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
112 *outConfig = mConfig;
113 }
114
Jackal Guof9696682018-10-05 12:23:23 +0800115 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
116 switch (inputEvent->getType()) {
117 case AINPUT_EVENT_TYPE_KEY: {
118 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
119 mTime = keyEvent->getEventTime();
120 mAction = keyEvent->getAction();
121 mDisplayId = keyEvent->getDisplayId();
122 break;
123 }
124
125 case AINPUT_EVENT_TYPE_MOTION: {
126 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
127 mTime = motionEvent->getEventTime();
128 mAction = motionEvent->getAction();
129 mDisplayId = motionEvent->getDisplayId();
130 break;
131 }
132 }
133
134 mInputEventFiltered = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800135 return true;
136 }
137
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100138 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139 }
140
Charles Chen3611f1f2019-01-29 17:26:18 +0800141 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800142 }
143
Robert Carr803535b2018-08-02 16:38:15 -0700144 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100145 const KeyEvent*, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800146 return 0;
147 }
148
Robert Carr803535b2018-08-02 16:38:15 -0700149 virtual bool dispatchUnhandledKey(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100150 const KeyEvent*, uint32_t, KeyEvent*) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800151 return false;
152 }
153
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100154 virtual void notifySwitch(nsecs_t, uint32_t, uint32_t, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800155 }
156
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100157 virtual void pokeUserActivity(nsecs_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800158 }
159
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100160 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800161 return false;
162 }
Jackal Guof9696682018-10-05 12:23:23 +0800163
164 void reset() {
165 mInputEventFiltered = false;
166 mTime = -1;
167 mAction = -1;
168 mDisplayId = -1;
169 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800170};
171
172
173// --- InputDispatcherTest ---
174
175class InputDispatcherTest : public testing::Test {
176protected:
177 sp<FakeInputDispatcherPolicy> mFakePolicy;
178 sp<InputDispatcher> mDispatcher;
Arthur Hungb92218b2018-08-14 12:00:21 +0800179 sp<InputDispatcherThread> mDispatcherThread;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800180
181 virtual void SetUp() {
182 mFakePolicy = new FakeInputDispatcherPolicy();
183 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800184 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
185 //Start InputDispatcher thread
186 mDispatcherThread = new InputDispatcherThread(mDispatcher);
187 mDispatcherThread->run("InputDispatcherTest", PRIORITY_URGENT_DISPLAY);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800188 }
189
190 virtual void TearDown() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800191 mDispatcherThread->requestExit();
192 mDispatcherThread.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800193 mFakePolicy.clear();
194 mDispatcher.clear();
195 }
196};
197
198
199TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
200 KeyEvent event;
201
202 // Rejects undefined key actions.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100203 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 /*action*/ -1, 0,
205 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800206 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800207 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800208 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
209 << "Should reject key events with undefined action.";
210
211 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100212 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800213 AKEY_EVENT_ACTION_MULTIPLE, 0,
214 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800215 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800216 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
218 << "Should reject key events with ACTION_MULTIPLE.";
219}
220
221TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
222 MotionEvent event;
223 PointerProperties pointerProperties[MAX_POINTERS + 1];
224 PointerCoords pointerCoords[MAX_POINTERS + 1];
225 for (int i = 0; i <= MAX_POINTERS; i++) {
226 pointerProperties[i].clear();
227 pointerProperties[i].id = i;
228 pointerCoords[i].clear();
229 }
230
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800231 // Some constants commonly used below
232 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
233 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
234 constexpr int32_t metaState = AMETA_NONE;
235 constexpr MotionClassification classification = MotionClassification::NONE;
236
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 // Rejects undefined motion actions.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800238 event.initialize(DEVICE_ID, source, DISPLAY_ID,
239 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
240 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800241 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800242 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800243 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
244 << "Should reject motion events with undefined action.";
245
246 // Rejects pointer down with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800247 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800248 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800249 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
250 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800251 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800252 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800253 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
254 << "Should reject motion events with pointer down index too large.";
255
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800256 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Dan Albert8b10c652016-02-02 17:08:05 -0800257 AMOTION_EVENT_ACTION_POINTER_DOWN | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800258 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
259 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800260 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800261 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
263 << "Should reject motion events with pointer down index too small.";
264
265 // Rejects pointer up with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800266 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800267 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800268 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
269 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800270 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800271 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800272 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
273 << "Should reject motion events with pointer up index too large.";
274
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800275 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Dan Albert8b10c652016-02-02 17:08:05 -0800276 AMOTION_EVENT_ACTION_POINTER_UP | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800277 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
278 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800279 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800280 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800281 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
282 << "Should reject motion events with pointer up index too small.";
283
284 // Rejects motion events with invalid number of pointers.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800285 event.initialize(DEVICE_ID, source, DISPLAY_ID,
286 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
287 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 0, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800288 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800289 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800290 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
291 << "Should reject motion events with 0 pointers.";
292
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800293 event.initialize(DEVICE_ID, source, DISPLAY_ID,
294 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295 ARBITRARY_TIME, ARBITRARY_TIME,
296 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800297 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800298 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800299 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
300 << "Should reject motion events with more than MAX_POINTERS pointers.";
301
302 // Rejects motion events with invalid pointer ids.
303 pointerProperties[0].id = -1;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800304 event.initialize(DEVICE_ID, source, DISPLAY_ID,
305 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
306 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800307 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800308 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800309 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
310 << "Should reject motion events with pointer ids less than 0.";
311
312 pointerProperties[0].id = MAX_POINTER_ID + 1;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800313 event.initialize(DEVICE_ID, source, DISPLAY_ID,
314 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
315 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800316 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800317 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800318 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
319 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
320
321 // Rejects motion events with duplicate pointer ids.
322 pointerProperties[0].id = 1;
323 pointerProperties[1].id = 1;
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800324 event.initialize(DEVICE_ID, source, DISPLAY_ID,
325 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
326 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 2, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800327 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800328 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800329 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
330 << "Should reject motion events with duplicate pointer ids.";
331}
332
Arthur Hungb92218b2018-08-14 12:00:21 +0800333// --- InputDispatcherTest SetInputWindowTest ---
334static const int32_t INJECT_EVENT_TIMEOUT = 500;
335static const int32_t DISPATCHING_TIMEOUT = 100;
336
337class FakeApplicationHandle : public InputApplicationHandle {
338public:
339 FakeApplicationHandle() {}
340 virtual ~FakeApplicationHandle() {}
341
342 virtual bool updateInfo() {
Arthur Hung7a0c39a2019-03-20 16:52:24 +0800343 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
Arthur Hungb92218b2018-08-14 12:00:21 +0800344 return true;
345 }
346};
347
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800348class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800349public:
Tiger Huang8664f8c2018-10-11 19:14:35 +0800350 void consumeEvent(int32_t expectedEventType, int32_t expectedDisplayId,
351 int32_t expectedFlags = 0) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800352 uint32_t consumeSeq;
353 InputEvent* event;
354 status_t status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1,
355 &consumeSeq, &event);
356
357 ASSERT_EQ(OK, status)
358 << mName.c_str() << ": consumer consume should return OK.";
359 ASSERT_TRUE(event != nullptr)
360 << mName.c_str() << ": consumer should have returned non-NULL event.";
361 ASSERT_EQ(expectedEventType, event->getType())
Tiger Huang8664f8c2018-10-11 19:14:35 +0800362 << mName.c_str() << ": event type should match.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800363
364 ASSERT_EQ(expectedDisplayId, event->getDisplayId())
Tiger Huang8664f8c2018-10-11 19:14:35 +0800365 << mName.c_str() << ": event displayId should be the same as expected.";
366
367 int32_t flags;
368 switch (expectedEventType) {
369 case AINPUT_EVENT_TYPE_KEY: {
370 KeyEvent* typedEvent = static_cast<KeyEvent*>(event);
371 flags = typedEvent->getFlags();
372 break;
373 }
374 case AINPUT_EVENT_TYPE_MOTION: {
375 MotionEvent* typedEvent = static_cast<MotionEvent*>(event);
376 flags = typedEvent->getFlags();
377 break;
378 }
379 default: {
380 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
381 }
382 }
383 ASSERT_EQ(expectedFlags, flags)
384 << mName.c_str() << ": event flags should be the same as expected.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800385
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800386 status = mConsumer->sendFinishedSignal(consumeSeq, handled());
Arthur Hungb92218b2018-08-14 12:00:21 +0800387 ASSERT_EQ(OK, status)
388 << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
389 }
390
391 void assertNoEvents() {
392 uint32_t consumeSeq;
393 InputEvent* event;
394 status_t status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1,
395 &consumeSeq, &event);
396 ASSERT_NE(OK, status)
397 << mName.c_str()
398 << ": should not have received any events, so consume(..) should not return OK.";
399 }
400
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800401protected:
402 explicit FakeInputReceiver(const sp<InputDispatcher>& dispatcher,
403 const std::string name, int32_t displayId) :
404 mDispatcher(dispatcher), mName(name), mDisplayId(displayId) {
405 InputChannel::openInputChannelPair(name, mServerChannel, mClientChannel);
406 mConsumer = new InputConsumer(mClientChannel);
407 }
408
409 virtual ~FakeInputReceiver() {
410 }
411
412 // return true if the event has been handled.
413 virtual bool handled() {
414 return false;
415 }
416
Arthur Hungb92218b2018-08-14 12:00:21 +0800417 sp<InputDispatcher> mDispatcher;
418 sp<InputChannel> mServerChannel, mClientChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -0700419 sp<IBinder> mToken;
Arthur Hungb92218b2018-08-14 12:00:21 +0800420 InputConsumer *mConsumer;
421 PreallocatedInputEventFactory mEventFactory;
422
423 std::string mName;
Arthur Hungb92218b2018-08-14 12:00:21 +0800424 int32_t mDisplayId;
425};
426
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800427class FakeWindowHandle : public InputWindowHandle, public FakeInputReceiver {
428public:
429 static const int32_t WIDTH = 600;
430 static const int32_t HEIGHT = 800;
431
432 FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
433 const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) :
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800434 FakeInputReceiver(dispatcher, name, displayId),
435 mFocused(false) {
Robert Carr4e670e52018-08-15 13:26:12 -0700436 mServerChannel->setToken(new BBinder());
Robert Carr803535b2018-08-02 16:38:15 -0700437 mDispatcher->registerInputChannel(mServerChannel, displayId);
Robert Carr740167f2018-10-11 19:03:41 -0700438
439 inputApplicationHandle->updateInfo();
440 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800441 }
442
443 virtual bool updateInfo() {
Arthur Hung6b5a2b92019-01-31 16:39:28 +0800444 mInfo.token = mServerChannel ? mServerChannel->getToken() : nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +0800445 mInfo.name = mName;
446 mInfo.layoutParamsFlags = 0;
447 mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
448 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
449 mInfo.frameLeft = 0;
450 mInfo.frameTop = 0;
451 mInfo.frameRight = WIDTH;
452 mInfo.frameBottom = HEIGHT;
Robert Carre07e1032018-11-26 12:55:53 -0800453 mInfo.globalScaleFactor = 1.0;
Arthur Hung3b413f22018-10-26 18:05:34 +0800454 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
455 mInfo.visible = true;
456 mInfo.canReceiveKeys = true;
457 mInfo.hasFocus = mFocused;
458 mInfo.hasWallpaper = false;
459 mInfo.paused = false;
460 mInfo.layer = 0;
461 mInfo.ownerPid = INJECTOR_PID;
462 mInfo.ownerUid = INJECTOR_UID;
463 mInfo.inputFeatures = 0;
464 mInfo.displayId = mDisplayId;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800465
466 return true;
467 }
468
469 void setFocus() {
470 mFocused = true;
471 }
Arthur Hung832bc4a2019-01-28 11:43:17 +0800472
473 void releaseChannel() {
Arthur Hung6b5a2b92019-01-31 16:39:28 +0800474 mServerChannel.clear();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800475 InputWindowHandle::releaseChannel();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800476 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800477protected:
478 virtual bool handled() {
479 return true;
480 }
481
482 bool mFocused;
483};
484
Tiger Huang721e26f2018-07-24 22:26:19 +0800485static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
486 int32_t displayId = ADISPLAY_ID_NONE) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800487 KeyEvent event;
488 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
489
490 // Define a valid key down event.
Tiger Huang721e26f2018-07-24 22:26:19 +0800491 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Arthur Hungb92218b2018-08-14 12:00:21 +0800492 AKEY_EVENT_ACTION_DOWN, /* flags */ 0,
493 AKEYCODE_A, KEY_A, AMETA_NONE, /* repeatCount */ 0, currentTime, currentTime);
494
495 // Inject event until dispatch out.
496 return dispatcher->injectInputEvent(
497 &event,
498 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
499 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
500}
501
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800502static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
503 int32_t displayId) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800504 MotionEvent event;
505 PointerProperties pointerProperties[1];
506 PointerCoords pointerCoords[1];
507
508 pointerProperties[0].clear();
509 pointerProperties[0].id = 0;
510 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
511
512 pointerCoords[0].clear();
513 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
514 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
515
516 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
517 // Define a valid motion down event.
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800518 event.initialize(DEVICE_ID, source, displayId,
Arthur Hungb92218b2018-08-14 12:00:21 +0800519 AMOTION_EVENT_ACTION_DOWN, /* actionButton */0, /* flags */ 0, /* edgeFlags */ 0,
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800520 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
521 /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
Arthur Hungb92218b2018-08-14 12:00:21 +0800522 /* yPrecision */ 0, currentTime, currentTime, /*pointerCount*/ 1, pointerProperties,
523 pointerCoords);
524
525 // Inject event until dispatch out.
526 return dispatcher->injectInputEvent(
527 &event,
528 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
529 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
530}
531
Jackal Guof9696682018-10-05 12:23:23 +0800532static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
533 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
534 // Define a valid key event.
535 NotifyKeyArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
536 displayId, POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0,
537 AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);
538
539 return args;
540}
541
542static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
543 PointerProperties pointerProperties[1];
544 PointerCoords pointerCoords[1];
545
546 pointerProperties[0].clear();
547 pointerProperties[0].id = 0;
548 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
549
550 pointerCoords[0].clear();
551 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
552 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
553
554 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
555 // Define a valid motion event.
556 NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
557 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
558 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
559 AMOTION_EVENT_EDGE_FLAG_NONE, /* deviceTimestamp */ 0, 1, pointerProperties,
560 pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0, currentTime,
561 /* videoFrames */ {});
562
563 return args;
564}
565
Arthur Hungb92218b2018-08-14 12:00:21 +0800566TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
567 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800568 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
569 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800570
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800571 std::vector<sp<InputWindowHandle>> inputWindowHandles;
572 inputWindowHandles.push_back(window);
Arthur Hungb92218b2018-08-14 12:00:21 +0800573
574 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800575 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
576 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800577 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
578
579 // Window should receive motion event.
580 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
581}
582
583// The foreground window should receive the first touch down event.
584TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
585 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800586 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
587 ADISPLAY_ID_DEFAULT);
588 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
589 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800590
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800591 std::vector<sp<InputWindowHandle>> inputWindowHandles;
592 inputWindowHandles.push_back(windowTop);
593 inputWindowHandles.push_back(windowSecond);
Arthur Hungb92218b2018-08-14 12:00:21 +0800594
595 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800596 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
597 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800598 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
599
600 // Top window should receive the touch down event. Second window should not receive anything.
601 windowTop->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
602 windowSecond->assertNoEvents();
603}
604
605TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
606 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800607 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
608 ADISPLAY_ID_DEFAULT);
609 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
610 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800611
Arthur Hung7ab76b12019-01-09 19:17:20 +0800612 // Set focused application.
Tiger Huang721e26f2018-07-24 22:26:19 +0800613 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +0800614
615 // Expect one focus window exist in display.
616 windowSecond->setFocus();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800617 std::vector<sp<InputWindowHandle>> inputWindowHandles;
618 inputWindowHandles.push_back(windowTop);
619 inputWindowHandles.push_back(windowSecond);
Arthur Hungb92218b2018-08-14 12:00:21 +0800620
621 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
622 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
623 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
624
625 // Focused window should receive event.
626 windowTop->assertNoEvents();
627 windowSecond->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
628}
629
Arthur Hung7ab76b12019-01-09 19:17:20 +0800630TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
631 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
632 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
633 ADISPLAY_ID_DEFAULT);
634 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
635 ADISPLAY_ID_DEFAULT);
636
637 // Set focused application.
638 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
639
640 // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
641 windowTop->setFocus();
642 windowSecond->setFocus();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800643 std::vector<sp<InputWindowHandle>> inputWindowHandles;
644 inputWindowHandles.push_back(windowTop);
645 inputWindowHandles.push_back(windowSecond);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800646
647 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
648 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
649 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
650
651 // Top focused window should receive event.
652 windowTop->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
653 windowSecond->assertNoEvents();
654}
655
Arthur Hung3b413f22018-10-26 18:05:34 +0800656TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
657 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
658
659 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
660 ADISPLAY_ID_DEFAULT);
661 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
662 ADISPLAY_ID_DEFAULT);
663
Arthur Hung832bc4a2019-01-28 11:43:17 +0800664 // Set focused application.
665 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hung3b413f22018-10-26 18:05:34 +0800666
Arthur Hung832bc4a2019-01-28 11:43:17 +0800667 windowTop->setFocus();
668 windowSecond->setFocus();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800669 std::vector<sp<InputWindowHandle>> inputWindowHandles;
670 inputWindowHandles.push_back(windowTop);
671 inputWindowHandles.push_back(windowSecond);
Arthur Hung3b413f22018-10-26 18:05:34 +0800672 // Release channel for window is no longer valid.
673 windowTop->releaseChannel();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800674 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hung3b413f22018-10-26 18:05:34 +0800675
Arthur Hung832bc4a2019-01-28 11:43:17 +0800676 // Test inject a key down, should dispatch to a valid window.
677 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
678 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Arthur Hung3b413f22018-10-26 18:05:34 +0800679
680 // Top window is invalid, so it should not receive any input event.
681 windowTop->assertNoEvents();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800682 windowSecond->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
Arthur Hung3b413f22018-10-26 18:05:34 +0800683}
684
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800685/* Test InputDispatcher for MultiDisplay */
686class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
687public:
688 static constexpr int32_t SECOND_DISPLAY_ID = 1;
689 virtual void SetUp() {
690 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +0800691
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800692 application1 = new FakeApplicationHandle();
693 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
694 ADISPLAY_ID_DEFAULT);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800695 std::vector<sp<InputWindowHandle>> inputWindowHandles;
696 inputWindowHandles.push_back(windowInPrimary);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800697 // Set focus window for primary display, but focused display would be second one.
698 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
699 windowInPrimary->setFocus();
700 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800701
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800702 application2 = new FakeApplicationHandle();
703 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
704 SECOND_DISPLAY_ID);
705 // Set focus to second display window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800706 std::vector<sp<InputWindowHandle>> inputWindowHandles_Second;
707 inputWindowHandles_Second.push_back(windowInSecondary);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800708 // Set focus display to second one.
709 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
710 // Set focus window for second display.
711 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
712 windowInSecondary->setFocus();
713 mDispatcher->setInputWindows(inputWindowHandles_Second, SECOND_DISPLAY_ID);
714 }
715
716 virtual void TearDown() {
717 InputDispatcherTest::TearDown();
718
719 application1.clear();
720 windowInPrimary.clear();
721 application2.clear();
722 windowInSecondary.clear();
723 }
724
725protected:
726 sp<FakeApplicationHandle> application1;
727 sp<FakeWindowHandle> windowInPrimary;
728 sp<FakeApplicationHandle> application2;
729 sp<FakeWindowHandle> windowInSecondary;
730};
731
732TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
733 // Test touch down on primary display.
734 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
735 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800736 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
737 windowInPrimary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
738 windowInSecondary->assertNoEvents();
739
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800740 // Test touch down on second display.
741 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
742 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +0800743 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
744 windowInPrimary->assertNoEvents();
745 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, SECOND_DISPLAY_ID);
746}
747
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800748TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +0800749 // Test inject a key down with display id specified.
750 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
751 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
752 windowInPrimary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_DEFAULT);
753 windowInSecondary->assertNoEvents();
754
755 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +0800756 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
757 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
758 windowInPrimary->assertNoEvents();
759 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
760
761 // Remove secondary display.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800762 std::vector<sp<InputWindowHandle>> noWindows;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800763 mDispatcher->setInputWindows(noWindows, SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800764
765 // Expect old focus should receive a cancel event.
Tiger Huang8664f8c2018-10-11 19:14:35 +0800766 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE,
767 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +0800768
769 // Test inject a key down, should timeout because of no target window.
770 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
771 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
772 windowInPrimary->assertNoEvents();
773 windowInSecondary->assertNoEvents();
774}
775
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800776class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
777public:
778 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
779 int32_t displayId) : FakeInputReceiver(dispatcher, name, displayId) {
Robert Carr803535b2018-08-02 16:38:15 -0700780 mDispatcher->registerInputChannel(mServerChannel, displayId);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800781 }
782};
783
784// Test per-display input monitors for motion event.
785TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
786 sp<FakeMonitorReceiver> monitorInPrimary =
787 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
788 sp<FakeMonitorReceiver> monitorInSecondary =
789 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
790
791 // Test touch down on primary display.
792 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
793 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
794 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
795 windowInPrimary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
796 monitorInPrimary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
797 windowInSecondary->assertNoEvents();
798 monitorInSecondary->assertNoEvents();
799
800 // Test touch down on second display.
801 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
802 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
803 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
804 windowInPrimary->assertNoEvents();
805 monitorInPrimary->assertNoEvents();
806 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, SECOND_DISPLAY_ID);
807 monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, SECOND_DISPLAY_ID);
808
809 // Test inject a non-pointer motion event.
810 // If specific a display, it will dispatch to the focused window of particular display,
811 // or it will dispatch to the focused window of focused display.
812 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
813 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
814 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
815 windowInPrimary->assertNoEvents();
816 monitorInPrimary->assertNoEvents();
817 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_NONE);
818 monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_NONE);
819}
820
821// Test per-display input monitors for key event.
822TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
823 //Input monitor per display.
824 sp<FakeMonitorReceiver> monitorInPrimary =
825 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
826 sp<FakeMonitorReceiver> monitorInSecondary =
827 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
828
829 // Test inject a key down.
830 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
831 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
832 windowInPrimary->assertNoEvents();
833 monitorInPrimary->assertNoEvents();
834 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
835 monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
836}
837
Jackal Guof9696682018-10-05 12:23:23 +0800838class InputFilterTest : public InputDispatcherTest {
839protected:
840 static constexpr int32_t SECOND_DISPLAY_ID = 1;
841
842 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
843 NotifyMotionArgs motionArgs;
844
845 motionArgs = generateMotionArgs(
846 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
847 mDispatcher->notifyMotion(&motionArgs);
848 motionArgs = generateMotionArgs(
849 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
850 mDispatcher->notifyMotion(&motionArgs);
851
852 if (expectToBeFiltered) {
853 mFakePolicy->assertFilterInputEventWasCalledWithExpectedArgs(&motionArgs);
854 } else {
855 mFakePolicy->assertFilterInputEventWasNotCalled();
856 }
857 }
858
859 void testNotifyKey(bool expectToBeFiltered) {
860 NotifyKeyArgs keyArgs;
861
862 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
863 mDispatcher->notifyKey(&keyArgs);
864 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
865 mDispatcher->notifyKey(&keyArgs);
866
867 if (expectToBeFiltered) {
868 mFakePolicy->assertFilterInputEventWasCalledWithExpectedArgs(&keyArgs);
869 } else {
870 mFakePolicy->assertFilterInputEventWasNotCalled();
871 }
872 }
873};
874
875// Test InputFilter for MotionEvent
876TEST_F(InputFilterTest, MotionEvent_InputFilter) {
877 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
878 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
879 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
880
881 // Enable InputFilter
882 mDispatcher->setInputFilterEnabled(true);
883 // Test touch on both primary and second display, and check if both events are filtered.
884 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
885 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
886
887 // Disable InputFilter
888 mDispatcher->setInputFilterEnabled(false);
889 // Test touch on both primary and second display, and check if both events aren't filtered.
890 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
891 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
892}
893
894// Test InputFilter for KeyEvent
895TEST_F(InputFilterTest, KeyEvent_InputFilter) {
896 // Since the InputFilter is disabled by default, check if key event aren't filtered.
897 testNotifyKey(/*expectToBeFiltered*/ false);
898
899 // Enable InputFilter
900 mDispatcher->setInputFilterEnabled(true);
901 // Send a key event, and check if it is filtered.
902 testNotifyKey(/*expectToBeFiltered*/ true);
903
904 // Disable InputFilter
905 mDispatcher->setInputFilterEnabled(false);
906 // Send a key event, and check if it isn't filtered.
907 testNotifyKey(/*expectToBeFiltered*/ false);
908}
909
Michael Wrightd02c5b62014-02-10 15:10:22 -0800910} // namespace android