blob: f33cc65c2adcec3bc48486e177a3e5f2a4fd57d6 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Garfield Tan0fc2fa72019-08-29 17:22:15 -070017#include "../dispatcher/InputDispatcher.h"
Michael Wrightd02c5b62014-02-10 15:10:22 -080018
Garfield Tan1c7bc862020-01-28 13:24:04 -080019#include <android-base/stringprintf.h>
Robert Carr803535b2018-08-02 16:38:15 -070020#include <binder/Binder.h>
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080021#include <input/Input.h>
Robert Carr803535b2018-08-02 16:38:15 -070022
Michael Wrightd02c5b62014-02-10 15:10:22 -080023#include <gtest/gtest.h>
24#include <linux/input.h>
Garfield Tan1c7bc862020-01-28 13:24:04 -080025#include <cinttypes>
26#include <unordered_set>
chaviwd1c23182019-12-20 18:44:56 -080027#include <vector>
Michael Wrightd02c5b62014-02-10 15:10:22 -080028
Garfield Tan1c7bc862020-01-28 13:24:04 -080029using android::base::StringPrintf;
30
Garfield Tane84e6f92019-08-29 17:28:41 -070031namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080032
33// An arbitrary time value.
34static const nsecs_t ARBITRARY_TIME = 1234;
35
36// An arbitrary device id.
37static const int32_t DEVICE_ID = 1;
38
Jeff Brownf086ddb2014-02-11 14:28:48 -080039// An arbitrary display id.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -080040static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
Jeff Brownf086ddb2014-02-11 14:28:48 -080041
Michael Wrightd02c5b62014-02-10 15:10:22 -080042// An arbitrary injector pid / uid pair that has permission to inject events.
43static const int32_t INJECTOR_PID = 999;
44static const int32_t INJECTOR_UID = 1001;
45
chaviwd1c23182019-12-20 18:44:56 -080046struct PointF {
47 float x;
48 float y;
49};
Michael Wrightd02c5b62014-02-10 15:10:22 -080050
Gang Wang342c9272020-01-13 13:15:04 -050051/**
52 * Return a DOWN key event with KEYCODE_A.
53 */
54static KeyEvent getTestKeyEvent() {
55 KeyEvent event;
56
Garfield Tanfbe732e2020-01-24 11:26:14 -080057 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
58 INVALID_HMAC, AKEY_EVENT_ACTION_DOWN, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
59 ARBITRARY_TIME, ARBITRARY_TIME);
Gang Wang342c9272020-01-13 13:15:04 -050060 return event;
61}
62
Michael Wrightd02c5b62014-02-10 15:10:22 -080063// --- FakeInputDispatcherPolicy ---
64
65class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
66 InputDispatcherConfiguration mConfig;
67
68protected:
69 virtual ~FakeInputDispatcherPolicy() {
70 }
71
72public:
73 FakeInputDispatcherPolicy() {
Jackal Guof9696682018-10-05 12:23:23 +080074 }
75
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080076 void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080077 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_KEY, args.eventTime, args.action,
78 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080079 }
80
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080081 void assertFilterInputEventWasCalled(const NotifyMotionArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080082 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_MOTION, args.eventTime, args.action,
83 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080084 }
85
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070086 void assertFilterInputEventWasNotCalled() {
87 std::scoped_lock lock(mLock);
88 ASSERT_EQ(nullptr, mFilteredEvent);
89 }
Michael Wrightd02c5b62014-02-10 15:10:22 -080090
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080091 void assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070092 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080093 ASSERT_TRUE(mConfigurationChangedTime)
94 << "Timed out waiting for configuration changed call";
95 ASSERT_EQ(*mConfigurationChangedTime, when);
96 mConfigurationChangedTime = std::nullopt;
97 }
98
99 void assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700100 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800101 ASSERT_TRUE(mLastNotifySwitch);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800102 // We do not check id because it is not exposed to the policy
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800103 EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime);
104 EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags);
105 EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues);
106 EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask);
107 mLastNotifySwitch = std::nullopt;
108 }
109
chaviwfd6d3512019-03-25 13:23:49 -0700110 void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700111 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800112 ASSERT_EQ(touchedToken, mOnPointerDownToken);
113 mOnPointerDownToken.clear();
114 }
115
116 void assertOnPointerDownWasNotCalled() {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700117 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800118 ASSERT_TRUE(mOnPointerDownToken == nullptr)
119 << "Expected onPointerDownOutsideFocus to not have been called";
chaviwfd6d3512019-03-25 13:23:49 -0700120 }
121
Garfield Tan1c7bc862020-01-28 13:24:04 -0800122 void setKeyRepeatConfiguration(nsecs_t timeout, nsecs_t delay) {
123 mConfig.keyRepeatTimeout = timeout;
124 mConfig.keyRepeatDelay = delay;
125 }
126
Michael Wrightd02c5b62014-02-10 15:10:22 -0800127private:
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700128 std::mutex mLock;
129 std::unique_ptr<InputEvent> mFilteredEvent GUARDED_BY(mLock);
130 std::optional<nsecs_t> mConfigurationChangedTime GUARDED_BY(mLock);
131 sp<IBinder> mOnPointerDownToken GUARDED_BY(mLock);
132 std::optional<NotifySwitchArgs> mLastNotifySwitch GUARDED_BY(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800133
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800134 virtual void notifyConfigurationChanged(nsecs_t when) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700135 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800136 mConfigurationChangedTime = when;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800137 }
138
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700139 virtual nsecs_t notifyAnr(const sp<InputApplicationHandle>&, const sp<IBinder>&,
140 const std::string&) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800141 return 0;
142 }
143
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700144 virtual void notifyInputChannelBroken(const sp<IBinder>&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800145
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700146 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) override {}
Robert Carr740167f2018-10-11 19:03:41 -0700147
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700148 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800149 *outConfig = mConfig;
150 }
151
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800152 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700153 std::scoped_lock lock(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800154 switch (inputEvent->getType()) {
155 case AINPUT_EVENT_TYPE_KEY: {
156 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800157 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800158 break;
159 }
160
161 case AINPUT_EVENT_TYPE_MOTION: {
162 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800163 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800164 break;
165 }
166 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800167 return true;
168 }
169
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700170 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800171
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700172 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800173
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700174 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent*,
175 uint32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800176 return 0;
177 }
178
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700179 virtual bool dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent*, uint32_t,
180 KeyEvent*) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800181 return false;
182 }
183
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800184 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
185 uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700186 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800187 /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
188 * essentially a passthrough for notifySwitch.
189 */
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800190 mLastNotifySwitch = NotifySwitchArgs(1 /*id*/, when, policyFlags, switchValues, switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 }
192
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700193 virtual void pokeUserActivity(nsecs_t, int32_t) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800194
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700195 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800196 return false;
197 }
Jackal Guof9696682018-10-05 12:23:23 +0800198
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700199 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700200 std::scoped_lock lock(mLock);
chaviwfd6d3512019-03-25 13:23:49 -0700201 mOnPointerDownToken = newToken;
202 }
203
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800204 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
205 int32_t displayId) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700206 std::scoped_lock lock(mLock);
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800207 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
208 ASSERT_EQ(mFilteredEvent->getType(), type);
209
210 if (type == AINPUT_EVENT_TYPE_KEY) {
211 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
212 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
213 EXPECT_EQ(keyEvent.getAction(), action);
214 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
215 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
216 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
217 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
218 EXPECT_EQ(motionEvent.getAction(), action);
219 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
220 } else {
221 FAIL() << "Unknown type: " << type;
222 }
223
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800224 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800225 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800226};
227
Gang Wang342c9272020-01-13 13:15:04 -0500228// --- HmacKeyManagerTest ---
229
230class HmacKeyManagerTest : public testing::Test {
231protected:
232 HmacKeyManager mHmacKeyManager;
233};
234
235/**
236 * Ensure that separate calls to sign the same data are generating the same key.
237 * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance
238 * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky
239 * tests.
240 */
241TEST_F(HmacKeyManagerTest, GeneratedHmac_IsConsistent) {
242 KeyEvent event = getTestKeyEvent();
243 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
244
245 std::array<uint8_t, 32> hmac1 = mHmacKeyManager.sign(verifiedEvent);
246 std::array<uint8_t, 32> hmac2 = mHmacKeyManager.sign(verifiedEvent);
247 ASSERT_EQ(hmac1, hmac2);
248}
249
250/**
251 * Ensure that changes in VerifiedKeyEvent produce a different hmac.
252 */
253TEST_F(HmacKeyManagerTest, GeneratedHmac_ChangesWhenFieldsChange) {
254 KeyEvent event = getTestKeyEvent();
255 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
256 std::array<uint8_t, 32> initialHmac = mHmacKeyManager.sign(verifiedEvent);
257
258 verifiedEvent.deviceId += 1;
259 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
260
261 verifiedEvent.source += 1;
262 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
263
264 verifiedEvent.eventTimeNanos += 1;
265 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
266
267 verifiedEvent.displayId += 1;
268 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
269
270 verifiedEvent.action += 1;
271 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
272
273 verifiedEvent.downTimeNanos += 1;
274 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
275
276 verifiedEvent.flags += 1;
277 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
278
279 verifiedEvent.keyCode += 1;
280 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
281
282 verifiedEvent.scanCode += 1;
283 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
284
285 verifiedEvent.metaState += 1;
286 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
287
288 verifiedEvent.repeatCount += 1;
289 ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent));
290}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800291
292// --- InputDispatcherTest ---
293
294class InputDispatcherTest : public testing::Test {
295protected:
296 sp<FakeInputDispatcherPolicy> mFakePolicy;
297 sp<InputDispatcher> mDispatcher;
298
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700299 virtual void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800300 mFakePolicy = new FakeInputDispatcherPolicy();
301 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800302 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
303 //Start InputDispatcher thread
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700304 ASSERT_EQ(OK, mDispatcher->start());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800305 }
306
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700307 virtual void TearDown() override {
308 ASSERT_EQ(OK, mDispatcher->stop());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800309 mFakePolicy.clear();
310 mDispatcher.clear();
311 }
312};
313
314
315TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
316 KeyEvent event;
317
318 // Rejects undefined key actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800319 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
320 INVALID_HMAC,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600321 /*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME,
322 ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700323 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
324 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
325 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800326 << "Should reject key events with undefined action.";
327
328 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800329 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
330 INVALID_HMAC, AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600331 ARBITRARY_TIME, ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700332 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
333 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
334 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800335 << "Should reject key events with ACTION_MULTIPLE.";
336}
337
338TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
339 MotionEvent event;
340 PointerProperties pointerProperties[MAX_POINTERS + 1];
341 PointerCoords pointerCoords[MAX_POINTERS + 1];
342 for (int i = 0; i <= MAX_POINTERS; i++) {
343 pointerProperties[i].clear();
344 pointerProperties[i].id = i;
345 pointerCoords[i].clear();
346 }
347
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800348 // Some constants commonly used below
349 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
350 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
351 constexpr int32_t metaState = AMETA_NONE;
352 constexpr MotionClassification classification = MotionClassification::NONE;
353
Michael Wrightd02c5b62014-02-10 15:10:22 -0800354 // Rejects undefined motion actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800355 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600356 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */,
357 1 /* yScale */, 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
358 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700359 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700360 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
361 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
362 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800363 << "Should reject motion events with undefined action.";
364
365 // Rejects pointer down with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800366 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700367 AMOTION_EVENT_ACTION_POINTER_DOWN |
368 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600369 0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */,
370 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
371 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700372 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700373 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
374 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
375 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800376 << "Should reject motion events with pointer down index too large.";
377
Garfield Tanfbe732e2020-01-24 11:26:14 -0800378 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700379 AMOTION_EVENT_ACTION_POINTER_DOWN |
380 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600381 0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */,
382 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
383 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700384 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700385 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
386 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
387 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800388 << "Should reject motion events with pointer down index too small.";
389
390 // Rejects pointer up with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800391 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700392 AMOTION_EVENT_ACTION_POINTER_UP |
393 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600394 0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */,
395 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
396 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700397 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700398 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
399 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
400 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800401 << "Should reject motion events with pointer up index too large.";
402
Garfield Tanfbe732e2020-01-24 11:26:14 -0800403 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700404 AMOTION_EVENT_ACTION_POINTER_UP |
405 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600406 0, 0, edgeFlags, metaState, 0, classification, 1 /* xScale */, 1 /* yScale */,
407 0, 0, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
408 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700409 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700410 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
411 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
412 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800413 << "Should reject motion events with pointer up index too small.";
414
415 // Rejects motion events with invalid number of pointers.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800416 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
417 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
418 1 /* xScale */, 1 /* yScale */, 0, 0, 0, 0,
419 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
420 ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700421 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700422 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
423 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
424 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800425 << "Should reject motion events with 0 pointers.";
426
Garfield Tanfbe732e2020-01-24 11:26:14 -0800427 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
428 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
429 1 /* xScale */, 1 /* yScale */, 0, 0, 0, 0,
430 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
431 ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700432 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700433 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
434 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
435 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800436 << "Should reject motion events with more than MAX_POINTERS pointers.";
437
438 // Rejects motion events with invalid pointer ids.
439 pointerProperties[0].id = -1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800440 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
441 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
442 1 /* xScale */, 1 /* yScale */, 0, 0, 0, 0,
443 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
444 ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700445 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700446 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
447 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
448 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800449 << "Should reject motion events with pointer ids less than 0.";
450
451 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800452 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
453 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
454 1 /* xScale */, 1 /* yScale */, 0, 0, 0, 0,
455 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
456 ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700457 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700458 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
459 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
460 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800461 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
462
463 // Rejects motion events with duplicate pointer ids.
464 pointerProperties[0].id = 1;
465 pointerProperties[1].id = 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800466 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
467 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
468 1 /* xScale */, 1 /* yScale */, 0, 0, 0, 0,
469 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
470 ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700471 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700472 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
473 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
474 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800475 << "Should reject motion events with duplicate pointer ids.";
476}
477
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800478/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
479
480TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
481 constexpr nsecs_t eventTime = 20;
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800482 NotifyConfigurationChangedArgs args(10 /*id*/, eventTime);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800483 mDispatcher->notifyConfigurationChanged(&args);
484 ASSERT_TRUE(mDispatcher->waitForIdle());
485
486 mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
487}
488
489TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800490 NotifySwitchArgs args(10 /*id*/, 20 /*eventTime*/, 0 /*policyFlags*/, 1 /*switchValues*/,
491 2 /*switchMask*/);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800492 mDispatcher->notifySwitch(&args);
493
494 // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener
495 args.policyFlags |= POLICY_FLAG_TRUSTED;
496 mFakePolicy->assertNotifySwitchWasCalled(args);
497}
498
Arthur Hungb92218b2018-08-14 12:00:21 +0800499// --- InputDispatcherTest SetInputWindowTest ---
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700500static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 500ms;
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700501static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
Arthur Hungb92218b2018-08-14 12:00:21 +0800502
503class FakeApplicationHandle : public InputApplicationHandle {
504public:
505 FakeApplicationHandle() {}
506 virtual ~FakeApplicationHandle() {}
507
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700508 virtual bool updateInfo() override {
509 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT.count();
Arthur Hungb92218b2018-08-14 12:00:21 +0800510 return true;
511 }
512};
513
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800514class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800515public:
chaviwd1c23182019-12-20 18:44:56 -0800516 explicit FakeInputReceiver(const sp<InputChannel>& clientChannel, const std::string name)
517 : mName(name) {
518 mConsumer = std::make_unique<InputConsumer>(clientChannel);
519 }
520
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800521 InputEvent* consume() {
Arthur Hungb92218b2018-08-14 12:00:21 +0800522 uint32_t consumeSeq;
523 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800524
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800525 std::chrono::time_point start = std::chrono::steady_clock::now();
526 status_t status = WOULD_BLOCK;
527 while (status == WOULD_BLOCK) {
chaviw81e2bb92019-12-18 15:03:51 -0800528 status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq,
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800529 &event);
530 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
531 if (elapsed > 100ms) {
532 break;
533 }
534 }
535
536 if (status == WOULD_BLOCK) {
537 // Just means there's no event available.
538 return nullptr;
539 }
540
541 if (status != OK) {
542 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
543 return nullptr;
544 }
545 if (event == nullptr) {
546 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
547 return nullptr;
548 }
549
chaviwd1c23182019-12-20 18:44:56 -0800550 status = mConsumer->sendFinishedSignal(consumeSeq, true);
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800551 if (status != OK) {
552 ADD_FAILURE() << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
553 }
554 return event;
555 }
556
557 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
558 int32_t expectedFlags) {
559 InputEvent* event = consume();
560
561 ASSERT_NE(nullptr, event) << mName.c_str()
562 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800563 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800564 << mName.c_str() << "expected " << inputEventTypeToString(expectedEventType)
565 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800566
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800567 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800568
Tiger Huang8664f8c2018-10-11 19:14:35 +0800569 switch (expectedEventType) {
570 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800571 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
572 EXPECT_EQ(expectedAction, keyEvent.getAction());
573 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800574 break;
575 }
576 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800577 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
578 EXPECT_EQ(expectedAction, motionEvent.getAction());
579 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800580 break;
581 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100582 case AINPUT_EVENT_TYPE_FOCUS: {
583 FAIL() << "Use 'consumeFocusEvent' for FOCUS events";
584 }
Tiger Huang8664f8c2018-10-11 19:14:35 +0800585 default: {
586 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
587 }
588 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800589 }
590
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100591 void consumeFocusEvent(bool hasFocus, bool inTouchMode) {
592 InputEvent* event = consume();
593 ASSERT_NE(nullptr, event) << mName.c_str()
594 << ": consumer should have returned non-NULL event.";
595 ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, event->getType())
596 << "Got " << inputEventTypeToString(event->getType())
597 << " event instead of FOCUS event";
598
599 ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId())
600 << mName.c_str() << ": event displayId should always be NONE.";
601
602 FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
603 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
604 EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode());
605 }
606
chaviwd1c23182019-12-20 18:44:56 -0800607 void assertNoEvents() {
608 InputEvent* event = consume();
609 ASSERT_EQ(nullptr, event)
610 << mName.c_str()
611 << ": should not have received any events, so consume() should return NULL";
612 }
613
614 sp<IBinder> getToken() { return mConsumer->getChannel()->getConnectionToken(); }
615
616protected:
617 std::unique_ptr<InputConsumer> mConsumer;
618 PreallocatedInputEventFactory mEventFactory;
619
620 std::string mName;
621};
622
623class FakeWindowHandle : public InputWindowHandle {
624public:
625 static const int32_t WIDTH = 600;
626 static const int32_t HEIGHT = 800;
chaviwd1c23182019-12-20 18:44:56 -0800627
628 FakeWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle,
629 const sp<InputDispatcher>& dispatcher, const std::string name,
630 int32_t displayId, sp<IBinder> token = nullptr)
631 : mName(name) {
632 if (token == nullptr) {
633 sp<InputChannel> serverChannel, clientChannel;
634 InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
635 mInputReceiver = std::make_unique<FakeInputReceiver>(clientChannel, name);
636 dispatcher->registerInputChannel(serverChannel);
637 token = serverChannel->getConnectionToken();
638 }
639
640 inputApplicationHandle->updateInfo();
641 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
642
643 mInfo.token = token;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700644 mInfo.id = sId++;
chaviwd1c23182019-12-20 18:44:56 -0800645 mInfo.name = name;
646 mInfo.layoutParamsFlags = 0;
647 mInfo.layoutParamsType = InputWindowInfo::TYPE_APPLICATION;
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700648 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT.count();
chaviwd1c23182019-12-20 18:44:56 -0800649 mInfo.frameLeft = 0;
650 mInfo.frameTop = 0;
651 mInfo.frameRight = WIDTH;
652 mInfo.frameBottom = HEIGHT;
653 mInfo.globalScaleFactor = 1.0;
654 mInfo.touchableRegion.clear();
655 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
656 mInfo.visible = true;
657 mInfo.canReceiveKeys = true;
658 mInfo.hasFocus = false;
659 mInfo.hasWallpaper = false;
660 mInfo.paused = false;
chaviwd1c23182019-12-20 18:44:56 -0800661 mInfo.ownerPid = INJECTOR_PID;
662 mInfo.ownerUid = INJECTOR_UID;
663 mInfo.inputFeatures = 0;
664 mInfo.displayId = displayId;
665 }
666
667 virtual bool updateInfo() { return true; }
668
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100669 void setFocus(bool hasFocus) { mInfo.hasFocus = hasFocus; }
chaviwd1c23182019-12-20 18:44:56 -0800670
671 void setFrame(const Rect& frame) {
672 mInfo.frameLeft = frame.left;
673 mInfo.frameTop = frame.top;
674 mInfo.frameRight = frame.right;
675 mInfo.frameBottom = frame.bottom;
676 mInfo.touchableRegion.clear();
677 mInfo.addTouchableRegion(frame);
678 }
679
680 void setLayoutParamFlags(int32_t flags) { mInfo.layoutParamsFlags = flags; }
681
chaviwaf87b3e2019-10-01 16:59:28 -0700682 void setWindowScale(float xScale, float yScale) {
683 mInfo.windowXScale = xScale;
684 mInfo.windowYScale = yScale;
685 }
686
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800687 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
688 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
689 expectedFlags);
690 }
691
Svet Ganov5d3bc372020-01-26 23:11:07 -0800692 void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
693 int32_t expectedFlags = 0) {
694 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId,
695 expectedFlags);
696 }
697
698 void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
699 int32_t expectedFlags = 0) {
700 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId,
701 expectedFlags);
702 }
703
704 void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
705 int32_t expectedFlags = 0) {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800706 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
707 expectedFlags);
708 }
709
Svet Ganov5d3bc372020-01-26 23:11:07 -0800710 void consumeMotionPointerDown(int32_t pointerIdx,
711 int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) {
712 int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN
713 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
714 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
715 }
716
717 void consumeMotionPointerUp(int32_t pointerIdx, int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
718 int32_t expectedFlags = 0) {
719 int32_t action = AMOTION_EVENT_ACTION_POINTER_UP
720 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
721 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
722 }
723
724 void consumeMotionUp(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
725 int32_t expectedFlags = 0) {
Michael Wright3a240c42019-12-10 20:53:41 +0000726 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
727 expectedFlags);
728 }
729
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100730 void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
731 ASSERT_NE(mInputReceiver, nullptr)
732 << "Cannot consume events from a window with no receiver";
733 mInputReceiver->consumeFocusEvent(hasFocus, inTouchMode);
734 }
735
chaviwd1c23182019-12-20 18:44:56 -0800736 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
737 int32_t expectedFlags) {
738 ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
739 mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
740 expectedFlags);
741 }
742
chaviwaf87b3e2019-10-01 16:59:28 -0700743 InputEvent* consume() {
744 if (mInputReceiver == nullptr) {
745 return nullptr;
746 }
747 return mInputReceiver->consume();
748 }
749
Arthur Hungb92218b2018-08-14 12:00:21 +0800750 void assertNoEvents() {
chaviwd1c23182019-12-20 18:44:56 -0800751 ASSERT_NE(mInputReceiver, nullptr)
752 << "Call 'assertNoEvents' on a window with an InputReceiver";
753 mInputReceiver->assertNoEvents();
Arthur Hungb92218b2018-08-14 12:00:21 +0800754 }
755
chaviwaf87b3e2019-10-01 16:59:28 -0700756 sp<IBinder> getToken() { return mInfo.token; }
757
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100758 const std::string& getName() { return mName; }
759
chaviwd1c23182019-12-20 18:44:56 -0800760private:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100761 const std::string mName;
chaviwd1c23182019-12-20 18:44:56 -0800762 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700763 static std::atomic<int32_t> sId; // each window gets a unique id, like in surfaceflinger
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800764};
765
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700766std::atomic<int32_t> FakeWindowHandle::sId{1};
767
Tiger Huang721e26f2018-07-24 22:26:19 +0800768static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
769 int32_t displayId = ADISPLAY_ID_NONE) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800770 KeyEvent event;
771 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
772
773 // Define a valid key down event.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800774 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
775 INVALID_HMAC, AKEY_EVENT_ACTION_DOWN, /* flags */ 0, AKEYCODE_A, KEY_A,
776 AMETA_NONE,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600777 /* repeatCount */ 0, currentTime, currentTime);
Arthur Hungb92218b2018-08-14 12:00:21 +0800778
779 // Inject event until dispatch out.
780 return dispatcher->injectInputEvent(
781 &event,
782 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
783 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
784}
785
Garfield Tan00f511d2019-06-12 16:55:40 -0700786static int32_t injectMotionEvent(const sp<InputDispatcher>& dispatcher, int32_t action,
787 int32_t source, int32_t displayId, int32_t x, int32_t y,
788 int32_t xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION,
789 int32_t yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800790 MotionEvent event;
791 PointerProperties pointerProperties[1];
792 PointerCoords pointerCoords[1];
793
794 pointerProperties[0].clear();
795 pointerProperties[0].id = 0;
796 pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
797
798 pointerCoords[0].clear();
chaviwfd6d3512019-03-25 13:23:49 -0700799 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
800 pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
Arthur Hungb92218b2018-08-14 12:00:21 +0800801
802 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
803 // Define a valid motion down event.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800804 event.initialize(InputEvent::nextId(), DEVICE_ID, source, displayId, INVALID_HMAC, action,
805 /* actionButton */ 0,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600806 /* flags */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -0700807 /* edgeFlags */ 0, AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600808 /* xScale */ 1, /* yScale */ 1, /* xOffset */ 0, /* yOffset */ 0,
809 /* xPrecision */ 0, /* yPrecision */ 0, xCursorPosition, yCursorPosition,
810 currentTime, currentTime,
Garfield Tan00f511d2019-06-12 16:55:40 -0700811 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Arthur Hungb92218b2018-08-14 12:00:21 +0800812
813 // Inject event until dispatch out.
814 return dispatcher->injectInputEvent(
815 &event,
816 INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
817 INJECT_EVENT_TIMEOUT, POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
818}
819
Garfield Tan00f511d2019-06-12 16:55:40 -0700820static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -0700821 int32_t displayId, const PointF& location = {100, 200}) {
822 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, location.x,
823 location.y);
Garfield Tan00f511d2019-06-12 16:55:40 -0700824}
825
Michael Wright3a240c42019-12-10 20:53:41 +0000826static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -0700827 int32_t displayId, const PointF& location = {100, 200}) {
828 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, location.x,
829 location.y);
Michael Wright3a240c42019-12-10 20:53:41 +0000830}
831
Jackal Guof9696682018-10-05 12:23:23 +0800832static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
833 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
834 // Define a valid key event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800835 NotifyKeyArgs args(/* id */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
836 POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0, AKEYCODE_A, KEY_A,
837 AMETA_NONE, currentTime);
Jackal Guof9696682018-10-05 12:23:23 +0800838
839 return args;
840}
841
chaviwd1c23182019-12-20 18:44:56 -0800842static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId,
843 const std::vector<PointF>& points) {
844 size_t pointerCount = points.size();
chaviwaf87b3e2019-10-01 16:59:28 -0700845 if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_UP) {
846 EXPECT_EQ(1U, pointerCount) << "Actions DOWN and UP can only contain a single pointer";
847 }
848
chaviwd1c23182019-12-20 18:44:56 -0800849 PointerProperties pointerProperties[pointerCount];
850 PointerCoords pointerCoords[pointerCount];
Jackal Guof9696682018-10-05 12:23:23 +0800851
chaviwd1c23182019-12-20 18:44:56 -0800852 for (size_t i = 0; i < pointerCount; i++) {
853 pointerProperties[i].clear();
854 pointerProperties[i].id = i;
855 pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
Jackal Guof9696682018-10-05 12:23:23 +0800856
chaviwd1c23182019-12-20 18:44:56 -0800857 pointerCoords[i].clear();
858 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
859 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, points[i].y);
860 }
Jackal Guof9696682018-10-05 12:23:23 +0800861
862 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
863 // Define a valid motion event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800864 NotifyMotionArgs args(/* id */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -0700865 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
866 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
chaviwd1c23182019-12-20 18:44:56 -0800867 AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, pointerProperties,
868 pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -0700869 AMOTION_EVENT_INVALID_CURSOR_POSITION,
870 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +0800871
872 return args;
873}
874
chaviwd1c23182019-12-20 18:44:56 -0800875static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
876 return generateMotionArgs(action, source, displayId, {PointF{100, 200}});
877}
878
Arthur Hungb92218b2018-08-14 12:00:21 +0800879TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
880 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800881 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
882 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800883
Arthur Hung72d8dc32020-03-28 00:48:39 +0000884 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800885 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
886 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800887 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
888
889 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800890 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800891}
892
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -0700893/**
894 * Calling setInputWindows once with FLAG_NOT_TOUCH_MODAL should not cause any issues.
895 * To ensure that window receives only events that were directly inside of it, add
896 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
897 * when finding touched windows.
898 * This test serves as a sanity check for the next test, where setInputWindows is
899 * called twice.
900 */
901TEST_F(InputDispatcherTest, SetInputWindowOnce_SingleWindowTouch) {
902 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
903 sp<FakeWindowHandle> window =
904 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
905 window->setFrame(Rect(0, 0, 100, 100));
906 window->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
907
908 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
909 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
910 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
911 {50, 50}))
912 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
913
914 // Window should receive motion event.
915 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
916}
917
918/**
919 * Calling setInputWindows twice, with the same info, should not cause any issues.
920 * To ensure that window receives only events that were directly inside of it, add
921 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
922 * when finding touched windows.
923 */
924TEST_F(InputDispatcherTest, SetInputWindowTwice_SingleWindowTouch) {
925 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
926 sp<FakeWindowHandle> window =
927 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
928 window->setFrame(Rect(0, 0, 100, 100));
929 window->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
930
931 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
932 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
933 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
934 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
935 {50, 50}))
936 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
937
938 // Window should receive motion event.
939 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
940}
941
Arthur Hungb92218b2018-08-14 12:00:21 +0800942// The foreground window should receive the first touch down event.
943TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
944 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800945 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
946 ADISPLAY_ID_DEFAULT);
947 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
948 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800949
Arthur Hung72d8dc32020-03-28 00:48:39 +0000950 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800951 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
952 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +0800953 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
954
955 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800956 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800957 windowSecond->assertNoEvents();
958}
959
960TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
961 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800962 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
963 ADISPLAY_ID_DEFAULT);
964 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
965 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +0800966
Arthur Hung7ab76b12019-01-09 19:17:20 +0800967 // Set focused application.
Tiger Huang721e26f2018-07-24 22:26:19 +0800968 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +0800969
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100970 // Display should have only one focused window
971 windowSecond->setFocus(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +0000972 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100973
974 windowSecond->consumeFocusEvent(true);
Arthur Hungb92218b2018-08-14 12:00:21 +0800975 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
976 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
977
978 // Focused window should receive event.
979 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800980 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +0800981}
982
Arthur Hung7ab76b12019-01-09 19:17:20 +0800983TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
984 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
985 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
986 ADISPLAY_ID_DEFAULT);
987 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
988 ADISPLAY_ID_DEFAULT);
989
990 // Set focused application.
991 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
992
993 // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100994 windowTop->setFocus(true);
995 windowSecond->setFocus(true);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800996
Arthur Hung72d8dc32020-03-28 00:48:39 +0000997 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100998 windowTop->consumeFocusEvent(true);
Arthur Hung7ab76b12019-01-09 19:17:20 +0800999 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1000 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1001
1002 // Top focused window should receive event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001003 windowTop->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung7ab76b12019-01-09 19:17:20 +08001004 windowSecond->assertNoEvents();
1005}
1006
Arthur Hung3b413f22018-10-26 18:05:34 +08001007TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
1008 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1009
1010 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1011 ADISPLAY_ID_DEFAULT);
1012 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1013 ADISPLAY_ID_DEFAULT);
1014
Arthur Hung832bc4a2019-01-28 11:43:17 +08001015 // Set focused application.
1016 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hung3b413f22018-10-26 18:05:34 +08001017
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001018 windowTop->setFocus(true);
1019 windowSecond->setFocus(true);
Arthur Hung3b413f22018-10-26 18:05:34 +08001020 // Release channel for window is no longer valid.
1021 windowTop->releaseChannel();
Arthur Hung72d8dc32020-03-28 00:48:39 +00001022 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001023 windowSecond->consumeFocusEvent(true);
Arthur Hung3b413f22018-10-26 18:05:34 +08001024
Arthur Hung832bc4a2019-01-28 11:43:17 +08001025 // Test inject a key down, should dispatch to a valid window.
1026 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1027 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Arthur Hung3b413f22018-10-26 18:05:34 +08001028
1029 // Top window is invalid, so it should not receive any input event.
1030 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001031 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung3b413f22018-10-26 18:05:34 +08001032}
1033
Garfield Tan00f511d2019-06-12 16:55:40 -07001034TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
1035 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1036
1037 sp<FakeWindowHandle> windowLeft =
1038 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1039 windowLeft->setFrame(Rect(0, 0, 600, 800));
1040 windowLeft->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1041 sp<FakeWindowHandle> windowRight =
1042 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1043 windowRight->setFrame(Rect(600, 0, 1200, 800));
1044 windowRight->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1045
1046 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1047
Arthur Hung72d8dc32020-03-28 00:48:39 +00001048 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
Garfield Tan00f511d2019-06-12 16:55:40 -07001049
1050 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
1051 // left window. This event should be dispatched to the left window.
1052 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1053 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
1054 ADISPLAY_ID_DEFAULT, 610, 400, 599, 400));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001055 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -07001056 windowRight->assertNoEvents();
1057}
1058
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001059TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
1060 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1061 sp<FakeWindowHandle> window =
1062 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001063 window->setFocus(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001064
Arthur Hung72d8dc32020-03-28 00:48:39 +00001065 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001066 window->consumeFocusEvent(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001067
1068 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1069 mDispatcher->notifyKey(&keyArgs);
1070
1071 // Window should receive key down event.
1072 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1073
1074 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
1075 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001076 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001077 mDispatcher->notifyDeviceReset(&args);
1078 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
1079 AKEY_EVENT_FLAG_CANCELED);
1080}
1081
1082TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
1083 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1084 sp<FakeWindowHandle> window =
1085 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1086
Arthur Hung72d8dc32020-03-28 00:48:39 +00001087 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001088
1089 NotifyMotionArgs motionArgs =
1090 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1091 ADISPLAY_ID_DEFAULT);
1092 mDispatcher->notifyMotion(&motionArgs);
1093
1094 // Window should receive motion down event.
1095 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1096
1097 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
1098 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001099 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001100 mDispatcher->notifyDeviceReset(&args);
1101 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
1102 0 /*expectedFlags*/);
1103}
1104
Svet Ganov5d3bc372020-01-26 23:11:07 -08001105TEST_F(InputDispatcherTest, TransferTouchFocus_OnePointer) {
1106 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1107
1108 // Create a couple of windows
1109 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1110 "First Window", ADISPLAY_ID_DEFAULT);
1111 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1112 "Second Window", ADISPLAY_ID_DEFAULT);
1113
1114 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001115 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001116
1117 // Send down to the first window
1118 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1119 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1120 mDispatcher->notifyMotion(&downMotionArgs);
1121 // Only the first window should get the down event
1122 firstWindow->consumeMotionDown();
1123 secondWindow->assertNoEvents();
1124
1125 // Transfer touch focus to the second window
1126 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1127 // The first window gets cancel and the second gets down
1128 firstWindow->consumeMotionCancel();
1129 secondWindow->consumeMotionDown();
1130
1131 // Send up event to the second window
1132 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1133 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1134 mDispatcher->notifyMotion(&upMotionArgs);
1135 // The first window gets no events and the second gets up
1136 firstWindow->assertNoEvents();
1137 secondWindow->consumeMotionUp();
1138}
1139
1140TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointerNoSplitTouch) {
1141 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1142
1143 PointF touchPoint = {10, 10};
1144
1145 // Create a couple of windows
1146 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1147 "First Window", ADISPLAY_ID_DEFAULT);
1148 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1149 "Second Window", ADISPLAY_ID_DEFAULT);
1150
1151 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001152 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001153
1154 // Send down to the first window
1155 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1156 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint});
1157 mDispatcher->notifyMotion(&downMotionArgs);
1158 // Only the first window should get the down event
1159 firstWindow->consumeMotionDown();
1160 secondWindow->assertNoEvents();
1161
1162 // Send pointer down to the first window
1163 NotifyMotionArgs pointerDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1164 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1165 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1166 mDispatcher->notifyMotion(&pointerDownMotionArgs);
1167 // Only the first window should get the pointer down event
1168 firstWindow->consumeMotionPointerDown(1);
1169 secondWindow->assertNoEvents();
1170
1171 // Transfer touch focus to the second window
1172 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1173 // The first window gets cancel and the second gets down and pointer down
1174 firstWindow->consumeMotionCancel();
1175 secondWindow->consumeMotionDown();
1176 secondWindow->consumeMotionPointerDown(1);
1177
1178 // Send pointer up to the second window
1179 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1180 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1181 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1182 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1183 // The first window gets nothing and the second gets pointer up
1184 firstWindow->assertNoEvents();
1185 secondWindow->consumeMotionPointerUp(1);
1186
1187 // Send up event to the second window
1188 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1189 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1190 mDispatcher->notifyMotion(&upMotionArgs);
1191 // The first window gets nothing and the second gets up
1192 firstWindow->assertNoEvents();
1193 secondWindow->consumeMotionUp();
1194}
1195
1196TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointersSplitTouch) {
1197 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1198
1199 // Create a non touch modal window that supports split touch
1200 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1201 "First Window", ADISPLAY_ID_DEFAULT);
1202 firstWindow->setFrame(Rect(0, 0, 600, 400));
1203 firstWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL
1204 | InputWindowInfo::FLAG_SPLIT_TOUCH);
1205
1206 // Create a non touch modal window that supports split touch
1207 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1208 "Second Window", ADISPLAY_ID_DEFAULT);
1209 secondWindow->setFrame(Rect(0, 400, 600, 800));
1210 secondWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL
1211 | InputWindowInfo::FLAG_SPLIT_TOUCH);
1212
1213 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001214 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001215
1216 PointF pointInFirst = {300, 200};
1217 PointF pointInSecond = {300, 600};
1218
1219 // Send down to the first window
1220 NotifyMotionArgs firstDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1221 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst});
1222 mDispatcher->notifyMotion(&firstDownMotionArgs);
1223 // Only the first window should get the down event
1224 firstWindow->consumeMotionDown();
1225 secondWindow->assertNoEvents();
1226
1227 // Send down to the second window
1228 NotifyMotionArgs secondDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1229 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1230 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1231 mDispatcher->notifyMotion(&secondDownMotionArgs);
1232 // The first window gets a move and the second a down
1233 firstWindow->consumeMotionMove();
1234 secondWindow->consumeMotionDown();
1235
1236 // Transfer touch focus to the second window
1237 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1238 // The first window gets cancel and the new gets pointer down (it already saw down)
1239 firstWindow->consumeMotionCancel();
1240 secondWindow->consumeMotionPointerDown(1);
1241
1242 // Send pointer up to the second window
1243 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1244 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1245 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1246 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1247 // The first window gets nothing and the second gets pointer up
1248 firstWindow->assertNoEvents();
1249 secondWindow->consumeMotionPointerUp(1);
1250
1251 // Send up event to the second window
1252 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1253 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1254 mDispatcher->notifyMotion(&upMotionArgs);
1255 // The first window gets nothing and the second gets up
1256 firstWindow->assertNoEvents();
1257 secondWindow->consumeMotionUp();
1258}
1259
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001260TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {
1261 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1262 sp<FakeWindowHandle> window =
1263 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1264
1265 window->setFocus(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001266 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001267
1268 window->consumeFocusEvent(true);
1269
1270 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1271 mDispatcher->notifyKey(&keyArgs);
1272
1273 // Window should receive key down event.
1274 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1275}
1276
1277TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) {
1278 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1279 sp<FakeWindowHandle> window =
1280 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1281
Arthur Hung72d8dc32020-03-28 00:48:39 +00001282 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001283
1284 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1285 mDispatcher->notifyKey(&keyArgs);
1286 mDispatcher->waitForIdle();
1287
1288 window->assertNoEvents();
1289}
1290
1291// If a window is touchable, but does not have focus, it should receive motion events, but not keys
1292TEST_F(InputDispatcherTest, UnfocusedWindow_ReceivesMotionsButNotKeys) {
1293 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1294 sp<FakeWindowHandle> window =
1295 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1296
Arthur Hung72d8dc32020-03-28 00:48:39 +00001297 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001298
1299 // Send key
1300 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1301 mDispatcher->notifyKey(&keyArgs);
1302 // Send motion
1303 NotifyMotionArgs motionArgs =
1304 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1305 ADISPLAY_ID_DEFAULT);
1306 mDispatcher->notifyMotion(&motionArgs);
1307
1308 // Window should receive only the motion event
1309 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1310 window->assertNoEvents(); // Key event or focus event will not be received
1311}
1312
chaviwd1c23182019-12-20 18:44:56 -08001313class FakeMonitorReceiver {
Michael Wright3a240c42019-12-10 20:53:41 +00001314public:
1315 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
chaviwd1c23182019-12-20 18:44:56 -08001316 int32_t displayId, bool isGestureMonitor = false) {
1317 sp<InputChannel> serverChannel, clientChannel;
1318 InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
1319 mInputReceiver = std::make_unique<FakeInputReceiver>(clientChannel, name);
1320 dispatcher->registerInputMonitor(serverChannel, displayId, isGestureMonitor);
Michael Wright3a240c42019-12-10 20:53:41 +00001321 }
1322
chaviwd1c23182019-12-20 18:44:56 -08001323 sp<IBinder> getToken() { return mInputReceiver->getToken(); }
1324
1325 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1326 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN,
1327 expectedDisplayId, expectedFlags);
1328 }
1329
1330 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1331 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN,
1332 expectedDisplayId, expectedFlags);
1333 }
1334
1335 void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1336 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP,
1337 expectedDisplayId, expectedFlags);
1338 }
1339
1340 void assertNoEvents() { mInputReceiver->assertNoEvents(); }
1341
1342private:
1343 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Michael Wright3a240c42019-12-10 20:53:41 +00001344};
1345
1346// Tests for gesture monitors
1347TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) {
1348 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1349 sp<FakeWindowHandle> window =
1350 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001351 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001352
chaviwd1c23182019-12-20 18:44:56 -08001353 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1354 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001355
1356 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1357 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1358 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1359 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001360 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001361}
1362
1363TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) {
1364 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1365 sp<FakeWindowHandle> window =
1366 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1367
1368 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001369 window->setFocus(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001370
Arthur Hung72d8dc32020-03-28 00:48:39 +00001371 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001372 window->consumeFocusEvent(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001373
chaviwd1c23182019-12-20 18:44:56 -08001374 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1375 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001376
1377 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1378 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1379 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001380 monitor.assertNoEvents();
Michael Wright3a240c42019-12-10 20:53:41 +00001381}
1382
1383TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) {
1384 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1385 sp<FakeWindowHandle> window =
1386 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001387 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001388
chaviwd1c23182019-12-20 18:44:56 -08001389 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1390 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001391
1392 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1393 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1394 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1395 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001396 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001397
1398 window->releaseChannel();
1399
chaviwd1c23182019-12-20 18:44:56 -08001400 mDispatcher->pilferPointers(monitor.getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00001401
1402 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1403 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1404 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwd1c23182019-12-20 18:44:56 -08001405 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001406}
1407
chaviw81e2bb92019-12-18 15:03:51 -08001408TEST_F(InputDispatcherTest, TestMoveEvent) {
1409 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1410 sp<FakeWindowHandle> window =
1411 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1412
Arthur Hung72d8dc32020-03-28 00:48:39 +00001413 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
chaviw81e2bb92019-12-18 15:03:51 -08001414
1415 NotifyMotionArgs motionArgs =
1416 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1417 ADISPLAY_ID_DEFAULT);
1418
1419 mDispatcher->notifyMotion(&motionArgs);
1420 // Window should receive motion down event.
1421 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1422
1423 motionArgs.action = AMOTION_EVENT_ACTION_MOVE;
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001424 motionArgs.id += 1;
chaviw81e2bb92019-12-18 15:03:51 -08001425 motionArgs.eventTime = systemTime(SYSTEM_TIME_MONOTONIC);
1426 motionArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
1427 motionArgs.pointerCoords[0].getX() - 10);
1428
1429 mDispatcher->notifyMotion(&motionArgs);
1430 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, ADISPLAY_ID_DEFAULT,
1431 0 /*expectedFlags*/);
1432}
1433
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001434/**
1435 * Dispatcher has touch mode enabled by default. Typically, the policy overrides that value to
1436 * the device default right away. In the test scenario, we check both the default value,
1437 * and the action of enabling / disabling.
1438 */
1439TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
1440 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1441 sp<FakeWindowHandle> window =
1442 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1443
1444 // Set focused application.
1445 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1446 window->setFocus(true);
1447
1448 SCOPED_TRACE("Check default value of touch mode");
Arthur Hung72d8dc32020-03-28 00:48:39 +00001449 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001450 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1451
1452 SCOPED_TRACE("Remove the window to trigger focus loss");
1453 window->setFocus(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001454 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001455 window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
1456
1457 SCOPED_TRACE("Disable touch mode");
1458 mDispatcher->setInTouchMode(false);
1459 window->setFocus(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001460 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001461 window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
1462
1463 SCOPED_TRACE("Remove the window to trigger focus loss");
1464 window->setFocus(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001465 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001466 window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
1467
1468 SCOPED_TRACE("Enable touch mode again");
1469 mDispatcher->setInTouchMode(true);
1470 window->setFocus(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001471 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001472 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1473
1474 window->assertNoEvents();
1475}
1476
Gang Wange9087892020-01-07 12:17:14 -05001477TEST_F(InputDispatcherTest, VerifyInputEvent_KeyEvent) {
1478 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1479 sp<FakeWindowHandle> window =
1480 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1481
1482 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1483 window->setFocus(true);
1484
Arthur Hung72d8dc32020-03-28 00:48:39 +00001485 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Gang Wange9087892020-01-07 12:17:14 -05001486 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1487
1488 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1489 mDispatcher->notifyKey(&keyArgs);
1490
1491 InputEvent* event = window->consume();
1492 ASSERT_NE(event, nullptr);
1493
1494 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1495 ASSERT_NE(verified, nullptr);
1496 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::KEY);
1497
1498 ASSERT_EQ(keyArgs.eventTime, verified->eventTimeNanos);
1499 ASSERT_EQ(keyArgs.deviceId, verified->deviceId);
1500 ASSERT_EQ(keyArgs.source, verified->source);
1501 ASSERT_EQ(keyArgs.displayId, verified->displayId);
1502
1503 const VerifiedKeyEvent& verifiedKey = static_cast<const VerifiedKeyEvent&>(*verified);
1504
1505 ASSERT_EQ(keyArgs.action, verifiedKey.action);
1506 ASSERT_EQ(keyArgs.downTime, verifiedKey.downTimeNanos);
Gang Wange9087892020-01-07 12:17:14 -05001507 ASSERT_EQ(keyArgs.flags & VERIFIED_KEY_EVENT_FLAGS, verifiedKey.flags);
1508 ASSERT_EQ(keyArgs.keyCode, verifiedKey.keyCode);
1509 ASSERT_EQ(keyArgs.scanCode, verifiedKey.scanCode);
1510 ASSERT_EQ(keyArgs.metaState, verifiedKey.metaState);
1511 ASSERT_EQ(0, verifiedKey.repeatCount);
1512}
1513
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001514TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) {
1515 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1516 sp<FakeWindowHandle> window =
1517 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1518
1519 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1520
Arthur Hung72d8dc32020-03-28 00:48:39 +00001521 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001522
1523 NotifyMotionArgs motionArgs =
1524 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1525 ADISPLAY_ID_DEFAULT);
1526 mDispatcher->notifyMotion(&motionArgs);
1527
1528 InputEvent* event = window->consume();
1529 ASSERT_NE(event, nullptr);
1530
1531 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1532 ASSERT_NE(verified, nullptr);
1533 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::MOTION);
1534
1535 EXPECT_EQ(motionArgs.eventTime, verified->eventTimeNanos);
1536 EXPECT_EQ(motionArgs.deviceId, verified->deviceId);
1537 EXPECT_EQ(motionArgs.source, verified->source);
1538 EXPECT_EQ(motionArgs.displayId, verified->displayId);
1539
1540 const VerifiedMotionEvent& verifiedMotion = static_cast<const VerifiedMotionEvent&>(*verified);
1541
1542 EXPECT_EQ(motionArgs.pointerCoords[0].getX(), verifiedMotion.rawX);
1543 EXPECT_EQ(motionArgs.pointerCoords[0].getY(), verifiedMotion.rawY);
1544 EXPECT_EQ(motionArgs.action & AMOTION_EVENT_ACTION_MASK, verifiedMotion.actionMasked);
1545 EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos);
1546 EXPECT_EQ(motionArgs.flags & VERIFIED_MOTION_EVENT_FLAGS, verifiedMotion.flags);
1547 EXPECT_EQ(motionArgs.metaState, verifiedMotion.metaState);
1548 EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState);
1549}
1550
Garfield Tan1c7bc862020-01-28 13:24:04 -08001551class InputDispatcherKeyRepeatTest : public InputDispatcherTest {
1552protected:
1553 static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms
1554 static constexpr nsecs_t KEY_REPEAT_DELAY = 40 * 1000000; // 40 ms
1555
1556 sp<FakeApplicationHandle> mApp;
1557 sp<FakeWindowHandle> mWindow;
1558
1559 virtual void SetUp() override {
1560 mFakePolicy = new FakeInputDispatcherPolicy();
1561 mFakePolicy->setKeyRepeatConfiguration(KEY_REPEAT_TIMEOUT, KEY_REPEAT_DELAY);
1562 mDispatcher = new InputDispatcher(mFakePolicy);
1563 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
1564 ASSERT_EQ(OK, mDispatcher->start());
1565
1566 setUpWindow();
1567 }
1568
1569 void setUpWindow() {
1570 mApp = new FakeApplicationHandle();
1571 mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1572
1573 mWindow->setFocus(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001574 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Garfield Tan1c7bc862020-01-28 13:24:04 -08001575
1576 mWindow->consumeFocusEvent(true);
1577 }
1578
1579 void sendAndConsumeKeyDown() {
1580 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1581 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Otherwise it won't generate repeat event
1582 mDispatcher->notifyKey(&keyArgs);
1583
1584 // Window should receive key down event.
1585 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1586 }
1587
1588 void expectKeyRepeatOnce(int32_t repeatCount) {
1589 SCOPED_TRACE(StringPrintf("Checking event with repeat count %" PRId32, repeatCount));
1590 InputEvent* repeatEvent = mWindow->consume();
1591 ASSERT_NE(nullptr, repeatEvent);
1592
1593 uint32_t eventType = repeatEvent->getType();
1594 ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, eventType);
1595
1596 KeyEvent* repeatKeyEvent = static_cast<KeyEvent*>(repeatEvent);
1597 uint32_t eventAction = repeatKeyEvent->getAction();
1598 EXPECT_EQ(AKEY_EVENT_ACTION_DOWN, eventAction);
1599 EXPECT_EQ(repeatCount, repeatKeyEvent->getRepeatCount());
1600 }
1601
1602 void sendAndConsumeKeyUp() {
1603 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
1604 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Unless it won't generate repeat event
1605 mDispatcher->notifyKey(&keyArgs);
1606
1607 // Window should receive key down event.
1608 mWindow->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
1609 0 /*expectedFlags*/);
1610 }
1611};
1612
1613TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeat) {
1614 sendAndConsumeKeyDown();
1615 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
1616 expectKeyRepeatOnce(repeatCount);
1617 }
1618}
1619
1620TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterUp) {
1621 sendAndConsumeKeyDown();
1622 expectKeyRepeatOnce(1 /*repeatCount*/);
1623 sendAndConsumeKeyUp();
1624 mWindow->assertNoEvents();
1625}
1626
1627TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseEventIdFromInputDispatcher) {
1628 sendAndConsumeKeyDown();
1629 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
1630 InputEvent* repeatEvent = mWindow->consume();
1631 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
1632 EXPECT_EQ(IdGenerator::Source::INPUT_DISPATCHER,
1633 IdGenerator::getSource(repeatEvent->getId()));
1634 }
1635}
1636
1637TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseUniqueEventId) {
1638 sendAndConsumeKeyDown();
1639
1640 std::unordered_set<int32_t> idSet;
1641 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
1642 InputEvent* repeatEvent = mWindow->consume();
1643 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
1644 int32_t id = repeatEvent->getId();
1645 EXPECT_EQ(idSet.end(), idSet.find(id));
1646 idSet.insert(id);
1647 }
1648}
1649
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001650/* Test InputDispatcher for MultiDisplay */
1651class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
1652public:
1653 static constexpr int32_t SECOND_DISPLAY_ID = 1;
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001654 virtual void SetUp() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001655 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +08001656
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001657 application1 = new FakeApplicationHandle();
1658 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
1659 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001660
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001661 // Set focus window for primary display, but focused display would be second one.
1662 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001663 windowInPrimary->setFocus(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001664 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001665 windowInPrimary->consumeFocusEvent(true);
Arthur Hungb92218b2018-08-14 12:00:21 +08001666
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001667 application2 = new FakeApplicationHandle();
1668 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
1669 SECOND_DISPLAY_ID);
1670 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001671 // Set focus display to second one.
1672 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
1673 // Set focus window for second display.
1674 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001675 windowInSecondary->setFocus(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001676 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001677 windowInSecondary->consumeFocusEvent(true);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001678 }
1679
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001680 virtual void TearDown() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001681 InputDispatcherTest::TearDown();
1682
1683 application1.clear();
1684 windowInPrimary.clear();
1685 application2.clear();
1686 windowInSecondary.clear();
1687 }
1688
1689protected:
1690 sp<FakeApplicationHandle> application1;
1691 sp<FakeWindowHandle> windowInPrimary;
1692 sp<FakeApplicationHandle> application2;
1693 sp<FakeWindowHandle> windowInSecondary;
1694};
1695
1696TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
1697 // Test touch down on primary display.
1698 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1699 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001700 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001701 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001702 windowInSecondary->assertNoEvents();
1703
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001704 // Test touch down on second display.
1705 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1706 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +08001707 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1708 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001709 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +08001710}
1711
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001712TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001713 // Test inject a key down with display id specified.
1714 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1715 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001716 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +08001717 windowInSecondary->assertNoEvents();
1718
1719 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +08001720 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1721 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1722 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001723 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +08001724
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001725 // Remove all windows in secondary display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00001726 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
Arthur Hungb92218b2018-08-14 12:00:21 +08001727
1728 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001729 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
1730 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +08001731
1732 // Test inject a key down, should timeout because of no target window.
1733 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
1734 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
1735 windowInPrimary->assertNoEvents();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001736 windowInSecondary->consumeFocusEvent(false);
Arthur Hungb92218b2018-08-14 12:00:21 +08001737 windowInSecondary->assertNoEvents();
1738}
1739
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001740// Test per-display input monitors for motion event.
1741TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
chaviwd1c23182019-12-20 18:44:56 -08001742 FakeMonitorReceiver monitorInPrimary =
1743 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
1744 FakeMonitorReceiver monitorInSecondary =
1745 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001746
1747 // Test touch down on primary display.
1748 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1749 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1750 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001751 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001752 monitorInPrimary.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001753 windowInSecondary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08001754 monitorInSecondary.assertNoEvents();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001755
1756 // Test touch down on second display.
1757 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1758 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
1759 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1760 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08001761 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001762 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
chaviwd1c23182019-12-20 18:44:56 -08001763 monitorInSecondary.consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001764
1765 // Test inject a non-pointer motion event.
1766 // If specific a display, it will dispatch to the focused window of particular display,
1767 // or it will dispatch to the focused window of focused display.
1768 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1769 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
1770 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1771 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08001772 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001773 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08001774 monitorInSecondary.consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001775}
1776
1777// Test per-display input monitors for key event.
1778TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
1779 //Input monitor per display.
chaviwd1c23182019-12-20 18:44:56 -08001780 FakeMonitorReceiver monitorInPrimary =
1781 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
1782 FakeMonitorReceiver monitorInSecondary =
1783 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001784
1785 // Test inject a key down.
1786 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1787 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1788 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08001789 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001790 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08001791 monitorInSecondary.consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001792}
1793
Jackal Guof9696682018-10-05 12:23:23 +08001794class InputFilterTest : public InputDispatcherTest {
1795protected:
1796 static constexpr int32_t SECOND_DISPLAY_ID = 1;
1797
1798 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
1799 NotifyMotionArgs motionArgs;
1800
1801 motionArgs = generateMotionArgs(
1802 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1803 mDispatcher->notifyMotion(&motionArgs);
1804 motionArgs = generateMotionArgs(
1805 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
1806 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001807 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001808 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001809 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001810 } else {
1811 mFakePolicy->assertFilterInputEventWasNotCalled();
1812 }
1813 }
1814
1815 void testNotifyKey(bool expectToBeFiltered) {
1816 NotifyKeyArgs keyArgs;
1817
1818 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1819 mDispatcher->notifyKey(&keyArgs);
1820 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
1821 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001822 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08001823
1824 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08001825 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08001826 } else {
1827 mFakePolicy->assertFilterInputEventWasNotCalled();
1828 }
1829 }
1830};
1831
1832// Test InputFilter for MotionEvent
1833TEST_F(InputFilterTest, MotionEvent_InputFilter) {
1834 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
1835 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1836 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1837
1838 // Enable InputFilter
1839 mDispatcher->setInputFilterEnabled(true);
1840 // Test touch on both primary and second display, and check if both events are filtered.
1841 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
1842 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
1843
1844 // Disable InputFilter
1845 mDispatcher->setInputFilterEnabled(false);
1846 // Test touch on both primary and second display, and check if both events aren't filtered.
1847 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
1848 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
1849}
1850
1851// Test InputFilter for KeyEvent
1852TEST_F(InputFilterTest, KeyEvent_InputFilter) {
1853 // Since the InputFilter is disabled by default, check if key event aren't filtered.
1854 testNotifyKey(/*expectToBeFiltered*/ false);
1855
1856 // Enable InputFilter
1857 mDispatcher->setInputFilterEnabled(true);
1858 // Send a key event, and check if it is filtered.
1859 testNotifyKey(/*expectToBeFiltered*/ true);
1860
1861 // Disable InputFilter
1862 mDispatcher->setInputFilterEnabled(false);
1863 // Send a key event, and check if it isn't filtered.
1864 testNotifyKey(/*expectToBeFiltered*/ false);
1865}
1866
chaviwfd6d3512019-03-25 13:23:49 -07001867class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001868 virtual void SetUp() override {
chaviwfd6d3512019-03-25 13:23:49 -07001869 InputDispatcherTest::SetUp();
1870
1871 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1872 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
1873 ADISPLAY_ID_DEFAULT);
1874 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
1875 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
1876 // window.
1877 mUnfocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
1878
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001879 mFocusedWindow =
1880 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1881 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
1882 mFocusedWindow->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07001883
1884 // Set focused application.
1885 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001886 mFocusedWindow->setFocus(true);
chaviwfd6d3512019-03-25 13:23:49 -07001887
1888 // Expect one focus window exist in display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00001889 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001890 mFocusedWindow->consumeFocusEvent(true);
chaviwfd6d3512019-03-25 13:23:49 -07001891 }
1892
Prabir Pradhan3608aad2019-10-02 17:08:26 -07001893 virtual void TearDown() override {
chaviwfd6d3512019-03-25 13:23:49 -07001894 InputDispatcherTest::TearDown();
1895
1896 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001897 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07001898 }
1899
1900protected:
1901 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001902 sp<FakeWindowHandle> mFocusedWindow;
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001903 static constexpr PointF FOCUSED_WINDOW_TOUCH_POINT = {60, 60};
chaviwfd6d3512019-03-25 13:23:49 -07001904};
1905
1906// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1907// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
1908// the onPointerDownOutsideFocus callback.
1909TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001910 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1911 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1912 {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07001913 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07001914 mUnfocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07001915
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001916 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07001917 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
1918}
1919
1920// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
1921// DOWN on the window that doesn't have focus. Ensure no window received the
1922// onPointerDownOutsideFocus callback.
1923TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001924 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1925 injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07001926 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07001927 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07001928
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001929 ASSERT_TRUE(mDispatcher->waitForIdle());
1930 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001931}
1932
1933// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
1934// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
1935TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
1936 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1937 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07001938 mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07001939
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001940 ASSERT_TRUE(mDispatcher->waitForIdle());
1941 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001942}
1943
1944// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
1945// DOWN on the window that already has focus. Ensure no window received the
1946// onPointerDownOutsideFocus callback.
1947TEST_F(InputDispatcherOnPointerDownOutsideFocus,
1948 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08001949 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1950 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001951 FOCUSED_WINDOW_TOUCH_POINT))
chaviwfd6d3512019-03-25 13:23:49 -07001952 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07001953 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07001954
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001955 ASSERT_TRUE(mDispatcher->waitForIdle());
1956 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07001957}
1958
chaviwaf87b3e2019-10-01 16:59:28 -07001959// These tests ensures we can send touch events to a single client when there are multiple input
1960// windows that point to the same client token.
1961class InputDispatcherMultiWindowSameTokenTests : public InputDispatcherTest {
1962 virtual void SetUp() override {
1963 InputDispatcherTest::SetUp();
1964
1965 sp<FakeApplicationHandle> application = new FakeApplicationHandle();
1966 mWindow1 = new FakeWindowHandle(application, mDispatcher, "Fake Window 1",
1967 ADISPLAY_ID_DEFAULT);
1968 // Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
1969 // We also need FLAG_SPLIT_TOUCH or we won't be able to get touches for both windows.
1970 mWindow1->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL |
1971 InputWindowInfo::FLAG_SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07001972 mWindow1->setFrame(Rect(0, 0, 100, 100));
1973
1974 mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
1975 ADISPLAY_ID_DEFAULT, mWindow1->getToken());
1976 mWindow2->setLayoutParamFlags(InputWindowInfo::FLAG_NOT_TOUCH_MODAL |
1977 InputWindowInfo::FLAG_SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07001978 mWindow2->setFrame(Rect(100, 100, 200, 200));
1979
Arthur Hung72d8dc32020-03-28 00:48:39 +00001980 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
chaviwaf87b3e2019-10-01 16:59:28 -07001981 }
1982
1983protected:
1984 sp<FakeWindowHandle> mWindow1;
1985 sp<FakeWindowHandle> mWindow2;
1986
1987 // Helper function to convert the point from screen coordinates into the window's space
1988 static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) {
1989 float x = windowInfo->windowXScale * (point.x - windowInfo->frameLeft);
1990 float y = windowInfo->windowYScale * (point.y - windowInfo->frameTop);
1991 return {x, y};
1992 }
1993
1994 void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction,
1995 const std::vector<PointF>& points) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001996 const std::string name = window->getName();
chaviwaf87b3e2019-10-01 16:59:28 -07001997 InputEvent* event = window->consume();
1998
1999 ASSERT_NE(nullptr, event) << name.c_str()
2000 << ": consumer should have returned non-NULL event.";
2001
2002 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
2003 << name.c_str() << "expected " << inputEventTypeToString(AINPUT_EVENT_TYPE_MOTION)
2004 << " event, got " << inputEventTypeToString(event->getType()) << " event";
2005
2006 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
2007 EXPECT_EQ(expectedAction, motionEvent.getAction());
2008
2009 for (size_t i = 0; i < points.size(); i++) {
2010 float expectedX = points[i].x;
2011 float expectedY = points[i].y;
2012
2013 EXPECT_EQ(expectedX, motionEvent.getX(i))
2014 << "expected " << expectedX << " for x[" << i << "] coord of " << name.c_str()
2015 << ", got " << motionEvent.getX(i);
2016 EXPECT_EQ(expectedY, motionEvent.getY(i))
2017 << "expected " << expectedY << " for y[" << i << "] coord of " << name.c_str()
2018 << ", got " << motionEvent.getY(i);
2019 }
2020 }
2021};
2022
2023TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchSameScale) {
2024 // Touch Window 1
2025 PointF touchedPoint = {10, 10};
2026 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
2027
2028 NotifyMotionArgs motionArgs =
2029 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2030 ADISPLAY_ID_DEFAULT, {touchedPoint});
2031 mDispatcher->notifyMotion(&motionArgs);
2032 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
2033
2034 // Release touch on Window 1
2035 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
2036 ADISPLAY_ID_DEFAULT, {touchedPoint});
2037 mDispatcher->notifyMotion(&motionArgs);
2038 // consume the UP event
2039 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_UP, {expectedPoint});
2040
2041 // Touch Window 2
2042 touchedPoint = {150, 150};
2043 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
2044
2045 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2046 ADISPLAY_ID_DEFAULT, {touchedPoint});
2047 mDispatcher->notifyMotion(&motionArgs);
2048
2049 // Consuming from window1 since it's the window that has the InputReceiver
2050 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
2051}
2052
2053TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchDifferentScale) {
2054 mWindow2->setWindowScale(0.5f, 0.5f);
2055
2056 // Touch Window 1
2057 PointF touchedPoint = {10, 10};
2058 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
2059
2060 NotifyMotionArgs motionArgs =
2061 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2062 ADISPLAY_ID_DEFAULT, {touchedPoint});
2063 mDispatcher->notifyMotion(&motionArgs);
2064 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
2065
2066 // Release touch on Window 1
2067 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
2068 ADISPLAY_ID_DEFAULT, {touchedPoint});
2069 mDispatcher->notifyMotion(&motionArgs);
2070 // consume the UP event
2071 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_UP, {expectedPoint});
2072
2073 // Touch Window 2
2074 touchedPoint = {150, 150};
2075 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
2076
2077 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2078 ADISPLAY_ID_DEFAULT, {touchedPoint});
2079 mDispatcher->notifyMotion(&motionArgs);
2080
2081 // Consuming from window1 since it's the window that has the InputReceiver
2082 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
2083}
2084
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002085TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchDifferentScale) {
2086 mWindow2->setWindowScale(0.5f, 0.5f);
2087
2088 // Touch Window 1
2089 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2090 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
2091
2092 NotifyMotionArgs motionArgs =
2093 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2094 ADISPLAY_ID_DEFAULT, touchedPoints);
2095 mDispatcher->notifyMotion(&motionArgs);
2096 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, expectedPoints);
2097
2098 // Touch Window 2
2099 int32_t actionPointerDown =
2100 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2101 touchedPoints.emplace_back(PointF{150, 150});
2102 expectedPoints.emplace_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2103
2104 motionArgs = generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN,
2105 ADISPLAY_ID_DEFAULT, touchedPoints);
2106 mDispatcher->notifyMotion(&motionArgs);
2107
2108 // Consuming from window1 since it's the window that has the InputReceiver
2109 consumeMotionEvent(mWindow1, actionPointerDown, expectedPoints);
2110}
2111
2112TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchMoveDifferentScale) {
2113 mWindow2->setWindowScale(0.5f, 0.5f);
2114
2115 // Touch Window 1
2116 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2117 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
2118
2119 NotifyMotionArgs motionArgs =
2120 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2121 ADISPLAY_ID_DEFAULT, touchedPoints);
2122 mDispatcher->notifyMotion(&motionArgs);
2123 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, expectedPoints);
2124
2125 // Touch Window 2
2126 int32_t actionPointerDown =
2127 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2128 touchedPoints.emplace_back(PointF{150, 150});
2129 expectedPoints.emplace_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2130
2131 motionArgs = generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN,
2132 ADISPLAY_ID_DEFAULT, touchedPoints);
2133 mDispatcher->notifyMotion(&motionArgs);
2134
2135 // Consuming from window1 since it's the window that has the InputReceiver
2136 consumeMotionEvent(mWindow1, actionPointerDown, expectedPoints);
2137
2138 // Move both windows
2139 touchedPoints = {{20, 20}, {175, 175}};
2140 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2141 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2142
2143 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
2144 ADISPLAY_ID_DEFAULT, touchedPoints);
2145 mDispatcher->notifyMotion(&motionArgs);
2146
2147 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_MOVE, expectedPoints);
2148}
2149
2150TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithScale) {
2151 mWindow1->setWindowScale(0.5f, 0.5f);
2152
2153 // Touch Window 1
2154 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2155 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
2156
2157 NotifyMotionArgs motionArgs =
2158 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2159 ADISPLAY_ID_DEFAULT, touchedPoints);
2160 mDispatcher->notifyMotion(&motionArgs);
2161 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, expectedPoints);
2162
2163 // Touch Window 2
2164 int32_t actionPointerDown =
2165 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2166 touchedPoints.emplace_back(PointF{150, 150});
2167 expectedPoints.emplace_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2168
2169 motionArgs = generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN,
2170 ADISPLAY_ID_DEFAULT, touchedPoints);
2171 mDispatcher->notifyMotion(&motionArgs);
2172
2173 // Consuming from window1 since it's the window that has the InputReceiver
2174 consumeMotionEvent(mWindow1, actionPointerDown, expectedPoints);
2175
2176 // Move both windows
2177 touchedPoints = {{20, 20}, {175, 175}};
2178 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2179 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2180
2181 motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
2182 ADISPLAY_ID_DEFAULT, touchedPoints);
2183 mDispatcher->notifyMotion(&motionArgs);
2184
2185 consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_MOVE, expectedPoints);
2186}
2187
Garfield Tane84e6f92019-08-29 17:28:41 -07002188} // namespace android::inputdispatcher