blob: c8d39cf6300b3b112bf74035a6e1151ae985aa2b [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() {
Jackal Guof9696682018-10-05 12:23:23 +080054 }
55
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080056 void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080057 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_KEY, args.eventTime, args.action,
58 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080059 }
60
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080061 void assertFilterInputEventWasCalled(const NotifyMotionArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080062 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_MOTION, args.eventTime, args.action,
63 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080064 }
65
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080066 void assertFilterInputEventWasNotCalled() { ASSERT_EQ(nullptr, mFilteredEvent); }
Michael Wrightd02c5b62014-02-10 15:10:22 -080067
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080068 void assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
69 ASSERT_TRUE(mConfigurationChangedTime)
70 << "Timed out waiting for configuration changed call";
71 ASSERT_EQ(*mConfigurationChangedTime, when);
72 mConfigurationChangedTime = std::nullopt;
73 }
74
75 void assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
76 ASSERT_TRUE(mLastNotifySwitch);
77 // We do not check sequenceNum because it is not exposed to the policy
78 EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime);
79 EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags);
80 EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues);
81 EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask);
82 mLastNotifySwitch = std::nullopt;
83 }
84
chaviwfd6d3512019-03-25 13:23:49 -070085 void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080086 ASSERT_EQ(touchedToken, mOnPointerDownToken);
87 mOnPointerDownToken.clear();
88 }
89
90 void assertOnPointerDownWasNotCalled() {
91 ASSERT_TRUE(mOnPointerDownToken == nullptr)
92 << "Expected onPointerDownOutsideFocus to not have been called";
chaviwfd6d3512019-03-25 13:23:49 -070093 }
94
Michael Wrightd02c5b62014-02-10 15:10:22 -080095private:
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080096 std::unique_ptr<InputEvent> mFilteredEvent;
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080097 std::optional<nsecs_t> mConfigurationChangedTime;
chaviwfd6d3512019-03-25 13:23:49 -070098 sp<IBinder> mOnPointerDownToken;
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080099 std::optional<NotifySwitchArgs> mLastNotifySwitch;
Jackal Guof9696682018-10-05 12:23:23 +0800100
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800101 virtual void notifyConfigurationChanged(nsecs_t when) override {
102 mConfigurationChangedTime = when;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103 }
104
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100105 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&,
Robert Carr803535b2018-08-02 16:38:15 -0700106 const sp<IBinder>&,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800107 const std::string&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800108 return 0;
109 }
110
Robert Carr803535b2018-08-02 16:38:15 -0700111 virtual void notifyInputChannelBroken(const sp<IBinder>&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800112 }
113
chaviw0c06c6e2019-01-09 13:27:07 -0800114 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) {
Robert Carr740167f2018-10-11 19:03:41 -0700115 }
116
Michael Wrightd02c5b62014-02-10 15:10:22 -0800117 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
118 *outConfig = mConfig;
119 }
120
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800121 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Jackal Guof9696682018-10-05 12:23:23 +0800122 switch (inputEvent->getType()) {
123 case AINPUT_EVENT_TYPE_KEY: {
124 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800125 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800126 break;
127 }
128
129 case AINPUT_EVENT_TYPE_MOTION: {
130 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800131 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800132 break;
133 }
134 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800135 return true;
136 }
137
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100138 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139 }
140
Charles Chen3611f1f2019-01-29 17:26:18 +0800141 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800142 }
143
Robert Carr803535b2018-08-02 16:38:15 -0700144 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100145 const KeyEvent*, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800146 return 0;
147 }
148
Robert Carr803535b2018-08-02 16:38:15 -0700149 virtual bool dispatchUnhandledKey(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100150 const KeyEvent*, uint32_t, KeyEvent*) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800151 return false;
152 }
153
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800154 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
155 uint32_t policyFlags) override {
156 /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
157 * essentially a passthrough for notifySwitch.
158 */
159 mLastNotifySwitch =
160 NotifySwitchArgs(1 /*sequenceNum*/, when, policyFlags, switchValues, switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800161 }
162
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100163 virtual void pokeUserActivity(nsecs_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800164 }
165
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100166 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800167 return false;
168 }
Jackal Guof9696682018-10-05 12:23:23 +0800169
chaviwfd6d3512019-03-25 13:23:49 -0700170 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) {
171 mOnPointerDownToken = newToken;
172 }
173
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800174 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
175 int32_t displayId) {
176 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
177 ASSERT_EQ(mFilteredEvent->getType(), type);
178
179 if (type == AINPUT_EVENT_TYPE_KEY) {
180 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
181 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
182 EXPECT_EQ(keyEvent.getAction(), action);
183 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
184 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
185 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
186 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
187 EXPECT_EQ(motionEvent.getAction(), action);
188 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
189 } else {
190 FAIL() << "Unknown type: " << type;
191 }
192
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800193 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800194 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800195};
196
197
198// --- InputDispatcherTest ---
199
200class InputDispatcherTest : public testing::Test {
201protected:
202 sp<FakeInputDispatcherPolicy> mFakePolicy;
203 sp<InputDispatcher> mDispatcher;
Arthur Hungb92218b2018-08-14 12:00:21 +0800204 sp<InputDispatcherThread> mDispatcherThread;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800205
206 virtual void SetUp() {
207 mFakePolicy = new FakeInputDispatcherPolicy();
208 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800209 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
210 //Start InputDispatcher thread
211 mDispatcherThread = new InputDispatcherThread(mDispatcher);
212 mDispatcherThread->run("InputDispatcherTest", PRIORITY_URGENT_DISPLAY);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800213 }
214
215 virtual void TearDown() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800216 mDispatcherThread->requestExit();
217 mDispatcherThread.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 mFakePolicy.clear();
219 mDispatcher.clear();
220 }
221};
222
223
224TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
225 KeyEvent event;
226
227 // Rejects undefined key actions.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100228 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229 /*action*/ -1, 0,
230 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800231 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800232 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800233 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
234 << "Should reject key events with undefined action.";
235
236 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100237 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800238 AKEY_EVENT_ACTION_MULTIPLE, 0,
239 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800240 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800241 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
243 << "Should reject key events with ACTION_MULTIPLE.";
244}
245
246TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
247 MotionEvent event;
248 PointerProperties pointerProperties[MAX_POINTERS + 1];
249 PointerCoords pointerCoords[MAX_POINTERS + 1];
250 for (int i = 0; i <= MAX_POINTERS; i++) {
251 pointerProperties[i].clear();
252 pointerProperties[i].id = i;
253 pointerCoords[i].clear();
254 }
255
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800256 // Some constants commonly used below
257 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
258 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
259 constexpr int32_t metaState = AMETA_NONE;
260 constexpr MotionClassification classification = MotionClassification::NONE;
261
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262 // Rejects undefined motion actions.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800263 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700264 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
265 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
266 ARBITRARY_TIME, ARBITRARY_TIME,
267 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800268 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800269 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800270 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
271 << "Should reject motion events with undefined action.";
272
273 // Rejects pointer down with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800274 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700275 AMOTION_EVENT_ACTION_POINTER_DOWN |
276 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
277 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
278 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
279 ARBITRARY_TIME, ARBITRARY_TIME,
280 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800281 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800282 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800283 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
284 << "Should reject motion events with pointer down index too large.";
285
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800286 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700287 AMOTION_EVENT_ACTION_POINTER_DOWN |
288 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
289 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
290 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
291 ARBITRARY_TIME, ARBITRARY_TIME,
292 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800293 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800294 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
296 << "Should reject motion events with pointer down index too small.";
297
298 // Rejects pointer up with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800299 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700300 AMOTION_EVENT_ACTION_POINTER_UP |
301 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
302 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
303 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
304 ARBITRARY_TIME, ARBITRARY_TIME,
305 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800306 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800307 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800308 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
309 << "Should reject motion events with pointer up index too large.";
310
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800311 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700312 AMOTION_EVENT_ACTION_POINTER_UP |
313 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
314 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
315 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
316 ARBITRARY_TIME, ARBITRARY_TIME,
317 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800318 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800319 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800320 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
321 << "Should reject motion events with pointer up index too small.";
322
323 // Rejects motion events with invalid number of pointers.
Garfield Tan00f511d2019-06-12 16:55:40 -0700324 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
325 metaState, 0, classification, 0, 0, 0, 0,
326 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
327 ARBITRARY_TIME, ARBITRARY_TIME,
328 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800329 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800330 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800331 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
332 << "Should reject motion events with 0 pointers.";
333
Garfield Tan00f511d2019-06-12 16:55:40 -0700334 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
335 metaState, 0, classification, 0, 0, 0, 0,
336 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
337 ARBITRARY_TIME, ARBITRARY_TIME,
338 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800339 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800340 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800341 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
342 << "Should reject motion events with more than MAX_POINTERS pointers.";
343
344 // Rejects motion events with invalid pointer ids.
345 pointerProperties[0].id = -1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700346 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
347 metaState, 0, classification, 0, 0, 0, 0,
348 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
349 ARBITRARY_TIME, ARBITRARY_TIME,
350 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800351 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800352 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800353 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
354 << "Should reject motion events with pointer ids less than 0.";
355
356 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700357 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
358 metaState, 0, classification, 0, 0, 0, 0,
359 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
360 ARBITRARY_TIME, ARBITRARY_TIME,
361 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800362 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800363 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800364 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
365 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
366
367 // Rejects motion events with duplicate pointer ids.
368 pointerProperties[0].id = 1;
369 pointerProperties[1].id = 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700370 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
371 metaState, 0, classification, 0, 0, 0, 0,
372 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
373 ARBITRARY_TIME, ARBITRARY_TIME,
374 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800375 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800376 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800377 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
378 << "Should reject motion events with duplicate pointer ids.";
379}
380
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800381/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
382
383TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
384 constexpr nsecs_t eventTime = 20;
385 NotifyConfigurationChangedArgs args(10 /*sequenceNum*/, eventTime);
386 mDispatcher->notifyConfigurationChanged(&args);
387 ASSERT_TRUE(mDispatcher->waitForIdle());
388
389 mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
390}
391
392TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
393 NotifySwitchArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, 0 /*policyFlags*/,
394 1 /*switchValues*/, 2 /*switchMask*/);
395 mDispatcher->notifySwitch(&args);
396
397 // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener
398 args.policyFlags |= POLICY_FLAG_TRUSTED;
399 mFakePolicy->assertNotifySwitchWasCalled(args);
400}
401
Arthur Hungb92218b2018-08-14 12:00:21 +0800402// --- InputDispatcherTest SetInputWindowTest ---
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800403static constexpr int32_t INJECT_EVENT_TIMEOUT = 500;
404static constexpr int32_t DISPATCHING_TIMEOUT = 100;
Arthur Hungb92218b2018-08-14 12:00:21 +0800405
406class FakeApplicationHandle : public InputApplicationHandle {
407public:
408 FakeApplicationHandle() {}
409 virtual ~FakeApplicationHandle() {}
410
411 virtual bool updateInfo() {
Arthur Hung7a0c39a2019-03-20 16:52:24 +0800412 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
Arthur Hungb92218b2018-08-14 12:00:21 +0800413 return true;
414 }
415};
416
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800417class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800418public:
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800419 InputEvent* consume() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800420 uint32_t consumeSeq;
421 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800422
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800423 std::chrono::time_point start = std::chrono::steady_clock::now();
424 status_t status = WOULD_BLOCK;
425 while (status == WOULD_BLOCK) {
426 status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1, &consumeSeq,
427 &event);
428 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
429 if (elapsed > 100ms) {
430 break;
431 }
432 }
433
434 if (status == WOULD_BLOCK) {
435 // Just means there's no event available.
436 return nullptr;
437 }
438
439 if (status != OK) {
440 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
441 return nullptr;
442 }
443 if (event == nullptr) {
444 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
445 return nullptr;
446 }
447
448 status = mConsumer->sendFinishedSignal(consumeSeq, handled());
449 if (status != OK) {
450 ADD_FAILURE() << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
451 }
452 return event;
453 }
454
455 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
456 int32_t expectedFlags) {
457 InputEvent* event = consume();
458
459 ASSERT_NE(nullptr, event) << mName.c_str()
460 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800461 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800462 << mName.c_str() << "expected " << inputEventTypeToString(expectedEventType)
463 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800464
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800465 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800466
Tiger Huang8664f8c2018-10-11 19:14:35 +0800467 switch (expectedEventType) {
468 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800469 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
470 EXPECT_EQ(expectedAction, keyEvent.getAction());
471 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800472 break;
473 }
474 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800475 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
476 EXPECT_EQ(expectedAction, motionEvent.getAction());
477 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800478 break;
479 }
480 default: {
481 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
482 }
483 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800484 }
485
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800486 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
487 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
488 expectedFlags);
489 }
490
491 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
492 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
493 expectedFlags);
494 }
495
Arthur Hungb92218b2018-08-14 12:00:21 +0800496 void assertNoEvents() {
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800497 InputEvent* event = consume();
498 ASSERT_EQ(nullptr, event)
Arthur Hungb92218b2018-08-14 12:00:21 +0800499 << mName.c_str()
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800500 << ": should not have received any events, so consume() should return NULL";
Arthur Hungb92218b2018-08-14 12:00:21 +0800501 }
502
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800503protected:
504 explicit FakeInputReceiver(const sp<InputDispatcher>& dispatcher,
505 const std::string name, int32_t displayId) :
506 mDispatcher(dispatcher), mName(name), mDisplayId(displayId) {
507 InputChannel::openInputChannelPair(name, mServerChannel, mClientChannel);
508 mConsumer = new InputConsumer(mClientChannel);
509 }
510
511 virtual ~FakeInputReceiver() {
512 }
513
514 // return true if the event has been handled.
515 virtual bool handled() {
516 return false;
517 }
518
Arthur Hungb92218b2018-08-14 12:00:21 +0800519 sp<InputDispatcher> mDispatcher;
520 sp<InputChannel> mServerChannel, mClientChannel;
521 InputConsumer *mConsumer;
522 PreallocatedInputEventFactory mEventFactory;
523
524 std::string mName;
Arthur Hungb92218b2018-08-14 12:00:21 +0800525 int32_t mDisplayId;
526};
527
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800528class FakeWindowHandle : public InputWindowHandle, public FakeInputReceiver {
529public:
530 static const int32_t WIDTH = 600;
531 static const int32_t HEIGHT = 800;
532
533 FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
534 const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) :
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800535 FakeInputReceiver(dispatcher, name, displayId),
chaviwfd6d3512019-03-25 13:23:49 -0700536 mFocused(false), mFrame(Rect(0, 0, WIDTH, HEIGHT)), mLayoutParamFlags(0) {
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -0700537 mDispatcher->registerInputChannel(mServerChannel);
chaviwfd6d3512019-03-25 13:23:49 -0700538
Robert Carr740167f2018-10-11 19:03:41 -0700539 inputApplicationHandle->updateInfo();
540 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800541 }
542
543 virtual bool updateInfo() {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700544 mInfo.token = mServerChannel ? mServerChannel->getConnectionToken() : nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +0800545 mInfo.name = mName;
chaviwfd6d3512019-03-25 13:23:49 -0700546 mInfo.layoutParamsFlags = mLayoutParamFlags;
Arthur Hung3b413f22018-10-26 18:05:34 +0800547 mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
548 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwfd6d3512019-03-25 13:23:49 -0700549 mInfo.frameLeft = mFrame.left;
550 mInfo.frameTop = mFrame.top;
551 mInfo.frameRight = mFrame.right;
552 mInfo.frameBottom = mFrame.bottom;
Robert Carre07e1032018-11-26 12:55:53 -0800553 mInfo.globalScaleFactor = 1.0;
Garfield Tan00f511d2019-06-12 16:55:40 -0700554 mInfo.touchableRegion.clear();
chaviwfd6d3512019-03-25 13:23:49 -0700555 mInfo.addTouchableRegion(mFrame);
Arthur Hung3b413f22018-10-26 18:05:34 +0800556 mInfo.visible = true;
557 mInfo.canReceiveKeys = true;
558 mInfo.hasFocus = mFocused;
559 mInfo.hasWallpaper = false;
560 mInfo.paused = false;
561 mInfo.layer = 0;
562 mInfo.ownerPid = INJECTOR_PID;
563 mInfo.ownerUid = INJECTOR_UID;
564 mInfo.inputFeatures = 0;
565 mInfo.displayId = mDisplayId;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800566
567 return true;
568 }
569
570 void setFocus() {
571 mFocused = true;
572 }
Arthur Hung832bc4a2019-01-28 11:43:17 +0800573
chaviwfd6d3512019-03-25 13:23:49 -0700574 void setFrame(const Rect& frame) {
575 mFrame.set(frame);
576 }
577
578 void setLayoutParamFlags(int32_t flags) {
579 mLayoutParamFlags = flags;
580 }
581
Arthur Hung832bc4a2019-01-28 11:43:17 +0800582 void releaseChannel() {
Arthur Hung6b5a2b92019-01-31 16:39:28 +0800583 mServerChannel.clear();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800584 InputWindowHandle::releaseChannel();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800585 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800586protected:
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800587 virtual bool handled() override { return true; }
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800588
589 bool mFocused;
chaviwfd6d3512019-03-25 13:23:49 -0700590 Rect mFrame;
591 int32_t mLayoutParamFlags;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800592};
593
Tiger Huang721e26f2018-07-24 22:26:19 +0800594static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
595 int32_t displayId = ADISPLAY_ID_NONE) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800596 KeyEvent event;
597 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
598
599 // Define a valid key down event.
Tiger Huang721e26f2018-07-24 22:26:19 +0800600 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Arthur Hungb92218b2018-08-14 12:00:21 +0800601 AKEY_EVENT_ACTION_DOWN, /* flags */ 0,
602 AKEYCODE_A, KEY_A, AMETA_NONE, /* repeatCount */ 0, currentTime, currentTime);
603
604 // Inject event until dispatch out.
605 return dispatcher->injectInputEvent(
606 &event,
607 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
608 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
609}
610
Garfield Tan00f511d2019-06-12 16:55:40 -0700611static int32_t injectMotionEvent(const sp<InputDispatcher>& dispatcher, int32_t action,
612 int32_t source, int32_t displayId, int32_t x, int32_t y,
613 int32_t xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION,
614 int32_t yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800615 MotionEvent event;
616 PointerProperties pointerProperties[1];
617 PointerCoords pointerCoords[1];
618
619 pointerProperties[0].clear();
620 pointerProperties[0].id = 0;
621 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
622
623 pointerCoords[0].clear();
chaviwfd6d3512019-03-25 13:23:49 -0700624 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
625 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
Arthur Hungb92218b2018-08-14 12:00:21 +0800626
627 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
628 // Define a valid motion down event.
Garfield Tan00f511d2019-06-12 16:55:40 -0700629 event.initialize(DEVICE_ID, source, displayId, action, /* actionButton */ 0, /* flags */ 0,
630 /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
631 /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
632 /* yPrecision */ 0, xCursorPosition, yCursorPosition, currentTime, currentTime,
633 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Arthur Hungb92218b2018-08-14 12:00:21 +0800634
635 // Inject event until dispatch out.
636 return dispatcher->injectInputEvent(
637 &event,
638 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
639 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
640}
641
Garfield Tan00f511d2019-06-12 16:55:40 -0700642static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
643 int32_t displayId, int32_t x = 100, int32_t y = 200) {
644 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, x, y);
645}
646
Jackal Guof9696682018-10-05 12:23:23 +0800647static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
648 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
649 // Define a valid key event.
650 NotifyKeyArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
651 displayId, POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0,
652 AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);
653
654 return args;
655}
656
657static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
658 PointerProperties pointerProperties[1];
659 PointerCoords pointerCoords[1];
660
661 pointerProperties[0].clear();
662 pointerProperties[0].id = 0;
663 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
664
665 pointerCoords[0].clear();
666 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
667 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
668
669 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
670 // Define a valid motion event.
671 NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -0700672 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
673 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
Atif Niyaz21da0ff2019-06-28 13:22:51 -0700674 AMOTION_EVENT_EDGE_FLAG_NONE, 1, pointerProperties, pointerCoords,
675 /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -0700676 AMOTION_EVENT_INVALID_CURSOR_POSITION,
677 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +0800678
679 return args;
680}
681
Arthur Hungb92218b2018-08-14 12:00:21 +0800682TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
683 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800684 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
685 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800686
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800687 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800688 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
689 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800690 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
691
692 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800693 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800694}
695
696// The foreground window should receive the first touch down event.
697TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
698 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800699 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
700 ADISPLAY_ID_DEFAULT);
701 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
702 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800703
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800704 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800705 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
706 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800707 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
708
709 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800710 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800711 windowSecond->assertNoEvents();
712}
713
714TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
715 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800716 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);
Arthur Hungb92218b2018-08-14 12:00:21 +0800720
Arthur Hung7ab76b12019-01-09 19:17:20 +0800721 // Set focused application.
Tiger Huang721e26f2018-07-24 22:26:19 +0800722 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +0800723
724 // Expect one focus window exist in display.
725 windowSecond->setFocus();
Arthur Hungb92218b2018-08-14 12:00:21 +0800726
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800727 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800728 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
729 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
730
731 // Focused window should receive event.
732 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800733 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800734}
735
Arthur Hung7ab76b12019-01-09 19:17:20 +0800736TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
737 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
738 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
739 ADISPLAY_ID_DEFAULT);
740 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
741 ADISPLAY_ID_DEFAULT);
742
743 // Set focused application.
744 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
745
746 // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
747 windowTop->setFocus();
748 windowSecond->setFocus();
Arthur Hung7ab76b12019-01-09 19:17:20 +0800749
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800750 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800751 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
752 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
753
754 // Top focused window should receive event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800755 windowTop->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800756 windowSecond->assertNoEvents();
757}
758
Arthur Hung3b413f22018-10-26 18:05:34 +0800759TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
760 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
761
762 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
763 ADISPLAY_ID_DEFAULT);
764 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
765 ADISPLAY_ID_DEFAULT);
766
Arthur Hung832bc4a2019-01-28 11:43:17 +0800767 // Set focused application.
768 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hung3b413f22018-10-26 18:05:34 +0800769
Arthur Hung832bc4a2019-01-28 11:43:17 +0800770 windowTop->setFocus();
771 windowSecond->setFocus();
Arthur Hung3b413f22018-10-26 18:05:34 +0800772 // Release channel for window is no longer valid.
773 windowTop->releaseChannel();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800774 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung3b413f22018-10-26 18:05:34 +0800775
Arthur Hung832bc4a2019-01-28 11:43:17 +0800776 // Test inject a key down, should dispatch to a valid window.
777 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
778 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Arthur Hung3b413f22018-10-26 18:05:34 +0800779
780 // Top window is invalid, so it should not receive any input event.
781 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800782 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung3b413f22018-10-26 18:05:34 +0800783}
784
Garfield Tan00f511d2019-06-12 16:55:40 -0700785TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
786 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
787
788 sp<FakeWindowHandle> windowLeft =
789 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
790 windowLeft->setFrame(Rect(0, 0, 600, 800));
791 windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
792 sp<FakeWindowHandle> windowRight =
793 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
794 windowRight->setFrame(Rect(600, 0, 1200, 800));
795 windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
796
797 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
798
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800799 mDispatcher->setInputWindows({windowLeft, windowRight}, ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700800
801 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
802 // left window. This event should be dispatched to the left window.
803 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
804 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
805 ADISPLAY_ID_DEFAULT, 610, 400, 599, 400));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800806 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700807 windowRight->assertNoEvents();
808}
809
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800810TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
811 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
812 sp<FakeWindowHandle> window =
813 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
814 window->setFocus();
815
816 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
817
818 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
819 mDispatcher->notifyKey(&keyArgs);
820
821 // Window should receive key down event.
822 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
823
824 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
825 // on the app side.
826 NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID);
827 mDispatcher->notifyDeviceReset(&args);
828 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
829 AKEY_EVENT_FLAG_CANCELED);
830}
831
832TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
833 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
834 sp<FakeWindowHandle> window =
835 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
836
837 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
838
839 NotifyMotionArgs motionArgs =
840 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
841 ADISPLAY_ID_DEFAULT);
842 mDispatcher->notifyMotion(&motionArgs);
843
844 // Window should receive motion down event.
845 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
846
847 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
848 // on the app side.
849 NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID);
850 mDispatcher->notifyDeviceReset(&args);
851 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
852 0 /*expectedFlags*/);
853}
854
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800855/* Test InputDispatcher for MultiDisplay */
856class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
857public:
858 static constexpr int32_t SECOND_DISPLAY_ID = 1;
859 virtual void SetUp() {
860 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +0800861
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800862 application1 = new FakeApplicationHandle();
863 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
864 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800865
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800866 // Set focus window for primary display, but focused display would be second one.
867 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
868 windowInPrimary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800869 mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800870
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800871 application2 = new FakeApplicationHandle();
872 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
873 SECOND_DISPLAY_ID);
874 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800875 // Set focus display to second one.
876 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
877 // Set focus window for second display.
878 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
879 windowInSecondary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800880 mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800881 }
882
883 virtual void TearDown() {
884 InputDispatcherTest::TearDown();
885
886 application1.clear();
887 windowInPrimary.clear();
888 application2.clear();
889 windowInSecondary.clear();
890 }
891
892protected:
893 sp<FakeApplicationHandle> application1;
894 sp<FakeWindowHandle> windowInPrimary;
895 sp<FakeApplicationHandle> application2;
896 sp<FakeWindowHandle> windowInSecondary;
897};
898
899TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
900 // Test touch down on primary display.
901 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
902 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800903 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800904 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800905 windowInSecondary->assertNoEvents();
906
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800907 // Test touch down on second display.
908 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
909 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +0800910 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
911 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800912 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800913}
914
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800915TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +0800916 // Test inject a key down with display id specified.
917 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
918 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800919 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +0800920 windowInSecondary->assertNoEvents();
921
922 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +0800923 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
924 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
925 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800926 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800927
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800928 // Remove all windows in secondary display.
929 mDispatcher->setInputWindows({}, SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800930
931 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800932 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
933 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +0800934
935 // Test inject a key down, should timeout because of no target window.
936 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
937 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
938 windowInPrimary->assertNoEvents();
939 windowInSecondary->assertNoEvents();
940}
941
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800942class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
943public:
944 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
Michael Wright3dd60e22019-03-27 22:06:44 +0000945 int32_t displayId, bool isGestureMonitor = false)
946 : FakeInputReceiver(dispatcher, name, displayId) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000947 mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800948 }
949};
950
951// Test per-display input monitors for motion event.
952TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
953 sp<FakeMonitorReceiver> monitorInPrimary =
954 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
955 sp<FakeMonitorReceiver> monitorInSecondary =
956 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
957
958 // Test touch down on primary display.
959 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
960 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
961 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800962 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
963 monitorInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800964 windowInSecondary->assertNoEvents();
965 monitorInSecondary->assertNoEvents();
966
967 // Test touch down on second display.
968 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
969 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
970 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
971 windowInPrimary->assertNoEvents();
972 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800973 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
974 monitorInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800975
976 // Test inject a non-pointer motion event.
977 // If specific a display, it will dispatch to the focused window of particular display,
978 // or it will dispatch to the focused window of focused display.
979 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
980 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
981 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
982 windowInPrimary->assertNoEvents();
983 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800984 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
985 monitorInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800986}
987
988// Test per-display input monitors for key event.
989TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
990 //Input monitor per display.
991 sp<FakeMonitorReceiver> monitorInPrimary =
992 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
993 sp<FakeMonitorReceiver> monitorInSecondary =
994 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
995
996 // Test inject a key down.
997 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
998 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
999 windowInPrimary->assertNoEvents();
1000 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001001 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
1002 monitorInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001003}
1004
Jackal Guof9696682018-10-05 12:23:23 +08001005class InputFilterTest : public InputDispatcherTest {
1006protected:
1007 static constexpr int32_t SECOND_DISPLAY_ID = 1;
1008
1009 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
1010 NotifyMotionArgs motionArgs;
1011
1012 motionArgs = generateMotionArgs(
1013 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1014 mDispatcher->notifyMotion(&motionArgs);
1015 motionArgs = generateMotionArgs(
1016 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1017 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001018 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001019 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001020 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001021 } else {
1022 mFakePolicy->assertFilterInputEventWasNotCalled();
1023 }
1024 }
1025
1026 void testNotifyKey(bool expectToBeFiltered) {
1027 NotifyKeyArgs keyArgs;
1028
1029 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1030 mDispatcher->notifyKey(&keyArgs);
1031 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
1032 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001033 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001034
1035 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001036 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001037 } else {
1038 mFakePolicy->assertFilterInputEventWasNotCalled();
1039 }
1040 }
1041};
1042
1043// Test InputFilter for MotionEvent
1044TEST_F(InputFilterTest, MotionEvent_InputFilter) {
1045 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
1046 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1047 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1048
1049 // Enable InputFilter
1050 mDispatcher->setInputFilterEnabled(true);
1051 // Test touch on both primary and second display, and check if both events are filtered.
1052 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
1053 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
1054
1055 // Disable InputFilter
1056 mDispatcher->setInputFilterEnabled(false);
1057 // Test touch on both primary and second display, and check if both events aren't filtered.
1058 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1059 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1060}
1061
1062// Test InputFilter for KeyEvent
1063TEST_F(InputFilterTest, KeyEvent_InputFilter) {
1064 // Since the InputFilter is disabled by default, check if key event aren't filtered.
1065 testNotifyKey(/*expectToBeFiltered*/ false);
1066
1067 // Enable InputFilter
1068 mDispatcher->setInputFilterEnabled(true);
1069 // Send a key event, and check if it is filtered.
1070 testNotifyKey(/*expectToBeFiltered*/ true);
1071
1072 // Disable InputFilter
1073 mDispatcher->setInputFilterEnabled(false);
1074 // Send a key event, and check if it isn't filtered.
1075 testNotifyKey(/*expectToBeFiltered*/ false);
1076}
1077
chaviwfd6d3512019-03-25 13:23:49 -07001078class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
1079 virtual void SetUp() {
1080 InputDispatcherTest::SetUp();
1081
1082 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1083 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
1084 ADISPLAY_ID_DEFAULT);
1085 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
1086 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
1087 // window.
1088 mUnfocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1089
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001090 mFocusedWindow =
1091 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1092 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
1093 mFocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1094 mFocusedWindowTouchPoint = 60;
chaviwfd6d3512019-03-25 13:23:49 -07001095
1096 // Set focused application.
1097 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001098 mFocusedWindow->setFocus();
chaviwfd6d3512019-03-25 13:23:49 -07001099
1100 // Expect one focus window exist in display.
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001101 mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07001102 }
1103
1104 virtual void TearDown() {
1105 InputDispatcherTest::TearDown();
1106
1107 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001108 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07001109 }
1110
1111protected:
1112 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001113 sp<FakeWindowHandle> mFocusedWindow;
1114 int32_t mFocusedWindowTouchPoint;
chaviwfd6d3512019-03-25 13:23:49 -07001115};
1116
1117// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1118// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
1119// the onPointerDownOutsideFocus callback.
1120TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
1121 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1122 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20))
1123 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001124
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001125 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07001126 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
1127}
1128
1129// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
1130// DOWN on the window that doesn't have focus. Ensure no window received the
1131// onPointerDownOutsideFocus callback.
1132TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
1133 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1134 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20))
1135 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001136
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001137 ASSERT_TRUE(mDispatcher->waitForIdle());
1138 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001139}
1140
1141// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
1142// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
1143TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
1144 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1145 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001146
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001147 ASSERT_TRUE(mDispatcher->waitForIdle());
1148 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001149}
1150
1151// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1152// DOWN on the window that already has focus. Ensure no window received the
1153// onPointerDownOutsideFocus callback.
1154TEST_F(InputDispatcherOnPointerDownOutsideFocus,
1155 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001156 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1157 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1158 mFocusedWindowTouchPoint, mFocusedWindowTouchPoint))
chaviwfd6d3512019-03-25 13:23:49 -07001159 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001160
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001161 ASSERT_TRUE(mDispatcher->waitForIdle());
1162 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001163}
1164
Garfield Tane84e6f92019-08-29 17:28:41 -07001165} // namespace android::inputdispatcher