blob: 5ffc89d21058251fa98fd78ace70255b779da0d7 [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>
chaviwd1c23182019-12-20 18:44:56 -080024#include <vector>
Michael Wrightd02c5b62014-02-10 15:10:22 -080025
Garfield Tane84e6f92019-08-29 17:28:41 -070026namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080027
28// An arbitrary time value.
29static const nsecs_t ARBITRARY_TIME = 1234;
30
31// An arbitrary device id.
32static const int32_t DEVICE_ID = 1;
33
Jeff Brownf086ddb2014-02-11 14:28:48 -080034// An arbitrary display id.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -080035static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
Jeff Brownf086ddb2014-02-11 14:28:48 -080036
Michael Wrightd02c5b62014-02-10 15:10:22 -080037// An arbitrary injector pid / uid pair that has permission to inject events.
38static const int32_t INJECTOR_PID = 999;
39static const int32_t INJECTOR_UID = 1001;
40
chaviwd1c23182019-12-20 18:44:56 -080041struct PointF {
42 float x;
43 float y;
44};
Michael Wrightd02c5b62014-02-10 15:10:22 -080045
46// --- FakeInputDispatcherPolicy ---
47
48class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
49 InputDispatcherConfiguration mConfig;
50
51protected:
52 virtual ~FakeInputDispatcherPolicy() {
53 }
54
55public:
56 FakeInputDispatcherPolicy() {
Jackal Guof9696682018-10-05 12:23:23 +080057 }
58
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080059 void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080060 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_KEY, args.eventTime, args.action,
61 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080062 }
63
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080064 void assertFilterInputEventWasCalled(const NotifyMotionArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080065 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_MOTION, args.eventTime, args.action,
66 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080067 }
68
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080069 void assertFilterInputEventWasNotCalled() { ASSERT_EQ(nullptr, mFilteredEvent); }
Michael Wrightd02c5b62014-02-10 15:10:22 -080070
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080071 void assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
72 ASSERT_TRUE(mConfigurationChangedTime)
73 << "Timed out waiting for configuration changed call";
74 ASSERT_EQ(*mConfigurationChangedTime, when);
75 mConfigurationChangedTime = std::nullopt;
76 }
77
78 void assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
79 ASSERT_TRUE(mLastNotifySwitch);
80 // We do not check sequenceNum because it is not exposed to the policy
81 EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime);
82 EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags);
83 EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues);
84 EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask);
85 mLastNotifySwitch = std::nullopt;
86 }
87
chaviwfd6d3512019-03-25 13:23:49 -070088 void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080089 ASSERT_EQ(touchedToken, mOnPointerDownToken);
90 mOnPointerDownToken.clear();
91 }
92
93 void assertOnPointerDownWasNotCalled() {
94 ASSERT_TRUE(mOnPointerDownToken == nullptr)
95 << "Expected onPointerDownOutsideFocus to not have been called";
chaviwfd6d3512019-03-25 13:23:49 -070096 }
97
Michael Wrightd02c5b62014-02-10 15:10:22 -080098private:
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080099 std::unique_ptr<InputEvent> mFilteredEvent;
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800100 std::optional<nsecs_t> mConfigurationChangedTime;
chaviwfd6d3512019-03-25 13:23:49 -0700101 sp<IBinder> mOnPointerDownToken;
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800102 std::optional<NotifySwitchArgs> mLastNotifySwitch;
Jackal Guof9696682018-10-05 12:23:23 +0800103
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800104 virtual void notifyConfigurationChanged(nsecs_t when) override {
105 mConfigurationChangedTime = when;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800106 }
107
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100108 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>&,
Robert Carr803535b2018-08-02 16:38:15 -0700109 const sp<IBinder>&,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800110 const std::string&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800111 return 0;
112 }
113
Robert Carr803535b2018-08-02 16:38:15 -0700114 virtual void notifyInputChannelBroken(const sp<IBinder>&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115 }
116
chaviw0c06c6e2019-01-09 13:27:07 -0800117 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) {
Robert Carr740167f2018-10-11 19:03:41 -0700118 }
119
Michael Wrightd02c5b62014-02-10 15:10:22 -0800120 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
121 *outConfig = mConfig;
122 }
123
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800124 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Jackal Guof9696682018-10-05 12:23:23 +0800125 switch (inputEvent->getType()) {
126 case AINPUT_EVENT_TYPE_KEY: {
127 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800128 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800129 break;
130 }
131
132 case AINPUT_EVENT_TYPE_MOTION: {
133 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800134 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800135 break;
136 }
137 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800138 return true;
139 }
140
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100141 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800142 }
143
Charles Chen3611f1f2019-01-29 17:26:18 +0800144 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800145 }
146
Robert Carr803535b2018-08-02 16:38:15 -0700147 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100148 const KeyEvent*, uint32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800149 return 0;
150 }
151
Robert Carr803535b2018-08-02 16:38:15 -0700152 virtual bool dispatchUnhandledKey(const sp<IBinder>&,
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100153 const KeyEvent*, uint32_t, KeyEvent*) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800154 return false;
155 }
156
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800157 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
158 uint32_t policyFlags) override {
159 /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
160 * essentially a passthrough for notifySwitch.
161 */
162 mLastNotifySwitch =
163 NotifySwitchArgs(1 /*sequenceNum*/, when, policyFlags, switchValues, switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800164 }
165
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100166 virtual void pokeUserActivity(nsecs_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800167 }
168
Narayan Kamath39efe3e2014-10-17 10:37:08 +0100169 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800170 return false;
171 }
Jackal Guof9696682018-10-05 12:23:23 +0800172
chaviwfd6d3512019-03-25 13:23:49 -0700173 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) {
174 mOnPointerDownToken = newToken;
175 }
176
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800177 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
178 int32_t displayId) {
179 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
180 ASSERT_EQ(mFilteredEvent->getType(), type);
181
182 if (type == AINPUT_EVENT_TYPE_KEY) {
183 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
184 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
185 EXPECT_EQ(keyEvent.getAction(), action);
186 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
187 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
188 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
189 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
190 EXPECT_EQ(motionEvent.getAction(), action);
191 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
192 } else {
193 FAIL() << "Unknown type: " << type;
194 }
195
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800196 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800197 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800198};
199
200
201// --- InputDispatcherTest ---
202
203class InputDispatcherTest : public testing::Test {
204protected:
205 sp<FakeInputDispatcherPolicy> mFakePolicy;
206 sp<InputDispatcher> mDispatcher;
207
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700208 virtual void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800209 mFakePolicy = new FakeInputDispatcherPolicy();
210 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800211 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
212 //Start InputDispatcher thread
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700213 ASSERT_EQ(OK, mDispatcher->start());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 }
215
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700216 virtual void TearDown() override {
217 ASSERT_EQ(OK, mDispatcher->stop());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 mFakePolicy.clear();
219 mDispatcher.clear();
220 }
221};
222
223
224TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
225 KeyEvent event;
226
227 // Rejects undefined key actions.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100228 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229 /*action*/ -1, 0,
230 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800231 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800232 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800233 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
234 << "Should reject key events with undefined action.";
235
236 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100237 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800238 AKEY_EVENT_ACTION_MULTIPLE, 0,
239 AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800240 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800241 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
243 << "Should reject key events with ACTION_MULTIPLE.";
244}
245
246TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
247 MotionEvent event;
248 PointerProperties pointerProperties[MAX_POINTERS + 1];
249 PointerCoords pointerCoords[MAX_POINTERS + 1];
250 for (int i = 0; i <= MAX_POINTERS; i++) {
251 pointerProperties[i].clear();
252 pointerProperties[i].id = i;
253 pointerCoords[i].clear();
254 }
255
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800256 // Some constants commonly used below
257 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
258 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
259 constexpr int32_t metaState = AMETA_NONE;
260 constexpr MotionClassification classification = MotionClassification::NONE;
261
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262 // Rejects undefined motion actions.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800263 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700264 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
265 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
266 ARBITRARY_TIME, ARBITRARY_TIME,
267 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800268 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800269 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800270 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
271 << "Should reject motion events with undefined action.";
272
273 // Rejects pointer down with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800274 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700275 AMOTION_EVENT_ACTION_POINTER_DOWN |
276 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
277 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
278 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
279 ARBITRARY_TIME, ARBITRARY_TIME,
280 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800281 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800282 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800283 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
284 << "Should reject motion events with pointer down index too large.";
285
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800286 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700287 AMOTION_EVENT_ACTION_POINTER_DOWN |
288 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
289 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
290 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
291 ARBITRARY_TIME, ARBITRARY_TIME,
292 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800293 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800294 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
296 << "Should reject motion events with pointer down index too small.";
297
298 // Rejects pointer up with invalid index.
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800299 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700300 AMOTION_EVENT_ACTION_POINTER_UP |
301 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
302 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
303 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
304 ARBITRARY_TIME, ARBITRARY_TIME,
305 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800306 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800307 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800308 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
309 << "Should reject motion events with pointer up index too large.";
310
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800311 event.initialize(DEVICE_ID, source, DISPLAY_ID,
Garfield Tan00f511d2019-06-12 16:55:40 -0700312 AMOTION_EVENT_ACTION_POINTER_UP |
313 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
314 0, 0, edgeFlags, metaState, 0, classification, 0, 0, 0, 0,
315 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
316 ARBITRARY_TIME, ARBITRARY_TIME,
317 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800318 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800319 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800320 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
321 << "Should reject motion events with pointer up index too small.";
322
323 // Rejects motion events with invalid number of pointers.
Garfield Tan00f511d2019-06-12 16:55:40 -0700324 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
325 metaState, 0, classification, 0, 0, 0, 0,
326 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
327 ARBITRARY_TIME, ARBITRARY_TIME,
328 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800329 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800330 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800331 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
332 << "Should reject motion events with 0 pointers.";
333
Garfield Tan00f511d2019-06-12 16:55:40 -0700334 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
335 metaState, 0, classification, 0, 0, 0, 0,
336 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
337 ARBITRARY_TIME, ARBITRARY_TIME,
338 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800339 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800340 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800341 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
342 << "Should reject motion events with more than MAX_POINTERS pointers.";
343
344 // Rejects motion events with invalid pointer ids.
345 pointerProperties[0].id = -1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700346 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
347 metaState, 0, classification, 0, 0, 0, 0,
348 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
349 ARBITRARY_TIME, ARBITRARY_TIME,
350 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800351 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800352 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800353 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
354 << "Should reject motion events with pointer ids less than 0.";
355
356 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700357 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
358 metaState, 0, classification, 0, 0, 0, 0,
359 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
360 ARBITRARY_TIME, ARBITRARY_TIME,
361 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800362 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800363 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800364 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
365 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
366
367 // Rejects motion events with duplicate pointer ids.
368 pointerProperties[0].id = 1;
369 pointerProperties[1].id = 1;
Garfield Tan00f511d2019-06-12 16:55:40 -0700370 event.initialize(DEVICE_ID, source, DISPLAY_ID, AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags,
371 metaState, 0, classification, 0, 0, 0, 0,
372 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
373 ARBITRARY_TIME, ARBITRARY_TIME,
374 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Jeff Brownf086ddb2014-02-11 14:28:48 -0800375 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800376 &event,
Michael Wrightd02c5b62014-02-10 15:10:22 -0800377 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
378 << "Should reject motion events with duplicate pointer ids.";
379}
380
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800381/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
382
383TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
384 constexpr nsecs_t eventTime = 20;
385 NotifyConfigurationChangedArgs args(10 /*sequenceNum*/, eventTime);
386 mDispatcher->notifyConfigurationChanged(&args);
387 ASSERT_TRUE(mDispatcher->waitForIdle());
388
389 mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
390}
391
392TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
393 NotifySwitchArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, 0 /*policyFlags*/,
394 1 /*switchValues*/, 2 /*switchMask*/);
395 mDispatcher->notifySwitch(&args);
396
397 // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener
398 args.policyFlags |= POLICY_FLAG_TRUSTED;
399 mFakePolicy->assertNotifySwitchWasCalled(args);
400}
401
Arthur Hungb92218b2018-08-14 12:00:21 +0800402// --- InputDispatcherTest SetInputWindowTest ---
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800403static constexpr int32_t INJECT_EVENT_TIMEOUT = 500;
404static constexpr int32_t DISPATCHING_TIMEOUT = 100;
Arthur Hungb92218b2018-08-14 12:00:21 +0800405
406class FakeApplicationHandle : public InputApplicationHandle {
407public:
408 FakeApplicationHandle() {}
409 virtual ~FakeApplicationHandle() {}
410
411 virtual bool updateInfo() {
Arthur Hung7a0c39a2019-03-20 16:52:24 +0800412 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
Arthur Hungb92218b2018-08-14 12:00:21 +0800413 return true;
414 }
415};
416
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800417class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800418public:
chaviwd1c23182019-12-20 18:44:56 -0800419 explicit FakeInputReceiver(const sp<InputChannel>& clientChannel, const std::string name)
420 : mName(name) {
421 mConsumer = std::make_unique<InputConsumer>(clientChannel);
422 }
423
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800424 InputEvent* consume() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800425 uint32_t consumeSeq;
426 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800427
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800428 std::chrono::time_point start = std::chrono::steady_clock::now();
429 status_t status = WOULD_BLOCK;
430 while (status == WOULD_BLOCK) {
chaviw81e2bb92019-12-18 15:03:51 -0800431 status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq,
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800432 &event);
433 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
434 if (elapsed > 100ms) {
435 break;
436 }
437 }
438
439 if (status == WOULD_BLOCK) {
440 // Just means there's no event available.
441 return nullptr;
442 }
443
444 if (status != OK) {
445 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
446 return nullptr;
447 }
448 if (event == nullptr) {
449 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
450 return nullptr;
451 }
452
chaviwd1c23182019-12-20 18:44:56 -0800453 status = mConsumer->sendFinishedSignal(consumeSeq, true);
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800454 if (status != OK) {
455 ADD_FAILURE() << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
456 }
457 return event;
458 }
459
460 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
461 int32_t expectedFlags) {
462 InputEvent* event = consume();
463
464 ASSERT_NE(nullptr, event) << mName.c_str()
465 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800466 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800467 << mName.c_str() << "expected " << inputEventTypeToString(expectedEventType)
468 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800469
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800470 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800471
Tiger Huang8664f8c2018-10-11 19:14:35 +0800472 switch (expectedEventType) {
473 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800474 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
475 EXPECT_EQ(expectedAction, keyEvent.getAction());
476 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800477 break;
478 }
479 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800480 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
481 EXPECT_EQ(expectedAction, motionEvent.getAction());
482 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800483 break;
484 }
485 default: {
486 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
487 }
488 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800489 }
490
chaviwd1c23182019-12-20 18:44:56 -0800491 void assertNoEvents() {
492 InputEvent* event = consume();
493 ASSERT_EQ(nullptr, event)
494 << mName.c_str()
495 << ": should not have received any events, so consume() should return NULL";
496 }
497
498 sp<IBinder> getToken() { return mConsumer->getChannel()->getConnectionToken(); }
499
500protected:
501 std::unique_ptr<InputConsumer> mConsumer;
502 PreallocatedInputEventFactory mEventFactory;
503
504 std::string mName;
505};
506
507class FakeWindowHandle : public InputWindowHandle {
508public:
509 static const int32_t WIDTH = 600;
510 static const int32_t HEIGHT = 800;
511 const std::string mName;
512
513 FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
514 const sp<InputDispatcher>& dispatcher, const std::string name,
515 int32_t displayId, sp<IBinder> token = nullptr)
516 : mName(name) {
517 if (token == nullptr) {
518 sp<InputChannel> serverChannel, clientChannel;
519 InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
520 mInputReceiver = std::make_unique<FakeInputReceiver>(clientChannel, name);
521 dispatcher->registerInputChannel(serverChannel);
522 token = serverChannel->getConnectionToken();
523 }
524
525 inputApplicationHandle->updateInfo();
526 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
527
528 mInfo.token = token;
chaviwaf87b3e2019-10-01 16:59:28 -0700529 mInfo.id = 0;
chaviwd1c23182019-12-20 18:44:56 -0800530 mInfo.name = name;
531 mInfo.layoutParamsFlags = 0;
532 mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
533 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
534 mInfo.frameLeft = 0;
535 mInfo.frameTop = 0;
536 mInfo.frameRight = WIDTH;
537 mInfo.frameBottom = HEIGHT;
538 mInfo.globalScaleFactor = 1.0;
539 mInfo.touchableRegion.clear();
540 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
541 mInfo.visible = true;
542 mInfo.canReceiveKeys = true;
543 mInfo.hasFocus = false;
544 mInfo.hasWallpaper = false;
545 mInfo.paused = false;
chaviwd1c23182019-12-20 18:44:56 -0800546 mInfo.ownerPid = INJECTOR_PID;
547 mInfo.ownerUid = INJECTOR_UID;
548 mInfo.inputFeatures = 0;
549 mInfo.displayId = displayId;
550 }
551
552 virtual bool updateInfo() { return true; }
553
554 void setFocus() { mInfo.hasFocus = true; }
555
556 void setFrame(const Rect& frame) {
557 mInfo.frameLeft = frame.left;
558 mInfo.frameTop = frame.top;
559 mInfo.frameRight = frame.right;
560 mInfo.frameBottom = frame.bottom;
561 mInfo.touchableRegion.clear();
562 mInfo.addTouchableRegion(frame);
563 }
564
565 void setLayoutParamFlags(int32_t flags) { mInfo.layoutParamsFlags = flags; }
566
chaviwaf87b3e2019-10-01 16:59:28 -0700567 void setId(int32_t id) { mInfo.id = id; }
568
569 void setWindowScale(float xScale, float yScale) {
570 mInfo.windowXScale = xScale;
571 mInfo.windowYScale = yScale;
572 }
573
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800574 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
575 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
576 expectedFlags);
577 }
578
579 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
580 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
581 expectedFlags);
582 }
583
Michael Wright3a240c42019-12-10 20:53:41 +0000584 void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
585 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
586 expectedFlags);
587 }
588
chaviwd1c23182019-12-20 18:44:56 -0800589 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
590 int32_t expectedFlags) {
591 ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
592 mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
593 expectedFlags);
594 }
595
chaviwaf87b3e2019-10-01 16:59:28 -0700596 InputEvent* consume() {
597 if (mInputReceiver == nullptr) {
598 return nullptr;
599 }
600 return mInputReceiver->consume();
601 }
602
Arthur Hungb92218b2018-08-14 12:00:21 +0800603 void assertNoEvents() {
chaviwd1c23182019-12-20 18:44:56 -0800604 ASSERT_NE(mInputReceiver, nullptr)
605 << "Call 'assertNoEvents' on a window with an InputReceiver";
606 mInputReceiver->assertNoEvents();
Arthur Hungb92218b2018-08-14 12:00:21 +0800607 }
608
chaviwaf87b3e2019-10-01 16:59:28 -0700609 sp<IBinder> getToken() { return mInfo.token; }
610
chaviwd1c23182019-12-20 18:44:56 -0800611private:
612 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800613};
614
Tiger Huang721e26f2018-07-24 22:26:19 +0800615static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
616 int32_t displayId = ADISPLAY_ID_NONE) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800617 KeyEvent event;
618 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
619
620 // Define a valid key down event.
Tiger Huang721e26f2018-07-24 22:26:19 +0800621 event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Arthur Hungb92218b2018-08-14 12:00:21 +0800622 AKEY_EVENT_ACTION_DOWN, /* flags */ 0,
623 AKEYCODE_A, KEY_A, AMETA_NONE, /* repeatCount */ 0, currentTime, currentTime);
624
625 // Inject event until dispatch out.
626 return dispatcher->injectInputEvent(
627 &event,
628 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
629 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
630}
631
Garfield Tan00f511d2019-06-12 16:55:40 -0700632static int32_t injectMotionEvent(const sp<InputDispatcher>& dispatcher, int32_t action,
633 int32_t source, int32_t displayId, int32_t x, int32_t y,
634 int32_t xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION,
635 int32_t yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800636 MotionEvent event;
637 PointerProperties pointerProperties[1];
638 PointerCoords pointerCoords[1];
639
640 pointerProperties[0].clear();
641 pointerProperties[0].id = 0;
642 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
643
644 pointerCoords[0].clear();
chaviwfd6d3512019-03-25 13:23:49 -0700645 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
646 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
Arthur Hungb92218b2018-08-14 12:00:21 +0800647
648 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
649 // Define a valid motion down event.
Garfield Tan00f511d2019-06-12 16:55:40 -0700650 event.initialize(DEVICE_ID, source, displayId, action, /* actionButton */ 0, /* flags */ 0,
651 /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
652 /* xOffset */ 0, /* yOffset */ 0, /* xPrecision */ 0,
653 /* yPrecision */ 0, xCursorPosition, yCursorPosition, currentTime, currentTime,
654 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Arthur Hungb92218b2018-08-14 12:00:21 +0800655
656 // Inject event until dispatch out.
657 return dispatcher->injectInputEvent(
658 &event,
659 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
660 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
661}
662
Garfield Tan00f511d2019-06-12 16:55:40 -0700663static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
664 int32_t displayId, int32_t x = 100, int32_t y = 200) {
665 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, x, y);
666}
667
Michael Wright3a240c42019-12-10 20:53:41 +0000668static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
669 int32_t displayId, int32_t x = 100, int32_t y = 200) {
670 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, x, y);
671}
672
Jackal Guof9696682018-10-05 12:23:23 +0800673static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
674 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
675 // Define a valid key event.
676 NotifyKeyArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
677 displayId, POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0,
678 AKEYCODE_A, KEY_A, AMETA_NONE, currentTime);
679
680 return args;
681}
682
chaviwd1c23182019-12-20 18:44:56 -0800683static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId,
684 const std::vector<PointF>& points) {
685 size_t pointerCount = points.size();
chaviwaf87b3e2019-10-01 16:59:28 -0700686 if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_UP) {
687 EXPECT_EQ(1U, pointerCount) << "Actions DOWN and UP can only contain a single pointer";
688 }
689
chaviwd1c23182019-12-20 18:44:56 -0800690 PointerProperties pointerProperties[pointerCount];
691 PointerCoords pointerCoords[pointerCount];
Jackal Guof9696682018-10-05 12:23:23 +0800692
chaviwd1c23182019-12-20 18:44:56 -0800693 for (size_t i = 0; i < pointerCount; i++) {
694 pointerProperties[i].clear();
695 pointerProperties[i].id = i;
696 pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
Jackal Guof9696682018-10-05 12:23:23 +0800697
chaviwd1c23182019-12-20 18:44:56 -0800698 pointerCoords[i].clear();
699 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
700 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, points[i].y);
701 }
Jackal Guof9696682018-10-05 12:23:23 +0800702
703 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
704 // Define a valid motion event.
705 NotifyMotionArgs args(/* sequenceNum */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -0700706 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
707 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
chaviwd1c23182019-12-20 18:44:56 -0800708 AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, pointerProperties,
709 pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -0700710 AMOTION_EVENT_INVALID_CURSOR_POSITION,
711 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +0800712
713 return args;
714}
715
chaviwd1c23182019-12-20 18:44:56 -0800716static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
717 return generateMotionArgs(action, source, displayId, {PointF{100, 200}});
718}
719
Arthur Hungb92218b2018-08-14 12:00:21 +0800720TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
721 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800722 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
723 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800724
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800725 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800726 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
727 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800728 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
729
730 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800731 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800732}
733
734// The foreground window should receive the first touch down event.
735TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
736 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800737 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
738 ADISPLAY_ID_DEFAULT);
739 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
740 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800741
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800742 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800743 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
744 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800745 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
746
747 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800748 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800749 windowSecond->assertNoEvents();
750}
751
752TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
753 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800754 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
755 ADISPLAY_ID_DEFAULT);
756 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
757 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800758
Arthur Hung7ab76b12019-01-09 19:17:20 +0800759 // Set focused application.
Tiger Huang721e26f2018-07-24 22:26:19 +0800760 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +0800761
762 // Expect one focus window exist in display.
763 windowSecond->setFocus();
Arthur Hungb92218b2018-08-14 12:00:21 +0800764
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800765 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800766 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
767 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
768
769 // Focused window should receive event.
770 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800771 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800772}
773
Arthur Hung7ab76b12019-01-09 19:17:20 +0800774TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
775 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
776 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
777 ADISPLAY_ID_DEFAULT);
778 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
779 ADISPLAY_ID_DEFAULT);
780
781 // Set focused application.
782 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
783
784 // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
785 windowTop->setFocus();
786 windowSecond->setFocus();
Arthur Hung7ab76b12019-01-09 19:17:20 +0800787
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800788 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800789 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
790 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
791
792 // Top focused window should receive event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800793 windowTop->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800794 windowSecond->assertNoEvents();
795}
796
Arthur Hung3b413f22018-10-26 18:05:34 +0800797TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
798 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
799
800 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
801 ADISPLAY_ID_DEFAULT);
802 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
803 ADISPLAY_ID_DEFAULT);
804
Arthur Hung832bc4a2019-01-28 11:43:17 +0800805 // Set focused application.
806 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hung3b413f22018-10-26 18:05:34 +0800807
Arthur Hung832bc4a2019-01-28 11:43:17 +0800808 windowTop->setFocus();
809 windowSecond->setFocus();
Arthur Hung3b413f22018-10-26 18:05:34 +0800810 // Release channel for window is no longer valid.
811 windowTop->releaseChannel();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800812 mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
Arthur Hung3b413f22018-10-26 18:05:34 +0800813
Arthur Hung832bc4a2019-01-28 11:43:17 +0800814 // Test inject a key down, should dispatch to a valid window.
815 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
816 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Arthur Hung3b413f22018-10-26 18:05:34 +0800817
818 // Top window is invalid, so it should not receive any input event.
819 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800820 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung3b413f22018-10-26 18:05:34 +0800821}
822
Garfield Tan00f511d2019-06-12 16:55:40 -0700823TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
824 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
825
826 sp<FakeWindowHandle> windowLeft =
827 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
828 windowLeft->setFrame(Rect(0, 0, 600, 800));
829 windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
830 sp<FakeWindowHandle> windowRight =
831 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
832 windowRight->setFrame(Rect(600, 0, 1200, 800));
833 windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
834
835 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
836
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -0800837 mDispatcher->setInputWindows({windowLeft, windowRight}, ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700838
839 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
840 // left window. This event should be dispatched to the left window.
841 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
842 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
843 ADISPLAY_ID_DEFAULT, 610, 400, 599, 400));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800844 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -0700845 windowRight->assertNoEvents();
846}
847
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800848TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
849 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
850 sp<FakeWindowHandle> window =
851 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
852 window->setFocus();
853
854 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
855
856 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
857 mDispatcher->notifyKey(&keyArgs);
858
859 // Window should receive key down event.
860 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
861
862 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
863 // on the app side.
864 NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID);
865 mDispatcher->notifyDeviceReset(&args);
866 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
867 AKEY_EVENT_FLAG_CANCELED);
868}
869
870TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
871 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
872 sp<FakeWindowHandle> window =
873 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
874
875 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
876
877 NotifyMotionArgs motionArgs =
878 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
879 ADISPLAY_ID_DEFAULT);
880 mDispatcher->notifyMotion(&motionArgs);
881
882 // Window should receive motion down event.
883 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
884
885 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
886 // on the app side.
887 NotifyDeviceResetArgs args(10 /*sequenceNum*/, 20 /*eventTime*/, DEVICE_ID);
888 mDispatcher->notifyDeviceReset(&args);
889 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
890 0 /*expectedFlags*/);
891}
892
chaviwd1c23182019-12-20 18:44:56 -0800893class FakeMonitorReceiver {
Michael Wright3a240c42019-12-10 20:53:41 +0000894public:
895 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
chaviwd1c23182019-12-20 18:44:56 -0800896 int32_t displayId, bool isGestureMonitor = false) {
897 sp<InputChannel> serverChannel, clientChannel;
898 InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
899 mInputReceiver = std::make_unique<FakeInputReceiver>(clientChannel, name);
900 dispatcher->registerInputMonitor(serverChannel, displayId, isGestureMonitor);
Michael Wright3a240c42019-12-10 20:53:41 +0000901 }
902
chaviwd1c23182019-12-20 18:44:56 -0800903 sp<IBinder> getToken() { return mInputReceiver->getToken(); }
904
905 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
906 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN,
907 expectedDisplayId, expectedFlags);
908 }
909
910 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
911 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN,
912 expectedDisplayId, expectedFlags);
913 }
914
915 void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
916 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP,
917 expectedDisplayId, expectedFlags);
918 }
919
920 void assertNoEvents() { mInputReceiver->assertNoEvents(); }
921
922private:
923 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Michael Wright3a240c42019-12-10 20:53:41 +0000924};
925
926// Tests for gesture monitors
927TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) {
928 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
929 sp<FakeWindowHandle> window =
930 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
931 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
932
chaviwd1c23182019-12-20 18:44:56 -0800933 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
934 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +0000935
936 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
937 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
938 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
939 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -0800940 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +0000941}
942
943TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) {
944 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
945 sp<FakeWindowHandle> window =
946 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
947
948 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
949 window->setFocus();
950
951 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
952
chaviwd1c23182019-12-20 18:44:56 -0800953 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
954 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +0000955
956 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
957 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
958 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -0800959 monitor.assertNoEvents();
Michael Wright3a240c42019-12-10 20:53:41 +0000960}
961
962TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) {
963 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
964 sp<FakeWindowHandle> window =
965 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
966 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
967
chaviwd1c23182019-12-20 18:44:56 -0800968 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
969 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +0000970
971 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
972 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
973 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
974 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -0800975 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +0000976
977 window->releaseChannel();
978
chaviwd1c23182019-12-20 18:44:56 -0800979 mDispatcher->pilferPointers(monitor.getToken());
Michael Wright3a240c42019-12-10 20:53:41 +0000980
981 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
982 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
983 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwd1c23182019-12-20 18:44:56 -0800984 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +0000985}
986
chaviw81e2bb92019-12-18 15:03:51 -0800987TEST_F(InputDispatcherTest, TestMoveEvent) {
988 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
989 sp<FakeWindowHandle> window =
990 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
991
992 mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
993
994 NotifyMotionArgs motionArgs =
995 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
996 ADISPLAY_ID_DEFAULT);
997
998 mDispatcher->notifyMotion(&motionArgs);
999 // Window should receive motion down event.
1000 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1001
1002 motionArgs.action = AMOTION_EVENT_ACTION_MOVE;
1003 motionArgs.sequenceNum += 1;
1004 motionArgs.eventTime = systemTime(SYSTEM_TIME_MONOTONIC);
1005 motionArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
1006 motionArgs.pointerCoords[0].getX() - 10);
1007
1008 mDispatcher->notifyMotion(&motionArgs);
1009 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, ADISPLAY_ID_DEFAULT,
1010 0 /*expectedFlags*/);
1011}
1012
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001013/* Test InputDispatcher for MultiDisplay */
1014class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
1015public:
1016 static constexpr int32_t SECOND_DISPLAY_ID = 1;
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001017 virtual void SetUp() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001018 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +08001019
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001020 application1 = new FakeApplicationHandle();
1021 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
1022 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001023
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001024 // Set focus window for primary display, but focused display would be second one.
1025 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
1026 windowInPrimary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001027 mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001028
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001029 application2 = new FakeApplicationHandle();
1030 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
1031 SECOND_DISPLAY_ID);
1032 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001033 // Set focus display to second one.
1034 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
1035 // Set focus window for second display.
1036 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
1037 windowInSecondary->setFocus();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001038 mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001039 }
1040
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001041 virtual void TearDown() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001042 InputDispatcherTest::TearDown();
1043
1044 application1.clear();
1045 windowInPrimary.clear();
1046 application2.clear();
1047 windowInSecondary.clear();
1048 }
1049
1050protected:
1051 sp<FakeApplicationHandle> application1;
1052 sp<FakeWindowHandle> windowInPrimary;
1053 sp<FakeApplicationHandle> application2;
1054 sp<FakeWindowHandle> windowInSecondary;
1055};
1056
1057TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
1058 // Test touch down on primary display.
1059 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1060 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001061 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001062 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001063 windowInSecondary->assertNoEvents();
1064
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001065 // Test touch down on second display.
1066 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1067 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +08001068 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1069 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001070 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +08001071}
1072
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001073TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001074 // Test inject a key down with display id specified.
1075 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1076 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001077 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +08001078 windowInSecondary->assertNoEvents();
1079
1080 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +08001081 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1082 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1083 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001084 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +08001085
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001086 // Remove all windows in secondary display.
1087 mDispatcher->setInputWindows({}, SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +08001088
1089 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001090 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
1091 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +08001092
1093 // Test inject a key down, should timeout because of no target window.
1094 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
1095 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
1096 windowInPrimary->assertNoEvents();
1097 windowInSecondary->assertNoEvents();
1098}
1099
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001100// Test per-display input monitors for motion event.
1101TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
chaviwd1c23182019-12-20 18:44:56 -08001102 FakeMonitorReceiver monitorInPrimary =
1103 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
1104 FakeMonitorReceiver monitorInSecondary =
1105 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001106
1107 // Test touch down on primary display.
1108 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1109 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1110 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001111 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001112 monitorInPrimary.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001113 windowInSecondary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08001114 monitorInSecondary.assertNoEvents();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001115
1116 // Test touch down on second display.
1117 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1118 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
1119 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1120 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08001121 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001122 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
chaviwd1c23182019-12-20 18:44:56 -08001123 monitorInSecondary.consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001124
1125 // Test inject a non-pointer motion event.
1126 // If specific a display, it will dispatch to the focused window of particular display,
1127 // or it will dispatch to the focused window of focused display.
1128 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1129 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
1130 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1131 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08001132 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001133 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08001134 monitorInSecondary.consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001135}
1136
1137// Test per-display input monitors for key event.
1138TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
1139 //Input monitor per display.
chaviwd1c23182019-12-20 18:44:56 -08001140 FakeMonitorReceiver monitorInPrimary =
1141 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
1142 FakeMonitorReceiver monitorInSecondary =
1143 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001144
1145 // Test inject a key down.
1146 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1147 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1148 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08001149 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001150 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08001151 monitorInSecondary.consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001152}
1153
Jackal Guof9696682018-10-05 12:23:23 +08001154class InputFilterTest : public InputDispatcherTest {
1155protected:
1156 static constexpr int32_t SECOND_DISPLAY_ID = 1;
1157
1158 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
1159 NotifyMotionArgs motionArgs;
1160
1161 motionArgs = generateMotionArgs(
1162 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1163 mDispatcher->notifyMotion(&motionArgs);
1164 motionArgs = generateMotionArgs(
1165 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1166 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001167 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001168 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001169 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001170 } else {
1171 mFakePolicy->assertFilterInputEventWasNotCalled();
1172 }
1173 }
1174
1175 void testNotifyKey(bool expectToBeFiltered) {
1176 NotifyKeyArgs keyArgs;
1177
1178 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1179 mDispatcher->notifyKey(&keyArgs);
1180 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
1181 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001182 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001183
1184 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001185 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001186 } else {
1187 mFakePolicy->assertFilterInputEventWasNotCalled();
1188 }
1189 }
1190};
1191
1192// Test InputFilter for MotionEvent
1193TEST_F(InputFilterTest, MotionEvent_InputFilter) {
1194 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
1195 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1196 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1197
1198 // Enable InputFilter
1199 mDispatcher->setInputFilterEnabled(true);
1200 // Test touch on both primary and second display, and check if both events are filtered.
1201 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
1202 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
1203
1204 // Disable InputFilter
1205 mDispatcher->setInputFilterEnabled(false);
1206 // Test touch on both primary and second display, and check if both events aren't filtered.
1207 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1208 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1209}
1210
1211// Test InputFilter for KeyEvent
1212TEST_F(InputFilterTest, KeyEvent_InputFilter) {
1213 // Since the InputFilter is disabled by default, check if key event aren't filtered.
1214 testNotifyKey(/*expectToBeFiltered*/ false);
1215
1216 // Enable InputFilter
1217 mDispatcher->setInputFilterEnabled(true);
1218 // Send a key event, and check if it is filtered.
1219 testNotifyKey(/*expectToBeFiltered*/ true);
1220
1221 // Disable InputFilter
1222 mDispatcher->setInputFilterEnabled(false);
1223 // Send a key event, and check if it isn't filtered.
1224 testNotifyKey(/*expectToBeFiltered*/ false);
1225}
1226
chaviwfd6d3512019-03-25 13:23:49 -07001227class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001228 virtual void SetUp() override {
chaviwfd6d3512019-03-25 13:23:49 -07001229 InputDispatcherTest::SetUp();
1230
1231 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1232 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
1233 ADISPLAY_ID_DEFAULT);
1234 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
1235 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
1236 // window.
1237 mUnfocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1238
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001239 mFocusedWindow =
1240 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1241 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
1242 mFocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1243 mFocusedWindowTouchPoint = 60;
chaviwfd6d3512019-03-25 13:23:49 -07001244
1245 // Set focused application.
1246 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001247 mFocusedWindow->setFocus();
chaviwfd6d3512019-03-25 13:23:49 -07001248
1249 // Expect one focus window exist in display.
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001250 mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07001251 }
1252
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001253 virtual void TearDown() override {
chaviwfd6d3512019-03-25 13:23:49 -07001254 InputDispatcherTest::TearDown();
1255
1256 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001257 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07001258 }
1259
1260protected:
1261 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001262 sp<FakeWindowHandle> mFocusedWindow;
1263 int32_t mFocusedWindowTouchPoint;
chaviwfd6d3512019-03-25 13:23:49 -07001264};
1265
1266// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1267// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
1268// the onPointerDownOutsideFocus callback.
1269TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
1270 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1271 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20))
1272 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001273
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001274 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07001275 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
1276}
1277
1278// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
1279// DOWN on the window that doesn't have focus. Ensure no window received the
1280// onPointerDownOutsideFocus callback.
1281TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
1282 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1283 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20))
1284 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001285
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001286 ASSERT_TRUE(mDispatcher->waitForIdle());
1287 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001288}
1289
1290// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
1291// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
1292TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
1293 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1294 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001295
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001296 ASSERT_TRUE(mDispatcher->waitForIdle());
1297 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001298}
1299
1300// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1301// DOWN on the window that already has focus. Ensure no window received the
1302// onPointerDownOutsideFocus callback.
1303TEST_F(InputDispatcherOnPointerDownOutsideFocus,
1304 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001305 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1306 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1307 mFocusedWindowTouchPoint, mFocusedWindowTouchPoint))
chaviwfd6d3512019-03-25 13:23:49 -07001308 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwfd6d3512019-03-25 13:23:49 -07001309
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001310 ASSERT_TRUE(mDispatcher->waitForIdle());
1311 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001312}
1313
chaviwaf87b3e2019-10-01 16:59:28 -07001314// These tests ensures we can send touch events to a single client when there are multiple input
1315// windows that point to the same client token.
1316class InputDispatcherMultiWindowSameTokenTests : public InputDispatcherTest {
1317 virtual void SetUp() override {
1318 InputDispatcherTest::SetUp();
1319
1320 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1321 mWindow1 = new FakeWindowHandle(application, mDispatcher, "Fake Window 1",
1322 ADISPLAY_ID_DEFAULT);
1323 // Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
1324 // We also need FLAG_SPLIT_TOUCH or we won't be able to get touches for both windows.
1325 mWindow1->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL |
1326 InputWindowInfo::FLAG_SPLIT_TOUCH);
1327 mWindow1->setId(0);
1328 mWindow1->setFrame(Rect(0, 0, 100, 100));
1329
1330 mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
1331 ADISPLAY_ID_DEFAULT, mWindow1->getToken());
1332 mWindow2->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL |
1333 InputWindowInfo::FLAG_SPLIT_TOUCH);
1334 mWindow2->setId(1);
1335 mWindow2->setFrame(Rect(100, 100, 200, 200));
1336
1337 mDispatcher->setInputWindows({mWindow1, mWindow2}, ADISPLAY_ID_DEFAULT);
1338 }
1339
1340protected:
1341 sp<FakeWindowHandle> mWindow1;
1342 sp<FakeWindowHandle> mWindow2;
1343
1344 // Helper function to convert the point from screen coordinates into the window's space
1345 static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) {
1346 float x = windowInfo->windowXScale * (point.x - windowInfo->frameLeft);
1347 float y = windowInfo->windowYScale * (point.y - windowInfo->frameTop);
1348 return {x, y};
1349 }
1350
1351 void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction,
1352 const std::vector<PointF>& points) {
1353 std::string name = window->mName;
1354 InputEvent* event = window->consume();
1355
1356 ASSERT_NE(nullptr, event) << name.c_str()
1357 << ": consumer should have returned non-NULL event.";
1358
1359 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
1360 << name.c_str() << "expected " << inputEventTypeToString(AINPUT_EVENT_TYPE_MOTION)
1361 << " event, got " << inputEventTypeToString(event->getType()) << " event";
1362
1363 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
1364 EXPECT_EQ(expectedAction, motionEvent.getAction());
1365
1366 for (size_t i = 0; i < points.size(); i++) {
1367 float expectedX = points[i].x;
1368 float expectedY = points[i].y;
1369
1370 EXPECT_EQ(expectedX, motionEvent.getX(i))
1371 << "expected " << expectedX << " for x[" << i << "] coord of " << name.c_str()
1372 << ", got " << motionEvent.getX(i);
1373 EXPECT_EQ(expectedY, motionEvent.getY(i))
1374 << "expected " << expectedY << " for y[" << i << "] coord of " << name.c_str()
1375 << ", got " << motionEvent.getY(i);
1376 }
1377 }
1378};
1379
1380TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchSameScale) {
1381 // Touch Window 1
1382 PointF touchedPoint = {10, 10};
1383 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
1384
1385 NotifyMotionArgs motionArgs =
1386 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1387 ADISPLAY_ID_DEFAULT, {touchedPoint});
1388 mDispatcher->notifyMotion(&motionArgs);
1389 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
1390
1391 // Release touch on Window 1
1392 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
1393 ADISPLAY_ID_DEFAULT, {touchedPoint});
1394 mDispatcher->notifyMotion(&motionArgs);
1395 // consume the UP event
1396 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_UP, {expectedPoint});
1397
1398 // Touch Window 2
1399 touchedPoint = {150, 150};
1400 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
1401
1402 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1403 ADISPLAY_ID_DEFAULT, {touchedPoint});
1404 mDispatcher->notifyMotion(&motionArgs);
1405
1406 // Consuming from window1 since it's the window that has the InputReceiver
1407 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
1408}
1409
1410TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchDifferentScale) {
1411 mWindow2->setWindowScale(0.5f, 0.5f);
1412
1413 // Touch Window 1
1414 PointF touchedPoint = {10, 10};
1415 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
1416
1417 NotifyMotionArgs motionArgs =
1418 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1419 ADISPLAY_ID_DEFAULT, {touchedPoint});
1420 mDispatcher->notifyMotion(&motionArgs);
1421 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
1422
1423 // Release touch on Window 1
1424 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
1425 ADISPLAY_ID_DEFAULT, {touchedPoint});
1426 mDispatcher->notifyMotion(&motionArgs);
1427 // consume the UP event
1428 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_UP, {expectedPoint});
1429
1430 // Touch Window 2
1431 touchedPoint = {150, 150};
1432 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
1433
1434 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1435 ADISPLAY_ID_DEFAULT, {touchedPoint});
1436 mDispatcher->notifyMotion(&motionArgs);
1437
1438 // Consuming from window1 since it's the window that has the InputReceiver
1439 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
1440}
1441
Garfield Tane84e6f92019-08-29 17:28:41 -07001442} // namespace android::inputdispatcher