blob: 4f282611d5d36037f6301303ceec4de5dfba47fd [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>
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080022#include <input/Input.h>
Robert Carr803535b2018-08-02 16:38:15 -070023
Michael Wrightd02c5b62014-02-10 15:10:22 -080024#include <gtest/gtest.h>
25#include <linux/input.h>
26
Garfield Tane84e6f92019-08-29 17:28:41 -070027namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080028
29// An arbitrary time value.
30static const nsecs_t ARBITRARY_TIME = 1234;
31
32// An arbitrary device id.
33static const int32_t DEVICE_ID = 1;
34
Jeff Brownf086ddb2014-02-11 14:28:48 -080035// An arbitrary display id.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -080036static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
Jeff Brownf086ddb2014-02-11 14:28:48 -080037
Michael Wrightd02c5b62014-02-10 15:10:22 -080038// An arbitrary injector pid / uid pair that has permission to inject events.
39static const int32_t INJECTOR_PID = 999;
40static const int32_t INJECTOR_UID = 1001;
41
42
43// --- FakeInputDispatcherPolicy ---
44
45class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
46 InputDispatcherConfiguration mConfig;
47
48protected:
49 virtual ~FakeInputDispatcherPolicy() {
50 }
51
52public:
53 FakeInputDispatcherPolicy() {
chaviwfd6d3512019-03-25 13:23:49 -070054 mOnPointerDownToken.clear();
Jackal Guof9696682018-10-05 12:23:23 +080055 }
56
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080057 void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080058 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_KEY, args.eventTime, args.action,
59 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080060 }
61
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080062 void assertFilterInputEventWasCalled(const NotifyMotionArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080063 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_MOTION, args.eventTime, args.action,
64 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080065 }
66
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080067 void assertFilterInputEventWasNotCalled() { ASSERT_EQ(nullptr, mFilteredEvent); }
Michael Wrightd02c5b62014-02-10 15:10:22 -080068
chaviwfd6d3512019-03-25 13:23:49 -070069 void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
70 ASSERT_EQ(mOnPointerDownToken, touchedToken)
71 << "Expected token from onPointerDownOutsideFocus was not matched";
72 reset();
73 }
74
Michael Wrightd02c5b62014-02-10 15:10:22 -080075private:
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080076 std::unique_ptr<InputEvent> mFilteredEvent;
chaviwfd6d3512019-03-25 13:23:49 -070077 sp<IBinder> mOnPointerDownToken;
Jackal Guof9696682018-10-05 12:23:23 +080078
Narayan Kamath39efe3e2014-10-17 10:37:08 +010079 virtual void notifyConfigurationChanged(nsecs_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080080 }
81
Narayan Kamath39efe3e2014-10-17 10:37:08 +010082 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&,
Robert Carr803535b2018-08-02 16:38:15 -070083 const sp<IBinder>&,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080084 const std::string&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080085 return 0;
86 }
87
Robert Carr803535b2018-08-02 16:38:15 -070088 virtual void notifyInputChannelBroken(const sp<IBinder>&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -080089 }
90
chaviw0c06c6e2019-01-09 13:27:07 -080091 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) {
Robert Carr740167f2018-10-11 19:03:41 -070092 }
93
Michael Wrightd02c5b62014-02-10 15:10:22 -080094 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
95 *outConfig = mConfig;
96 }
97
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080098 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Jackal Guof9696682018-10-05 12:23:23 +080099 switch (inputEvent->getType()) {
100 case AINPUT_EVENT_TYPE_KEY: {
101 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800102 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800103 break;
104 }
105
106 case AINPUT_EVENT_TYPE_MOTION: {
107 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800108 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800109 break;
110 }
111 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800112 return true;
113 }
114
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100115 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800116 }
117
Charles Chen3611f1f2019-01-29 17:26:18 +0800118 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800119 }
120
Robert Carr803535b2018-08-02 16:38:15 -0700121 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100122 const KeyEvent*, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800123 return 0;
124 }
125
Robert Carr803535b2018-08-02 16:38:15 -0700126 virtual bool dispatchUnhandledKey(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100127 const KeyEvent*, uint32_t, KeyEvent*) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800128 return false;
129 }
130
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100131 virtual void notifySwitch(nsecs_t, uint32_t, uint32_t, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800132 }
133
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100134 virtual void pokeUserActivity(nsecs_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800135 }
136
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100137 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800138 return false;
139 }
Jackal Guof9696682018-10-05 12:23:23 +0800140
chaviwfd6d3512019-03-25 13:23:49 -0700141 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) {
142 mOnPointerDownToken = newToken;
143 }
144
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800145 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
146 int32_t displayId) {
147 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
148 ASSERT_EQ(mFilteredEvent->getType(), type);
149
150 if (type == AINPUT_EVENT_TYPE_KEY) {
151 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
152 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
153 EXPECT_EQ(keyEvent.getAction(), action);
154 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
155 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
156 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
157 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
158 EXPECT_EQ(motionEvent.getAction(), action);
159 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
160 } else {
161 FAIL() << "Unknown type: " << type;
162 }
163
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800164 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800165 }
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800166
167 void reset() { mOnPointerDownToken.clear(); }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800168};
169
170
171// --- InputDispatcherTest ---
172
173class InputDispatcherTest : public testing::Test {
174protected:
175 sp<FakeInputDispatcherPolicy> mFakePolicy;
176 sp<InputDispatcher> mDispatcher;
Arthur Hungb92218b2018-08-14 12:00:21 +0800177 sp<InputDispatcherThread> mDispatcherThread;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800178
179 virtual void SetUp() {
180 mFakePolicy = new FakeInputDispatcherPolicy();
181 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800182 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
183 //Start InputDispatcher thread
184 mDispatcherThread = new InputDispatcherThread(mDispatcher);
185 mDispatcherThread->run("InputDispatcherTest", PRIORITY_URGENT_DISPLAY);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186 }
187
188 virtual void TearDown() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800189 mDispatcherThread->requestExit();
190 mDispatcherThread.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 mFakePolicy.clear();
192 mDispatcher.clear();
193 }
194};
195
196
197TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
198 KeyEvent event;
199
200 // Rejects undefined key actions.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100201 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 /*action*/ -1, 0,
203 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800204 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800205 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800206 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
207 << "Should reject key events with undefined action.";
208
209 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100210 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 AKEY_EVENT_ACTION_MULTIPLE, 0,
212 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800213 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800214 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800215 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
216 << "Should reject key events with ACTION_MULTIPLE.";
217}
218
219TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
220 MotionEvent event;
221 PointerProperties pointerProperties[MAX_POINTERS + 1];
222 PointerCoords pointerCoords[MAX_POINTERS + 1];
223 for (int i = 0; i <= MAX_POINTERS; i++) {
224 pointerProperties[i].clear();
225 pointerProperties[i].id = i;
226 pointerCoords[i].clear();
227 }
228
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800229 // Some constants commonly used below
230 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
231 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
232 constexpr int32_t metaState = AMETA_NONE;
233 constexpr MotionClassification classification = MotionClassification::NONE;
234
Michael Wrightd02c5b62014-02-10 15:10:22 -0800235 // Rejects undefined motion actions.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800236 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700237 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
238 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
239 ARBITRARY_TIME, ARBITRARY_TIME,
240 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800241 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800242 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800243 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
244 << "Should reject motion events with undefined action.";
245
246 // Rejects pointer down with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800247 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700248 AMOTION_EVENT_ACTION_POINTER_DOWN |
249 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
250 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
251 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
252 ARBITRARY_TIME, ARBITRARY_TIME,
253 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800254 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800255 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800256 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
257 << "Should reject motion events with pointer down index too large.";
258
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800259 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700260 AMOTION_EVENT_ACTION_POINTER_DOWN |
261 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
262 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
263 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
264 ARBITRARY_TIME, ARBITRARY_TIME,
265 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800266 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800267 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800268 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
269 << "Should reject motion events with pointer down index too small.";
270
271 // Rejects pointer up with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800272 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700273 AMOTION_EVENT_ACTION_POINTER_UP |
274 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
275 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
276 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
277 ARBITRARY_TIME, ARBITRARY_TIME,
278 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800279 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800280 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800281 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
282 << "Should reject motion events with pointer up index too large.";
283
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800284 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700285 AMOTION_EVENT_ACTION_POINTER_UP |
286 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
287 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
288 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
289 ARBITRARY_TIME, ARBITRARY_TIME,
290 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800291 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800292 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800293 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
294 << "Should reject motion events with pointer up index too small.";
295
296 // Rejects motion events with invalid number of pointers.
Garfield Tan00f511d2019-06-12 16:55:40 -0700297 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
298 metaState, 0, classification, 0, 0, 0, 0,
299 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
300 ARBITRARY_TIME, ARBITRARY_TIME,
301 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800302 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800303 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800304 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
305 << "Should reject motion events with 0 pointers.";
306
Garfield Tan00f511d2019-06-12 16:55:40 -0700307 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
308 metaState, 0, classification, 0, 0, 0, 0,
309 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
310 ARBITRARY_TIME, ARBITRARY_TIME,
311 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800312 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800313 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800314 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
315 << "Should reject motion events with more than MAX_POINTERS pointers.";
316
317 // Rejects motion events with invalid pointer ids.
318 pointerProperties[0].id = -1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700319 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
320 metaState, 0, classification, 0, 0, 0, 0,
321 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
322 ARBITRARY_TIME, ARBITRARY_TIME,
323 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800324 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800325 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800326 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
327 << "Should reject motion events with pointer ids less than 0.";
328
329 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700330 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
331 metaState, 0, classification, 0, 0, 0, 0,
332 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
333 ARBITRARY_TIME, ARBITRARY_TIME,
334 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800335 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800336 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800337 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
338 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
339
340 // Rejects motion events with duplicate pointer ids.
341 pointerProperties[0].id = 1;
342 pointerProperties[1].id = 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700343 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
344 metaState, 0, classification, 0, 0, 0, 0,
345 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
346 ARBITRARY_TIME, ARBITRARY_TIME,
347 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800348 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800349 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800350 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
351 << "Should reject motion events with duplicate pointer ids.";
352}
353
Arthur Hungb92218b2018-08-14 12:00:21 +0800354// --- InputDispatcherTest SetInputWindowTest ---
355static const int32_t INJECT_EVENT_TIMEOUT = 500;
356static const int32_t DISPATCHING_TIMEOUT = 100;
357
358class FakeApplicationHandle : public InputApplicationHandle {
359public:
360 FakeApplicationHandle() {}
361 virtual ~FakeApplicationHandle() {}
362
363 virtual bool updateInfo() {
Arthur Hung7a0c39a2019-03-20 16:52:24 +0800364 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
Arthur Hungb92218b2018-08-14 12:00:21 +0800365 return true;
366 }
367};
368
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800369class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800370public:
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800371 InputEvent* consume() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800372 uint32_t consumeSeq;
373 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800374
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800375 std::chrono::time_point start = std::chrono::steady_clock::now();
376 status_t status = WOULD_BLOCK;
377 while (status == WOULD_BLOCK) {
378 status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1, &consumeSeq,
379 &event);
380 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
381 if (elapsed > 100ms) {
382 break;
383 }
384 }
385
386 if (status == WOULD_BLOCK) {
387 // Just means there's no event available.
388 return nullptr;
389 }
390
391 if (status != OK) {
392 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
393 return nullptr;
394 }
395 if (event == nullptr) {
396 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
397 return nullptr;
398 }
399
400 status = mConsumer->sendFinishedSignal(consumeSeq, handled());
401 if (status != OK) {
402 ADD_FAILURE() << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
403 }
404 return event;
405 }
406
407 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
408 int32_t expectedFlags) {
409 InputEvent* event = consume();
410
411 ASSERT_NE(nullptr, event) << mName.c_str()
412 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800413 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800414 << mName.c_str() << "expected " << inputEventTypeToString(expectedEventType)
415 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800416
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800417 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800418
Tiger Huang8664f8c2018-10-11 19:14:35 +0800419 switch (expectedEventType) {
420 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800421 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
422 EXPECT_EQ(expectedAction, keyEvent.getAction());
423 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800424 break;
425 }
426 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800427 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
428 EXPECT_EQ(expectedAction, motionEvent.getAction());
429 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800430 break;
431 }
432 default: {
433 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
434 }
435 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800436 }
437
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800438 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
439 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
440 expectedFlags);
441 }
442
443 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
444 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
445 expectedFlags);
446 }
447
Arthur Hungb92218b2018-08-14 12:00:21 +0800448 void assertNoEvents() {
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800449 InputEvent* event = consume();
450 ASSERT_EQ(nullptr, event)
Arthur Hungb92218b2018-08-14 12:00:21 +0800451 << mName.c_str()
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800452 << ": should not have received any events, so consume() should return NULL";
Arthur Hungb92218b2018-08-14 12:00:21 +0800453 }
454
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800455protected:
456 explicit FakeInputReceiver(const sp<InputDispatcher>& dispatcher,
457 const std::string name, int32_t displayId) :
458 mDispatcher(dispatcher), mName(name), mDisplayId(displayId) {
459 InputChannel::openInputChannelPair(name, mServerChannel, mClientChannel);
460 mConsumer = new InputConsumer(mClientChannel);
461 }
462
463 virtual ~FakeInputReceiver() {
464 }
465
466 // return true if the event has been handled.
467 virtual bool handled() {
468 return false;
469 }
470
Arthur Hungb92218b2018-08-14 12:00:21 +0800471 sp<InputDispatcher> mDispatcher;
472 sp<InputChannel> mServerChannel, mClientChannel;
473 InputConsumer *mConsumer;
474 PreallocatedInputEventFactory mEventFactory;
475
476 std::string mName;
Arthur Hungb92218b2018-08-14 12:00:21 +0800477 int32_t mDisplayId;
478};
479
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800480class FakeWindowHandle : public InputWindowHandle, public FakeInputReceiver {
481public:
482 static const int32_t WIDTH = 600;
483 static const int32_t HEIGHT = 800;
484
485 FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
486 const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) :
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800487 FakeInputReceiver(dispatcher, name, displayId),
chaviwfd6d3512019-03-25 13:23:49 -0700488 mFocused(false), mFrame(Rect(0, 0, WIDTH, HEIGHT)), mLayoutParamFlags(0) {
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -0700489 mDispatcher->registerInputChannel(mServerChannel);
chaviwfd6d3512019-03-25 13:23:49 -0700490
Robert Carr740167f2018-10-11 19:03:41 -0700491 inputApplicationHandle->updateInfo();
492 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800493 }
494
495 virtual bool updateInfo() {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700496 mInfo.token = mServerChannel ? mServerChannel->getConnectionToken() : nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +0800497 mInfo.name = mName;
chaviwfd6d3512019-03-25 13:23:49 -0700498 mInfo.layoutParamsFlags = mLayoutParamFlags;
Arthur Hung3b413f22018-10-26 18:05:34 +0800499 mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
500 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwfd6d3512019-03-25 13:23:49 -0700501 mInfo.frameLeft = mFrame.left;
502 mInfo.frameTop = mFrame.top;
503 mInfo.frameRight = mFrame.right;
504 mInfo.frameBottom = mFrame.bottom;
Robert Carre07e1032018-11-26 12:55:53 -0800505 mInfo.globalScaleFactor = 1.0;
Garfield Tan00f511d2019-06-12 16:55:40 -0700506 mInfo.touchableRegion.clear();
chaviwfd6d3512019-03-25 13:23:49 -0700507 mInfo.addTouchableRegion(mFrame);
Arthur Hung3b413f22018-10-26 18:05:34 +0800508 mInfo.visible = true;
509 mInfo.canReceiveKeys = true;
510 mInfo.hasFocus = mFocused;
511 mInfo.hasWallpaper = false;
512 mInfo.paused = false;
513 mInfo.layer = 0;
514 mInfo.ownerPid = INJECTOR_PID;
515 mInfo.ownerUid = INJECTOR_UID;
516 mInfo.inputFeatures = 0;
517 mInfo.displayId = mDisplayId;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800518
519 return true;
520 }
521
522 void setFocus() {
523 mFocused = true;
524 }
Arthur Hung832bc4a2019-01-28 11:43:17 +0800525
chaviwfd6d3512019-03-25 13:23:49 -0700526 void setFrame(const Rect& frame) {
527 mFrame.set(frame);
528 }
529
530 void setLayoutParamFlags(int32_t flags) {
531 mLayoutParamFlags = flags;
532 }
533
Arthur Hung832bc4a2019-01-28 11:43:17 +0800534 void releaseChannel() {
Arthur Hung6b5a2b92019-01-31 16:39:28 +0800535 mServerChannel.clear();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800536 InputWindowHandle::releaseChannel();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800537 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800538protected:
539 virtual bool handled() {
540 return true;
541 }
542
543 bool mFocused;
chaviwfd6d3512019-03-25 13:23:49 -0700544 Rect mFrame;
545 int32_t mLayoutParamFlags;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800546};
547
Tiger Huang721e26f2018-07-24 22:26:19 +0800548static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
549 int32_t displayId = ADISPLAY_ID_NONE) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800550 KeyEvent event;
551 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
552
553 // Define a valid key down event.
Tiger Huang721e26f2018-07-24 22:26:19 +0800554 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Arthur Hungb92218b2018-08-14 12:00:21 +0800555 AKEY_EVENT_ACTION_DOWN, /* flags */ 0,
556 AKEYCODE_A, KEY_A, AMETA_NONE, /* repeatCount */ 0, currentTime, currentTime);
557
558 // Inject event until dispatch out.
559 return dispatcher->injectInputEvent(
560 &event,
561 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
562 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
563}
564
Garfield Tan00f511d2019-06-12 16:55:40 -0700565static int32_t injectMotionEvent(const sp<InputDispatcher>& dispatcher, int32_t action,
566 int32_t source, int32_t displayId, int32_t x, int32_t y,
567 int32_t xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION,
568 int32_t yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800569 MotionEvent event;
570 PointerProperties pointerProperties[1];
571 PointerCoords pointerCoords[1];
572
573 pointerProperties[0].clear();
574 pointerProperties[0].id = 0;
575 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
576
577 pointerCoords[0].clear();
chaviwfd6d3512019-03-25 13:23:49 -0700578 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
579 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
Arthur Hungb92218b2018-08-14 12:00:21 +0800580
581 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
582 // Define a valid motion down event.
Garfield Tan00f511d2019-06-12 16:55:40 -0700583 event.initialize(DEVICE_ID, source, displayId, action, /* actionButton */ 0, /* flags */ 0,
584 /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
585 /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
586 /* yPrecision */ 0, xCursorPosition, yCursorPosition, currentTime, currentTime,
587 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Arthur Hungb92218b2018-08-14 12:00:21 +0800588
589 // Inject event until dispatch out.
590 return dispatcher->injectInputEvent(
591 &event,
592 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
593 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
594}
595
Garfield Tan00f511d2019-06-12 16:55:40 -0700596static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
597 int32_t displayId, int32_t x = 100, int32_t y = 200) {
598 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, x, y);
599}
600
Jackal Guof9696682018-10-05 12:23:23 +0800601static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
602 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
603 // Define a valid key event.
604 NotifyKeyArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
605 displayId, POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0,
606 AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);
607
608 return args;
609}
610
611static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
612 PointerProperties pointerProperties[1];
613 PointerCoords pointerCoords[1];
614
615 pointerProperties[0].clear();
616 pointerProperties[0].id = 0;
617 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
618
619 pointerCoords[0].clear();
620 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
621 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
622
623 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
624 // Define a valid motion event.
625 NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -0700626 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
627 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
Atif Niyaz21da0ff2019-06-28 13:22:51 -0700628 AMOTION_EVENT_EDGE_FLAG_NONE, 1, pointerProperties, pointerCoords,
629 /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -0700630 AMOTION_EVENT_INVALID_CURSOR_POSITION,
631 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +0800632
633 return args;
634}
635
Arthur Hungb92218b2018-08-14 12:00:21 +0800636TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
637 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800638 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
639 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800640
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800641 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800642 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
643 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800644 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
645
646 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800647 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800648}
649
650// The foreground window should receive the first touch down event.
651TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
652 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800653 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
654 ADISPLAY_ID_DEFAULT);
655 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
656 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800657
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800658 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800659 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
660 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800661 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
662
663 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800664 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800665 windowSecond->assertNoEvents();
666}
667
668TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
669 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800670 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
671 ADISPLAY_ID_DEFAULT);
672 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
673 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800674
Arthur Hung7ab76b12019-01-09 19:17:20 +0800675 // Set focused application.
Tiger Huang721e26f2018-07-24 22:26:19 +0800676 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +0800677
678 // Expect one focus window exist in display.
679 windowSecond->setFocus();
Arthur Hungb92218b2018-08-14 12:00:21 +0800680
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800681 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800682 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
683 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
684
685 // Focused window should receive event.
686 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800687 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800688}
689
Arthur Hung7ab76b12019-01-09 19:17:20 +0800690TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
691 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
692 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
693 ADISPLAY_ID_DEFAULT);
694 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
695 ADISPLAY_ID_DEFAULT);
696
697 // Set focused application.
698 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
699
700 // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
701 windowTop->setFocus();
702 windowSecond->setFocus();
Arthur Hung7ab76b12019-01-09 19:17:20 +0800703
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800704 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800705 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
706 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
707
708 // Top focused window should receive event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800709 windowTop->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800710 windowSecond->assertNoEvents();
711}
712
Arthur Hung3b413f22018-10-26 18:05:34 +0800713TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
714 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
715
716 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
717 ADISPLAY_ID_DEFAULT);
718 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
719 ADISPLAY_ID_DEFAULT);
720
Arthur Hung832bc4a2019-01-28 11:43:17 +0800721 // Set focused application.
722 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hung3b413f22018-10-26 18:05:34 +0800723
Arthur Hung832bc4a2019-01-28 11:43:17 +0800724 windowTop->setFocus();
725 windowSecond->setFocus();
Arthur Hung3b413f22018-10-26 18:05:34 +0800726 // Release channel for window is no longer valid.
727 windowTop->releaseChannel();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800728 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung3b413f22018-10-26 18:05:34 +0800729
Arthur Hung832bc4a2019-01-28 11:43:17 +0800730 // Test inject a key down, should dispatch to a valid window.
731 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
732 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Arthur Hung3b413f22018-10-26 18:05:34 +0800733
734 // Top window is invalid, so it should not receive any input event.
735 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800736 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung3b413f22018-10-26 18:05:34 +0800737}
738
Garfield Tan00f511d2019-06-12 16:55:40 -0700739TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
740 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
741
742 sp<FakeWindowHandle> windowLeft =
743 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
744 windowLeft->setFrame(Rect(0, 0, 600, 800));
745 windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
746 sp<FakeWindowHandle> windowRight =
747 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
748 windowRight->setFrame(Rect(600, 0, 1200, 800));
749 windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
750
751 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
752
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800753 mDispatcher->setInputWindows({windowLeft, windowRight}, ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700754
755 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
756 // left window. This event should be dispatched to the left window.
757 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
758 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
759 ADISPLAY_ID_DEFAULT, 610, 400, 599, 400));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800760 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700761 windowRight->assertNoEvents();
762}
763
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800764/* Test InputDispatcher for MultiDisplay */
765class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
766public:
767 static constexpr int32_t SECOND_DISPLAY_ID = 1;
768 virtual void SetUp() {
769 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +0800770
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800771 application1 = new FakeApplicationHandle();
772 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
773 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800774
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800775 // Set focus window for primary display, but focused display would be second one.
776 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
777 windowInPrimary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800778 mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800779
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800780 application2 = new FakeApplicationHandle();
781 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
782 SECOND_DISPLAY_ID);
783 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800784 // Set focus display to second one.
785 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
786 // Set focus window for second display.
787 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
788 windowInSecondary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800789 mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800790 }
791
792 virtual void TearDown() {
793 InputDispatcherTest::TearDown();
794
795 application1.clear();
796 windowInPrimary.clear();
797 application2.clear();
798 windowInSecondary.clear();
799 }
800
801protected:
802 sp<FakeApplicationHandle> application1;
803 sp<FakeWindowHandle> windowInPrimary;
804 sp<FakeApplicationHandle> application2;
805 sp<FakeWindowHandle> windowInSecondary;
806};
807
808TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
809 // Test touch down on primary display.
810 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
811 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800812 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800813 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800814 windowInSecondary->assertNoEvents();
815
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800816 // Test touch down on second display.
817 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
818 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +0800819 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
820 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800821 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800822}
823
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800824TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +0800825 // Test inject a key down with display id specified.
826 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
827 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800828 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +0800829 windowInSecondary->assertNoEvents();
830
831 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +0800832 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
833 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
834 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800835 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800836
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800837 // Remove all windows in secondary display.
838 mDispatcher->setInputWindows({}, SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800839
840 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800841 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
842 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +0800843
844 // Test inject a key down, should timeout because of no target window.
845 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
846 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
847 windowInPrimary->assertNoEvents();
848 windowInSecondary->assertNoEvents();
849}
850
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800851class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
852public:
853 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
Michael Wright3dd60e22019-03-27 22:06:44 +0000854 int32_t displayId, bool isGestureMonitor = false)
855 : FakeInputReceiver(dispatcher, name, displayId) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000856 mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800857 }
858};
859
860// Test per-display input monitors for motion event.
861TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
862 sp<FakeMonitorReceiver> monitorInPrimary =
863 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
864 sp<FakeMonitorReceiver> monitorInSecondary =
865 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
866
867 // Test touch down on primary display.
868 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
869 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
870 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800871 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
872 monitorInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800873 windowInSecondary->assertNoEvents();
874 monitorInSecondary->assertNoEvents();
875
876 // Test touch down on second display.
877 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
878 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
879 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
880 windowInPrimary->assertNoEvents();
881 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800882 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
883 monitorInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800884
885 // Test inject a non-pointer motion event.
886 // If specific a display, it will dispatch to the focused window of particular display,
887 // or it will dispatch to the focused window of focused display.
888 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
889 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
890 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
891 windowInPrimary->assertNoEvents();
892 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800893 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
894 monitorInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800895}
896
897// Test per-display input monitors for key event.
898TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
899 //Input monitor per display.
900 sp<FakeMonitorReceiver> monitorInPrimary =
901 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
902 sp<FakeMonitorReceiver> monitorInSecondary =
903 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
904
905 // Test inject a key down.
906 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
907 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
908 windowInPrimary->assertNoEvents();
909 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800910 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
911 monitorInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800912}
913
Jackal Guof9696682018-10-05 12:23:23 +0800914class InputFilterTest : public InputDispatcherTest {
915protected:
916 static constexpr int32_t SECOND_DISPLAY_ID = 1;
917
918 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
919 NotifyMotionArgs motionArgs;
920
921 motionArgs = generateMotionArgs(
922 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
923 mDispatcher->notifyMotion(&motionArgs);
924 motionArgs = generateMotionArgs(
925 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
926 mDispatcher->notifyMotion(&motionArgs);
927
928 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800929 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +0800930 } else {
931 mFakePolicy->assertFilterInputEventWasNotCalled();
932 }
933 }
934
935 void testNotifyKey(bool expectToBeFiltered) {
936 NotifyKeyArgs keyArgs;
937
938 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
939 mDispatcher->notifyKey(&keyArgs);
940 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
941 mDispatcher->notifyKey(&keyArgs);
942
943 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800944 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +0800945 } else {
946 mFakePolicy->assertFilterInputEventWasNotCalled();
947 }
948 }
949};
950
951// Test InputFilter for MotionEvent
952TEST_F(InputFilterTest, MotionEvent_InputFilter) {
953 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
954 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
955 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
956
957 // Enable InputFilter
958 mDispatcher->setInputFilterEnabled(true);
959 // Test touch on both primary and second display, and check if both events are filtered.
960 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
961 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
962
963 // Disable InputFilter
964 mDispatcher->setInputFilterEnabled(false);
965 // Test touch on both primary and second display, and check if both events aren't filtered.
966 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
967 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
968}
969
970// Test InputFilter for KeyEvent
971TEST_F(InputFilterTest, KeyEvent_InputFilter) {
972 // Since the InputFilter is disabled by default, check if key event aren't filtered.
973 testNotifyKey(/*expectToBeFiltered*/ false);
974
975 // Enable InputFilter
976 mDispatcher->setInputFilterEnabled(true);
977 // Send a key event, and check if it is filtered.
978 testNotifyKey(/*expectToBeFiltered*/ true);
979
980 // Disable InputFilter
981 mDispatcher->setInputFilterEnabled(false);
982 // Send a key event, and check if it isn't filtered.
983 testNotifyKey(/*expectToBeFiltered*/ false);
984}
985
chaviwfd6d3512019-03-25 13:23:49 -0700986class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
987 virtual void SetUp() {
988 InputDispatcherTest::SetUp();
989
990 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
991 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
992 ADISPLAY_ID_DEFAULT);
993 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
994 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
995 // window.
996 mUnfocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
997
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800998 mFocusedWindow =
999 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1000 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
1001 mFocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1002 mFocusedWindowTouchPoint = 60;
chaviwfd6d3512019-03-25 13:23:49 -07001003
1004 // Set focused application.
1005 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001006 mFocusedWindow->setFocus();
chaviwfd6d3512019-03-25 13:23:49 -07001007
1008 // Expect one focus window exist in display.
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001009 mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07001010 }
1011
1012 virtual void TearDown() {
1013 InputDispatcherTest::TearDown();
1014
1015 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001016 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07001017 }
1018
1019protected:
1020 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001021 sp<FakeWindowHandle> mFocusedWindow;
1022 int32_t mFocusedWindowTouchPoint;
chaviwfd6d3512019-03-25 13:23:49 -07001023};
1024
1025// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1026// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
1027// the onPointerDownOutsideFocus callback.
1028TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
1029 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1030 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20))
1031 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1032 // Call monitor to wait for the command queue to get flushed.
1033 mDispatcher->monitor();
1034
1035 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
1036}
1037
1038// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
1039// DOWN on the window that doesn't have focus. Ensure no window received the
1040// onPointerDownOutsideFocus callback.
1041TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
1042 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1043 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20))
1044 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1045 // Call monitor to wait for the command queue to get flushed.
1046 mDispatcher->monitor();
1047
1048 mFakePolicy->assertOnPointerDownEquals(nullptr);
1049}
1050
1051// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
1052// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
1053TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
1054 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1055 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1056 // Call monitor to wait for the command queue to get flushed.
1057 mDispatcher->monitor();
1058
1059 mFakePolicy->assertOnPointerDownEquals(nullptr);
1060}
1061
1062// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1063// DOWN on the window that already has focus. Ensure no window received the
1064// onPointerDownOutsideFocus callback.
1065TEST_F(InputDispatcherOnPointerDownOutsideFocus,
1066 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001067 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1068 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1069 mFocusedWindowTouchPoint, mFocusedWindowTouchPoint))
chaviwfd6d3512019-03-25 13:23:49 -07001070 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1071 // Call monitor to wait for the command queue to get flushed.
1072 mDispatcher->monitor();
1073
1074 mFakePolicy->assertOnPointerDownEquals(nullptr);
1075}
1076
Garfield Tane84e6f92019-08-29 17:28:41 -07001077} // namespace android::inputdispatcher