blob: 8863ec2517cb89710d72342b60d6179ad72f44dd [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
Garfield Tan0fc2fa72019-08-29 17:22:15 -070017#include "../dispatcher/InputDispatcher.h"
Michael Wrightd02c5b62014-02-10 15:10:22 -080018
Garfield Tane84e6f92019-08-29 17:28:41 -070019#include <InputDispatcherThread.h>
20
Robert Carr803535b2018-08-02 16:38:15 -070021#include <binder/Binder.h>
22
Michael Wrightd02c5b62014-02-10 15:10:22 -080023#include <gtest/gtest.h>
24#include <linux/input.h>
25
Garfield Tane84e6f92019-08-29 17:28:41 -070026namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080027
28// An arbitrary time value.
29static const nsecs_t ARBITRARY_TIME = 1234;
30
31// An arbitrary device id.
32static const int32_t DEVICE_ID = 1;
33
Jeff Brownf086ddb2014-02-11 14:28:48 -080034// An arbitrary display id.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -080035static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
Jeff Brownf086ddb2014-02-11 14:28:48 -080036
Michael Wrightd02c5b62014-02-10 15:10:22 -080037// An arbitrary injector pid / uid pair that has permission to inject events.
38static const int32_t INJECTOR_PID = 999;
39static const int32_t INJECTOR_UID = 1001;
40
41
42// --- FakeInputDispatcherPolicy ---
43
44class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
45 InputDispatcherConfiguration mConfig;
46
47protected:
48 virtual ~FakeInputDispatcherPolicy() {
49 }
50
51public:
52 FakeInputDispatcherPolicy() {
chaviwfd6d3512019-03-25 13:23:49 -070053 mOnPointerDownToken.clear();
Jackal Guof9696682018-10-05 12:23:23 +080054 }
55
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080056 void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
57 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
58 ASSERT_EQ(mFilteredEvent->getType(), AINPUT_EVENT_TYPE_KEY);
Jackal Guof9696682018-10-05 12:23:23 +080059
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080060 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
61 ASSERT_EQ(keyEvent.getEventTime(), args.eventTime);
62 ASSERT_EQ(keyEvent.getAction(), args.action);
63 ASSERT_EQ(keyEvent.getDisplayId(), args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080064
65 reset();
66 }
67
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080068 void assertFilterInputEventWasCalled(const NotifyMotionArgs& args) {
69 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
70 ASSERT_EQ(mFilteredEvent->getType(), AINPUT_EVENT_TYPE_MOTION);
Jackal Guof9696682018-10-05 12:23:23 +080071
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080072 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
73 ASSERT_EQ(motionEvent.getEventTime(), args.eventTime);
74 ASSERT_EQ(motionEvent.getAction(), args.action);
75 ASSERT_EQ(motionEvent.getDisplayId(), args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080076
77 reset();
78 }
79
80 void assertFilterInputEventWasNotCalled() {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080081 ASSERT_EQ(nullptr, mFilteredEvent)
Jackal Guof9696682018-10-05 12:23:23 +080082 << "Expected filterInputEvent() to not have been called.";
Michael Wrightd02c5b62014-02-10 15:10:22 -080083 }
84
chaviwfd6d3512019-03-25 13:23:49 -070085 void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
86 ASSERT_EQ(mOnPointerDownToken, touchedToken)
87 << "Expected token from onPointerDownOutsideFocus was not matched";
88 reset();
89 }
90
Michael Wrightd02c5b62014-02-10 15:10:22 -080091private:
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080092 std::unique_ptr<InputEvent> mFilteredEvent;
chaviwfd6d3512019-03-25 13:23:49 -070093 sp<IBinder> mOnPointerDownToken;
Jackal Guof9696682018-10-05 12:23:23 +080094
Narayan Kamath39efe3e2014-10-17 10:37:08 +010095 virtual void notifyConfigurationChanged(nsecs_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080096 }
97
Narayan Kamath39efe3e2014-10-17 10:37:08 +010098 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&,
Robert Carr803535b2018-08-02 16:38:15 -070099 const sp<IBinder>&,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800100 const std::string&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800101 return 0;
102 }
103
Robert Carr803535b2018-08-02 16:38:15 -0700104 virtual void notifyInputChannelBroken(const sp<IBinder>&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800105 }
106
chaviw0c06c6e2019-01-09 13:27:07 -0800107 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) {
Robert Carr740167f2018-10-11 19:03:41 -0700108 }
109
Michael Wrightd02c5b62014-02-10 15:10:22 -0800110 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
111 *outConfig = mConfig;
112 }
113
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800114 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Jackal Guof9696682018-10-05 12:23:23 +0800115 switch (inputEvent->getType()) {
116 case AINPUT_EVENT_TYPE_KEY: {
117 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800118 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800119 break;
120 }
121
122 case AINPUT_EVENT_TYPE_MOTION: {
123 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800124 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800125 break;
126 }
127 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800128 return true;
129 }
130
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100131 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800132 }
133
Charles Chen3611f1f2019-01-29 17:26:18 +0800134 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800135 }
136
Robert Carr803535b2018-08-02 16:38:15 -0700137 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100138 const KeyEvent*, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139 return 0;
140 }
141
Robert Carr803535b2018-08-02 16:38:15 -0700142 virtual bool dispatchUnhandledKey(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100143 const KeyEvent*, uint32_t, KeyEvent*) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800144 return false;
145 }
146
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100147 virtual void notifySwitch(nsecs_t, uint32_t, uint32_t, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800148 }
149
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100150 virtual void pokeUserActivity(nsecs_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800151 }
152
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100153 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800154 return false;
155 }
Jackal Guof9696682018-10-05 12:23:23 +0800156
chaviwfd6d3512019-03-25 13:23:49 -0700157 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) {
158 mOnPointerDownToken = newToken;
159 }
160
Jackal Guof9696682018-10-05 12:23:23 +0800161 void reset() {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800162 mFilteredEvent = nullptr;
chaviwfd6d3512019-03-25 13:23:49 -0700163 mOnPointerDownToken.clear();
Jackal Guof9696682018-10-05 12:23:23 +0800164 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165};
166
167
168// --- InputDispatcherTest ---
169
170class InputDispatcherTest : public testing::Test {
171protected:
172 sp<FakeInputDispatcherPolicy> mFakePolicy;
173 sp<InputDispatcher> mDispatcher;
Arthur Hungb92218b2018-08-14 12:00:21 +0800174 sp<InputDispatcherThread> mDispatcherThread;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175
176 virtual void SetUp() {
177 mFakePolicy = new FakeInputDispatcherPolicy();
178 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800179 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
180 //Start InputDispatcher thread
181 mDispatcherThread = new InputDispatcherThread(mDispatcher);
182 mDispatcherThread->run("InputDispatcherTest", PRIORITY_URGENT_DISPLAY);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800183 }
184
185 virtual void TearDown() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800186 mDispatcherThread->requestExit();
187 mDispatcherThread.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800188 mFakePolicy.clear();
189 mDispatcher.clear();
190 }
191};
192
193
194TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
195 KeyEvent event;
196
197 // Rejects undefined key actions.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100198 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800199 /*action*/ -1, 0,
200 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800201 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800202 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800203 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
204 << "Should reject key events with undefined action.";
205
206 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100207 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800208 AKEY_EVENT_ACTION_MULTIPLE, 0,
209 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
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 key events with ACTION_MULTIPLE.";
214}
215
216TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
217 MotionEvent event;
218 PointerProperties pointerProperties[MAX_POINTERS + 1];
219 PointerCoords pointerCoords[MAX_POINTERS + 1];
220 for (int i = 0; i <= MAX_POINTERS; i++) {
221 pointerProperties[i].clear();
222 pointerProperties[i].id = i;
223 pointerCoords[i].clear();
224 }
225
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800226 // Some constants commonly used below
227 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
228 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
229 constexpr int32_t metaState = AMETA_NONE;
230 constexpr MotionClassification classification = MotionClassification::NONE;
231
Michael Wrightd02c5b62014-02-10 15:10:22 -0800232 // Rejects undefined motion actions.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800233 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700234 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
235 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
236 ARBITRARY_TIME, ARBITRARY_TIME,
237 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800238 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800239 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800240 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
241 << "Should reject motion events with undefined action.";
242
243 // Rejects pointer down with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800244 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700245 AMOTION_EVENT_ACTION_POINTER_DOWN |
246 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
247 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
248 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
249 ARBITRARY_TIME, ARBITRARY_TIME,
250 /*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,
Garfield Tan00f511d2019-06-12 16:55:40 -0700257 AMOTION_EVENT_ACTION_POINTER_DOWN |
258 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
259 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
260 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
261 ARBITRARY_TIME, ARBITRARY_TIME,
262 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800263 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800264 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
266 << "Should reject motion events with pointer down index too small.";
267
268 // Rejects pointer up with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800269 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700270 AMOTION_EVENT_ACTION_POINTER_UP |
271 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
272 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
273 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
274 ARBITRARY_TIME, ARBITRARY_TIME,
275 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800276 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800277 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800278 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
279 << "Should reject motion events with pointer up index too large.";
280
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800281 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700282 AMOTION_EVENT_ACTION_POINTER_UP |
283 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
284 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
285 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
286 ARBITRARY_TIME, ARBITRARY_TIME,
287 /*pointerCount*/ 1, 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 pointer up index too small.";
292
293 // Rejects motion events with invalid number of pointers.
Garfield Tan00f511d2019-06-12 16:55:40 -0700294 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
295 metaState, 0, classification, 0, 0, 0, 0,
296 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
297 ARBITRARY_TIME, ARBITRARY_TIME,
298 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800299 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800300 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800301 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
302 << "Should reject motion events with 0 pointers.";
303
Garfield Tan00f511d2019-06-12 16:55:40 -0700304 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
305 metaState, 0, classification, 0, 0, 0, 0,
306 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
307 ARBITRARY_TIME, ARBITRARY_TIME,
308 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800309 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800310 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800311 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
312 << "Should reject motion events with more than MAX_POINTERS pointers.";
313
314 // Rejects motion events with invalid pointer ids.
315 pointerProperties[0].id = -1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700316 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
317 metaState, 0, classification, 0, 0, 0, 0,
318 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
319 ARBITRARY_TIME, ARBITRARY_TIME,
320 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800321 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800322 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800323 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
324 << "Should reject motion events with pointer ids less than 0.";
325
326 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700327 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
328 metaState, 0, classification, 0, 0, 0, 0,
329 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
330 ARBITRARY_TIME, ARBITRARY_TIME,
331 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800332 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800333 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800334 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
335 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
336
337 // Rejects motion events with duplicate pointer ids.
338 pointerProperties[0].id = 1;
339 pointerProperties[1].id = 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700340 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
341 metaState, 0, classification, 0, 0, 0, 0,
342 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
343 ARBITRARY_TIME, ARBITRARY_TIME,
344 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800345 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800346 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800347 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
348 << "Should reject motion events with duplicate pointer ids.";
349}
350
Arthur Hungb92218b2018-08-14 12:00:21 +0800351// --- InputDispatcherTest SetInputWindowTest ---
352static const int32_t INJECT_EVENT_TIMEOUT = 500;
353static const int32_t DISPATCHING_TIMEOUT = 100;
354
355class FakeApplicationHandle : public InputApplicationHandle {
356public:
357 FakeApplicationHandle() {}
358 virtual ~FakeApplicationHandle() {}
359
360 virtual bool updateInfo() {
Arthur Hung7a0c39a2019-03-20 16:52:24 +0800361 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
Arthur Hungb92218b2018-08-14 12:00:21 +0800362 return true;
363 }
364};
365
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800366class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800367public:
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800368 InputEvent* consume() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800369 uint32_t consumeSeq;
370 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800371
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800372 std::chrono::time_point start = std::chrono::steady_clock::now();
373 status_t status = WOULD_BLOCK;
374 while (status == WOULD_BLOCK) {
375 status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1, &consumeSeq,
376 &event);
377 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
378 if (elapsed > 100ms) {
379 break;
380 }
381 }
382
383 if (status == WOULD_BLOCK) {
384 // Just means there's no event available.
385 return nullptr;
386 }
387
388 if (status != OK) {
389 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
390 return nullptr;
391 }
392 if (event == nullptr) {
393 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
394 return nullptr;
395 }
396
397 status = mConsumer->sendFinishedSignal(consumeSeq, handled());
398 if (status != OK) {
399 ADD_FAILURE() << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
400 }
401 return event;
402 }
403
404 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
405 int32_t expectedFlags) {
406 InputEvent* event = consume();
407
408 ASSERT_NE(nullptr, event) << mName.c_str()
409 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800410 ASSERT_EQ(expectedEventType, event->getType())
Tiger Huang8664f8c2018-10-11 19:14:35 +0800411 << mName.c_str() << ": event type should match.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800412
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800413 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800414
Tiger Huang8664f8c2018-10-11 19:14:35 +0800415 switch (expectedEventType) {
416 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800417 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
418 EXPECT_EQ(expectedAction, keyEvent.getAction());
419 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800420 break;
421 }
422 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800423 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
424 EXPECT_EQ(expectedAction, motionEvent.getAction());
425 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800426 break;
427 }
428 default: {
429 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
430 }
431 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800432 }
433
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800434 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
435 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
436 expectedFlags);
437 }
438
439 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
440 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
441 expectedFlags);
442 }
443
Arthur Hungb92218b2018-08-14 12:00:21 +0800444 void assertNoEvents() {
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800445 InputEvent* event = consume();
446 ASSERT_EQ(nullptr, event)
Arthur Hungb92218b2018-08-14 12:00:21 +0800447 << mName.c_str()
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800448 << ": should not have received any events, so consume() should return NULL";
Arthur Hungb92218b2018-08-14 12:00:21 +0800449 }
450
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800451protected:
452 explicit FakeInputReceiver(const sp<InputDispatcher>& dispatcher,
453 const std::string name, int32_t displayId) :
454 mDispatcher(dispatcher), mName(name), mDisplayId(displayId) {
455 InputChannel::openInputChannelPair(name, mServerChannel, mClientChannel);
456 mConsumer = new InputConsumer(mClientChannel);
457 }
458
459 virtual ~FakeInputReceiver() {
460 }
461
462 // return true if the event has been handled.
463 virtual bool handled() {
464 return false;
465 }
466
Arthur Hungb92218b2018-08-14 12:00:21 +0800467 sp<InputDispatcher> mDispatcher;
468 sp<InputChannel> mServerChannel, mClientChannel;
469 InputConsumer *mConsumer;
470 PreallocatedInputEventFactory mEventFactory;
471
472 std::string mName;
Arthur Hungb92218b2018-08-14 12:00:21 +0800473 int32_t mDisplayId;
474};
475
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800476class FakeWindowHandle : public InputWindowHandle, public FakeInputReceiver {
477public:
478 static const int32_t WIDTH = 600;
479 static const int32_t HEIGHT = 800;
480
481 FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
482 const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) :
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800483 FakeInputReceiver(dispatcher, name, displayId),
chaviwfd6d3512019-03-25 13:23:49 -0700484 mFocused(false), mFrame(Rect(0, 0, WIDTH, HEIGHT)), mLayoutParamFlags(0) {
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -0700485 mDispatcher->registerInputChannel(mServerChannel);
chaviwfd6d3512019-03-25 13:23:49 -0700486
Robert Carr740167f2018-10-11 19:03:41 -0700487 inputApplicationHandle->updateInfo();
488 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800489 }
490
491 virtual bool updateInfo() {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700492 mInfo.token = mServerChannel ? mServerChannel->getConnectionToken() : nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +0800493 mInfo.name = mName;
chaviwfd6d3512019-03-25 13:23:49 -0700494 mInfo.layoutParamsFlags = mLayoutParamFlags;
Arthur Hung3b413f22018-10-26 18:05:34 +0800495 mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
496 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwfd6d3512019-03-25 13:23:49 -0700497 mInfo.frameLeft = mFrame.left;
498 mInfo.frameTop = mFrame.top;
499 mInfo.frameRight = mFrame.right;
500 mInfo.frameBottom = mFrame.bottom;
Robert Carre07e1032018-11-26 12:55:53 -0800501 mInfo.globalScaleFactor = 1.0;
Garfield Tan00f511d2019-06-12 16:55:40 -0700502 mInfo.touchableRegion.clear();
chaviwfd6d3512019-03-25 13:23:49 -0700503 mInfo.addTouchableRegion(mFrame);
Arthur Hung3b413f22018-10-26 18:05:34 +0800504 mInfo.visible = true;
505 mInfo.canReceiveKeys = true;
506 mInfo.hasFocus = mFocused;
507 mInfo.hasWallpaper = false;
508 mInfo.paused = false;
509 mInfo.layer = 0;
510 mInfo.ownerPid = INJECTOR_PID;
511 mInfo.ownerUid = INJECTOR_UID;
512 mInfo.inputFeatures = 0;
513 mInfo.displayId = mDisplayId;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800514
515 return true;
516 }
517
518 void setFocus() {
519 mFocused = true;
520 }
Arthur Hung832bc4a2019-01-28 11:43:17 +0800521
chaviwfd6d3512019-03-25 13:23:49 -0700522 void setFrame(const Rect& frame) {
523 mFrame.set(frame);
524 }
525
526 void setLayoutParamFlags(int32_t flags) {
527 mLayoutParamFlags = flags;
528 }
529
Arthur Hung832bc4a2019-01-28 11:43:17 +0800530 void releaseChannel() {
Arthur Hung6b5a2b92019-01-31 16:39:28 +0800531 mServerChannel.clear();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800532 InputWindowHandle::releaseChannel();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800533 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800534protected:
535 virtual bool handled() {
536 return true;
537 }
538
539 bool mFocused;
chaviwfd6d3512019-03-25 13:23:49 -0700540 Rect mFrame;
541 int32_t mLayoutParamFlags;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800542};
543
Tiger Huang721e26f2018-07-24 22:26:19 +0800544static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
545 int32_t displayId = ADISPLAY_ID_NONE) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800546 KeyEvent event;
547 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
548
549 // Define a valid key down event.
Tiger Huang721e26f2018-07-24 22:26:19 +0800550 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Arthur Hungb92218b2018-08-14 12:00:21 +0800551 AKEY_EVENT_ACTION_DOWN, /* flags */ 0,
552 AKEYCODE_A, KEY_A, AMETA_NONE, /* repeatCount */ 0, currentTime, currentTime);
553
554 // Inject event until dispatch out.
555 return dispatcher->injectInputEvent(
556 &event,
557 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
558 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
559}
560
Garfield Tan00f511d2019-06-12 16:55:40 -0700561static int32_t injectMotionEvent(const sp<InputDispatcher>& dispatcher, int32_t action,
562 int32_t source, int32_t displayId, int32_t x, int32_t y,
563 int32_t xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION,
564 int32_t yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800565 MotionEvent event;
566 PointerProperties pointerProperties[1];
567 PointerCoords pointerCoords[1];
568
569 pointerProperties[0].clear();
570 pointerProperties[0].id = 0;
571 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
572
573 pointerCoords[0].clear();
chaviwfd6d3512019-03-25 13:23:49 -0700574 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
575 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
Arthur Hungb92218b2018-08-14 12:00:21 +0800576
577 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
578 // Define a valid motion down event.
Garfield Tan00f511d2019-06-12 16:55:40 -0700579 event.initialize(DEVICE_ID, source, displayId, action, /* actionButton */ 0, /* flags */ 0,
580 /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
581 /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
582 /* yPrecision */ 0, xCursorPosition, yCursorPosition, currentTime, currentTime,
583 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Arthur Hungb92218b2018-08-14 12:00:21 +0800584
585 // Inject event until dispatch out.
586 return dispatcher->injectInputEvent(
587 &event,
588 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
589 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
590}
591
Garfield Tan00f511d2019-06-12 16:55:40 -0700592static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
593 int32_t displayId, int32_t x = 100, int32_t y = 200) {
594 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, x, y);
595}
596
Jackal Guof9696682018-10-05 12:23:23 +0800597static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
598 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
599 // Define a valid key event.
600 NotifyKeyArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
601 displayId, POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0,
602 AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);
603
604 return args;
605}
606
607static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
608 PointerProperties pointerProperties[1];
609 PointerCoords pointerCoords[1];
610
611 pointerProperties[0].clear();
612 pointerProperties[0].id = 0;
613 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
614
615 pointerCoords[0].clear();
616 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
617 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
618
619 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
620 // Define a valid motion event.
621 NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -0700622 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
623 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
Atif Niyaz21da0ff2019-06-28 13:22:51 -0700624 AMOTION_EVENT_EDGE_FLAG_NONE, 1, pointerProperties, pointerCoords,
625 /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -0700626 AMOTION_EVENT_INVALID_CURSOR_POSITION,
627 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +0800628
629 return args;
630}
631
Arthur Hungb92218b2018-08-14 12:00:21 +0800632TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
633 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800634 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
635 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800636
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800637 std::vector<sp<InputWindowHandle>> inputWindowHandles;
638 inputWindowHandles.push_back(window);
Arthur Hungb92218b2018-08-14 12:00:21 +0800639
640 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800641 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
642 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800643 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
644
645 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800646 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800647}
648
649// The foreground window should receive the first touch down event.
650TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
651 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800652 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
653 ADISPLAY_ID_DEFAULT);
654 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
655 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800656
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800657 std::vector<sp<InputWindowHandle>> inputWindowHandles;
658 inputWindowHandles.push_back(windowTop);
659 inputWindowHandles.push_back(windowSecond);
Arthur Hungb92218b2018-08-14 12:00:21 +0800660
661 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800662 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
663 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800664 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
665
666 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800667 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800668 windowSecond->assertNoEvents();
669}
670
671TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
672 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800673 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
674 ADISPLAY_ID_DEFAULT);
675 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
676 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800677
Arthur Hung7ab76b12019-01-09 19:17:20 +0800678 // Set focused application.
Tiger Huang721e26f2018-07-24 22:26:19 +0800679 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +0800680
681 // Expect one focus window exist in display.
682 windowSecond->setFocus();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800683 std::vector<sp<InputWindowHandle>> inputWindowHandles;
684 inputWindowHandles.push_back(windowTop);
685 inputWindowHandles.push_back(windowSecond);
Arthur Hungb92218b2018-08-14 12:00:21 +0800686
687 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
688 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
689 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
690
691 // Focused window should receive event.
692 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800693 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800694}
695
Arthur Hung7ab76b12019-01-09 19:17:20 +0800696TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
697 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
698 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
699 ADISPLAY_ID_DEFAULT);
700 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
701 ADISPLAY_ID_DEFAULT);
702
703 // Set focused application.
704 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
705
706 // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
707 windowTop->setFocus();
708 windowSecond->setFocus();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800709 std::vector<sp<InputWindowHandle>> inputWindowHandles;
710 inputWindowHandles.push_back(windowTop);
711 inputWindowHandles.push_back(windowSecond);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800712
713 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
714 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
715 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
716
717 // Top focused window should receive event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800718 windowTop->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800719 windowSecond->assertNoEvents();
720}
721
Arthur Hung3b413f22018-10-26 18:05:34 +0800722TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
723 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
724
725 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
726 ADISPLAY_ID_DEFAULT);
727 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
728 ADISPLAY_ID_DEFAULT);
729
Arthur Hung832bc4a2019-01-28 11:43:17 +0800730 // Set focused application.
731 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hung3b413f22018-10-26 18:05:34 +0800732
Arthur Hung832bc4a2019-01-28 11:43:17 +0800733 windowTop->setFocus();
734 windowSecond->setFocus();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800735 std::vector<sp<InputWindowHandle>> inputWindowHandles;
736 inputWindowHandles.push_back(windowTop);
737 inputWindowHandles.push_back(windowSecond);
Arthur Hung3b413f22018-10-26 18:05:34 +0800738 // Release channel for window is no longer valid.
739 windowTop->releaseChannel();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800740 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hung3b413f22018-10-26 18:05:34 +0800741
Arthur Hung832bc4a2019-01-28 11:43:17 +0800742 // Test inject a key down, should dispatch to a valid window.
743 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
744 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Arthur Hung3b413f22018-10-26 18:05:34 +0800745
746 // Top window is invalid, so it should not receive any input event.
747 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800748 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung3b413f22018-10-26 18:05:34 +0800749}
750
Garfield Tan00f511d2019-06-12 16:55:40 -0700751TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
752 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
753
754 sp<FakeWindowHandle> windowLeft =
755 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
756 windowLeft->setFrame(Rect(0, 0, 600, 800));
757 windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
758 sp<FakeWindowHandle> windowRight =
759 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
760 windowRight->setFrame(Rect(600, 0, 1200, 800));
761 windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
762
763 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
764
765 std::vector<sp<InputWindowHandle>> inputWindowHandles{windowLeft, windowRight};
766 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
767
768 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
769 // left window. This event should be dispatched to the left window.
770 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
771 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
772 ADISPLAY_ID_DEFAULT, 610, 400, 599, 400));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800773 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700774 windowRight->assertNoEvents();
775}
776
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800777/* Test InputDispatcher for MultiDisplay */
778class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
779public:
780 static constexpr int32_t SECOND_DISPLAY_ID = 1;
781 virtual void SetUp() {
782 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +0800783
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800784 application1 = new FakeApplicationHandle();
785 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
786 ADISPLAY_ID_DEFAULT);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800787 std::vector<sp<InputWindowHandle>> inputWindowHandles;
788 inputWindowHandles.push_back(windowInPrimary);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800789 // Set focus window for primary display, but focused display would be second one.
790 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
791 windowInPrimary->setFocus();
792 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800793
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800794 application2 = new FakeApplicationHandle();
795 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
796 SECOND_DISPLAY_ID);
797 // Set focus to second display window.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800798 std::vector<sp<InputWindowHandle>> inputWindowHandles_Second;
799 inputWindowHandles_Second.push_back(windowInSecondary);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800800 // Set focus display to second one.
801 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
802 // Set focus window for second display.
803 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
804 windowInSecondary->setFocus();
805 mDispatcher->setInputWindows(inputWindowHandles_Second, SECOND_DISPLAY_ID);
806 }
807
808 virtual void TearDown() {
809 InputDispatcherTest::TearDown();
810
811 application1.clear();
812 windowInPrimary.clear();
813 application2.clear();
814 windowInSecondary.clear();
815 }
816
817protected:
818 sp<FakeApplicationHandle> application1;
819 sp<FakeWindowHandle> windowInPrimary;
820 sp<FakeApplicationHandle> application2;
821 sp<FakeWindowHandle> windowInSecondary;
822};
823
824TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
825 // Test touch down on primary display.
826 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
827 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800828 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800829 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800830 windowInSecondary->assertNoEvents();
831
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800832 // Test touch down on second display.
833 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
834 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +0800835 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
836 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800837 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800838}
839
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800840TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +0800841 // Test inject a key down with display id specified.
842 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
843 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800844 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +0800845 windowInSecondary->assertNoEvents();
846
847 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +0800848 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
849 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
850 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800851 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800852
853 // Remove secondary display.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800854 std::vector<sp<InputWindowHandle>> noWindows;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800855 mDispatcher->setInputWindows(noWindows, SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800856
857 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800858 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
859 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +0800860
861 // Test inject a key down, should timeout because of no target window.
862 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
863 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
864 windowInPrimary->assertNoEvents();
865 windowInSecondary->assertNoEvents();
866}
867
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800868class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
869public:
870 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
Michael Wright3dd60e22019-03-27 22:06:44 +0000871 int32_t displayId, bool isGestureMonitor = false)
872 : FakeInputReceiver(dispatcher, name, displayId) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000873 mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800874 }
875};
876
877// Test per-display input monitors for motion event.
878TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
879 sp<FakeMonitorReceiver> monitorInPrimary =
880 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
881 sp<FakeMonitorReceiver> monitorInSecondary =
882 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
883
884 // Test touch down on primary display.
885 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
886 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
887 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800888 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
889 monitorInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800890 windowInSecondary->assertNoEvents();
891 monitorInSecondary->assertNoEvents();
892
893 // Test touch down on second display.
894 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
895 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
896 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
897 windowInPrimary->assertNoEvents();
898 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800899 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
900 monitorInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800901
902 // Test inject a non-pointer motion event.
903 // If specific a display, it will dispatch to the focused window of particular display,
904 // or it will dispatch to the focused window of focused display.
905 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
906 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
907 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
908 windowInPrimary->assertNoEvents();
909 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800910 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
911 monitorInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800912}
913
914// Test per-display input monitors for key event.
915TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
916 //Input monitor per display.
917 sp<FakeMonitorReceiver> monitorInPrimary =
918 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
919 sp<FakeMonitorReceiver> monitorInSecondary =
920 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
921
922 // Test inject a key down.
923 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
924 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
925 windowInPrimary->assertNoEvents();
926 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800927 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
928 monitorInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800929}
930
Jackal Guof9696682018-10-05 12:23:23 +0800931class InputFilterTest : public InputDispatcherTest {
932protected:
933 static constexpr int32_t SECOND_DISPLAY_ID = 1;
934
935 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
936 NotifyMotionArgs motionArgs;
937
938 motionArgs = generateMotionArgs(
939 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
940 mDispatcher->notifyMotion(&motionArgs);
941 motionArgs = generateMotionArgs(
942 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
943 mDispatcher->notifyMotion(&motionArgs);
944
945 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800946 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +0800947 } else {
948 mFakePolicy->assertFilterInputEventWasNotCalled();
949 }
950 }
951
952 void testNotifyKey(bool expectToBeFiltered) {
953 NotifyKeyArgs keyArgs;
954
955 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
956 mDispatcher->notifyKey(&keyArgs);
957 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
958 mDispatcher->notifyKey(&keyArgs);
959
960 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800961 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +0800962 } else {
963 mFakePolicy->assertFilterInputEventWasNotCalled();
964 }
965 }
966};
967
968// Test InputFilter for MotionEvent
969TEST_F(InputFilterTest, MotionEvent_InputFilter) {
970 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
971 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
972 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
973
974 // Enable InputFilter
975 mDispatcher->setInputFilterEnabled(true);
976 // Test touch on both primary and second display, and check if both events are filtered.
977 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
978 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
979
980 // Disable InputFilter
981 mDispatcher->setInputFilterEnabled(false);
982 // Test touch on both primary and second display, and check if both events aren't filtered.
983 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
984 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
985}
986
987// Test InputFilter for KeyEvent
988TEST_F(InputFilterTest, KeyEvent_InputFilter) {
989 // Since the InputFilter is disabled by default, check if key event aren't filtered.
990 testNotifyKey(/*expectToBeFiltered*/ false);
991
992 // Enable InputFilter
993 mDispatcher->setInputFilterEnabled(true);
994 // Send a key event, and check if it is filtered.
995 testNotifyKey(/*expectToBeFiltered*/ true);
996
997 // Disable InputFilter
998 mDispatcher->setInputFilterEnabled(false);
999 // Send a key event, and check if it isn't filtered.
1000 testNotifyKey(/*expectToBeFiltered*/ false);
1001}
1002
chaviwfd6d3512019-03-25 13:23:49 -07001003class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
1004 virtual void SetUp() {
1005 InputDispatcherTest::SetUp();
1006
1007 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1008 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
1009 ADISPLAY_ID_DEFAULT);
1010 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
1011 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
1012 // window.
1013 mUnfocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1014
1015 mWindowFocused = new FakeWindowHandle(application, mDispatcher, "Second",
1016 ADISPLAY_ID_DEFAULT);
1017 mWindowFocused->setFrame(Rect(50, 50, 100, 100));
1018 mWindowFocused->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1019 mWindowFocusedTouchPoint = 60;
1020
1021 // Set focused application.
1022 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1023 mWindowFocused->setFocus();
1024
1025 // Expect one focus window exist in display.
1026 std::vector<sp<InputWindowHandle>> inputWindowHandles;
1027 inputWindowHandles.push_back(mUnfocusedWindow);
1028 inputWindowHandles.push_back(mWindowFocused);
1029 mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT);
1030 }
1031
1032 virtual void TearDown() {
1033 InputDispatcherTest::TearDown();
1034
1035 mUnfocusedWindow.clear();
1036 mWindowFocused.clear();
1037 }
1038
1039protected:
1040 sp<FakeWindowHandle> mUnfocusedWindow;
1041 sp<FakeWindowHandle> mWindowFocused;
1042 int32_t mWindowFocusedTouchPoint;
1043};
1044
1045// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1046// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
1047// the onPointerDownOutsideFocus callback.
1048TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
1049 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1050 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20))
1051 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1052 // Call monitor to wait for the command queue to get flushed.
1053 mDispatcher->monitor();
1054
1055 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
1056}
1057
1058// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
1059// DOWN on the window that doesn't have focus. Ensure no window received the
1060// onPointerDownOutsideFocus callback.
1061TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
1062 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1063 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20))
1064 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1065 // Call monitor to wait for the command queue to get flushed.
1066 mDispatcher->monitor();
1067
1068 mFakePolicy->assertOnPointerDownEquals(nullptr);
1069}
1070
1071// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
1072// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
1073TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
1074 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1075 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1076 // Call monitor to wait for the command queue to get flushed.
1077 mDispatcher->monitor();
1078
1079 mFakePolicy->assertOnPointerDownEquals(nullptr);
1080}
1081
1082// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1083// DOWN on the window that already has focus. Ensure no window received the
1084// onPointerDownOutsideFocus callback.
1085TEST_F(InputDispatcherOnPointerDownOutsideFocus,
1086 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
1087 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1088 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, mWindowFocusedTouchPoint,
1089 mWindowFocusedTouchPoint))
1090 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1091 // Call monitor to wait for the command queue to get flushed.
1092 mDispatcher->monitor();
1093
1094 mFakePolicy->assertOnPointerDownEquals(nullptr);
1095}
1096
Garfield Tane84e6f92019-08-29 17:28:41 -07001097} // namespace android::inputdispatcher