blob: b385fe9fa17091c546679b16d045776fe441a188 [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() {
51 }
52
53private:
Narayan Kamath39efe3e2014-10-17 10:37:08 +010054 virtual void notifyConfigurationChanged(nsecs_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080055 }
56
Narayan Kamath39efe3e2014-10-17 10:37:08 +010057 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&,
Robert Carr803535b2018-08-02 16:38:15 -070058 const sp<IBinder>&,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080059 const std::string&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080060 return 0;
61 }
62
Robert Carr803535b2018-08-02 16:38:15 -070063 virtual void notifyInputChannelBroken(const sp<IBinder>&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080064 }
65
chaviw0c06c6e2019-01-09 13:27:07 -080066 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) {
Robert Carr740167f2018-10-11 19:03:41 -070067 }
68
Michael Wrightd02c5b62014-02-10 15:10:22 -080069 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
70 *outConfig = mConfig;
71 }
72
Narayan Kamath39efe3e2014-10-17 10:37:08 +010073 virtual bool filterInputEvent(const InputEvent*, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080074 return true;
75 }
76
Narayan Kamath39efe3e2014-10-17 10:37:08 +010077 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080078 }
79
Narayan Kamath39efe3e2014-10-17 10:37:08 +010080 virtual void interceptMotionBeforeQueueing(nsecs_t, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080081 }
82
Robert Carr803535b2018-08-02 16:38:15 -070083 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +010084 const KeyEvent*, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080085 return 0;
86 }
87
Robert Carr803535b2018-08-02 16:38:15 -070088 virtual bool dispatchUnhandledKey(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +010089 const KeyEvent*, uint32_t, KeyEvent*) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080090 return false;
91 }
92
Narayan Kamath39efe3e2014-10-17 10:37:08 +010093 virtual void notifySwitch(nsecs_t, uint32_t, uint32_t, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080094 }
95
Narayan Kamath39efe3e2014-10-17 10:37:08 +010096 virtual void pokeUserActivity(nsecs_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080097 }
98
Narayan Kamath39efe3e2014-10-17 10:37:08 +010099 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800100 return false;
101 }
102};
103
104
105// --- InputDispatcherTest ---
106
107class InputDispatcherTest : public testing::Test {
108protected:
109 sp<FakeInputDispatcherPolicy> mFakePolicy;
110 sp<InputDispatcher> mDispatcher;
Arthur Hungb92218b2018-08-14 12:00:21 +0800111 sp<InputDispatcherThread> mDispatcherThread;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800112
113 virtual void SetUp() {
114 mFakePolicy = new FakeInputDispatcherPolicy();
115 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800116 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
117 //Start InputDispatcher thread
118 mDispatcherThread = new InputDispatcherThread(mDispatcher);
119 mDispatcherThread->run("InputDispatcherTest", PRIORITY_URGENT_DISPLAY);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800120 }
121
122 virtual void TearDown() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800123 mDispatcherThread->requestExit();
124 mDispatcherThread.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800125 mFakePolicy.clear();
126 mDispatcher.clear();
127 }
128};
129
130
131TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
132 KeyEvent event;
133
134 // Rejects undefined key actions.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100135 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800136 /*action*/ -1, 0,
137 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800138 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800139 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
141 << "Should reject key events with undefined action.";
142
143 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100144 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800145 AKEY_EVENT_ACTION_MULTIPLE, 0,
146 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800147 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800148 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800149 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
150 << "Should reject key events with ACTION_MULTIPLE.";
151}
152
153TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
154 MotionEvent event;
155 PointerProperties pointerProperties[MAX_POINTERS + 1];
156 PointerCoords pointerCoords[MAX_POINTERS + 1];
157 for (int i = 0; i <= MAX_POINTERS; i++) {
158 pointerProperties[i].clear();
159 pointerProperties[i].id = i;
160 pointerCoords[i].clear();
161 }
162
163 // Rejects undefined motion actions.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800164 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Michael Wright7b159c92015-05-14 14:48:03 +0100165 /*action*/ -1, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800166 ARBITRARY_TIME, ARBITRARY_TIME,
167 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800168 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800169 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800170 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
171 << "Should reject motion events with undefined action.";
172
173 // Rejects pointer down with invalid index.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800174 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Michael Wright7b159c92015-05-14 14:48:03 +0100176 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800177 ARBITRARY_TIME, ARBITRARY_TIME,
178 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800179 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800180 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
182 << "Should reject motion events with pointer down index too large.";
183
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800184 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Dan Albert8b10c652016-02-02 17:08:05 -0800185 AMOTION_EVENT_ACTION_POINTER_DOWN | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Michael Wright7b159c92015-05-14 14:48:03 +0100186 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800187 ARBITRARY_TIME, ARBITRARY_TIME,
188 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800189 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800190 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
192 << "Should reject motion events with pointer down index too small.";
193
194 // Rejects pointer up with invalid index.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800195 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800196 AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Michael Wright7b159c92015-05-14 14:48:03 +0100197 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800198 ARBITRARY_TIME, ARBITRARY_TIME,
199 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800200 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800201 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
203 << "Should reject motion events with pointer up index too large.";
204
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800205 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Dan Albert8b10c652016-02-02 17:08:05 -0800206 AMOTION_EVENT_ACTION_POINTER_UP | (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Michael Wright7b159c92015-05-14 14:48:03 +0100207 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800208 ARBITRARY_TIME, ARBITRARY_TIME,
209 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800210 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800211 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
213 << "Should reject motion events with pointer up index too small.";
214
215 // Rejects motion events with invalid number of pointers.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800216 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Michael Wright7b159c92015-05-14 14:48:03 +0100217 AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 ARBITRARY_TIME, ARBITRARY_TIME,
219 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800220 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800221 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800222 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
223 << "Should reject motion events with 0 pointers.";
224
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800225 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Michael Wright7b159c92015-05-14 14:48:03 +0100226 AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227 ARBITRARY_TIME, ARBITRARY_TIME,
228 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800229 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800230 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800231 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
232 << "Should reject motion events with more than MAX_POINTERS pointers.";
233
234 // Rejects motion events with invalid pointer ids.
235 pointerProperties[0].id = -1;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800236 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Michael Wright7b159c92015-05-14 14:48:03 +0100237 AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800238 ARBITRARY_TIME, ARBITRARY_TIME,
239 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800240 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800241 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
243 << "Should reject motion events with pointer ids less than 0.";
244
245 pointerProperties[0].id = MAX_POINTER_ID + 1;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800246 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Michael Wright7b159c92015-05-14 14:48:03 +0100247 AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800248 ARBITRARY_TIME, ARBITRARY_TIME,
249 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800250 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800251 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800252 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
253 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
254
255 // Rejects motion events with duplicate pointer ids.
256 pointerProperties[0].id = 1;
257 pointerProperties[1].id = 1;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800258 event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
Michael Wright7b159c92015-05-14 14:48:03 +0100259 AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800260 ARBITRARY_TIME, ARBITRARY_TIME,
261 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800262 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800263 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800264 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
265 << "Should reject motion events with duplicate pointer ids.";
266}
267
Arthur Hungb92218b2018-08-14 12:00:21 +0800268// --- InputDispatcherTest SetInputWindowTest ---
269static const int32_t INJECT_EVENT_TIMEOUT = 500;
270static const int32_t DISPATCHING_TIMEOUT = 100;
271
272class FakeApplicationHandle : public InputApplicationHandle {
273public:
274 FakeApplicationHandle() {}
275 virtual ~FakeApplicationHandle() {}
276
277 virtual bool updateInfo() {
278 if (!mInfo) {
279 mInfo = new InputApplicationInfo();
280 }
281 mInfo->dispatchingTimeout = DISPATCHING_TIMEOUT;
282 return true;
283 }
284};
285
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800286class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800287public:
Tiger Huang8664f8c2018-10-11 19:14:35 +0800288 void consumeEvent(int32_t expectedEventType, int32_t expectedDisplayId,
289 int32_t expectedFlags = 0) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800290 uint32_t consumeSeq;
291 InputEvent* event;
292 status_t status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1,
293 &consumeSeq, &event);
294
295 ASSERT_EQ(OK, status)
296 << mName.c_str() << ": consumer consume should return OK.";
297 ASSERT_TRUE(event != nullptr)
298 << mName.c_str() << ": consumer should have returned non-NULL event.";
299 ASSERT_EQ(expectedEventType, event->getType())
Tiger Huang8664f8c2018-10-11 19:14:35 +0800300 << mName.c_str() << ": event type should match.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800301
302 ASSERT_EQ(expectedDisplayId, event->getDisplayId())
Tiger Huang8664f8c2018-10-11 19:14:35 +0800303 << mName.c_str() << ": event displayId should be the same as expected.";
304
305 int32_t flags;
306 switch (expectedEventType) {
307 case AINPUT_EVENT_TYPE_KEY: {
308 KeyEvent* typedEvent = static_cast<KeyEvent*>(event);
309 flags = typedEvent->getFlags();
310 break;
311 }
312 case AINPUT_EVENT_TYPE_MOTION: {
313 MotionEvent* typedEvent = static_cast<MotionEvent*>(event);
314 flags = typedEvent->getFlags();
315 break;
316 }
317 default: {
318 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
319 }
320 }
321 ASSERT_EQ(expectedFlags, flags)
322 << mName.c_str() << ": event flags should be the same as expected.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800323
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800324 status = mConsumer->sendFinishedSignal(consumeSeq, handled());
Arthur Hungb92218b2018-08-14 12:00:21 +0800325 ASSERT_EQ(OK, status)
326 << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
327 }
328
329 void assertNoEvents() {
330 uint32_t consumeSeq;
331 InputEvent* event;
332 status_t status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1,
333 &consumeSeq, &event);
334 ASSERT_NE(OK, status)
335 << mName.c_str()
336 << ": should not have received any events, so consume(..) should not return OK.";
337 }
338
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800339protected:
340 explicit FakeInputReceiver(const sp<InputDispatcher>& dispatcher,
341 const std::string name, int32_t displayId) :
342 mDispatcher(dispatcher), mName(name), mDisplayId(displayId) {
343 InputChannel::openInputChannelPair(name, mServerChannel, mClientChannel);
344 mConsumer = new InputConsumer(mClientChannel);
345 }
346
347 virtual ~FakeInputReceiver() {
348 }
349
350 // return true if the event has been handled.
351 virtual bool handled() {
352 return false;
353 }
354
Arthur Hungb92218b2018-08-14 12:00:21 +0800355 sp<InputDispatcher> mDispatcher;
356 sp<InputChannel> mServerChannel, mClientChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -0700357 sp<IBinder> mToken;
Arthur Hungb92218b2018-08-14 12:00:21 +0800358 InputConsumer *mConsumer;
359 PreallocatedInputEventFactory mEventFactory;
360
361 std::string mName;
Arthur Hungb92218b2018-08-14 12:00:21 +0800362 int32_t mDisplayId;
363};
364
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800365class FakeWindowHandle : public InputWindowHandle, public FakeInputReceiver {
366public:
367 static const int32_t WIDTH = 600;
368 static const int32_t HEIGHT = 800;
369
370 FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
371 const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) :
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800372 FakeInputReceiver(dispatcher, name, displayId),
373 mFocused(false) {
Robert Carr4e670e52018-08-15 13:26:12 -0700374 mServerChannel->setToken(new BBinder());
Robert Carr803535b2018-08-02 16:38:15 -0700375 mDispatcher->registerInputChannel(mServerChannel, displayId);
Robert Carr740167f2018-10-11 19:03:41 -0700376
377 inputApplicationHandle->updateInfo();
378 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800379 }
380
381 virtual bool updateInfo() {
Robert Carr5c8a0262018-10-03 16:30:44 -0700382 mInfo.token = mServerChannel->getToken();
Arthur Hung3b413f22018-10-26 18:05:34 +0800383 mInfo.name = mName;
384 mInfo.layoutParamsFlags = 0;
385 mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
386 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
387 mInfo.frameLeft = 0;
388 mInfo.frameTop = 0;
389 mInfo.frameRight = WIDTH;
390 mInfo.frameBottom = HEIGHT;
Robert Carre07e1032018-11-26 12:55:53 -0800391 mInfo.globalScaleFactor = 1.0;
Arthur Hung3b413f22018-10-26 18:05:34 +0800392 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
393 mInfo.visible = true;
394 mInfo.canReceiveKeys = true;
395 mInfo.hasFocus = mFocused;
396 mInfo.hasWallpaper = false;
397 mInfo.paused = false;
398 mInfo.layer = 0;
399 mInfo.ownerPid = INJECTOR_PID;
400 mInfo.ownerUid = INJECTOR_UID;
401 mInfo.inputFeatures = 0;
402 mInfo.displayId = mDisplayId;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800403
404 return true;
405 }
406
407 void setFocus() {
408 mFocused = true;
409 }
410
411 void assertNoEvents() {
412 uint32_t consumeSeq;
413 InputEvent* event;
414 status_t status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1,
415 &consumeSeq, &event);
416 ASSERT_NE(OK, status)
417 << mName.c_str()
418 << ": should not have received any events, so consume(..) should not return OK.";
419 }
420protected:
421 virtual bool handled() {
422 return true;
423 }
424
425 bool mFocused;
426};
427
Tiger Huang721e26f2018-07-24 22:26:19 +0800428static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
429 int32_t displayId = ADISPLAY_ID_NONE) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800430 KeyEvent event;
431 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
432
433 // Define a valid key down event.
Tiger Huang721e26f2018-07-24 22:26:19 +0800434 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Arthur Hungb92218b2018-08-14 12:00:21 +0800435 AKEY_EVENT_ACTION_DOWN, /* flags */ 0,
436 AKEYCODE_A, KEY_A, AMETA_NONE, /* repeatCount */ 0, currentTime, currentTime);
437
438 // Inject event until dispatch out.
439 return dispatcher->injectInputEvent(
440 &event,
441 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
442 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
443}
444
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800445static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
446 int32_t displayId) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800447 MotionEvent event;
448 PointerProperties pointerProperties[1];
449 PointerCoords pointerCoords[1];
450
451 pointerProperties[0].clear();
452 pointerProperties[0].id = 0;
453 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
454
455 pointerCoords[0].clear();
456 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
457 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
458
459 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
460 // Define a valid motion down event.
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800461 event.initialize(DEVICE_ID, source, displayId,
Arthur Hungb92218b2018-08-14 12:00:21 +0800462 AMOTION_EVENT_ACTION_DOWN, /* actionButton */0, /* flags */ 0, /* edgeFlags */ 0,
463 AMETA_NONE, /* buttonState */ 0, /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
464 /* yPrecision */ 0, currentTime, currentTime, /*pointerCount*/ 1, pointerProperties,
465 pointerCoords);
466
467 // Inject event until dispatch out.
468 return dispatcher->injectInputEvent(
469 &event,
470 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
471 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
472}
473
474TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
475 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800476 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
477 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800478
479 Vector<sp<InputWindowHandle>> inputWindowHandles;
480 inputWindowHandles.add(window);
481
482 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800483 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
484 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800485 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
486
487 // Window should receive motion event.
488 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
489}
490
491// The foreground window should receive the first touch down event.
492TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
493 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800494 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
495 ADISPLAY_ID_DEFAULT);
496 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
497 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800498
499 Vector<sp<InputWindowHandle>> inputWindowHandles;
500 inputWindowHandles.add(windowTop);
501 inputWindowHandles.add(windowSecond);
502
503 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800504 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
505 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800506 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
507
508 // Top window should receive the touch down event. Second window should not receive anything.
509 windowTop->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
510 windowSecond->assertNoEvents();
511}
512
513TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
514 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800515 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
516 ADISPLAY_ID_DEFAULT);
517 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
518 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800519
520 // Set focus application.
Tiger Huang721e26f2018-07-24 22:26:19 +0800521 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +0800522
523 // Expect one focus window exist in display.
524 windowSecond->setFocus();
525 Vector<sp<InputWindowHandle>> inputWindowHandles;
526 inputWindowHandles.add(windowTop);
527 inputWindowHandles.add(windowSecond);
528
529 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
530 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
531 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
532
533 // Focused window should receive event.
534 windowTop->assertNoEvents();
535 windowSecond->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
536}
537
Arthur Hung3b413f22018-10-26 18:05:34 +0800538TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
539 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
540
541 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
542 ADISPLAY_ID_DEFAULT);
543 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
544 ADISPLAY_ID_DEFAULT);
545
546 windowTop->setFocus();
547
548 Vector<sp<InputWindowHandle>> inputWindowHandles;
549 inputWindowHandles.add(windowTop);
550 inputWindowHandles.add(windowSecond);
551
552 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
553
554 // Release channel for window is no longer valid.
555 windowTop->releaseChannel();
556
557 // Test inject a motion down, should timeout because of no target channel.
558 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
559 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
560
561 // Top window is invalid, so it should not receive any input event.
562 windowTop->assertNoEvents();
563 windowSecond->assertNoEvents();
564}
565
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800566/* Test InputDispatcher for MultiDisplay */
567class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
568public:
569 static constexpr int32_t SECOND_DISPLAY_ID = 1;
570 virtual void SetUp() {
571 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +0800572
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800573 application1 = new FakeApplicationHandle();
574 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
575 ADISPLAY_ID_DEFAULT);
576 Vector<sp<InputWindowHandle>> inputWindowHandles;
577 inputWindowHandles.push(windowInPrimary);
578 // Set focus window for primary display, but focused display would be second one.
579 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
580 windowInPrimary->setFocus();
581 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800582
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800583 application2 = new FakeApplicationHandle();
584 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
585 SECOND_DISPLAY_ID);
586 // Set focus to second display window.
587 Vector<sp<InputWindowHandle>> inputWindowHandles_Second;
588 inputWindowHandles_Second.push(windowInSecondary);
589 // Set focus display to second one.
590 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
591 // Set focus window for second display.
592 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
593 windowInSecondary->setFocus();
594 mDispatcher->setInputWindows(inputWindowHandles_Second, SECOND_DISPLAY_ID);
595 }
596
597 virtual void TearDown() {
598 InputDispatcherTest::TearDown();
599
600 application1.clear();
601 windowInPrimary.clear();
602 application2.clear();
603 windowInSecondary.clear();
604 }
605
606protected:
607 sp<FakeApplicationHandle> application1;
608 sp<FakeWindowHandle> windowInPrimary;
609 sp<FakeApplicationHandle> application2;
610 sp<FakeWindowHandle> windowInSecondary;
611};
612
613TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
614 // Test touch down on primary display.
615 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
616 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800617 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
618 windowInPrimary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
619 windowInSecondary->assertNoEvents();
620
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800621 // Test touch down on second display.
622 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
623 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +0800624 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
625 windowInPrimary->assertNoEvents();
626 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, SECOND_DISPLAY_ID);
627}
628
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800629TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +0800630 // Test inject a key down with display id specified.
631 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
632 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
633 windowInPrimary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_DEFAULT);
634 windowInSecondary->assertNoEvents();
635
636 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +0800637 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
638 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
639 windowInPrimary->assertNoEvents();
640 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
641
642 // Remove secondary display.
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800643 Vector<sp<InputWindowHandle>> noWindows;
644 mDispatcher->setInputWindows(noWindows, SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800645
646 // Expect old focus should receive a cancel event.
Tiger Huang8664f8c2018-10-11 19:14:35 +0800647 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE,
648 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +0800649
650 // Test inject a key down, should timeout because of no target window.
651 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
652 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
653 windowInPrimary->assertNoEvents();
654 windowInSecondary->assertNoEvents();
655}
656
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800657class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
658public:
659 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
660 int32_t displayId) : FakeInputReceiver(dispatcher, name, displayId) {
Robert Carr803535b2018-08-02 16:38:15 -0700661 mDispatcher->registerInputChannel(mServerChannel, displayId);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800662 }
663};
664
665// Test per-display input monitors for motion event.
666TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
667 sp<FakeMonitorReceiver> monitorInPrimary =
668 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
669 sp<FakeMonitorReceiver> monitorInSecondary =
670 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
671
672 // Test touch down on primary display.
673 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
674 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
675 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
676 windowInPrimary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
677 monitorInPrimary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_DEFAULT);
678 windowInSecondary->assertNoEvents();
679 monitorInSecondary->assertNoEvents();
680
681 // Test touch down on second display.
682 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
683 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
684 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
685 windowInPrimary->assertNoEvents();
686 monitorInPrimary->assertNoEvents();
687 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, SECOND_DISPLAY_ID);
688 monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, SECOND_DISPLAY_ID);
689
690 // Test inject a non-pointer motion event.
691 // If specific a display, it will dispatch to the focused window of particular display,
692 // or it will dispatch to the focused window of focused display.
693 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
694 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
695 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
696 windowInPrimary->assertNoEvents();
697 monitorInPrimary->assertNoEvents();
698 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_NONE);
699 monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, ADISPLAY_ID_NONE);
700}
701
702// Test per-display input monitors for key event.
703TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
704 //Input monitor per display.
705 sp<FakeMonitorReceiver> monitorInPrimary =
706 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
707 sp<FakeMonitorReceiver> monitorInSecondary =
708 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
709
710 // Test inject a key down.
711 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
712 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
713 windowInPrimary->assertNoEvents();
714 monitorInPrimary->assertNoEvents();
715 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
716 monitorInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE);
717}
718
Michael Wrightd02c5b62014-02-10 15:10:22 -0800719} // namespace android