blob: 0701f3b3ee2e953be4e5492b2b7be5063b617e27 [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
Michael Wright3a240c42019-12-10 20:53:41 +0000491 void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
492 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, 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
Michael Wright3a240c42019-12-10 20:53:41 +0000647static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
648 int32_t displayId, int32_t x = 100, int32_t y = 200) {
649 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, x, y);
650}
651
Jackal Guof9696682018-10-05 12:23:23 +0800652static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
653 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
654 // Define a valid key event.
655 NotifyKeyArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
656 displayId, POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0,
657 AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);
658
659 return args;
660}
661
662static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
663 PointerProperties pointerProperties[1];
664 PointerCoords pointerCoords[1];
665
666 pointerProperties[0].clear();
667 pointerProperties[0].id = 0;
668 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
669
670 pointerCoords[0].clear();
671 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 100);
672 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 200);
673
674 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
675 // Define a valid motion event.
676 NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -0700677 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
678 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
Atif Niyaz21da0ff2019-06-28 13:22:51 -0700679 AMOTION_EVENT_EDGE_FLAG_NONE, 1, pointerProperties, pointerCoords,
680 /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -0700681 AMOTION_EVENT_INVALID_CURSOR_POSITION,
682 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +0800683
684 return args;
685}
686
Arthur Hungb92218b2018-08-14 12:00:21 +0800687TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
688 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800689 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
690 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800691
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800692 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800693 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
694 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800695 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
696
697 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800698 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800699}
700
701// The foreground window should receive the first touch down event.
702TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
703 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800704 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
705 ADISPLAY_ID_DEFAULT);
706 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
707 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800708
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800709 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800710 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
711 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800712 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
713
714 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800715 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800716 windowSecond->assertNoEvents();
717}
718
719TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
720 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800721 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
722 ADISPLAY_ID_DEFAULT);
723 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
724 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800725
Arthur Hung7ab76b12019-01-09 19:17:20 +0800726 // Set focused application.
Tiger Huang721e26f2018-07-24 22:26:19 +0800727 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +0800728
729 // Expect one focus window exist in display.
730 windowSecond->setFocus();
Arthur Hungb92218b2018-08-14 12:00:21 +0800731
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800732 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800733 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
734 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
735
736 // Focused window should receive event.
737 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800738 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800739}
740
Arthur Hung7ab76b12019-01-09 19:17:20 +0800741TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
742 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
743 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
744 ADISPLAY_ID_DEFAULT);
745 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
746 ADISPLAY_ID_DEFAULT);
747
748 // Set focused application.
749 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
750
751 // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
752 windowTop->setFocus();
753 windowSecond->setFocus();
Arthur Hung7ab76b12019-01-09 19:17:20 +0800754
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800755 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800756 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
757 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
758
759 // Top focused window should receive event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800760 windowTop->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800761 windowSecond->assertNoEvents();
762}
763
Arthur Hung3b413f22018-10-26 18:05:34 +0800764TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
765 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
766
767 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
768 ADISPLAY_ID_DEFAULT);
769 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
770 ADISPLAY_ID_DEFAULT);
771
Arthur Hung832bc4a2019-01-28 11:43:17 +0800772 // Set focused application.
773 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hung3b413f22018-10-26 18:05:34 +0800774
Arthur Hung832bc4a2019-01-28 11:43:17 +0800775 windowTop->setFocus();
776 windowSecond->setFocus();
Arthur Hung3b413f22018-10-26 18:05:34 +0800777 // Release channel for window is no longer valid.
778 windowTop->releaseChannel();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800779 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung3b413f22018-10-26 18:05:34 +0800780
Arthur Hung832bc4a2019-01-28 11:43:17 +0800781 // Test inject a key down, should dispatch to a valid window.
782 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
783 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Arthur Hung3b413f22018-10-26 18:05:34 +0800784
785 // Top window is invalid, so it should not receive any input event.
786 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800787 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung3b413f22018-10-26 18:05:34 +0800788}
789
Garfield Tan00f511d2019-06-12 16:55:40 -0700790TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
791 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
792
793 sp<FakeWindowHandle> windowLeft =
794 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
795 windowLeft->setFrame(Rect(0, 0, 600, 800));
796 windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
797 sp<FakeWindowHandle> windowRight =
798 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
799 windowRight->setFrame(Rect(600, 0, 1200, 800));
800 windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
801
802 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
803
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800804 mDispatcher->setInputWindows({windowLeft, windowRight}, ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700805
806 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
807 // left window. This event should be dispatched to the left window.
808 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
809 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
810 ADISPLAY_ID_DEFAULT, 610, 400, 599, 400));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800811 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700812 windowRight->assertNoEvents();
813}
814
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800815TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
816 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
817 sp<FakeWindowHandle> window =
818 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
819 window->setFocus();
820
821 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
822
823 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
824 mDispatcher->notifyKey(&keyArgs);
825
826 // Window should receive key down event.
827 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
828
829 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
830 // on the app side.
831 NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID);
832 mDispatcher->notifyDeviceReset(&args);
833 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
834 AKEY_EVENT_FLAG_CANCELED);
835}
836
837TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
838 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
839 sp<FakeWindowHandle> window =
840 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
841
842 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
843
844 NotifyMotionArgs motionArgs =
845 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
846 ADISPLAY_ID_DEFAULT);
847 mDispatcher->notifyMotion(&motionArgs);
848
849 // Window should receive motion down event.
850 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
851
852 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
853 // on the app side.
854 NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID);
855 mDispatcher->notifyDeviceReset(&args);
856 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
857 0 /*expectedFlags*/);
858}
859
Michael Wright3a240c42019-12-10 20:53:41 +0000860class FakeMonitorReceiver : public FakeInputReceiver, public RefBase {
861public:
862 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
863 int32_t displayId, bool isGestureMonitor = false)
864 : FakeInputReceiver(dispatcher, name, displayId) {
865 mDispatcher->registerInputMonitor(mServerChannel, displayId, isGestureMonitor);
866 }
867
868 sp<IBinder> getToken() { return mServerChannel->getConnectionToken(); }
869};
870
871// Tests for gesture monitors
872TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) {
873 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
874 sp<FakeWindowHandle> window =
875 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
876 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
877
878 sp<FakeMonitorReceiver> monitor =
879 new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
880 true /*isGestureMonitor*/);
881
882 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
883 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
884 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
885 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
886 monitor->consumeMotionDown(ADISPLAY_ID_DEFAULT);
887}
888
889TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) {
890 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
891 sp<FakeWindowHandle> window =
892 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
893
894 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
895 window->setFocus();
896
897 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
898
899 sp<FakeMonitorReceiver> monitor =
900 new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
901 true /*isGestureMonitor*/);
902
903 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
904 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
905 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
906 monitor->assertNoEvents();
907}
908
909TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) {
910 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
911 sp<FakeWindowHandle> window =
912 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
913 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
914
915 sp<FakeMonitorReceiver> monitor =
916 new FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
917 true /*isGestureMonitor*/);
918
919 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
920 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
921 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
922 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
923 monitor->consumeMotionDown(ADISPLAY_ID_DEFAULT);
924
925 window->releaseChannel();
926
927 mDispatcher->pilferPointers(monitor->getToken());
928
929 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
930 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
931 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
932 monitor->consumeMotionUp(ADISPLAY_ID_DEFAULT);
933}
934
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800935/* Test InputDispatcher for MultiDisplay */
936class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
937public:
938 static constexpr int32_t SECOND_DISPLAY_ID = 1;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700939 virtual void SetUp() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800940 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +0800941
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800942 application1 = new FakeApplicationHandle();
943 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
944 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800945
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800946 // Set focus window for primary display, but focused display would be second one.
947 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
948 windowInPrimary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800949 mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800950
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800951 application2 = new FakeApplicationHandle();
952 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
953 SECOND_DISPLAY_ID);
954 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800955 // Set focus display to second one.
956 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
957 // Set focus window for second display.
958 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
959 windowInSecondary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800960 mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800961 }
962
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700963 virtual void TearDown() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800964 InputDispatcherTest::TearDown();
965
966 application1.clear();
967 windowInPrimary.clear();
968 application2.clear();
969 windowInSecondary.clear();
970 }
971
972protected:
973 sp<FakeApplicationHandle> application1;
974 sp<FakeWindowHandle> windowInPrimary;
975 sp<FakeApplicationHandle> application2;
976 sp<FakeWindowHandle> windowInSecondary;
977};
978
979TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
980 // Test touch down on primary display.
981 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
982 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800983 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800984 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800985 windowInSecondary->assertNoEvents();
986
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800987 // Test touch down on second display.
988 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
989 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +0800990 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
991 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800992 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +0800993}
994
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800995TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +0800996 // Test inject a key down with display id specified.
997 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
998 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800999 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +08001000 windowInSecondary->assertNoEvents();
1001
1002 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +08001003 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1004 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1005 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001006 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +08001007
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001008 // Remove all windows in secondary display.
1009 mDispatcher->setInputWindows({}, SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +08001010
1011 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001012 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
1013 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +08001014
1015 // Test inject a key down, should timeout because of no target window.
1016 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
1017 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
1018 windowInPrimary->assertNoEvents();
1019 windowInSecondary->assertNoEvents();
1020}
1021
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001022// Test per-display input monitors for motion event.
1023TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
1024 sp<FakeMonitorReceiver> monitorInPrimary =
1025 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
1026 sp<FakeMonitorReceiver> monitorInSecondary =
1027 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
1028
1029 // Test touch down on primary display.
1030 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1031 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1032 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001033 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1034 monitorInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001035 windowInSecondary->assertNoEvents();
1036 monitorInSecondary->assertNoEvents();
1037
1038 // Test touch down on second display.
1039 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1040 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
1041 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1042 windowInPrimary->assertNoEvents();
1043 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001044 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
1045 monitorInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001046
1047 // Test inject a non-pointer motion event.
1048 // If specific a display, it will dispatch to the focused window of particular display,
1049 // or it will dispatch to the focused window of focused display.
1050 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1051 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
1052 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1053 windowInPrimary->assertNoEvents();
1054 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001055 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
1056 monitorInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001057}
1058
1059// Test per-display input monitors for key event.
1060TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
1061 //Input monitor per display.
1062 sp<FakeMonitorReceiver> monitorInPrimary =
1063 new FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
1064 sp<FakeMonitorReceiver> monitorInSecondary =
1065 new FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
1066
1067 // Test inject a key down.
1068 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1069 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1070 windowInPrimary->assertNoEvents();
1071 monitorInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001072 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
1073 monitorInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001074}
1075
Jackal Guof9696682018-10-05 12:23:23 +08001076class InputFilterTest : public InputDispatcherTest {
1077protected:
1078 static constexpr int32_t SECOND_DISPLAY_ID = 1;
1079
1080 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
1081 NotifyMotionArgs motionArgs;
1082
1083 motionArgs = generateMotionArgs(
1084 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1085 mDispatcher->notifyMotion(&motionArgs);
1086 motionArgs = generateMotionArgs(
1087 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1088 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001089 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001090 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001091 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001092 } else {
1093 mFakePolicy->assertFilterInputEventWasNotCalled();
1094 }
1095 }
1096
1097 void testNotifyKey(bool expectToBeFiltered) {
1098 NotifyKeyArgs keyArgs;
1099
1100 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1101 mDispatcher->notifyKey(&keyArgs);
1102 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
1103 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001104 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001105
1106 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001107 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001108 } else {
1109 mFakePolicy->assertFilterInputEventWasNotCalled();
1110 }
1111 }
1112};
1113
1114// Test InputFilter for MotionEvent
1115TEST_F(InputFilterTest, MotionEvent_InputFilter) {
1116 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
1117 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1118 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1119
1120 // Enable InputFilter
1121 mDispatcher->setInputFilterEnabled(true);
1122 // Test touch on both primary and second display, and check if both events are filtered.
1123 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
1124 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
1125
1126 // Disable InputFilter
1127 mDispatcher->setInputFilterEnabled(false);
1128 // Test touch on both primary and second display, and check if both events aren't filtered.
1129 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1130 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1131}
1132
1133// Test InputFilter for KeyEvent
1134TEST_F(InputFilterTest, KeyEvent_InputFilter) {
1135 // Since the InputFilter is disabled by default, check if key event aren't filtered.
1136 testNotifyKey(/*expectToBeFiltered*/ false);
1137
1138 // Enable InputFilter
1139 mDispatcher->setInputFilterEnabled(true);
1140 // Send a key event, and check if it is filtered.
1141 testNotifyKey(/*expectToBeFiltered*/ true);
1142
1143 // Disable InputFilter
1144 mDispatcher->setInputFilterEnabled(false);
1145 // Send a key event, and check if it isn't filtered.
1146 testNotifyKey(/*expectToBeFiltered*/ false);
1147}
1148
chaviwfd6d3512019-03-25 13:23:49 -07001149class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001150 virtual void SetUp() override {
chaviwfd6d3512019-03-25 13:23:49 -07001151 InputDispatcherTest::SetUp();
1152
1153 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1154 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
1155 ADISPLAY_ID_DEFAULT);
1156 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
1157 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
1158 // window.
1159 mUnfocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1160
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001161 mFocusedWindow =
1162 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1163 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
1164 mFocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1165 mFocusedWindowTouchPoint = 60;
chaviwfd6d3512019-03-25 13:23:49 -07001166
1167 // Set focused application.
1168 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001169 mFocusedWindow->setFocus();
chaviwfd6d3512019-03-25 13:23:49 -07001170
1171 // Expect one focus window exist in display.
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001172 mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07001173 }
1174
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001175 virtual void TearDown() override {
chaviwfd6d3512019-03-25 13:23:49 -07001176 InputDispatcherTest::TearDown();
1177
1178 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001179 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07001180 }
1181
1182protected:
1183 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001184 sp<FakeWindowHandle> mFocusedWindow;
1185 int32_t mFocusedWindowTouchPoint;
chaviwfd6d3512019-03-25 13:23:49 -07001186};
1187
1188// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1189// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
1190// the onPointerDownOutsideFocus callback.
1191TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
1192 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1193 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20))
1194 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001195
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001196 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07001197 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
1198}
1199
1200// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
1201// DOWN on the window that doesn't have focus. Ensure no window received the
1202// onPointerDownOutsideFocus callback.
1203TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
1204 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1205 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20))
1206 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001207
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001208 ASSERT_TRUE(mDispatcher->waitForIdle());
1209 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001210}
1211
1212// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
1213// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
1214TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
1215 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1216 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001217
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001218 ASSERT_TRUE(mDispatcher->waitForIdle());
1219 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001220}
1221
1222// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1223// DOWN on the window that already has focus. Ensure no window received the
1224// onPointerDownOutsideFocus callback.
1225TEST_F(InputDispatcherOnPointerDownOutsideFocus,
1226 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001227 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1228 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1229 mFocusedWindowTouchPoint, mFocusedWindowTouchPoint))
chaviwfd6d3512019-03-25 13:23:49 -07001230 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001231
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001232 ASSERT_TRUE(mDispatcher->waitForIdle());
1233 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001234}
1235
Garfield Tane84e6f92019-08-29 17:28:41 -07001236} // namespace android::inputdispatcher