blob: d861a5f62362be75cbe3d725c2bf326ad2a8f6ea [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
Robert Carr803535b2018-08-02 16:38:15 -070019#include <binder/Binder.h>
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080020#include <input/Input.h>
Robert Carr803535b2018-08-02 16:38:15 -070021
Michael Wrightd02c5b62014-02-10 15:10:22 -080022#include <gtest/gtest.h>
23#include <linux/input.h>
24
Garfield Tane84e6f92019-08-29 17:28:41 -070025namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080026
27// An arbitrary time value.
28static const nsecs_t ARBITRARY_TIME = 1234;
29
30// An arbitrary device id.
31static const int32_t DEVICE_ID = 1;
32
Jeff Brownf086ddb2014-02-11 14:28:48 -080033// An arbitrary display id.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -080034static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
Jeff Brownf086ddb2014-02-11 14:28:48 -080035
Michael Wrightd02c5b62014-02-10 15:10:22 -080036// An arbitrary injector pid / uid pair that has permission to inject events.
37static const int32_t INJECTOR_PID = 999;
38static const int32_t INJECTOR_UID = 1001;
39
40
41// --- FakeInputDispatcherPolicy ---
42
43class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
44 InputDispatcherConfiguration mConfig;
45
46protected:
47 virtual ~FakeInputDispatcherPolicy() {
48 }
49
50public:
51 FakeInputDispatcherPolicy() {
Jackal Guof9696682018-10-05 12:23:23 +080052 }
53
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080054 void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080055 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_KEY, args.eventTime, args.action,
56 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080057 }
58
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080059 void assertFilterInputEventWasCalled(const NotifyMotionArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080060 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_MOTION, args.eventTime, args.action,
61 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080062 }
63
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080064 void assertFilterInputEventWasNotCalled() { ASSERT_EQ(nullptr, mFilteredEvent); }
Michael Wrightd02c5b62014-02-10 15:10:22 -080065
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080066 void assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
67 ASSERT_TRUE(mConfigurationChangedTime)
68 << "Timed out waiting for configuration changed call";
69 ASSERT_EQ(*mConfigurationChangedTime, when);
70 mConfigurationChangedTime = std::nullopt;
71 }
72
73 void assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
74 ASSERT_TRUE(mLastNotifySwitch);
75 // We do not check sequenceNum because it is not exposed to the policy
76 EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime);
77 EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags);
78 EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues);
79 EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask);
80 mLastNotifySwitch = std::nullopt;
81 }
82
chaviwfd6d3512019-03-25 13:23:49 -070083 void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080084 ASSERT_EQ(touchedToken, mOnPointerDownToken);
85 mOnPointerDownToken.clear();
86 }
87
88 void assertOnPointerDownWasNotCalled() {
89 ASSERT_TRUE(mOnPointerDownToken == nullptr)
90 << "Expected onPointerDownOutsideFocus to not have been called";
chaviwfd6d3512019-03-25 13:23:49 -070091 }
92
Michael Wrightd02c5b62014-02-10 15:10:22 -080093private:
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080094 std::unique_ptr<InputEvent> mFilteredEvent;
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080095 std::optional<nsecs_t> mConfigurationChangedTime;
chaviwfd6d3512019-03-25 13:23:49 -070096 sp<IBinder> mOnPointerDownToken;
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080097 std::optional<NotifySwitchArgs> mLastNotifySwitch;
Jackal Guof9696682018-10-05 12:23:23 +080098
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080099 virtual void notifyConfigurationChanged(nsecs_t when) override {
100 mConfigurationChangedTime = when;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800101 }
102
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100103 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&,
Robert Carr803535b2018-08-02 16:38:15 -0700104 const sp<IBinder>&,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800105 const std::string&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800106 return 0;
107 }
108
Robert Carr803535b2018-08-02 16:38:15 -0700109 virtual void notifyInputChannelBroken(const sp<IBinder>&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800110 }
111
chaviw0c06c6e2019-01-09 13:27:07 -0800112 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) {
Robert Carr740167f2018-10-11 19:03:41 -0700113 }
114
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
116 *outConfig = mConfig;
117 }
118
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800119 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Jackal Guof9696682018-10-05 12:23:23 +0800120 switch (inputEvent->getType()) {
121 case AINPUT_EVENT_TYPE_KEY: {
122 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800123 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800124 break;
125 }
126
127 case AINPUT_EVENT_TYPE_MOTION: {
128 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800129 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800130 break;
131 }
132 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800133 return true;
134 }
135
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100136 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800137 }
138
Charles Chen3611f1f2019-01-29 17:26:18 +0800139 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140 }
141
Robert Carr803535b2018-08-02 16:38:15 -0700142 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100143 const KeyEvent*, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800144 return 0;
145 }
146
Robert Carr803535b2018-08-02 16:38:15 -0700147 virtual bool dispatchUnhandledKey(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100148 const KeyEvent*, uint32_t, KeyEvent*) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800149 return false;
150 }
151
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800152 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
153 uint32_t policyFlags) override {
154 /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
155 * essentially a passthrough for notifySwitch.
156 */
157 mLastNotifySwitch =
158 NotifySwitchArgs(1 /*sequenceNum*/, when, policyFlags, switchValues, switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800159 }
160
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100161 virtual void pokeUserActivity(nsecs_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800162 }
163
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100164 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165 return false;
166 }
Jackal Guof9696682018-10-05 12:23:23 +0800167
chaviwfd6d3512019-03-25 13:23:49 -0700168 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) {
169 mOnPointerDownToken = newToken;
170 }
171
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800172 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
173 int32_t displayId) {
174 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
175 ASSERT_EQ(mFilteredEvent->getType(), type);
176
177 if (type == AINPUT_EVENT_TYPE_KEY) {
178 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
179 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
180 EXPECT_EQ(keyEvent.getAction(), action);
181 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
182 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
183 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
184 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
185 EXPECT_EQ(motionEvent.getAction(), action);
186 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
187 } else {
188 FAIL() << "Unknown type: " << type;
189 }
190
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800191 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800192 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800193};
194
195
196// --- InputDispatcherTest ---
197
198class InputDispatcherTest : public testing::Test {
199protected:
200 sp<FakeInputDispatcherPolicy> mFakePolicy;
201 sp<InputDispatcher> mDispatcher;
202
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700203 virtual void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 mFakePolicy = new FakeInputDispatcherPolicy();
205 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800206 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
207 //Start InputDispatcher thread
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700208 ASSERT_EQ(OK, mDispatcher->start());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800209 }
210
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700211 virtual void TearDown() override {
212 ASSERT_EQ(OK, mDispatcher->stop());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800213 mFakePolicy.clear();
214 mDispatcher.clear();
215 }
216};
217
218
219TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
220 KeyEvent event;
221
222 // Rejects undefined key actions.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100223 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800224 /*action*/ -1, 0,
225 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800226 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800227 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800228 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
229 << "Should reject key events with undefined action.";
230
231 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100232 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800233 AKEY_EVENT_ACTION_MULTIPLE, 0,
234 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800235 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800236 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
238 << "Should reject key events with ACTION_MULTIPLE.";
239}
240
241TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
242 MotionEvent event;
243 PointerProperties pointerProperties[MAX_POINTERS + 1];
244 PointerCoords pointerCoords[MAX_POINTERS + 1];
245 for (int i = 0; i <= MAX_POINTERS; i++) {
246 pointerProperties[i].clear();
247 pointerProperties[i].id = i;
248 pointerCoords[i].clear();
249 }
250
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800251 // Some constants commonly used below
252 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
253 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
254 constexpr int32_t metaState = AMETA_NONE;
255 constexpr MotionClassification classification = MotionClassification::NONE;
256
Michael Wrightd02c5b62014-02-10 15:10:22 -0800257 // Rejects undefined motion actions.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800258 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700259 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
260 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
261 ARBITRARY_TIME, ARBITRARY_TIME,
262 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800263 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800264 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
266 << "Should reject motion events with undefined action.";
267
268 // Rejects pointer down with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800269 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700270 AMOTION_EVENT_ACTION_POINTER_DOWN |
271 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
272 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
273 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
274 ARBITRARY_TIME, ARBITRARY_TIME,
275 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800276 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800277 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800278 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
279 << "Should reject motion events with pointer down index too large.";
280
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800281 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700282 AMOTION_EVENT_ACTION_POINTER_DOWN |
283 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
284 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
285 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
286 ARBITRARY_TIME, ARBITRARY_TIME,
287 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800288 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800289 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800290 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
291 << "Should reject motion events with pointer down index too small.";
292
293 // Rejects pointer up with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800294 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700295 AMOTION_EVENT_ACTION_POINTER_UP |
296 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
297 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
298 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
299 ARBITRARY_TIME, ARBITRARY_TIME,
300 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800301 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800302 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800303 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
304 << "Should reject motion events with pointer up index too large.";
305
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800306 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700307 AMOTION_EVENT_ACTION_POINTER_UP |
308 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
309 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
310 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
311 ARBITRARY_TIME, ARBITRARY_TIME,
312 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800313 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800314 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800315 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
316 << "Should reject motion events with pointer up index too small.";
317
318 // Rejects motion events with invalid number of pointers.
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*/ 0, 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 0 pointers.";
328
Garfield Tan00f511d2019-06-12 16:55:40 -0700329 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
330 metaState, 0, classification, 0, 0, 0, 0,
331 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
332 ARBITRARY_TIME, ARBITRARY_TIME,
333 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800334 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800335 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800336 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
337 << "Should reject motion events with more than MAX_POINTERS pointers.";
338
339 // Rejects motion events with invalid pointer ids.
340 pointerProperties[0].id = -1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700341 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
342 metaState, 0, classification, 0, 0, 0, 0,
343 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
344 ARBITRARY_TIME, ARBITRARY_TIME,
345 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800346 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800347 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800348 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
349 << "Should reject motion events with pointer ids less than 0.";
350
351 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700352 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
353 metaState, 0, classification, 0, 0, 0, 0,
354 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
355 ARBITRARY_TIME, ARBITRARY_TIME,
356 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800357 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800358 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800359 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
360 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
361
362 // Rejects motion events with duplicate pointer ids.
363 pointerProperties[0].id = 1;
364 pointerProperties[1].id = 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700365 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
366 metaState, 0, classification, 0, 0, 0, 0,
367 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
368 ARBITRARY_TIME, ARBITRARY_TIME,
369 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800370 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800371 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800372 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
373 << "Should reject motion events with duplicate pointer ids.";
374}
375
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800376/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
377
378TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
379 constexpr nsecs_t eventTime = 20;
380 NotifyConfigurationChangedArgs args(10 /*sequenceNum*/, eventTime);
381 mDispatcher->notifyConfigurationChanged(&args);
382 ASSERT_TRUE(mDispatcher->waitForIdle());
383
384 mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
385}
386
387TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
388 NotifySwitchArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, 0 /*policyFlags*/,
389 1 /*switchValues*/, 2 /*switchMask*/);
390 mDispatcher->notifySwitch(&args);
391
392 // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener
393 args.policyFlags |= POLICY_FLAG_TRUSTED;
394 mFakePolicy->assertNotifySwitchWasCalled(args);
395}
396
Arthur Hungb92218b2018-08-14 12:00:21 +0800397// --- InputDispatcherTest SetInputWindowTest ---
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800398static constexpr int32_t INJECT_EVENT_TIMEOUT = 500;
399static constexpr int32_t DISPATCHING_TIMEOUT = 100;
Arthur Hungb92218b2018-08-14 12:00:21 +0800400
401class FakeApplicationHandle : public InputApplicationHandle {
402public:
403 FakeApplicationHandle() {}
404 virtual ~FakeApplicationHandle() {}
405
406 virtual bool updateInfo() {
Arthur Hung7a0c39a2019-03-20 16:52:24 +0800407 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
Arthur Hungb92218b2018-08-14 12:00:21 +0800408 return true;
409 }
410};
411
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800412class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800413public:
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800414 InputEvent* consume() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800415 uint32_t consumeSeq;
416 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800417
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800418 std::chrono::time_point start = std::chrono::steady_clock::now();
419 status_t status = WOULD_BLOCK;
420 while (status == WOULD_BLOCK) {
421 status = mConsumer->consume(&mEventFactory, false /*consumeBatches*/, -1, &consumeSeq,
422 &event);
423 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
424 if (elapsed > 100ms) {
425 break;
426 }
427 }
428
429 if (status == WOULD_BLOCK) {
430 // Just means there's no event available.
431 return nullptr;
432 }
433
434 if (status != OK) {
435 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
436 return nullptr;
437 }
438 if (event == nullptr) {
439 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
440 return nullptr;
441 }
442
443 status = mConsumer->sendFinishedSignal(consumeSeq, handled());
444 if (status != OK) {
445 ADD_FAILURE() << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
446 }
447 return event;
448 }
449
450 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
451 int32_t expectedFlags) {
452 InputEvent* event = consume();
453
454 ASSERT_NE(nullptr, event) << mName.c_str()
455 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800456 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800457 << mName.c_str() << "expected " << inputEventTypeToString(expectedEventType)
458 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800459
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800460 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800461
Tiger Huang8664f8c2018-10-11 19:14:35 +0800462 switch (expectedEventType) {
463 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800464 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
465 EXPECT_EQ(expectedAction, keyEvent.getAction());
466 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800467 break;
468 }
469 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800470 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
471 EXPECT_EQ(expectedAction, motionEvent.getAction());
472 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800473 break;
474 }
475 default: {
476 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
477 }
478 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800479 }
480
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800481 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
482 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
483 expectedFlags);
484 }
485
486 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
487 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
488 expectedFlags);
489 }
490
Arthur Hungb92218b2018-08-14 12:00:21 +0800491 void assertNoEvents() {
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800492 InputEvent* event = consume();
493 ASSERT_EQ(nullptr, event)
Arthur Hungb92218b2018-08-14 12:00:21 +0800494 << mName.c_str()
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800495 << ": should not have received any events, so consume() should return NULL";
Arthur Hungb92218b2018-08-14 12:00:21 +0800496 }
497
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800498protected:
499 explicit FakeInputReceiver(const sp<InputDispatcher>& dispatcher,
500 const std::string name, int32_t displayId) :
501 mDispatcher(dispatcher), mName(name), mDisplayId(displayId) {
502 InputChannel::openInputChannelPair(name, mServerChannel, mClientChannel);
503 mConsumer = new InputConsumer(mClientChannel);
504 }
505
506 virtual ~FakeInputReceiver() {
507 }
508
509 // return true if the event has been handled.
510 virtual bool handled() {
511 return false;
512 }
513
Arthur Hungb92218b2018-08-14 12:00:21 +0800514 sp<InputDispatcher> mDispatcher;
515 sp<InputChannel> mServerChannel, mClientChannel;
516 InputConsumer *mConsumer;
517 PreallocatedInputEventFactory mEventFactory;
518
519 std::string mName;
Arthur Hungb92218b2018-08-14 12:00:21 +0800520 int32_t mDisplayId;
521};
522
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800523class FakeWindowHandle : public InputWindowHandle, public FakeInputReceiver {
524public:
525 static const int32_t WIDTH = 600;
526 static const int32_t HEIGHT = 800;
527
528 FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
529 const sp<InputDispatcher>& dispatcher, const std::string name, int32_t displayId) :
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800530 FakeInputReceiver(dispatcher, name, displayId),
chaviwfd6d3512019-03-25 13:23:49 -0700531 mFocused(false), mFrame(Rect(0, 0, WIDTH, HEIGHT)), mLayoutParamFlags(0) {
Siarhei Vishniakou7c34b232019-10-11 19:08:48 -0700532 mDispatcher->registerInputChannel(mServerChannel);
chaviwfd6d3512019-03-25 13:23:49 -0700533
Robert Carr740167f2018-10-11 19:03:41 -0700534 inputApplicationHandle->updateInfo();
535 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800536 }
537
538 virtual bool updateInfo() {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700539 mInfo.token = mServerChannel ? mServerChannel->getConnectionToken() : nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +0800540 mInfo.name = mName;
chaviwfd6d3512019-03-25 13:23:49 -0700541 mInfo.layoutParamsFlags = mLayoutParamFlags;
Arthur Hung3b413f22018-10-26 18:05:34 +0800542 mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
543 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwfd6d3512019-03-25 13:23:49 -0700544 mInfo.frameLeft = mFrame.left;
545 mInfo.frameTop = mFrame.top;
546 mInfo.frameRight = mFrame.right;
547 mInfo.frameBottom = mFrame.bottom;
Robert Carre07e1032018-11-26 12:55:53 -0800548 mInfo.globalScaleFactor = 1.0;
Garfield Tan00f511d2019-06-12 16:55:40 -0700549 mInfo.touchableRegion.clear();
chaviwfd6d3512019-03-25 13:23:49 -0700550 mInfo.addTouchableRegion(mFrame);
Arthur Hung3b413f22018-10-26 18:05:34 +0800551 mInfo.visible = true;
552 mInfo.canReceiveKeys = true;
553 mInfo.hasFocus = mFocused;
554 mInfo.hasWallpaper = false;
555 mInfo.paused = false;
556 mInfo.layer = 0;
557 mInfo.ownerPid = INJECTOR_PID;
558 mInfo.ownerUid = INJECTOR_UID;
559 mInfo.inputFeatures = 0;
560 mInfo.displayId = mDisplayId;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800561
562 return true;
563 }
564
565 void setFocus() {
566 mFocused = true;
567 }
Arthur Hung832bc4a2019-01-28 11:43:17 +0800568
chaviwfd6d3512019-03-25 13:23:49 -0700569 void setFrame(const Rect& frame) {
570 mFrame.set(frame);
571 }
572
573 void setLayoutParamFlags(int32_t flags) {
574 mLayoutParamFlags = flags;
575 }
576
Arthur Hung832bc4a2019-01-28 11:43:17 +0800577 void releaseChannel() {
Arthur Hung6b5a2b92019-01-31 16:39:28 +0800578 mServerChannel.clear();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800579 InputWindowHandle::releaseChannel();
Arthur Hung832bc4a2019-01-28 11:43:17 +0800580 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800581protected:
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800582 virtual bool handled() override { return true; }
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800583
584 bool mFocused;
chaviwfd6d3512019-03-25 13:23:49 -0700585 Rect mFrame;
586 int32_t mLayoutParamFlags;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800587};
588
Tiger Huang721e26f2018-07-24 22:26:19 +0800589static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
590 int32_t displayId = ADISPLAY_ID_NONE) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800591 KeyEvent event;
592 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
593
594 // Define a valid key down event.
Tiger Huang721e26f2018-07-24 22:26:19 +0800595 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Arthur Hungb92218b2018-08-14 12:00:21 +0800596 AKEY_EVENT_ACTION_DOWN, /* flags */ 0,
597 AKEYCODE_A, KEY_A, AMETA_NONE, /* repeatCount */ 0, currentTime, currentTime);
598
599 // Inject event until dispatch out.
600 return dispatcher->injectInputEvent(
601 &event,
602 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
603 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
604}
605
Garfield Tan00f511d2019-06-12 16:55:40 -0700606static int32_t injectMotionEvent(const sp<InputDispatcher>& dispatcher, int32_t action,
607 int32_t source, int32_t displayId, int32_t x, int32_t y,
608 int32_t xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION,
609 int32_t yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800610 MotionEvent event;
611 PointerProperties pointerProperties[1];
612 PointerCoords pointerCoords[1];
613
614 pointerProperties[0].clear();
615 pointerProperties[0].id = 0;
616 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
617
618 pointerCoords[0].clear();
chaviwfd6d3512019-03-25 13:23:49 -0700619 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
620 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
Arthur Hungb92218b2018-08-14 12:00:21 +0800621
622 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
623 // Define a valid motion down event.
Garfield Tan00f511d2019-06-12 16:55:40 -0700624 event.initialize(DEVICE_ID, source, displayId, action, /* actionButton */ 0, /* flags */ 0,
625 /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
626 /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
627 /* yPrecision */ 0, xCursorPosition, yCursorPosition, currentTime, currentTime,
628 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Arthur Hungb92218b2018-08-14 12:00:21 +0800629
630 // Inject event until dispatch out.
631 return dispatcher->injectInputEvent(
632 &event,
633 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
634 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
635}
636
Garfield Tan00f511d2019-06-12 16:55:40 -0700637static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
638 int32_t displayId, int32_t x = 100, int32_t y = 200) {
639 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, x, y);
640}
641
Jackal Guof9696682018-10-05 12:23:23 +0800642static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
643 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
644 // Define a valid key event.
645 NotifyKeyArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
646 displayId, POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0,
647 AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);
648
649 return args;
650}
651
652static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
653 PointerProperties pointerProperties[1];
654 PointerCoords pointerCoords[1];
655
656 pointerProperties[0].clear();
657 pointerProperties[0].id = 0;
658 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
659
660 pointerCoords[0].clear();
661 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
662 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
663
664 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
665 // Define a valid motion event.
666 NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -0700667 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
668 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
Atif Niyaz21da0ff2019-06-28 13:22:51 -0700669 AMOTION_EVENT_EDGE_FLAG_NONE, 1, pointerProperties, pointerCoords,
670 /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -0700671 AMOTION_EVENT_INVALID_CURSOR_POSITION,
672 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +0800673
674 return args;
675}
676
Arthur Hungb92218b2018-08-14 12:00:21 +0800677TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
678 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800679 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
680 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800681
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800682 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800683 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
684 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800685 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
686
687 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800688 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800689}
690
691// The foreground window should receive the first touch down event.
692TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
693 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800694 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
695 ADISPLAY_ID_DEFAULT);
696 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
697 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800698
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800699 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800700 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
701 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800702 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
703
704 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800705 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800706 windowSecond->assertNoEvents();
707}
708
709TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
710 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800711 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
712 ADISPLAY_ID_DEFAULT);
713 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
714 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800715
Arthur Hung7ab76b12019-01-09 19:17:20 +0800716 // Set focused application.
Tiger Huang721e26f2018-07-24 22:26:19 +0800717 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +0800718
719 // Expect one focus window exist in display.
720 windowSecond->setFocus();
Arthur Hungb92218b2018-08-14 12:00:21 +0800721
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800722 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800723 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
724 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
725
726 // Focused window should receive event.
727 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800728 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800729}
730
Arthur Hung7ab76b12019-01-09 19:17:20 +0800731TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
732 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
733 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
734 ADISPLAY_ID_DEFAULT);
735 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
736 ADISPLAY_ID_DEFAULT);
737
738 // Set focused application.
739 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
740
741 // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
742 windowTop->setFocus();
743 windowSecond->setFocus();
Arthur Hung7ab76b12019-01-09 19:17:20 +0800744
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800745 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800746 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
747 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
748
749 // Top focused window should receive event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800750 windowTop->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800751 windowSecond->assertNoEvents();
752}
753
Arthur Hung3b413f22018-10-26 18:05:34 +0800754TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
755 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
756
757 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
758 ADISPLAY_ID_DEFAULT);
759 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
760 ADISPLAY_ID_DEFAULT);
761
Arthur Hung832bc4a2019-01-28 11:43:17 +0800762 // Set focused application.
763 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hung3b413f22018-10-26 18:05:34 +0800764
Arthur Hung832bc4a2019-01-28 11:43:17 +0800765 windowTop->setFocus();
766 windowSecond->setFocus();
Arthur Hung3b413f22018-10-26 18:05:34 +0800767 // Release channel for window is no longer valid.
768 windowTop->releaseChannel();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800769 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung3b413f22018-10-26 18:05:34 +0800770
Arthur Hung832bc4a2019-01-28 11:43:17 +0800771 // Test inject a key down, should dispatch to a valid window.
772 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
773 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Arthur Hung3b413f22018-10-26 18:05:34 +0800774
775 // Top window is invalid, so it should not receive any input event.
776 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800777 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung3b413f22018-10-26 18:05:34 +0800778}
779
Garfield Tan00f511d2019-06-12 16:55:40 -0700780TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
781 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
782
783 sp<FakeWindowHandle> windowLeft =
784 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
785 windowLeft->setFrame(Rect(0, 0, 600, 800));
786 windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
787 sp<FakeWindowHandle> windowRight =
788 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
789 windowRight->setFrame(Rect(600, 0, 1200, 800));
790 windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
791
792 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
793
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800794 mDispatcher->setInputWindows({windowLeft, windowRight}, ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700795
796 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
797 // left window. This event should be dispatched to the left window.
798 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
799 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
800 ADISPLAY_ID_DEFAULT, 610, 400, 599, 400));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800801 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700802 windowRight->assertNoEvents();
803}
804
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800805TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
806 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
807 sp<FakeWindowHandle> window =
808 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
809 window->setFocus();
810
811 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
812
813 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
814 mDispatcher->notifyKey(&keyArgs);
815
816 // Window should receive key down event.
817 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
818
819 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
820 // on the app side.
821 NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID);
822 mDispatcher->notifyDeviceReset(&args);
823 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
824 AKEY_EVENT_FLAG_CANCELED);
825}
826
827TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
828 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
829 sp<FakeWindowHandle> window =
830 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
831
832 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
833
834 NotifyMotionArgs motionArgs =
835 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
836 ADISPLAY_ID_DEFAULT);
837 mDispatcher->notifyMotion(&motionArgs);
838
839 // Window should receive motion down event.
840 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
841
842 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
843 // on the app side.
844 NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID);
845 mDispatcher->notifyDeviceReset(&args);
846 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
847 0 /*expectedFlags*/);
848}
849
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800850/* Test InputDispatcher for MultiDisplay */
851class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
852public:
853 static constexpr int32_t SECOND_DISPLAY_ID = 1;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700854 virtual void SetUp() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800855 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +0800856
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800857 application1 = new FakeApplicationHandle();
858 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
859 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800860
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800861 // Set focus window for primary display, but focused display would be second one.
862 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
863 windowInPrimary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800864 mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800865
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800866 application2 = new FakeApplicationHandle();
867 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
868 SECOND_DISPLAY_ID);
869 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800870 // Set focus display to second one.
871 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
872 // Set focus window for second display.
873 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
874 windowInSecondary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800875 mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800876 }
877
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700878 virtual void TearDown() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800879 InputDispatcherTest::TearDown();
880
881 application1.clear();
882 windowInPrimary.clear();
883 application2.clear();
884 windowInSecondary.clear();
885 }
886
887protected:
888 sp<FakeApplicationHandle> application1;
889 sp<FakeWindowHandle> windowInPrimary;
890 sp<FakeApplicationHandle> application2;
891 sp<FakeWindowHandle> windowInSecondary;
892};
893
894TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
895 // Test touch down on primary display.
896 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
897 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800898 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800899 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800900 windowInSecondary->assertNoEvents();
901
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800902 // Test touch down on second display.
903 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
904 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +0800905 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
906 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800907 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800908}
909
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800910TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +0800911 // Test inject a key down with display id specified.
912 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
913 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800914 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +0800915 windowInSecondary->assertNoEvents();
916
917 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +0800918 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
919 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
920 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800921 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800922
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800923 // Remove all windows in secondary display.
924 mDispatcher->setInputWindows({}, SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800925
926 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800927 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
928 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +0800929
930 // Test inject a key down, should timeout because of no target window.
931 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
932 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
933 windowInPrimary->assertNoEvents();
934 windowInSecondary->assertNoEvents();
935}
936
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800937class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
938public:
939 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
Michael Wright3dd60e22019-03-27 22:06:44 +0000940 int32_t displayId, bool isGestureMonitor = false)
941 : FakeInputReceiver(dispatcher, name, displayId) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000942 mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800943 }
944};
945
946// Test per-display input monitors for motion event.
947TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
948 sp<FakeMonitorReceiver> monitorInPrimary =
949 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
950 sp<FakeMonitorReceiver> monitorInSecondary =
951 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
952
953 // Test touch down on primary display.
954 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
955 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
956 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800957 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
958 monitorInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800959 windowInSecondary->assertNoEvents();
960 monitorInSecondary->assertNoEvents();
961
962 // Test touch down on second display.
963 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
964 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
965 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
966 windowInPrimary->assertNoEvents();
967 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800968 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
969 monitorInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800970
971 // Test inject a non-pointer motion event.
972 // If specific a display, it will dispatch to the focused window of particular display,
973 // or it will dispatch to the focused window of focused display.
974 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
975 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
976 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
977 windowInPrimary->assertNoEvents();
978 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800979 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
980 monitorInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800981}
982
983// Test per-display input monitors for key event.
984TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
985 //Input monitor per display.
986 sp<FakeMonitorReceiver> monitorInPrimary =
987 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
988 sp<FakeMonitorReceiver> monitorInSecondary =
989 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
990
991 // Test inject a key down.
992 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
993 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
994 windowInPrimary->assertNoEvents();
995 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800996 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
997 monitorInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800998}
999
Jackal Guof9696682018-10-05 12:23:23 +08001000class InputFilterTest : public InputDispatcherTest {
1001protected:
1002 static constexpr int32_t SECOND_DISPLAY_ID = 1;
1003
1004 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
1005 NotifyMotionArgs motionArgs;
1006
1007 motionArgs = generateMotionArgs(
1008 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1009 mDispatcher->notifyMotion(&motionArgs);
1010 motionArgs = generateMotionArgs(
1011 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1012 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001013 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001014 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001015 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001016 } else {
1017 mFakePolicy->assertFilterInputEventWasNotCalled();
1018 }
1019 }
1020
1021 void testNotifyKey(bool expectToBeFiltered) {
1022 NotifyKeyArgs keyArgs;
1023
1024 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1025 mDispatcher->notifyKey(&keyArgs);
1026 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
1027 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001028 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001029
1030 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001031 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001032 } else {
1033 mFakePolicy->assertFilterInputEventWasNotCalled();
1034 }
1035 }
1036};
1037
1038// Test InputFilter for MotionEvent
1039TEST_F(InputFilterTest, MotionEvent_InputFilter) {
1040 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
1041 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1042 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1043
1044 // Enable InputFilter
1045 mDispatcher->setInputFilterEnabled(true);
1046 // Test touch on both primary and second display, and check if both events are filtered.
1047 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
1048 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
1049
1050 // Disable InputFilter
1051 mDispatcher->setInputFilterEnabled(false);
1052 // Test touch on both primary and second display, and check if both events aren't filtered.
1053 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1054 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1055}
1056
1057// Test InputFilter for KeyEvent
1058TEST_F(InputFilterTest, KeyEvent_InputFilter) {
1059 // Since the InputFilter is disabled by default, check if key event aren't filtered.
1060 testNotifyKey(/*expectToBeFiltered*/ false);
1061
1062 // Enable InputFilter
1063 mDispatcher->setInputFilterEnabled(true);
1064 // Send a key event, and check if it is filtered.
1065 testNotifyKey(/*expectToBeFiltered*/ true);
1066
1067 // Disable InputFilter
1068 mDispatcher->setInputFilterEnabled(false);
1069 // Send a key event, and check if it isn't filtered.
1070 testNotifyKey(/*expectToBeFiltered*/ false);
1071}
1072
chaviwfd6d3512019-03-25 13:23:49 -07001073class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001074 virtual void SetUp() override {
chaviwfd6d3512019-03-25 13:23:49 -07001075 InputDispatcherTest::SetUp();
1076
1077 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1078 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
1079 ADISPLAY_ID_DEFAULT);
1080 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
1081 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
1082 // window.
1083 mUnfocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1084
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001085 mFocusedWindow =
1086 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1087 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
1088 mFocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1089 mFocusedWindowTouchPoint = 60;
chaviwfd6d3512019-03-25 13:23:49 -07001090
1091 // Set focused application.
1092 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001093 mFocusedWindow->setFocus();
chaviwfd6d3512019-03-25 13:23:49 -07001094
1095 // Expect one focus window exist in display.
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001096 mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07001097 }
1098
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001099 virtual void TearDown() override {
chaviwfd6d3512019-03-25 13:23:49 -07001100 InputDispatcherTest::TearDown();
1101
1102 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001103 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07001104 }
1105
1106protected:
1107 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001108 sp<FakeWindowHandle> mFocusedWindow;
1109 int32_t mFocusedWindowTouchPoint;
chaviwfd6d3512019-03-25 13:23:49 -07001110};
1111
1112// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1113// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
1114// the onPointerDownOutsideFocus callback.
1115TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
1116 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1117 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20))
1118 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001119
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001120 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07001121 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
1122}
1123
1124// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
1125// DOWN on the window that doesn't have focus. Ensure no window received the
1126// onPointerDownOutsideFocus callback.
1127TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
1128 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1129 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20))
1130 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001131
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001132 ASSERT_TRUE(mDispatcher->waitForIdle());
1133 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001134}
1135
1136// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
1137// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
1138TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
1139 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1140 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001141
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001142 ASSERT_TRUE(mDispatcher->waitForIdle());
1143 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001144}
1145
1146// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1147// DOWN on the window that already has focus. Ensure no window received the
1148// onPointerDownOutsideFocus callback.
1149TEST_F(InputDispatcherOnPointerDownOutsideFocus,
1150 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001151 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1152 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1153 mFocusedWindowTouchPoint, mFocusedWindowTouchPoint))
chaviwfd6d3512019-03-25 13:23:49 -07001154 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001155
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001156 ASSERT_TRUE(mDispatcher->waitForIdle());
1157 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001158}
1159
Garfield Tane84e6f92019-08-29 17:28:41 -07001160} // namespace android::inputdispatcher