blob: ed0b415fb402f1aed77893506abe0ea3dd3b884f [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>
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -070020#include <android-base/thread_annotations.h>
Robert Carr803535b2018-08-02 16:38:15 -070021#include <binder/Binder.h>
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080022#include <input/Input.h>
Robert Carr803535b2018-08-02 16:38:15 -070023
Michael Wrightd02c5b62014-02-10 15:10:22 -080024#include <gtest/gtest.h>
25#include <linux/input.h>
Garfield Tan1c7bc862020-01-28 13:24:04 -080026#include <cinttypes>
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -070027#include <thread>
Garfield Tan1c7bc862020-01-28 13:24:04 -080028#include <unordered_set>
chaviwd1c23182019-12-20 18:44:56 -080029#include <vector>
Michael Wrightd02c5b62014-02-10 15:10:22 -080030
Garfield Tan1c7bc862020-01-28 13:24:04 -080031using android::base::StringPrintf;
Michael Wright44753b12020-07-08 13:48:11 +010032using namespace android::flag_operators;
Garfield Tan1c7bc862020-01-28 13:24:04 -080033
Garfield Tane84e6f92019-08-29 17:28:41 -070034namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080035
36// An arbitrary time value.
37static const nsecs_t ARBITRARY_TIME = 1234;
38
39// An arbitrary device id.
40static const int32_t DEVICE_ID = 1;
41
Jeff Brownf086ddb2014-02-11 14:28:48 -080042// An arbitrary display id.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -080043static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
Jeff Brownf086ddb2014-02-11 14:28:48 -080044
Michael Wrightd02c5b62014-02-10 15:10:22 -080045// An arbitrary injector pid / uid pair that has permission to inject events.
46static const int32_t INJECTOR_PID = 999;
47static const int32_t INJECTOR_UID = 1001;
48
chaviwd1c23182019-12-20 18:44:56 -080049struct PointF {
50 float x;
51 float y;
52};
Michael Wrightd02c5b62014-02-10 15:10:22 -080053
Gang Wang342c9272020-01-13 13:15:04 -050054/**
55 * Return a DOWN key event with KEYCODE_A.
56 */
57static KeyEvent getTestKeyEvent() {
58 KeyEvent event;
59
Garfield Tanfbe732e2020-01-24 11:26:14 -080060 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
61 INVALID_HMAC, AKEY_EVENT_ACTION_DOWN, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
62 ARBITRARY_TIME, ARBITRARY_TIME);
Gang Wang342c9272020-01-13 13:15:04 -050063 return event;
64}
65
Michael Wrightd02c5b62014-02-10 15:10:22 -080066// --- FakeInputDispatcherPolicy ---
67
68class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
69 InputDispatcherConfiguration mConfig;
70
71protected:
72 virtual ~FakeInputDispatcherPolicy() {
73 }
74
75public:
76 FakeInputDispatcherPolicy() {
Jackal Guof9696682018-10-05 12:23:23 +080077 }
78
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080079 void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080080 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_KEY, args.eventTime, args.action,
81 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080082 }
83
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080084 void assertFilterInputEventWasCalled(const NotifyMotionArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080085 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_MOTION, args.eventTime, args.action,
86 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080087 }
88
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070089 void assertFilterInputEventWasNotCalled() {
90 std::scoped_lock lock(mLock);
91 ASSERT_EQ(nullptr, mFilteredEvent);
92 }
Michael Wrightd02c5b62014-02-10 15:10:22 -080093
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080094 void assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070095 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080096 ASSERT_TRUE(mConfigurationChangedTime)
97 << "Timed out waiting for configuration changed call";
98 ASSERT_EQ(*mConfigurationChangedTime, when);
99 mConfigurationChangedTime = std::nullopt;
100 }
101
102 void assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700103 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800104 ASSERT_TRUE(mLastNotifySwitch);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800105 // We do not check id because it is not exposed to the policy
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800106 EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime);
107 EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags);
108 EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues);
109 EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask);
110 mLastNotifySwitch = std::nullopt;
111 }
112
chaviwfd6d3512019-03-25 13:23:49 -0700113 void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700114 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800115 ASSERT_EQ(touchedToken, mOnPointerDownToken);
116 mOnPointerDownToken.clear();
117 }
118
119 void assertOnPointerDownWasNotCalled() {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700120 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800121 ASSERT_TRUE(mOnPointerDownToken == nullptr)
122 << "Expected onPointerDownOutsideFocus to not have been called";
chaviwfd6d3512019-03-25 13:23:49 -0700123 }
124
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700125 // This function must be called soon after the expected ANR timer starts,
126 // because we are also checking how much time has passed.
Chris Yea209fde2020-07-22 13:54:51 -0700127 void assertNotifyAnrWasCalled(
128 std::chrono::nanoseconds timeout,
129 const std::shared_ptr<InputApplicationHandle>& expectedApplication,
130 const sp<IBinder>& expectedToken) {
131 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700132 ASSERT_NO_FATAL_FAILURE(anrData = getNotifyAnrData(timeout));
133 ASSERT_EQ(expectedApplication, anrData.first);
134 ASSERT_EQ(expectedToken, anrData.second);
135 }
136
Chris Yea209fde2020-07-22 13:54:51 -0700137 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> getNotifyAnrData(
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700138 std::chrono::nanoseconds timeout) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700139 const std::chrono::time_point start = std::chrono::steady_clock::now();
140 std::unique_lock lock(mLock);
141 std::chrono::duration timeToWait = timeout + 100ms; // provide some slack
142 android::base::ScopedLockAssertion assumeLocked(mLock);
143
144 // If there is an ANR, Dispatcher won't be idle because there are still events
145 // in the waitQueue that we need to check on. So we can't wait for dispatcher to be idle
146 // before checking if ANR was called.
147 // Since dispatcher is not guaranteed to call notifyAnr right away, we need to provide
148 // it some time to act. 100ms seems reasonable.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700149 mNotifyAnr.wait_for(lock, timeToWait, [this]() REQUIRES(mLock) {
150 return !mAnrApplications.empty() && !mAnrWindowTokens.empty();
151 });
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700152 const std::chrono::duration waited = std::chrono::steady_clock::now() - start;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700153 if (mAnrApplications.empty() || mAnrWindowTokens.empty()) {
154 ADD_FAILURE() << "Did not receive ANR callback";
155 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700156 // Ensure that the ANR didn't get raised too early. We can't be too strict here because
157 // the dispatcher started counting before this function was called
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700158 if (std::chrono::abs(timeout - waited) > 100ms) {
159 ADD_FAILURE() << "ANR was raised too early or too late. Expected "
160 << std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count()
161 << "ms, but waited "
162 << std::chrono::duration_cast<std::chrono::milliseconds>(waited).count()
163 << "ms instead";
164 }
Chris Yea209fde2020-07-22 13:54:51 -0700165 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> result =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700166 std::make_pair(mAnrApplications.front(), mAnrWindowTokens.front());
167 mAnrApplications.pop();
168 mAnrWindowTokens.pop();
169 return result;
170 }
171
172 void assertNotifyAnrWasNotCalled() {
173 std::scoped_lock lock(mLock);
174 ASSERT_TRUE(mAnrApplications.empty());
175 ASSERT_TRUE(mAnrWindowTokens.empty());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700176 }
177
Garfield Tan1c7bc862020-01-28 13:24:04 -0800178 void setKeyRepeatConfiguration(nsecs_t timeout, nsecs_t delay) {
179 mConfig.keyRepeatTimeout = timeout;
180 mConfig.keyRepeatDelay = delay;
181 }
182
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700183 void setAnrTimeout(std::chrono::nanoseconds timeout) { mAnrTimeout = timeout; }
184
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185private:
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700186 std::mutex mLock;
187 std::unique_ptr<InputEvent> mFilteredEvent GUARDED_BY(mLock);
188 std::optional<nsecs_t> mConfigurationChangedTime GUARDED_BY(mLock);
189 sp<IBinder> mOnPointerDownToken GUARDED_BY(mLock);
190 std::optional<NotifySwitchArgs> mLastNotifySwitch GUARDED_BY(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800191
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700192 // ANR handling
Chris Yea209fde2020-07-22 13:54:51 -0700193 std::queue<std::shared_ptr<InputApplicationHandle>> mAnrApplications GUARDED_BY(mLock);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700194 std::queue<sp<IBinder>> mAnrWindowTokens GUARDED_BY(mLock);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700195 std::condition_variable mNotifyAnr;
196 std::chrono::nanoseconds mAnrTimeout = 0ms;
197
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800198 virtual void notifyConfigurationChanged(nsecs_t when) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700199 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800200 mConfigurationChangedTime = when;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800201 }
202
Chris Yea209fde2020-07-22 13:54:51 -0700203 std::chrono::nanoseconds notifyAnr(const std::shared_ptr<InputApplicationHandle>& application,
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500204 const sp<IBinder>& windowToken,
205 const std::string&) override {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700206 std::scoped_lock lock(mLock);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700207 mAnrApplications.push(application);
208 mAnrWindowTokens.push(windowToken);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700209 mNotifyAnr.notify_all();
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500210 return mAnrTimeout;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 }
212
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700213 virtual void notifyInputChannelBroken(const sp<IBinder>&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700215 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) override {}
Robert Carr740167f2018-10-11 19:03:41 -0700216
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700217 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 *outConfig = mConfig;
219 }
220
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800221 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700222 std::scoped_lock lock(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800223 switch (inputEvent->getType()) {
224 case AINPUT_EVENT_TYPE_KEY: {
225 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800226 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800227 break;
228 }
229
230 case AINPUT_EVENT_TYPE_MOTION: {
231 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800232 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800233 break;
234 }
235 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800236 return true;
237 }
238
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700239 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800240
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700241 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700243 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent*,
244 uint32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800245 return 0;
246 }
247
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700248 virtual bool dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent*, uint32_t,
249 KeyEvent*) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 return false;
251 }
252
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800253 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
254 uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700255 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800256 /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
257 * essentially a passthrough for notifySwitch.
258 */
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800259 mLastNotifySwitch = NotifySwitchArgs(1 /*id*/, when, policyFlags, switchValues, switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800260 }
261
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700262 virtual void pokeUserActivity(nsecs_t, int32_t) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800263
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700264 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 return false;
266 }
Jackal Guof9696682018-10-05 12:23:23 +0800267
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700268 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700269 std::scoped_lock lock(mLock);
chaviwfd6d3512019-03-25 13:23:49 -0700270 mOnPointerDownToken = newToken;
271 }
272
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800273 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
274 int32_t displayId) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700275 std::scoped_lock lock(mLock);
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800276 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
277 ASSERT_EQ(mFilteredEvent->getType(), type);
278
279 if (type == AINPUT_EVENT_TYPE_KEY) {
280 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
281 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
282 EXPECT_EQ(keyEvent.getAction(), action);
283 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
284 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
285 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
286 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
287 EXPECT_EQ(motionEvent.getAction(), action);
288 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
289 } else {
290 FAIL() << "Unknown type: " << type;
291 }
292
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800293 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800294 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295};
296
Michael Wrightd02c5b62014-02-10 15:10:22 -0800297// --- InputDispatcherTest ---
298
299class InputDispatcherTest : public testing::Test {
300protected:
301 sp<FakeInputDispatcherPolicy> mFakePolicy;
302 sp<InputDispatcher> mDispatcher;
303
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700304 virtual void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800305 mFakePolicy = new FakeInputDispatcherPolicy();
306 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800307 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
308 //Start InputDispatcher thread
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700309 ASSERT_EQ(OK, mDispatcher->start());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800310 }
311
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700312 virtual void TearDown() override {
313 ASSERT_EQ(OK, mDispatcher->stop());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800314 mFakePolicy.clear();
315 mDispatcher.clear();
316 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700317
318 /**
319 * Used for debugging when writing the test
320 */
321 void dumpDispatcherState() {
322 std::string dump;
323 mDispatcher->dump(dump);
324 std::stringstream ss(dump);
325 std::string to;
326
327 while (std::getline(ss, to, '\n')) {
328 ALOGE("%s", to.c_str());
329 }
330 }
Vishnu Nair958da932020-08-21 17:12:37 -0700331
332 void setFocusedWindow(const sp<InputWindowHandle>& window,
333 const sp<InputWindowHandle>& focusedWindow = nullptr) {
334 FocusRequest request;
335 request.token = window->getToken();
336 if (focusedWindow) {
337 request.focusedToken = focusedWindow->getToken();
338 }
339 request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
340 request.displayId = window->getInfo()->displayId;
341 mDispatcher->setFocusedWindow(request);
342 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800343};
344
345
346TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
347 KeyEvent event;
348
349 // Rejects undefined key actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800350 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
351 INVALID_HMAC,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600352 /*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME,
353 ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700354 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
355 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
356 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800357 << "Should reject key events with undefined action.";
358
359 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800360 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
361 INVALID_HMAC, AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600362 ARBITRARY_TIME, ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700363 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
364 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
365 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800366 << "Should reject key events with ACTION_MULTIPLE.";
367}
368
369TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
370 MotionEvent event;
371 PointerProperties pointerProperties[MAX_POINTERS + 1];
372 PointerCoords pointerCoords[MAX_POINTERS + 1];
373 for (int i = 0; i <= MAX_POINTERS; i++) {
374 pointerProperties[i].clear();
375 pointerProperties[i].id = i;
376 pointerCoords[i].clear();
377 }
378
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800379 // Some constants commonly used below
380 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
381 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
382 constexpr int32_t metaState = AMETA_NONE;
383 constexpr MotionClassification classification = MotionClassification::NONE;
384
chaviw9eaa22c2020-07-01 16:21:27 -0700385 ui::Transform identityTransform;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800386 // Rejects undefined motion actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800387 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
chaviw9eaa22c2020-07-01 16:21:27 -0700388 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification,
389 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600390 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700391 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700392 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
393 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
394 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800395 << "Should reject motion events with undefined action.";
396
397 // Rejects pointer down with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800398 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700399 AMOTION_EVENT_ACTION_POINTER_DOWN |
400 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700401 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
402 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
403 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
404 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700405 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
406 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
407 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800408 << "Should reject motion events with pointer down index too large.";
409
Garfield Tanfbe732e2020-01-24 11:26:14 -0800410 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700411 AMOTION_EVENT_ACTION_POINTER_DOWN |
412 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700413 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
414 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
415 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
416 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700417 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
418 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
419 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800420 << "Should reject motion events with pointer down index too small.";
421
422 // Rejects pointer up with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800423 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700424 AMOTION_EVENT_ACTION_POINTER_UP |
425 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700426 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
427 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
428 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
429 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700430 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
431 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
432 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800433 << "Should reject motion events with pointer up index too large.";
434
Garfield Tanfbe732e2020-01-24 11:26:14 -0800435 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700436 AMOTION_EVENT_ACTION_POINTER_UP |
437 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700438 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
439 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
440 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
441 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700442 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
443 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
444 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800445 << "Should reject motion events with pointer up index too small.";
446
447 // Rejects motion events with invalid number of pointers.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800448 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
449 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700450 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
451 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700452 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700453 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
454 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
455 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800456 << "Should reject motion events with 0 pointers.";
457
Garfield Tanfbe732e2020-01-24 11:26:14 -0800458 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
459 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700460 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
461 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700462 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700463 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
464 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
465 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800466 << "Should reject motion events with more than MAX_POINTERS pointers.";
467
468 // Rejects motion events with invalid pointer ids.
469 pointerProperties[0].id = -1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800470 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
471 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700472 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
473 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700474 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700475 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
476 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
477 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800478 << "Should reject motion events with pointer ids less than 0.";
479
480 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800481 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
482 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700483 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
484 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700485 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700486 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
487 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
488 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800489 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
490
491 // Rejects motion events with duplicate pointer ids.
492 pointerProperties[0].id = 1;
493 pointerProperties[1].id = 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800494 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
495 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700496 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
497 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700498 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700499 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
500 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
501 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800502 << "Should reject motion events with duplicate pointer ids.";
503}
504
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800505/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
506
507TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
508 constexpr nsecs_t eventTime = 20;
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800509 NotifyConfigurationChangedArgs args(10 /*id*/, eventTime);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800510 mDispatcher->notifyConfigurationChanged(&args);
511 ASSERT_TRUE(mDispatcher->waitForIdle());
512
513 mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
514}
515
516TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800517 NotifySwitchArgs args(10 /*id*/, 20 /*eventTime*/, 0 /*policyFlags*/, 1 /*switchValues*/,
518 2 /*switchMask*/);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800519 mDispatcher->notifySwitch(&args);
520
521 // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener
522 args.policyFlags |= POLICY_FLAG_TRUSTED;
523 mFakePolicy->assertNotifySwitchWasCalled(args);
524}
525
Arthur Hungb92218b2018-08-14 12:00:21 +0800526// --- InputDispatcherTest SetInputWindowTest ---
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700527static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 500ms;
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700528static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
Arthur Hungb92218b2018-08-14 12:00:21 +0800529
530class FakeApplicationHandle : public InputApplicationHandle {
531public:
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700532 FakeApplicationHandle() {
533 mInfo.name = "Fake Application";
534 mInfo.token = new BBinder();
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500535 mInfo.dispatchingTimeoutMillis =
536 std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700537 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800538 virtual ~FakeApplicationHandle() {}
539
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700540 virtual bool updateInfo() override {
Arthur Hungb92218b2018-08-14 12:00:21 +0800541 return true;
542 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700543
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500544 void setDispatchingTimeout(std::chrono::milliseconds timeout) {
545 mInfo.dispatchingTimeoutMillis = timeout.count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700546 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800547};
548
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800549class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800550public:
Garfield Tan15601662020-09-22 15:32:38 -0700551 explicit FakeInputReceiver(std::unique_ptr<InputChannel> clientChannel, const std::string name)
chaviwd1c23182019-12-20 18:44:56 -0800552 : mName(name) {
Garfield Tan15601662020-09-22 15:32:38 -0700553 mConsumer = std::make_unique<InputConsumer>(std::move(clientChannel));
chaviwd1c23182019-12-20 18:44:56 -0800554 }
555
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800556 InputEvent* consume() {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700557 InputEvent* event;
558 std::optional<uint32_t> consumeSeq = receiveEvent(&event);
559 if (!consumeSeq) {
560 return nullptr;
561 }
562 finishEvent(*consumeSeq);
563 return event;
564 }
565
566 /**
567 * Receive an event without acknowledging it.
568 * Return the sequence number that could later be used to send finished signal.
569 */
570 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800571 uint32_t consumeSeq;
572 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800573
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800574 std::chrono::time_point start = std::chrono::steady_clock::now();
575 status_t status = WOULD_BLOCK;
576 while (status == WOULD_BLOCK) {
chaviw81e2bb92019-12-18 15:03:51 -0800577 status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq,
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800578 &event);
579 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
580 if (elapsed > 100ms) {
581 break;
582 }
583 }
584
585 if (status == WOULD_BLOCK) {
586 // Just means there's no event available.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700587 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800588 }
589
590 if (status != OK) {
591 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700592 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800593 }
594 if (event == nullptr) {
595 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700596 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800597 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700598 if (outEvent != nullptr) {
599 *outEvent = event;
600 }
601 return consumeSeq;
602 }
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800603
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700604 /**
605 * To be used together with "receiveEvent" to complete the consumption of an event.
606 */
607 void finishEvent(uint32_t consumeSeq) {
608 const status_t status = mConsumer->sendFinishedSignal(consumeSeq, true);
609 ASSERT_EQ(OK, status) << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800610 }
611
612 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
613 int32_t expectedFlags) {
614 InputEvent* event = consume();
615
616 ASSERT_NE(nullptr, event) << mName.c_str()
617 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800618 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700619 << mName.c_str() << " expected " << inputEventTypeToString(expectedEventType)
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800620 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800621
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800622 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800623
Tiger Huang8664f8c2018-10-11 19:14:35 +0800624 switch (expectedEventType) {
625 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800626 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
627 EXPECT_EQ(expectedAction, keyEvent.getAction());
628 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800629 break;
630 }
631 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800632 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
633 EXPECT_EQ(expectedAction, motionEvent.getAction());
634 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800635 break;
636 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100637 case AINPUT_EVENT_TYPE_FOCUS: {
638 FAIL() << "Use 'consumeFocusEvent' for FOCUS events";
639 }
Tiger Huang8664f8c2018-10-11 19:14:35 +0800640 default: {
641 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
642 }
643 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800644 }
645
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100646 void consumeFocusEvent(bool hasFocus, bool inTouchMode) {
647 InputEvent* event = consume();
648 ASSERT_NE(nullptr, event) << mName.c_str()
649 << ": consumer should have returned non-NULL event.";
650 ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, event->getType())
651 << "Got " << inputEventTypeToString(event->getType())
652 << " event instead of FOCUS event";
653
654 ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId())
655 << mName.c_str() << ": event displayId should always be NONE.";
656
657 FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
658 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
659 EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode());
660 }
661
chaviwd1c23182019-12-20 18:44:56 -0800662 void assertNoEvents() {
663 InputEvent* event = consume();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700664 if (event == nullptr) {
665 return;
666 }
667 if (event->getType() == AINPUT_EVENT_TYPE_KEY) {
668 KeyEvent& keyEvent = static_cast<KeyEvent&>(*event);
669 ADD_FAILURE() << "Received key event "
670 << KeyEvent::actionToString(keyEvent.getAction());
671 } else if (event->getType() == AINPUT_EVENT_TYPE_MOTION) {
672 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
673 ADD_FAILURE() << "Received motion event "
674 << MotionEvent::actionToString(motionEvent.getAction());
675 } else if (event->getType() == AINPUT_EVENT_TYPE_FOCUS) {
676 FocusEvent& focusEvent = static_cast<FocusEvent&>(*event);
677 ADD_FAILURE() << "Received focus event, hasFocus = "
678 << (focusEvent.getHasFocus() ? "true" : "false");
679 }
680 FAIL() << mName.c_str()
681 << ": should not have received any events, so consume() should return NULL";
chaviwd1c23182019-12-20 18:44:56 -0800682 }
683
684 sp<IBinder> getToken() { return mConsumer->getChannel()->getConnectionToken(); }
685
686protected:
687 std::unique_ptr<InputConsumer> mConsumer;
688 PreallocatedInputEventFactory mEventFactory;
689
690 std::string mName;
691};
692
693class FakeWindowHandle : public InputWindowHandle {
694public:
695 static const int32_t WIDTH = 600;
696 static const int32_t HEIGHT = 800;
chaviwd1c23182019-12-20 18:44:56 -0800697
Chris Yea209fde2020-07-22 13:54:51 -0700698 FakeWindowHandle(const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
chaviwd1c23182019-12-20 18:44:56 -0800699 const sp<InputDispatcher>& dispatcher, const std::string name,
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500700 int32_t displayId, std::optional<sp<IBinder>> token = std::nullopt)
chaviwd1c23182019-12-20 18:44:56 -0800701 : mName(name) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500702 if (token == std::nullopt) {
Garfield Tan15601662020-09-22 15:32:38 -0700703 base::Result<std::unique_ptr<InputChannel>> channel =
704 dispatcher->createInputChannel(name);
705 token = (*channel)->getConnectionToken();
706 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
chaviwd1c23182019-12-20 18:44:56 -0800707 }
708
709 inputApplicationHandle->updateInfo();
710 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
711
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500712 mInfo.token = *token;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700713 mInfo.id = sId++;
chaviwd1c23182019-12-20 18:44:56 -0800714 mInfo.name = name;
Michael Wright44753b12020-07-08 13:48:11 +0100715 mInfo.type = InputWindowInfo::Type::APPLICATION;
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500716 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwd1c23182019-12-20 18:44:56 -0800717 mInfo.frameLeft = 0;
718 mInfo.frameTop = 0;
719 mInfo.frameRight = WIDTH;
720 mInfo.frameBottom = HEIGHT;
chaviw1ff3d1e2020-07-01 15:53:47 -0700721 mInfo.transform.set(0, 0);
chaviwd1c23182019-12-20 18:44:56 -0800722 mInfo.globalScaleFactor = 1.0;
723 mInfo.touchableRegion.clear();
724 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
725 mInfo.visible = true;
Vishnu Nair47074b82020-08-14 11:54:47 -0700726 mInfo.focusable = false;
chaviwd1c23182019-12-20 18:44:56 -0800727 mInfo.hasWallpaper = false;
728 mInfo.paused = false;
chaviwd1c23182019-12-20 18:44:56 -0800729 mInfo.ownerPid = INJECTOR_PID;
730 mInfo.ownerUid = INJECTOR_UID;
chaviwd1c23182019-12-20 18:44:56 -0800731 mInfo.displayId = displayId;
732 }
733
734 virtual bool updateInfo() { return true; }
735
Vishnu Nair47074b82020-08-14 11:54:47 -0700736 void setFocusable(bool focusable) { mInfo.focusable = focusable; }
chaviwd1c23182019-12-20 18:44:56 -0800737
Vishnu Nair958da932020-08-21 17:12:37 -0700738 void setVisible(bool visible) { mInfo.visible = visible; }
739
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700740 void setDispatchingTimeout(std::chrono::nanoseconds timeout) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500741 mInfo.dispatchingTimeout = timeout;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700742 }
743
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700744 void setPaused(bool paused) { mInfo.paused = paused; }
745
chaviwd1c23182019-12-20 18:44:56 -0800746 void setFrame(const Rect& frame) {
747 mInfo.frameLeft = frame.left;
748 mInfo.frameTop = frame.top;
749 mInfo.frameRight = frame.right;
750 mInfo.frameBottom = frame.bottom;
chaviw1ff3d1e2020-07-01 15:53:47 -0700751 mInfo.transform.set(frame.left, frame.top);
chaviwd1c23182019-12-20 18:44:56 -0800752 mInfo.touchableRegion.clear();
753 mInfo.addTouchableRegion(frame);
754 }
755
Michael Wright44753b12020-07-08 13:48:11 +0100756 void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; }
chaviwd1c23182019-12-20 18:44:56 -0800757
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500758 void setInputFeatures(InputWindowInfo::Feature features) { mInfo.inputFeatures = features; }
759
chaviw9eaa22c2020-07-01 16:21:27 -0700760 void setWindowTransform(float dsdx, float dtdx, float dtdy, float dsdy) {
761 mInfo.transform.set(dsdx, dtdx, dtdy, dsdy);
762 }
763
764 void setWindowScale(float xScale, float yScale) { setWindowTransform(xScale, 0, 0, yScale); }
chaviwaf87b3e2019-10-01 16:59:28 -0700765
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800766 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
767 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
768 expectedFlags);
769 }
770
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700771 void consumeKeyUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
772 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, expectedDisplayId, expectedFlags);
773 }
774
Svet Ganov5d3bc372020-01-26 23:11:07 -0800775 void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
776 int32_t expectedFlags = 0) {
777 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId,
778 expectedFlags);
779 }
780
781 void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
782 int32_t expectedFlags = 0) {
783 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId,
784 expectedFlags);
785 }
786
787 void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
788 int32_t expectedFlags = 0) {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800789 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
790 expectedFlags);
791 }
792
Svet Ganov5d3bc372020-01-26 23:11:07 -0800793 void consumeMotionPointerDown(int32_t pointerIdx,
794 int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) {
795 int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN
796 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
797 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
798 }
799
800 void consumeMotionPointerUp(int32_t pointerIdx, int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
801 int32_t expectedFlags = 0) {
802 int32_t action = AMOTION_EVENT_ACTION_POINTER_UP
803 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
804 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
805 }
806
807 void consumeMotionUp(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
808 int32_t expectedFlags = 0) {
Michael Wright3a240c42019-12-10 20:53:41 +0000809 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
810 expectedFlags);
811 }
812
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100813 void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
814 ASSERT_NE(mInputReceiver, nullptr)
815 << "Cannot consume events from a window with no receiver";
816 mInputReceiver->consumeFocusEvent(hasFocus, inTouchMode);
817 }
818
chaviwd1c23182019-12-20 18:44:56 -0800819 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
820 int32_t expectedFlags) {
821 ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
822 mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
823 expectedFlags);
824 }
825
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700826 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700827 if (mInputReceiver == nullptr) {
828 ADD_FAILURE() << "Invalid receive event on window with no receiver";
829 return std::nullopt;
830 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700831 return mInputReceiver->receiveEvent(outEvent);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700832 }
833
834 void finishEvent(uint32_t sequenceNum) {
835 ASSERT_NE(mInputReceiver, nullptr) << "Invalid receive event on window with no receiver";
836 mInputReceiver->finishEvent(sequenceNum);
837 }
838
chaviwaf87b3e2019-10-01 16:59:28 -0700839 InputEvent* consume() {
840 if (mInputReceiver == nullptr) {
841 return nullptr;
842 }
843 return mInputReceiver->consume();
844 }
845
Arthur Hungb92218b2018-08-14 12:00:21 +0800846 void assertNoEvents() {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500847 if (mInputReceiver == nullptr &&
848 mInfo.inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL)) {
849 return; // Can't receive events if the window does not have input channel
850 }
851 ASSERT_NE(nullptr, mInputReceiver)
852 << "Window without InputReceiver must specify feature NO_INPUT_CHANNEL";
chaviwd1c23182019-12-20 18:44:56 -0800853 mInputReceiver->assertNoEvents();
Arthur Hungb92218b2018-08-14 12:00:21 +0800854 }
855
chaviwaf87b3e2019-10-01 16:59:28 -0700856 sp<IBinder> getToken() { return mInfo.token; }
857
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100858 const std::string& getName() { return mName; }
859
chaviwd1c23182019-12-20 18:44:56 -0800860private:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100861 const std::string mName;
chaviwd1c23182019-12-20 18:44:56 -0800862 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700863 static std::atomic<int32_t> sId; // each window gets a unique id, like in surfaceflinger
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800864};
865
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700866std::atomic<int32_t> FakeWindowHandle::sId{1};
867
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700868static int32_t injectKey(const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700869 int32_t displayId = ADISPLAY_ID_NONE,
870 int32_t syncMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
871 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800872 KeyEvent event;
873 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
874
875 // Define a valid key down event.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800876 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700877 INVALID_HMAC, action, /* flags */ 0, AKEYCODE_A, KEY_A, AMETA_NONE,
878 repeatCount, currentTime, currentTime);
Arthur Hungb92218b2018-08-14 12:00:21 +0800879
880 // Inject event until dispatch out.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700881 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, syncMode,
882 injectionTimeout,
883 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
Arthur Hungb92218b2018-08-14 12:00:21 +0800884}
885
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700886static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
887 int32_t displayId = ADISPLAY_ID_NONE) {
888 return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId);
889}
890
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700891static int32_t injectKeyUp(const sp<InputDispatcher>& dispatcher,
892 int32_t displayId = ADISPLAY_ID_NONE) {
893 return injectKey(dispatcher, AKEY_EVENT_ACTION_UP, /* repeatCount */ 0, displayId);
894}
895
Garfield Tandf26e862020-07-01 20:18:19 -0700896class PointerBuilder {
897public:
898 PointerBuilder(int32_t id, int32_t toolType) {
899 mProperties.clear();
900 mProperties.id = id;
901 mProperties.toolType = toolType;
902 mCoords.clear();
903 }
904
905 PointerBuilder& x(float x) { return axis(AMOTION_EVENT_AXIS_X, x); }
906
907 PointerBuilder& y(float y) { return axis(AMOTION_EVENT_AXIS_Y, y); }
908
909 PointerBuilder& axis(int32_t axis, float value) {
910 mCoords.setAxisValue(axis, value);
911 return *this;
912 }
913
914 PointerProperties buildProperties() const { return mProperties; }
915
916 PointerCoords buildCoords() const { return mCoords; }
917
918private:
919 PointerProperties mProperties;
920 PointerCoords mCoords;
921};
922
923class MotionEventBuilder {
924public:
925 MotionEventBuilder(int32_t action, int32_t source) {
926 mAction = action;
927 mSource = source;
928 mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
929 }
930
931 MotionEventBuilder& eventTime(nsecs_t eventTime) {
932 mEventTime = eventTime;
933 return *this;
934 }
935
936 MotionEventBuilder& displayId(int32_t displayId) {
937 mDisplayId = displayId;
938 return *this;
939 }
940
941 MotionEventBuilder& actionButton(int32_t actionButton) {
942 mActionButton = actionButton;
943 return *this;
944 }
945
946 MotionEventBuilder& buttonState(int32_t actionButton) {
947 mActionButton = actionButton;
948 return *this;
949 }
950
951 MotionEventBuilder& rawXCursorPosition(float rawXCursorPosition) {
952 mRawXCursorPosition = rawXCursorPosition;
953 return *this;
954 }
955
956 MotionEventBuilder& rawYCursorPosition(float rawYCursorPosition) {
957 mRawYCursorPosition = rawYCursorPosition;
958 return *this;
959 }
960
961 MotionEventBuilder& pointer(PointerBuilder pointer) {
962 mPointers.push_back(pointer);
963 return *this;
964 }
965
966 MotionEvent build() {
967 std::vector<PointerProperties> pointerProperties;
968 std::vector<PointerCoords> pointerCoords;
969 for (const PointerBuilder& pointer : mPointers) {
970 pointerProperties.push_back(pointer.buildProperties());
971 pointerCoords.push_back(pointer.buildCoords());
972 }
973
974 // Set mouse cursor position for the most common cases to avoid boilerplate.
975 if (mSource == AINPUT_SOURCE_MOUSE &&
976 !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition) &&
977 mPointers.size() == 1) {
978 mRawXCursorPosition = pointerCoords[0].getX();
979 mRawYCursorPosition = pointerCoords[0].getY();
980 }
981
982 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -0700983 ui::Transform identityTransform;
Garfield Tandf26e862020-07-01 20:18:19 -0700984 event.initialize(InputEvent::nextId(), DEVICE_ID, mSource, mDisplayId, INVALID_HMAC,
985 mAction, mActionButton, /* flags */ 0, /* edgeFlags */ 0, AMETA_NONE,
chaviw9eaa22c2020-07-01 16:21:27 -0700986 mButtonState, MotionClassification::NONE, identityTransform,
987 /* xPrecision */ 0, /* yPrecision */ 0, mRawXCursorPosition,
988 mRawYCursorPosition, mEventTime, mEventTime, mPointers.size(),
989 pointerProperties.data(), pointerCoords.data());
Garfield Tandf26e862020-07-01 20:18:19 -0700990
991 return event;
992 }
993
994private:
995 int32_t mAction;
996 int32_t mSource;
997 nsecs_t mEventTime;
998 int32_t mDisplayId{ADISPLAY_ID_DEFAULT};
999 int32_t mActionButton{0};
1000 int32_t mButtonState{0};
1001 float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1002 float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1003
1004 std::vector<PointerBuilder> mPointers;
1005};
1006
1007static int32_t injectMotionEvent(
1008 const sp<InputDispatcher>& dispatcher, const MotionEvent& event,
1009 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
1010 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT) {
1011 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, injectionMode,
1012 injectionTimeout,
1013 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
1014}
1015
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001016static int32_t injectMotionEvent(
1017 const sp<InputDispatcher>& dispatcher, int32_t action, int32_t source, int32_t displayId,
1018 const PointF& position,
1019 const PointF& cursorPosition = {AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001020 AMOTION_EVENT_INVALID_CURSOR_POSITION},
1021 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
1022 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
1023 nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC)) {
Garfield Tandf26e862020-07-01 20:18:19 -07001024 MotionEvent event = MotionEventBuilder(action, source)
1025 .displayId(displayId)
1026 .eventTime(eventTime)
1027 .rawXCursorPosition(cursorPosition.x)
1028 .rawYCursorPosition(cursorPosition.y)
1029 .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER)
1030 .x(position.x)
1031 .y(position.y))
1032 .build();
Arthur Hungb92218b2018-08-14 12:00:21 +08001033
1034 // Inject event until dispatch out.
Garfield Tandf26e862020-07-01 20:18:19 -07001035 return injectMotionEvent(dispatcher, event);
Arthur Hungb92218b2018-08-14 12:00:21 +08001036}
1037
Garfield Tan00f511d2019-06-12 16:55:40 -07001038static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001039 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001040 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, location);
Garfield Tan00f511d2019-06-12 16:55:40 -07001041}
1042
Michael Wright3a240c42019-12-10 20:53:41 +00001043static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001044 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001045 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, location);
Michael Wright3a240c42019-12-10 20:53:41 +00001046}
1047
Jackal Guof9696682018-10-05 12:23:23 +08001048static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
1049 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1050 // Define a valid key event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001051 NotifyKeyArgs args(/* id */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
1052 POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0, AKEYCODE_A, KEY_A,
1053 AMETA_NONE, currentTime);
Jackal Guof9696682018-10-05 12:23:23 +08001054
1055 return args;
1056}
1057
chaviwd1c23182019-12-20 18:44:56 -08001058static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId,
1059 const std::vector<PointF>& points) {
1060 size_t pointerCount = points.size();
chaviwaf87b3e2019-10-01 16:59:28 -07001061 if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_UP) {
1062 EXPECT_EQ(1U, pointerCount) << "Actions DOWN and UP can only contain a single pointer";
1063 }
1064
chaviwd1c23182019-12-20 18:44:56 -08001065 PointerProperties pointerProperties[pointerCount];
1066 PointerCoords pointerCoords[pointerCount];
Jackal Guof9696682018-10-05 12:23:23 +08001067
chaviwd1c23182019-12-20 18:44:56 -08001068 for (size_t i = 0; i < pointerCount; i++) {
1069 pointerProperties[i].clear();
1070 pointerProperties[i].id = i;
1071 pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
Jackal Guof9696682018-10-05 12:23:23 +08001072
chaviwd1c23182019-12-20 18:44:56 -08001073 pointerCoords[i].clear();
1074 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
1075 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, points[i].y);
1076 }
Jackal Guof9696682018-10-05 12:23:23 +08001077
1078 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1079 // Define a valid motion event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001080 NotifyMotionArgs args(/* id */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -07001081 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
1082 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
chaviwd1c23182019-12-20 18:44:56 -08001083 AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, pointerProperties,
1084 pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -07001085 AMOTION_EVENT_INVALID_CURSOR_POSITION,
1086 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +08001087
1088 return args;
1089}
1090
chaviwd1c23182019-12-20 18:44:56 -08001091static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
1092 return generateMotionArgs(action, source, displayId, {PointF{100, 200}});
1093}
1094
Arthur Hungb92218b2018-08-14 12:00:21 +08001095TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001096 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001097 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
1098 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001099
Arthur Hung72d8dc32020-03-28 00:48:39 +00001100 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001101 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1102 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001103 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1104
1105 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001106 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001107}
1108
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001109/**
1110 * Calling setInputWindows once with FLAG_NOT_TOUCH_MODAL should not cause any issues.
1111 * To ensure that window receives only events that were directly inside of it, add
1112 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1113 * when finding touched windows.
1114 * This test serves as a sanity check for the next test, where setInputWindows is
1115 * called twice.
1116 */
1117TEST_F(InputDispatcherTest, SetInputWindowOnce_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001118 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001119 sp<FakeWindowHandle> window =
1120 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1121 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001122 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001123
1124 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1125 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1126 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1127 {50, 50}))
1128 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1129
1130 // Window should receive motion event.
1131 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1132}
1133
1134/**
1135 * Calling setInputWindows twice, with the same info, should not cause any issues.
1136 * To ensure that window receives only events that were directly inside of it, add
1137 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1138 * when finding touched windows.
1139 */
1140TEST_F(InputDispatcherTest, SetInputWindowTwice_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001141 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001142 sp<FakeWindowHandle> window =
1143 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1144 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001145 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001146
1147 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1148 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1149 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1150 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1151 {50, 50}))
1152 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1153
1154 // Window should receive motion event.
1155 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1156}
1157
Arthur Hungb92218b2018-08-14 12:00:21 +08001158// The foreground window should receive the first touch down event.
1159TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001160 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001161 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1162 ADISPLAY_ID_DEFAULT);
1163 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1164 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001165
Arthur Hung72d8dc32020-03-28 00:48:39 +00001166 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001167 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1168 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001169 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1170
1171 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001172 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001173 windowSecond->assertNoEvents();
1174}
1175
Garfield Tandf26e862020-07-01 20:18:19 -07001176TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001177 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001178 sp<FakeWindowHandle> windowLeft =
1179 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1180 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001181 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001182 sp<FakeWindowHandle> windowRight =
1183 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1184 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001185 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001186
1187 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1188
1189 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
1190
1191 // Start cursor position in right window so that we can move the cursor to left window.
1192 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1193 injectMotionEvent(mDispatcher,
1194 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1195 AINPUT_SOURCE_MOUSE)
1196 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1197 .x(900)
1198 .y(400))
1199 .build()));
1200 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1201 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1202 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1203 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1204
1205 // Move cursor into left window
1206 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1207 injectMotionEvent(mDispatcher,
1208 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1209 AINPUT_SOURCE_MOUSE)
1210 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1211 .x(300)
1212 .y(400))
1213 .build()));
1214 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1215 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1216 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1217 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1218 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1219 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1220
1221 // Inject a series of mouse events for a mouse click
1222 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1223 injectMotionEvent(mDispatcher,
1224 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1225 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1226 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1227 .x(300)
1228 .y(400))
1229 .build()));
1230 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1231
1232 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1233 injectMotionEvent(mDispatcher,
1234 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1235 AINPUT_SOURCE_MOUSE)
1236 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1237 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1238 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1239 .x(300)
1240 .y(400))
1241 .build()));
1242 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1243 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1244
1245 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1246 injectMotionEvent(mDispatcher,
1247 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1248 AINPUT_SOURCE_MOUSE)
1249 .buttonState(0)
1250 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1251 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1252 .x(300)
1253 .y(400))
1254 .build()));
1255 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1256 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1257
1258 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1259 injectMotionEvent(mDispatcher,
1260 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1261 .buttonState(0)
1262 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1263 .x(300)
1264 .y(400))
1265 .build()));
1266 windowLeft->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1267
1268 // Move mouse cursor back to right window
1269 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1270 injectMotionEvent(mDispatcher,
1271 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1272 AINPUT_SOURCE_MOUSE)
1273 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1274 .x(900)
1275 .y(400))
1276 .build()));
1277 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1278 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1279 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1280 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1281 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1282 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1283}
1284
1285// This test is different from the test above that HOVER_ENTER and HOVER_EXIT events are injected
1286// directly in this test.
1287TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001288 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001289 sp<FakeWindowHandle> window =
1290 new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
1291 window->setFrame(Rect(0, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001292 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001293
1294 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1295
1296 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1297
1298 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1299 injectMotionEvent(mDispatcher,
1300 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
1301 AINPUT_SOURCE_MOUSE)
1302 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1303 .x(300)
1304 .y(400))
1305 .build()));
1306 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1307 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1308
1309 // Inject a series of mouse events for a mouse click
1310 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1311 injectMotionEvent(mDispatcher,
1312 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1313 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1314 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1315 .x(300)
1316 .y(400))
1317 .build()));
1318 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1319
1320 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1321 injectMotionEvent(mDispatcher,
1322 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1323 AINPUT_SOURCE_MOUSE)
1324 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1325 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1326 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1327 .x(300)
1328 .y(400))
1329 .build()));
1330 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1331 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1332
1333 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1334 injectMotionEvent(mDispatcher,
1335 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1336 AINPUT_SOURCE_MOUSE)
1337 .buttonState(0)
1338 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1339 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1340 .x(300)
1341 .y(400))
1342 .build()));
1343 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1344 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1345
1346 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1347 injectMotionEvent(mDispatcher,
1348 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1349 .buttonState(0)
1350 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1351 .x(300)
1352 .y(400))
1353 .build()));
1354 window->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1355
1356 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1357 injectMotionEvent(mDispatcher,
1358 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
1359 AINPUT_SOURCE_MOUSE)
1360 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1361 .x(300)
1362 .y(400))
1363 .build()));
1364 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1365 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1366}
1367
Garfield Tan00f511d2019-06-12 16:55:40 -07001368TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
Chris Yea209fde2020-07-22 13:54:51 -07001369 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tan00f511d2019-06-12 16:55:40 -07001370
1371 sp<FakeWindowHandle> windowLeft =
1372 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1373 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001374 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001375 sp<FakeWindowHandle> windowRight =
1376 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1377 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001378 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001379
1380 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1381
Arthur Hung72d8dc32020-03-28 00:48:39 +00001382 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
Garfield Tan00f511d2019-06-12 16:55:40 -07001383
1384 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
1385 // left window. This event should be dispatched to the left window.
1386 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1387 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001388 ADISPLAY_ID_DEFAULT, {610, 400}, {599, 400}));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001389 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -07001390 windowRight->assertNoEvents();
1391}
1392
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001393TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001394 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001395 sp<FakeWindowHandle> window =
1396 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Vishnu Nair47074b82020-08-14 11:54:47 -07001397 window->setFocusable(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001398
Arthur Hung72d8dc32020-03-28 00:48:39 +00001399 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001400 setFocusedWindow(window);
1401
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001402 window->consumeFocusEvent(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001403
1404 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1405 mDispatcher->notifyKey(&keyArgs);
1406
1407 // Window should receive key down event.
1408 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1409
1410 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
1411 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001412 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001413 mDispatcher->notifyDeviceReset(&args);
1414 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
1415 AKEY_EVENT_FLAG_CANCELED);
1416}
1417
1418TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001419 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001420 sp<FakeWindowHandle> window =
1421 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1422
Arthur Hung72d8dc32020-03-28 00:48:39 +00001423 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001424
1425 NotifyMotionArgs motionArgs =
1426 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1427 ADISPLAY_ID_DEFAULT);
1428 mDispatcher->notifyMotion(&motionArgs);
1429
1430 // Window should receive motion down event.
1431 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1432
1433 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
1434 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001435 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001436 mDispatcher->notifyDeviceReset(&args);
1437 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
1438 0 /*expectedFlags*/);
1439}
1440
Svet Ganov5d3bc372020-01-26 23:11:07 -08001441TEST_F(InputDispatcherTest, TransferTouchFocus_OnePointer) {
Chris Yea209fde2020-07-22 13:54:51 -07001442 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001443
1444 // Create a couple of windows
1445 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1446 "First Window", ADISPLAY_ID_DEFAULT);
1447 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1448 "Second Window", ADISPLAY_ID_DEFAULT);
1449
1450 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001451 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001452
1453 // Send down to the first window
1454 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1455 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1456 mDispatcher->notifyMotion(&downMotionArgs);
1457 // Only the first window should get the down event
1458 firstWindow->consumeMotionDown();
1459 secondWindow->assertNoEvents();
1460
1461 // Transfer touch focus to the second window
1462 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1463 // The first window gets cancel and the second gets down
1464 firstWindow->consumeMotionCancel();
1465 secondWindow->consumeMotionDown();
1466
1467 // Send up event to the second window
1468 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1469 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1470 mDispatcher->notifyMotion(&upMotionArgs);
1471 // The first window gets no events and the second gets up
1472 firstWindow->assertNoEvents();
1473 secondWindow->consumeMotionUp();
1474}
1475
1476TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointerNoSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001477 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001478
1479 PointF touchPoint = {10, 10};
1480
1481 // Create a couple of windows
1482 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1483 "First Window", ADISPLAY_ID_DEFAULT);
1484 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1485 "Second Window", ADISPLAY_ID_DEFAULT);
1486
1487 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001488 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001489
1490 // Send down to the first window
1491 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1492 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint});
1493 mDispatcher->notifyMotion(&downMotionArgs);
1494 // Only the first window should get the down event
1495 firstWindow->consumeMotionDown();
1496 secondWindow->assertNoEvents();
1497
1498 // Send pointer down to the first window
1499 NotifyMotionArgs pointerDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1500 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1501 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1502 mDispatcher->notifyMotion(&pointerDownMotionArgs);
1503 // Only the first window should get the pointer down event
1504 firstWindow->consumeMotionPointerDown(1);
1505 secondWindow->assertNoEvents();
1506
1507 // Transfer touch focus to the second window
1508 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1509 // The first window gets cancel and the second gets down and pointer down
1510 firstWindow->consumeMotionCancel();
1511 secondWindow->consumeMotionDown();
1512 secondWindow->consumeMotionPointerDown(1);
1513
1514 // Send pointer up to the second window
1515 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1516 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1517 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1518 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1519 // The first window gets nothing and the second gets pointer up
1520 firstWindow->assertNoEvents();
1521 secondWindow->consumeMotionPointerUp(1);
1522
1523 // Send up event to the second window
1524 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1525 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1526 mDispatcher->notifyMotion(&upMotionArgs);
1527 // The first window gets nothing and the second gets up
1528 firstWindow->assertNoEvents();
1529 secondWindow->consumeMotionUp();
1530}
1531
1532TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointersSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001533 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001534
1535 // Create a non touch modal window that supports split touch
1536 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1537 "First Window", ADISPLAY_ID_DEFAULT);
1538 firstWindow->setFrame(Rect(0, 0, 600, 400));
Michael Wright44753b12020-07-08 13:48:11 +01001539 firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1540 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001541
1542 // Create a non touch modal window that supports split touch
1543 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1544 "Second Window", ADISPLAY_ID_DEFAULT);
1545 secondWindow->setFrame(Rect(0, 400, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001546 secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1547 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001548
1549 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001550 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001551
1552 PointF pointInFirst = {300, 200};
1553 PointF pointInSecond = {300, 600};
1554
1555 // Send down to the first window
1556 NotifyMotionArgs firstDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1557 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst});
1558 mDispatcher->notifyMotion(&firstDownMotionArgs);
1559 // Only the first window should get the down event
1560 firstWindow->consumeMotionDown();
1561 secondWindow->assertNoEvents();
1562
1563 // Send down to the second window
1564 NotifyMotionArgs secondDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1565 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1566 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1567 mDispatcher->notifyMotion(&secondDownMotionArgs);
1568 // The first window gets a move and the second a down
1569 firstWindow->consumeMotionMove();
1570 secondWindow->consumeMotionDown();
1571
1572 // Transfer touch focus to the second window
1573 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1574 // The first window gets cancel and the new gets pointer down (it already saw down)
1575 firstWindow->consumeMotionCancel();
1576 secondWindow->consumeMotionPointerDown(1);
1577
1578 // Send pointer up to the second window
1579 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1580 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1581 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1582 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1583 // The first window gets nothing and the second gets pointer up
1584 firstWindow->assertNoEvents();
1585 secondWindow->consumeMotionPointerUp(1);
1586
1587 // Send up event to the second window
1588 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1589 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1590 mDispatcher->notifyMotion(&upMotionArgs);
1591 // The first window gets nothing and the second gets up
1592 firstWindow->assertNoEvents();
1593 secondWindow->consumeMotionUp();
1594}
1595
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001596TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001597 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001598 sp<FakeWindowHandle> window =
1599 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1600
Vishnu Nair47074b82020-08-14 11:54:47 -07001601 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001602 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001603 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001604
1605 window->consumeFocusEvent(true);
1606
1607 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1608 mDispatcher->notifyKey(&keyArgs);
1609
1610 // Window should receive key down event.
1611 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1612}
1613
1614TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001615 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001616 sp<FakeWindowHandle> window =
1617 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1618
Arthur Hung72d8dc32020-03-28 00:48:39 +00001619 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001620
1621 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1622 mDispatcher->notifyKey(&keyArgs);
1623 mDispatcher->waitForIdle();
1624
1625 window->assertNoEvents();
1626}
1627
1628// If a window is touchable, but does not have focus, it should receive motion events, but not keys
1629TEST_F(InputDispatcherTest, UnfocusedWindow_ReceivesMotionsButNotKeys) {
Chris Yea209fde2020-07-22 13:54:51 -07001630 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001631 sp<FakeWindowHandle> window =
1632 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1633
Arthur Hung72d8dc32020-03-28 00:48:39 +00001634 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001635
1636 // Send key
1637 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1638 mDispatcher->notifyKey(&keyArgs);
1639 // Send motion
1640 NotifyMotionArgs motionArgs =
1641 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1642 ADISPLAY_ID_DEFAULT);
1643 mDispatcher->notifyMotion(&motionArgs);
1644
1645 // Window should receive only the motion event
1646 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1647 window->assertNoEvents(); // Key event or focus event will not be received
1648}
1649
chaviwd1c23182019-12-20 18:44:56 -08001650class FakeMonitorReceiver {
Michael Wright3a240c42019-12-10 20:53:41 +00001651public:
1652 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
chaviwd1c23182019-12-20 18:44:56 -08001653 int32_t displayId, bool isGestureMonitor = false) {
Garfield Tan15601662020-09-22 15:32:38 -07001654 base::Result<std::unique_ptr<InputChannel>> channel =
1655 dispatcher->createInputMonitor(displayId, isGestureMonitor, name);
1656 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
Michael Wright3a240c42019-12-10 20:53:41 +00001657 }
1658
chaviwd1c23182019-12-20 18:44:56 -08001659 sp<IBinder> getToken() { return mInputReceiver->getToken(); }
1660
1661 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1662 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN,
1663 expectedDisplayId, expectedFlags);
1664 }
1665
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001666 std::optional<int32_t> receiveEvent() { return mInputReceiver->receiveEvent(); }
1667
1668 void finishEvent(uint32_t consumeSeq) { return mInputReceiver->finishEvent(consumeSeq); }
1669
chaviwd1c23182019-12-20 18:44:56 -08001670 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1671 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN,
1672 expectedDisplayId, expectedFlags);
1673 }
1674
1675 void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1676 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP,
1677 expectedDisplayId, expectedFlags);
1678 }
1679
1680 void assertNoEvents() { mInputReceiver->assertNoEvents(); }
1681
1682private:
1683 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Michael Wright3a240c42019-12-10 20:53:41 +00001684};
1685
1686// Tests for gesture monitors
1687TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001688 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001689 sp<FakeWindowHandle> window =
1690 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001691 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001692
chaviwd1c23182019-12-20 18:44:56 -08001693 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1694 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001695
1696 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1697 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1698 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1699 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001700 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001701}
1702
1703TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001704 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001705 sp<FakeWindowHandle> window =
1706 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1707
1708 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001709 window->setFocusable(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001710
Arthur Hung72d8dc32020-03-28 00:48:39 +00001711 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001712 setFocusedWindow(window);
1713
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001714 window->consumeFocusEvent(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001715
chaviwd1c23182019-12-20 18:44:56 -08001716 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1717 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001718
1719 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1720 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1721 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001722 monitor.assertNoEvents();
Michael Wright3a240c42019-12-10 20:53:41 +00001723}
1724
1725TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001726 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001727 sp<FakeWindowHandle> window =
1728 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001729 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001730
chaviwd1c23182019-12-20 18:44:56 -08001731 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1732 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001733
1734 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1735 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1736 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1737 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001738 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001739
1740 window->releaseChannel();
1741
chaviwd1c23182019-12-20 18:44:56 -08001742 mDispatcher->pilferPointers(monitor.getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00001743
1744 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1745 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1746 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwd1c23182019-12-20 18:44:56 -08001747 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001748}
1749
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001750TEST_F(InputDispatcherTest, UnresponsiveGestureMonitor_GetsAnr) {
1751 FakeMonitorReceiver monitor =
1752 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
1753 true /*isGestureMonitor*/);
1754
1755 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1756 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT));
1757 std::optional<uint32_t> consumeSeq = monitor.receiveEvent();
1758 ASSERT_TRUE(consumeSeq);
1759
1760 mFakePolicy->assertNotifyAnrWasCalled(DISPATCHING_TIMEOUT, nullptr, monitor.getToken());
1761 monitor.finishEvent(*consumeSeq);
1762 ASSERT_TRUE(mDispatcher->waitForIdle());
1763}
1764
chaviw81e2bb92019-12-18 15:03:51 -08001765TEST_F(InputDispatcherTest, TestMoveEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001766 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
chaviw81e2bb92019-12-18 15:03:51 -08001767 sp<FakeWindowHandle> window =
1768 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1769
Arthur Hung72d8dc32020-03-28 00:48:39 +00001770 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
chaviw81e2bb92019-12-18 15:03:51 -08001771
1772 NotifyMotionArgs motionArgs =
1773 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1774 ADISPLAY_ID_DEFAULT);
1775
1776 mDispatcher->notifyMotion(&motionArgs);
1777 // Window should receive motion down event.
1778 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1779
1780 motionArgs.action = AMOTION_EVENT_ACTION_MOVE;
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001781 motionArgs.id += 1;
chaviw81e2bb92019-12-18 15:03:51 -08001782 motionArgs.eventTime = systemTime(SYSTEM_TIME_MONOTONIC);
1783 motionArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
1784 motionArgs.pointerCoords[0].getX() - 10);
1785
1786 mDispatcher->notifyMotion(&motionArgs);
1787 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, ADISPLAY_ID_DEFAULT,
1788 0 /*expectedFlags*/);
1789}
1790
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001791/**
1792 * Dispatcher has touch mode enabled by default. Typically, the policy overrides that value to
1793 * the device default right away. In the test scenario, we check both the default value,
1794 * and the action of enabling / disabling.
1795 */
1796TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
Chris Yea209fde2020-07-22 13:54:51 -07001797 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001798 sp<FakeWindowHandle> window =
1799 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1800
1801 // Set focused application.
1802 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001803 window->setFocusable(true);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001804
1805 SCOPED_TRACE("Check default value of touch mode");
Arthur Hung72d8dc32020-03-28 00:48:39 +00001806 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001807 setFocusedWindow(window);
1808
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001809 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1810
1811 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001812 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001813 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001814 window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
1815
1816 SCOPED_TRACE("Disable touch mode");
1817 mDispatcher->setInTouchMode(false);
Vishnu Nair47074b82020-08-14 11:54:47 -07001818 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001819 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001820 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001821 window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
1822
1823 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001824 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001825 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001826 window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
1827
1828 SCOPED_TRACE("Enable touch mode again");
1829 mDispatcher->setInTouchMode(true);
Vishnu Nair47074b82020-08-14 11:54:47 -07001830 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001831 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001832 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001833 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1834
1835 window->assertNoEvents();
1836}
1837
Gang Wange9087892020-01-07 12:17:14 -05001838TEST_F(InputDispatcherTest, VerifyInputEvent_KeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001839 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Gang Wange9087892020-01-07 12:17:14 -05001840 sp<FakeWindowHandle> window =
1841 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1842
1843 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001844 window->setFocusable(true);
Gang Wange9087892020-01-07 12:17:14 -05001845
Arthur Hung72d8dc32020-03-28 00:48:39 +00001846 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001847 setFocusedWindow(window);
1848
Gang Wange9087892020-01-07 12:17:14 -05001849 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1850
1851 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1852 mDispatcher->notifyKey(&keyArgs);
1853
1854 InputEvent* event = window->consume();
1855 ASSERT_NE(event, nullptr);
1856
1857 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1858 ASSERT_NE(verified, nullptr);
1859 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::KEY);
1860
1861 ASSERT_EQ(keyArgs.eventTime, verified->eventTimeNanos);
1862 ASSERT_EQ(keyArgs.deviceId, verified->deviceId);
1863 ASSERT_EQ(keyArgs.source, verified->source);
1864 ASSERT_EQ(keyArgs.displayId, verified->displayId);
1865
1866 const VerifiedKeyEvent& verifiedKey = static_cast<const VerifiedKeyEvent&>(*verified);
1867
1868 ASSERT_EQ(keyArgs.action, verifiedKey.action);
1869 ASSERT_EQ(keyArgs.downTime, verifiedKey.downTimeNanos);
Gang Wange9087892020-01-07 12:17:14 -05001870 ASSERT_EQ(keyArgs.flags & VERIFIED_KEY_EVENT_FLAGS, verifiedKey.flags);
1871 ASSERT_EQ(keyArgs.keyCode, verifiedKey.keyCode);
1872 ASSERT_EQ(keyArgs.scanCode, verifiedKey.scanCode);
1873 ASSERT_EQ(keyArgs.metaState, verifiedKey.metaState);
1874 ASSERT_EQ(0, verifiedKey.repeatCount);
1875}
1876
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001877TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001878 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001879 sp<FakeWindowHandle> window =
1880 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1881
1882 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1883
Arthur Hung72d8dc32020-03-28 00:48:39 +00001884 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001885
1886 NotifyMotionArgs motionArgs =
1887 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1888 ADISPLAY_ID_DEFAULT);
1889 mDispatcher->notifyMotion(&motionArgs);
1890
1891 InputEvent* event = window->consume();
1892 ASSERT_NE(event, nullptr);
1893
1894 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1895 ASSERT_NE(verified, nullptr);
1896 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::MOTION);
1897
1898 EXPECT_EQ(motionArgs.eventTime, verified->eventTimeNanos);
1899 EXPECT_EQ(motionArgs.deviceId, verified->deviceId);
1900 EXPECT_EQ(motionArgs.source, verified->source);
1901 EXPECT_EQ(motionArgs.displayId, verified->displayId);
1902
1903 const VerifiedMotionEvent& verifiedMotion = static_cast<const VerifiedMotionEvent&>(*verified);
1904
1905 EXPECT_EQ(motionArgs.pointerCoords[0].getX(), verifiedMotion.rawX);
1906 EXPECT_EQ(motionArgs.pointerCoords[0].getY(), verifiedMotion.rawY);
1907 EXPECT_EQ(motionArgs.action & AMOTION_EVENT_ACTION_MASK, verifiedMotion.actionMasked);
1908 EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos);
1909 EXPECT_EQ(motionArgs.flags & VERIFIED_MOTION_EVENT_FLAGS, verifiedMotion.flags);
1910 EXPECT_EQ(motionArgs.metaState, verifiedMotion.metaState);
1911 EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState);
1912}
1913
chaviw09c8d2d2020-08-24 15:48:26 -07001914/**
1915 * Ensure that separate calls to sign the same data are generating the same key.
1916 * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance
1917 * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky
1918 * tests.
1919 */
1920TEST_F(InputDispatcherTest, GeneratedHmac_IsConsistent) {
1921 KeyEvent event = getTestKeyEvent();
1922 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1923
1924 std::array<uint8_t, 32> hmac1 = mDispatcher->sign(verifiedEvent);
1925 std::array<uint8_t, 32> hmac2 = mDispatcher->sign(verifiedEvent);
1926 ASSERT_EQ(hmac1, hmac2);
1927}
1928
1929/**
1930 * Ensure that changes in VerifiedKeyEvent produce a different hmac.
1931 */
1932TEST_F(InputDispatcherTest, GeneratedHmac_ChangesWhenFieldsChange) {
1933 KeyEvent event = getTestKeyEvent();
1934 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1935 std::array<uint8_t, 32> initialHmac = mDispatcher->sign(verifiedEvent);
1936
1937 verifiedEvent.deviceId += 1;
1938 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1939
1940 verifiedEvent.source += 1;
1941 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1942
1943 verifiedEvent.eventTimeNanos += 1;
1944 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1945
1946 verifiedEvent.displayId += 1;
1947 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1948
1949 verifiedEvent.action += 1;
1950 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1951
1952 verifiedEvent.downTimeNanos += 1;
1953 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1954
1955 verifiedEvent.flags += 1;
1956 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1957
1958 verifiedEvent.keyCode += 1;
1959 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1960
1961 verifiedEvent.scanCode += 1;
1962 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1963
1964 verifiedEvent.metaState += 1;
1965 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1966
1967 verifiedEvent.repeatCount += 1;
1968 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1969}
1970
Vishnu Nair958da932020-08-21 17:12:37 -07001971TEST_F(InputDispatcherTest, SetFocusedWindow) {
1972 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
1973 sp<FakeWindowHandle> windowTop =
1974 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
1975 sp<FakeWindowHandle> windowSecond =
1976 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1977 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1978
1979 // Top window is also focusable but is not granted focus.
1980 windowTop->setFocusable(true);
1981 windowSecond->setFocusable(true);
1982 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
1983 setFocusedWindow(windowSecond);
1984
1985 windowSecond->consumeFocusEvent(true);
1986 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1987 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1988
1989 // Focused window should receive event.
1990 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
1991 windowTop->assertNoEvents();
1992}
1993
1994TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestInvalidChannel) {
1995 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
1996 sp<FakeWindowHandle> window =
1997 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
1998 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1999
2000 window->setFocusable(true);
2001 // Release channel for window is no longer valid.
2002 window->releaseChannel();
2003 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2004 setFocusedWindow(window);
2005
2006 // Test inject a key down, should timeout.
2007 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2008 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2009
2010 // window channel is invalid, so it should not receive any input event.
2011 window->assertNoEvents();
2012}
2013
2014TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestNoFocusableWindow) {
2015 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2016 sp<FakeWindowHandle> window =
2017 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2018 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2019
2020 // Window is not focusable.
2021 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2022 setFocusedWindow(window);
2023
2024 // Test inject a key down, should timeout.
2025 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2026 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2027
2028 // window is invalid, so it should not receive any input event.
2029 window->assertNoEvents();
2030}
2031
2032TEST_F(InputDispatcherTest, SetFocusedWindow_CheckFocusedToken) {
2033 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2034 sp<FakeWindowHandle> windowTop =
2035 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
2036 sp<FakeWindowHandle> windowSecond =
2037 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2038 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2039
2040 windowTop->setFocusable(true);
2041 windowSecond->setFocusable(true);
2042 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
2043 setFocusedWindow(windowTop);
2044 windowTop->consumeFocusEvent(true);
2045
2046 setFocusedWindow(windowSecond, windowTop);
2047 windowSecond->consumeFocusEvent(true);
2048 windowTop->consumeFocusEvent(false);
2049
2050 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2051 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2052
2053 // Focused window should receive event.
2054 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
2055}
2056
2057TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestFocusTokenNotFocused) {
2058 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2059 sp<FakeWindowHandle> windowTop =
2060 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
2061 sp<FakeWindowHandle> windowSecond =
2062 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2063 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2064
2065 windowTop->setFocusable(true);
2066 windowSecond->setFocusable(true);
2067 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
2068 setFocusedWindow(windowSecond, windowTop);
2069
2070 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2071 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2072
2073 // Event should be dropped.
2074 windowTop->assertNoEvents();
2075 windowSecond->assertNoEvents();
2076}
2077
2078TEST_F(InputDispatcherTest, SetFocusedWindow_DeferInvisibleWindow) {
2079 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2080 sp<FakeWindowHandle> window =
2081 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2082 sp<FakeWindowHandle> previousFocusedWindow =
2083 new FakeWindowHandle(application, mDispatcher, "previousFocusedWindow",
2084 ADISPLAY_ID_DEFAULT);
2085 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2086
2087 window->setFocusable(true);
2088 previousFocusedWindow->setFocusable(true);
2089 window->setVisible(false);
2090 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window, previousFocusedWindow}}});
2091 setFocusedWindow(previousFocusedWindow);
2092 previousFocusedWindow->consumeFocusEvent(true);
2093
2094 // Requesting focus on invisible window takes focus from currently focused window.
2095 setFocusedWindow(window);
2096 previousFocusedWindow->consumeFocusEvent(false);
2097
2098 // Injected key goes to pending queue.
2099 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2100 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
2101 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
2102
2103 // Window does not get focus event or key down.
2104 window->assertNoEvents();
2105
2106 // Window becomes visible.
2107 window->setVisible(true);
2108 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2109
2110 // Window receives focus event.
2111 window->consumeFocusEvent(true);
2112 // Focused window receives key down.
2113 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2114}
2115
Garfield Tan1c7bc862020-01-28 13:24:04 -08002116class InputDispatcherKeyRepeatTest : public InputDispatcherTest {
2117protected:
2118 static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms
2119 static constexpr nsecs_t KEY_REPEAT_DELAY = 40 * 1000000; // 40 ms
2120
Chris Yea209fde2020-07-22 13:54:51 -07002121 std::shared_ptr<FakeApplicationHandle> mApp;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002122 sp<FakeWindowHandle> mWindow;
2123
2124 virtual void SetUp() override {
2125 mFakePolicy = new FakeInputDispatcherPolicy();
2126 mFakePolicy->setKeyRepeatConfiguration(KEY_REPEAT_TIMEOUT, KEY_REPEAT_DELAY);
2127 mDispatcher = new InputDispatcher(mFakePolicy);
2128 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
2129 ASSERT_EQ(OK, mDispatcher->start());
2130
2131 setUpWindow();
2132 }
2133
2134 void setUpWindow() {
Chris Yea209fde2020-07-22 13:54:51 -07002135 mApp = std::make_shared<FakeApplicationHandle>();
Garfield Tan1c7bc862020-01-28 13:24:04 -08002136 mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
2137
Vishnu Nair47074b82020-08-14 11:54:47 -07002138 mWindow->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002139 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002140 setFocusedWindow(mWindow);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002141 mWindow->consumeFocusEvent(true);
2142 }
2143
Chris Ye2ad95392020-09-01 13:44:44 -07002144 void sendAndConsumeKeyDown(int32_t deviceId) {
Garfield Tan1c7bc862020-01-28 13:24:04 -08002145 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
Chris Ye2ad95392020-09-01 13:44:44 -07002146 keyArgs.deviceId = deviceId;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002147 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Otherwise it won't generate repeat event
2148 mDispatcher->notifyKey(&keyArgs);
2149
2150 // Window should receive key down event.
2151 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2152 }
2153
2154 void expectKeyRepeatOnce(int32_t repeatCount) {
2155 SCOPED_TRACE(StringPrintf("Checking event with repeat count %" PRId32, repeatCount));
2156 InputEvent* repeatEvent = mWindow->consume();
2157 ASSERT_NE(nullptr, repeatEvent);
2158
2159 uint32_t eventType = repeatEvent->getType();
2160 ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, eventType);
2161
2162 KeyEvent* repeatKeyEvent = static_cast<KeyEvent*>(repeatEvent);
2163 uint32_t eventAction = repeatKeyEvent->getAction();
2164 EXPECT_EQ(AKEY_EVENT_ACTION_DOWN, eventAction);
2165 EXPECT_EQ(repeatCount, repeatKeyEvent->getRepeatCount());
2166 }
2167
Chris Ye2ad95392020-09-01 13:44:44 -07002168 void sendAndConsumeKeyUp(int32_t deviceId) {
Garfield Tan1c7bc862020-01-28 13:24:04 -08002169 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
Chris Ye2ad95392020-09-01 13:44:44 -07002170 keyArgs.deviceId = deviceId;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002171 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Unless it won't generate repeat event
2172 mDispatcher->notifyKey(&keyArgs);
2173
2174 // Window should receive key down event.
2175 mWindow->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
2176 0 /*expectedFlags*/);
2177 }
2178};
2179
2180TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeat) {
Chris Ye2ad95392020-09-01 13:44:44 -07002181 sendAndConsumeKeyDown(1 /* deviceId */);
2182 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2183 expectKeyRepeatOnce(repeatCount);
2184 }
2185}
2186
2187TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeatFromTwoDevices) {
2188 sendAndConsumeKeyDown(1 /* deviceId */);
2189 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2190 expectKeyRepeatOnce(repeatCount);
2191 }
2192 sendAndConsumeKeyDown(2 /* deviceId */);
2193 /* repeatCount will start from 1 for deviceId 2 */
Garfield Tan1c7bc862020-01-28 13:24:04 -08002194 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2195 expectKeyRepeatOnce(repeatCount);
2196 }
2197}
2198
2199TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterUp) {
Chris Ye2ad95392020-09-01 13:44:44 -07002200 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002201 expectKeyRepeatOnce(1 /*repeatCount*/);
Chris Ye2ad95392020-09-01 13:44:44 -07002202 sendAndConsumeKeyUp(1 /* deviceId */);
2203 mWindow->assertNoEvents();
2204}
2205
2206TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_KeyRepeatAfterStaleDeviceKeyUp) {
2207 sendAndConsumeKeyDown(1 /* deviceId */);
2208 expectKeyRepeatOnce(1 /*repeatCount*/);
2209 sendAndConsumeKeyDown(2 /* deviceId */);
2210 expectKeyRepeatOnce(1 /*repeatCount*/);
2211 // Stale key up from device 1.
2212 sendAndConsumeKeyUp(1 /* deviceId */);
2213 // Device 2 is still down, keep repeating
2214 expectKeyRepeatOnce(2 /*repeatCount*/);
2215 expectKeyRepeatOnce(3 /*repeatCount*/);
2216 // Device 2 key up
2217 sendAndConsumeKeyUp(2 /* deviceId */);
2218 mWindow->assertNoEvents();
2219}
2220
2221TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_KeyRepeatStopsAfterRepeatingKeyUp) {
2222 sendAndConsumeKeyDown(1 /* deviceId */);
2223 expectKeyRepeatOnce(1 /*repeatCount*/);
2224 sendAndConsumeKeyDown(2 /* deviceId */);
2225 expectKeyRepeatOnce(1 /*repeatCount*/);
2226 // Device 2 which holds the key repeating goes up, expect the repeating to stop.
2227 sendAndConsumeKeyUp(2 /* deviceId */);
2228 // Device 1 still holds key down, but the repeating was already stopped
Garfield Tan1c7bc862020-01-28 13:24:04 -08002229 mWindow->assertNoEvents();
2230}
2231
2232TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseEventIdFromInputDispatcher) {
Chris Ye2ad95392020-09-01 13:44:44 -07002233 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002234 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2235 InputEvent* repeatEvent = mWindow->consume();
2236 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2237 EXPECT_EQ(IdGenerator::Source::INPUT_DISPATCHER,
2238 IdGenerator::getSource(repeatEvent->getId()));
2239 }
2240}
2241
2242TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseUniqueEventId) {
Chris Ye2ad95392020-09-01 13:44:44 -07002243 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002244
2245 std::unordered_set<int32_t> idSet;
2246 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2247 InputEvent* repeatEvent = mWindow->consume();
2248 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2249 int32_t id = repeatEvent->getId();
2250 EXPECT_EQ(idSet.end(), idSet.find(id));
2251 idSet.insert(id);
2252 }
2253}
2254
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002255/* Test InputDispatcher for MultiDisplay */
2256class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
2257public:
2258 static constexpr int32_t SECOND_DISPLAY_ID = 1;
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002259 virtual void SetUp() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002260 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +08002261
Chris Yea209fde2020-07-22 13:54:51 -07002262 application1 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002263 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
2264 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002265
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002266 // Set focus window for primary display, but focused display would be second one.
2267 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
Vishnu Nair47074b82020-08-14 11:54:47 -07002268 windowInPrimary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002269 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002270 setFocusedWindow(windowInPrimary);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002271 windowInPrimary->consumeFocusEvent(true);
Arthur Hungb92218b2018-08-14 12:00:21 +08002272
Chris Yea209fde2020-07-22 13:54:51 -07002273 application2 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002274 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
2275 SECOND_DISPLAY_ID);
2276 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002277 // Set focus display to second one.
2278 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
2279 // Set focus window for second display.
2280 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
Vishnu Nair47074b82020-08-14 11:54:47 -07002281 windowInSecondary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002282 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002283 setFocusedWindow(windowInSecondary);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002284 windowInSecondary->consumeFocusEvent(true);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002285 }
2286
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002287 virtual void TearDown() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002288 InputDispatcherTest::TearDown();
2289
Chris Yea209fde2020-07-22 13:54:51 -07002290 application1.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002291 windowInPrimary.clear();
Chris Yea209fde2020-07-22 13:54:51 -07002292 application2.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002293 windowInSecondary.clear();
2294 }
2295
2296protected:
Chris Yea209fde2020-07-22 13:54:51 -07002297 std::shared_ptr<FakeApplicationHandle> application1;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002298 sp<FakeWindowHandle> windowInPrimary;
Chris Yea209fde2020-07-22 13:54:51 -07002299 std::shared_ptr<FakeApplicationHandle> application2;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002300 sp<FakeWindowHandle> windowInSecondary;
2301};
2302
2303TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
2304 // Test touch down on primary display.
2305 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2306 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08002307 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002308 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08002309 windowInSecondary->assertNoEvents();
2310
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002311 // Test touch down on second display.
2312 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2313 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +08002314 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2315 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002316 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +08002317}
2318
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002319TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002320 // Test inject a key down with display id specified.
2321 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2322 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002323 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +08002324 windowInSecondary->assertNoEvents();
2325
2326 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +08002327 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2328 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2329 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002330 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +08002331
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002332 // Remove all windows in secondary display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002333 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
Arthur Hungb92218b2018-08-14 12:00:21 +08002334
2335 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002336 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
2337 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +08002338
2339 // Test inject a key down, should timeout because of no target window.
2340 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2341 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2342 windowInPrimary->assertNoEvents();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002343 windowInSecondary->consumeFocusEvent(false);
Arthur Hungb92218b2018-08-14 12:00:21 +08002344 windowInSecondary->assertNoEvents();
2345}
2346
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002347// Test per-display input monitors for motion event.
2348TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
chaviwd1c23182019-12-20 18:44:56 -08002349 FakeMonitorReceiver monitorInPrimary =
2350 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2351 FakeMonitorReceiver monitorInSecondary =
2352 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002353
2354 // Test touch down on primary display.
2355 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2356 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
2357 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002358 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08002359 monitorInPrimary.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002360 windowInSecondary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002361 monitorInSecondary.assertNoEvents();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002362
2363 // Test touch down on second display.
2364 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2365 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
2366 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2367 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002368 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002369 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
chaviwd1c23182019-12-20 18:44:56 -08002370 monitorInSecondary.consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002371
2372 // Test inject a non-pointer motion event.
2373 // If specific a display, it will dispatch to the focused window of particular display,
2374 // or it will dispatch to the focused window of focused display.
2375 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2376 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
2377 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2378 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002379 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002380 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002381 monitorInSecondary.consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002382}
2383
2384// Test per-display input monitors for key event.
2385TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
2386 //Input monitor per display.
chaviwd1c23182019-12-20 18:44:56 -08002387 FakeMonitorReceiver monitorInPrimary =
2388 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2389 FakeMonitorReceiver monitorInSecondary =
2390 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002391
2392 // Test inject a key down.
2393 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2394 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2395 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002396 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002397 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002398 monitorInSecondary.consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002399}
2400
Vishnu Nair958da932020-08-21 17:12:37 -07002401TEST_F(InputDispatcherFocusOnTwoDisplaysTest, CanFocusWindowOnUnfocusedDisplay) {
2402 sp<FakeWindowHandle> secondWindowInPrimary =
2403 new FakeWindowHandle(application1, mDispatcher, "D_1_W2", ADISPLAY_ID_DEFAULT);
2404 secondWindowInPrimary->setFocusable(true);
2405 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary, secondWindowInPrimary}}});
2406 setFocusedWindow(secondWindowInPrimary);
2407 windowInPrimary->consumeFocusEvent(false);
2408 secondWindowInPrimary->consumeFocusEvent(true);
2409
2410 // Test inject a key down.
2411 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2412 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2413 windowInPrimary->assertNoEvents();
2414 windowInSecondary->assertNoEvents();
2415 secondWindowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2416}
2417
Jackal Guof9696682018-10-05 12:23:23 +08002418class InputFilterTest : public InputDispatcherTest {
2419protected:
2420 static constexpr int32_t SECOND_DISPLAY_ID = 1;
2421
2422 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
2423 NotifyMotionArgs motionArgs;
2424
2425 motionArgs = generateMotionArgs(
2426 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2427 mDispatcher->notifyMotion(&motionArgs);
2428 motionArgs = generateMotionArgs(
2429 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2430 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002431 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002432 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002433 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002434 } else {
2435 mFakePolicy->assertFilterInputEventWasNotCalled();
2436 }
2437 }
2438
2439 void testNotifyKey(bool expectToBeFiltered) {
2440 NotifyKeyArgs keyArgs;
2441
2442 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
2443 mDispatcher->notifyKey(&keyArgs);
2444 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
2445 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002446 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002447
2448 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002449 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002450 } else {
2451 mFakePolicy->assertFilterInputEventWasNotCalled();
2452 }
2453 }
2454};
2455
2456// Test InputFilter for MotionEvent
2457TEST_F(InputFilterTest, MotionEvent_InputFilter) {
2458 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
2459 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2460 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2461
2462 // Enable InputFilter
2463 mDispatcher->setInputFilterEnabled(true);
2464 // Test touch on both primary and second display, and check if both events are filtered.
2465 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
2466 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
2467
2468 // Disable InputFilter
2469 mDispatcher->setInputFilterEnabled(false);
2470 // Test touch on both primary and second display, and check if both events aren't filtered.
2471 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2472 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2473}
2474
2475// Test InputFilter for KeyEvent
2476TEST_F(InputFilterTest, KeyEvent_InputFilter) {
2477 // Since the InputFilter is disabled by default, check if key event aren't filtered.
2478 testNotifyKey(/*expectToBeFiltered*/ false);
2479
2480 // Enable InputFilter
2481 mDispatcher->setInputFilterEnabled(true);
2482 // Send a key event, and check if it is filtered.
2483 testNotifyKey(/*expectToBeFiltered*/ true);
2484
2485 // Disable InputFilter
2486 mDispatcher->setInputFilterEnabled(false);
2487 // Send a key event, and check if it isn't filtered.
2488 testNotifyKey(/*expectToBeFiltered*/ false);
2489}
2490
chaviwfd6d3512019-03-25 13:23:49 -07002491class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002492 virtual void SetUp() override {
chaviwfd6d3512019-03-25 13:23:49 -07002493 InputDispatcherTest::SetUp();
2494
Chris Yea209fde2020-07-22 13:54:51 -07002495 std::shared_ptr<FakeApplicationHandle> application =
2496 std::make_shared<FakeApplicationHandle>();
chaviwfd6d3512019-03-25 13:23:49 -07002497 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
2498 ADISPLAY_ID_DEFAULT);
2499 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
2500 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2501 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002502 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002503
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002504 mFocusedWindow =
2505 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2506 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01002507 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002508
2509 // Set focused application.
2510 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07002511 mFocusedWindow->setFocusable(true);
chaviwfd6d3512019-03-25 13:23:49 -07002512
2513 // Expect one focus window exist in display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002514 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002515 setFocusedWindow(mFocusedWindow);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002516 mFocusedWindow->consumeFocusEvent(true);
chaviwfd6d3512019-03-25 13:23:49 -07002517 }
2518
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002519 virtual void TearDown() override {
chaviwfd6d3512019-03-25 13:23:49 -07002520 InputDispatcherTest::TearDown();
2521
2522 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002523 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07002524 }
2525
2526protected:
2527 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002528 sp<FakeWindowHandle> mFocusedWindow;
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002529 static constexpr PointF FOCUSED_WINDOW_TOUCH_POINT = {60, 60};
chaviwfd6d3512019-03-25 13:23:49 -07002530};
2531
2532// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2533// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
2534// the onPointerDownOutsideFocus callback.
2535TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002536 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2537 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2538 {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07002539 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002540 mUnfocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002541
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002542 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07002543 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
2544}
2545
2546// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
2547// DOWN on the window that doesn't have focus. Ensure no window received the
2548// onPointerDownOutsideFocus callback.
2549TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002550 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2551 injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07002552 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002553 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002554
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002555 ASSERT_TRUE(mDispatcher->waitForIdle());
2556 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002557}
2558
2559// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
2560// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
2561TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
2562 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2563 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002564 mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07002565
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002566 ASSERT_TRUE(mDispatcher->waitForIdle());
2567 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002568}
2569
2570// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2571// DOWN on the window that already has focus. Ensure no window received the
2572// onPointerDownOutsideFocus callback.
2573TEST_F(InputDispatcherOnPointerDownOutsideFocus,
2574 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002575 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2576 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002577 FOCUSED_WINDOW_TOUCH_POINT))
chaviwfd6d3512019-03-25 13:23:49 -07002578 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002579 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002580
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002581 ASSERT_TRUE(mDispatcher->waitForIdle());
2582 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002583}
2584
chaviwaf87b3e2019-10-01 16:59:28 -07002585// These tests ensures we can send touch events to a single client when there are multiple input
2586// windows that point to the same client token.
2587class InputDispatcherMultiWindowSameTokenTests : public InputDispatcherTest {
2588 virtual void SetUp() override {
2589 InputDispatcherTest::SetUp();
2590
Chris Yea209fde2020-07-22 13:54:51 -07002591 std::shared_ptr<FakeApplicationHandle> application =
2592 std::make_shared<FakeApplicationHandle>();
chaviwaf87b3e2019-10-01 16:59:28 -07002593 mWindow1 = new FakeWindowHandle(application, mDispatcher, "Fake Window 1",
2594 ADISPLAY_ID_DEFAULT);
2595 // Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
2596 // We also need FLAG_SPLIT_TOUCH or we won't be able to get touches for both windows.
Michael Wright44753b12020-07-08 13:48:11 +01002597 mWindow1->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2598 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002599 mWindow1->setFrame(Rect(0, 0, 100, 100));
2600
2601 mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
2602 ADISPLAY_ID_DEFAULT, mWindow1->getToken());
Michael Wright44753b12020-07-08 13:48:11 +01002603 mWindow2->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2604 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002605 mWindow2->setFrame(Rect(100, 100, 200, 200));
2606
Arthur Hung72d8dc32020-03-28 00:48:39 +00002607 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
chaviwaf87b3e2019-10-01 16:59:28 -07002608 }
2609
2610protected:
2611 sp<FakeWindowHandle> mWindow1;
2612 sp<FakeWindowHandle> mWindow2;
2613
2614 // Helper function to convert the point from screen coordinates into the window's space
2615 static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) {
chaviw1ff3d1e2020-07-01 15:53:47 -07002616 vec2 vals = windowInfo->transform.transform(point.x, point.y);
2617 return {vals.x, vals.y};
chaviwaf87b3e2019-10-01 16:59:28 -07002618 }
2619
2620 void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction,
2621 const std::vector<PointF>& points) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002622 const std::string name = window->getName();
chaviwaf87b3e2019-10-01 16:59:28 -07002623 InputEvent* event = window->consume();
2624
2625 ASSERT_NE(nullptr, event) << name.c_str()
2626 << ": consumer should have returned non-NULL event.";
2627
2628 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
2629 << name.c_str() << "expected " << inputEventTypeToString(AINPUT_EVENT_TYPE_MOTION)
2630 << " event, got " << inputEventTypeToString(event->getType()) << " event";
2631
2632 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
2633 EXPECT_EQ(expectedAction, motionEvent.getAction());
2634
2635 for (size_t i = 0; i < points.size(); i++) {
2636 float expectedX = points[i].x;
2637 float expectedY = points[i].y;
2638
2639 EXPECT_EQ(expectedX, motionEvent.getX(i))
2640 << "expected " << expectedX << " for x[" << i << "] coord of " << name.c_str()
2641 << ", got " << motionEvent.getX(i);
2642 EXPECT_EQ(expectedY, motionEvent.getY(i))
2643 << "expected " << expectedY << " for y[" << i << "] coord of " << name.c_str()
2644 << ", got " << motionEvent.getY(i);
2645 }
2646 }
chaviw9eaa22c2020-07-01 16:21:27 -07002647
2648 void touchAndAssertPositions(int32_t action, std::vector<PointF> touchedPoints,
2649 std::vector<PointF> expectedPoints) {
2650 NotifyMotionArgs motionArgs = generateMotionArgs(action, AINPUT_SOURCE_TOUCHSCREEN,
2651 ADISPLAY_ID_DEFAULT, touchedPoints);
2652 mDispatcher->notifyMotion(&motionArgs);
2653
2654 // Always consume from window1 since it's the window that has the InputReceiver
2655 consumeMotionEvent(mWindow1, action, expectedPoints);
2656 }
chaviwaf87b3e2019-10-01 16:59:28 -07002657};
2658
2659TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchSameScale) {
2660 // Touch Window 1
2661 PointF touchedPoint = {10, 10};
2662 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002663 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002664
2665 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002666 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002667
2668 // Touch Window 2
2669 touchedPoint = {150, 150};
2670 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002671 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002672}
2673
chaviw9eaa22c2020-07-01 16:21:27 -07002674TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchDifferentTransform) {
2675 // Set scale value for window2
chaviwaf87b3e2019-10-01 16:59:28 -07002676 mWindow2->setWindowScale(0.5f, 0.5f);
2677
2678 // Touch Window 1
2679 PointF touchedPoint = {10, 10};
2680 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002681 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002682 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002683 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002684
2685 // Touch Window 2
2686 touchedPoint = {150, 150};
2687 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002688 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
2689 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002690
chaviw9eaa22c2020-07-01 16:21:27 -07002691 // Update the transform so rotation is set
2692 mWindow2->setWindowTransform(0, -1, 1, 0);
2693 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
2694 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002695}
2696
chaviw9eaa22c2020-07-01 16:21:27 -07002697TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002698 mWindow2->setWindowScale(0.5f, 0.5f);
2699
2700 // Touch Window 1
2701 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2702 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002703 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002704
2705 // Touch Window 2
2706 int32_t actionPointerDown =
2707 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002708 touchedPoints.push_back(PointF{150, 150});
2709 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2710 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002711
chaviw9eaa22c2020-07-01 16:21:27 -07002712 // Release Window 2
2713 int32_t actionPointerUp =
2714 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2715 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2716 expectedPoints.pop_back();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002717
chaviw9eaa22c2020-07-01 16:21:27 -07002718 // Update the transform so rotation is set for Window 2
2719 mWindow2->setWindowTransform(0, -1, 1, 0);
2720 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2721 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002722}
2723
chaviw9eaa22c2020-07-01 16:21:27 -07002724TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchMoveDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002725 mWindow2->setWindowScale(0.5f, 0.5f);
2726
2727 // Touch Window 1
2728 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2729 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002730 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002731
2732 // Touch Window 2
2733 int32_t actionPointerDown =
2734 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002735 touchedPoints.push_back(PointF{150, 150});
2736 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002737
chaviw9eaa22c2020-07-01 16:21:27 -07002738 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002739
2740 // Move both windows
2741 touchedPoints = {{20, 20}, {175, 175}};
2742 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2743 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2744
chaviw9eaa22c2020-07-01 16:21:27 -07002745 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002746
chaviw9eaa22c2020-07-01 16:21:27 -07002747 // Release Window 2
2748 int32_t actionPointerUp =
2749 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2750 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2751 expectedPoints.pop_back();
2752
2753 // Touch Window 2
2754 mWindow2->setWindowTransform(0, -1, 1, 0);
2755 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2756 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
2757
2758 // Move both windows
2759 touchedPoints = {{20, 20}, {175, 175}};
2760 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2761 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2762
2763 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002764}
2765
2766TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithScale) {
2767 mWindow1->setWindowScale(0.5f, 0.5f);
2768
2769 // Touch Window 1
2770 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2771 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002772 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002773
2774 // Touch Window 2
2775 int32_t actionPointerDown =
2776 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002777 touchedPoints.push_back(PointF{150, 150});
2778 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002779
chaviw9eaa22c2020-07-01 16:21:27 -07002780 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002781
2782 // Move both windows
2783 touchedPoints = {{20, 20}, {175, 175}};
2784 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2785 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2786
chaviw9eaa22c2020-07-01 16:21:27 -07002787 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002788}
2789
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002790class InputDispatcherSingleWindowAnr : public InputDispatcherTest {
2791 virtual void SetUp() override {
2792 InputDispatcherTest::SetUp();
2793
Chris Yea209fde2020-07-22 13:54:51 -07002794 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002795 mApplication->setDispatchingTimeout(20ms);
2796 mWindow =
2797 new FakeWindowHandle(mApplication, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2798 mWindow->setFrame(Rect(0, 0, 30, 30));
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05002799 mWindow->setDispatchingTimeout(30ms);
Vishnu Nair47074b82020-08-14 11:54:47 -07002800 mWindow->setFocusable(true);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002801 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2802 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002803 mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002804
2805 // Set focused application.
2806 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
2807
2808 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002809 setFocusedWindow(mWindow);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002810 mWindow->consumeFocusEvent(true);
2811 }
2812
2813 virtual void TearDown() override {
2814 InputDispatcherTest::TearDown();
2815 mWindow.clear();
2816 }
2817
2818protected:
Chris Yea209fde2020-07-22 13:54:51 -07002819 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002820 sp<FakeWindowHandle> mWindow;
2821 static constexpr PointF WINDOW_LOCATION = {20, 20};
2822
2823 void tapOnWindow() {
2824 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2825 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2826 WINDOW_LOCATION));
2827 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2828 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2829 WINDOW_LOCATION));
2830 }
2831};
2832
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002833// Send a tap and respond, which should not cause an ANR.
2834TEST_F(InputDispatcherSingleWindowAnr, WhenTouchIsConsumed_NoAnr) {
2835 tapOnWindow();
2836 mWindow->consumeMotionDown();
2837 mWindow->consumeMotionUp();
2838 ASSERT_TRUE(mDispatcher->waitForIdle());
2839 mFakePolicy->assertNotifyAnrWasNotCalled();
2840}
2841
2842// Send a regular key and respond, which should not cause an ANR.
2843TEST_F(InputDispatcherSingleWindowAnr, WhenKeyIsConsumed_NoAnr) {
2844 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
2845 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
2846 ASSERT_TRUE(mDispatcher->waitForIdle());
2847 mFakePolicy->assertNotifyAnrWasNotCalled();
2848}
2849
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05002850TEST_F(InputDispatcherSingleWindowAnr, WhenFocusedApplicationChanges_NoAnr) {
2851 mWindow->setFocusable(false);
2852 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2853 mWindow->consumeFocusEvent(false);
2854
2855 int32_t result =
2856 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
2857 INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
2858 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
2859 // Key will not go to window because we have no focused window.
2860 // The 'no focused window' ANR timer should start instead.
2861
2862 // Now, the focused application goes away.
2863 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, nullptr);
2864 // The key should get dropped and there should be no ANR.
2865
2866 ASSERT_TRUE(mDispatcher->waitForIdle());
2867 mFakePolicy->assertNotifyAnrWasNotCalled();
2868}
2869
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002870// Send an event to the app and have the app not respond right away.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002871// When ANR is raised, policy will tell the dispatcher to cancel the events for that window.
2872// So InputDispatcher will enqueue ACTION_CANCEL event as well.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002873TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) {
2874 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2875 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2876 WINDOW_LOCATION));
2877
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002878 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent(); // ACTION_DOWN
2879 ASSERT_TRUE(sequenceNum);
2880 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2881 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002882
2883 // The remaining lines are not really needed for the test, but kept as a sanity check
2884 mWindow->finishEvent(*sequenceNum);
2885 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
2886 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002887 ASSERT_TRUE(mDispatcher->waitForIdle());
2888}
2889
2890// Send a key to the app and have the app not respond right away.
2891TEST_F(InputDispatcherSingleWindowAnr, OnKeyDown_BasicAnr) {
2892 // Inject a key, and don't respond - expect that ANR is called.
2893 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
2894 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent();
2895 ASSERT_TRUE(sequenceNum);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002896 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002897 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002898 ASSERT_TRUE(mDispatcher->waitForIdle());
2899}
2900
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002901// We have a focused application, but no focused window
2902TEST_F(InputDispatcherSingleWindowAnr, FocusedApplication_NoFocusedWindow) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002903 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002904 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2905 mWindow->consumeFocusEvent(false);
2906
2907 // taps on the window work as normal
2908 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2909 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2910 WINDOW_LOCATION));
2911 ASSERT_NO_FATAL_FAILURE(mWindow->consumeMotionDown());
2912 mDispatcher->waitForIdle();
2913 mFakePolicy->assertNotifyAnrWasNotCalled();
2914
2915 // Once a focused event arrives, we get an ANR for this application
2916 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2917 // injection times out (instead of failing).
2918 const int32_t result =
2919 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2920 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2921 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2922 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2923 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2924 ASSERT_TRUE(mDispatcher->waitForIdle());
2925}
2926
2927// We have a focused application, but no focused window
2928// If the policy wants to keep waiting on the focused window to be added, make sure
2929// that this timeout extension is honored and ANR is raised again.
2930TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_ExtendsAnr) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002931 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002932 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2933 mWindow->consumeFocusEvent(false);
2934 const std::chrono::duration timeout = 5ms;
2935 mFakePolicy->setAnrTimeout(timeout);
2936
2937 // Once a focused event arrives, we get an ANR for this application
2938 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2939 // injection times out (instead of failing).
2940 const int32_t result =
2941 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2942 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2943 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2944 const std::chrono::duration appTimeout =
2945 mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2946 mFakePolicy->assertNotifyAnrWasCalled(appTimeout, mApplication, nullptr /*windowToken*/);
2947
2948 // After the extended time has passed, ANR should be raised again
2949 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2950
2951 // If we stop extending the timeout, dispatcher should go to idle.
2952 // Another ANR may be raised during this time
2953 mFakePolicy->setAnrTimeout(0ms);
2954 ASSERT_TRUE(mDispatcher->waitForIdle());
2955}
2956
2957// We have a focused application, but no focused window
2958TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_DropsFocusedEvents) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002959 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002960 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2961 mWindow->consumeFocusEvent(false);
2962
2963 // Once a focused event arrives, we get an ANR for this application
2964 const int32_t result =
2965 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2966 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2967 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2968
2969 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2970 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2971
2972 // Future focused events get dropped right away
2973 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, injectKeyDown(mDispatcher));
2974 ASSERT_TRUE(mDispatcher->waitForIdle());
2975 mWindow->assertNoEvents();
2976}
2977
2978/**
2979 * Ensure that the implementation is valid. Since we are using multiset to keep track of the
2980 * ANR timeouts, we are allowing entries with identical timestamps in the same connection.
2981 * If we process 1 of the events, but ANR on the second event with the same timestamp,
2982 * the ANR mechanism should still work.
2983 *
2984 * In this test, we are injecting DOWN and UP events with the same timestamps, and acknowledging the
2985 * DOWN event, while not responding on the second one.
2986 */
2987TEST_F(InputDispatcherSingleWindowAnr, Anr_HandlesEventsWithIdenticalTimestamps) {
2988 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
2989 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2990 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
2991 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
2992 AMOTION_EVENT_INVALID_CURSOR_POSITION},
2993 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
2994
2995 // Now send ACTION_UP, with identical timestamp
2996 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
2997 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
2998 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
2999 AMOTION_EVENT_INVALID_CURSOR_POSITION},
3000 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
3001
3002 // We have now sent down and up. Let's consume first event and then ANR on the second.
3003 mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
3004 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3005 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3006}
3007
3008// If an app is not responding to a key event, gesture monitors should continue to receive
3009// new motion events
3010TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnKey) {
3011 FakeMonitorReceiver monitor =
3012 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
3013 true /*isGestureMonitor*/);
3014
3015 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT));
3016 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3017 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher, ADISPLAY_ID_DEFAULT));
3018
3019 // Stuck on the ACTION_UP
3020 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3021 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
3022
3023 // New tap will go to the gesture monitor, but not to the window
3024 tapOnWindow();
3025 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3026 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3027
3028 mWindow->consumeKeyUp(ADISPLAY_ID_DEFAULT); // still the previous motion
3029 mDispatcher->waitForIdle();
3030 mWindow->assertNoEvents();
3031 monitor.assertNoEvents();
3032}
3033
3034// If an app is not responding to a motion event, gesture monitors should continue to receive
3035// new motion events
3036TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnMotion) {
3037 FakeMonitorReceiver monitor =
3038 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
3039 true /*isGestureMonitor*/);
3040
3041 tapOnWindow();
3042 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3043 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3044
3045 mWindow->consumeMotionDown();
3046 // Stuck on the ACTION_UP
3047 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3048 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
3049
3050 // New tap will go to the gesture monitor, but not to the window
3051 tapOnWindow();
3052 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3053 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3054
3055 mWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT); // still the previous motion
3056 mDispatcher->waitForIdle();
3057 mWindow->assertNoEvents();
3058 monitor.assertNoEvents();
3059}
3060
3061// If a window is unresponsive, then you get anr. if the window later catches up and starts to
3062// process events, you don't get an anr. When the window later becomes unresponsive again, you
3063// get an ANR again.
3064// 1. tap -> block on ACTION_UP -> receive ANR
3065// 2. consume all pending events (= queue becomes healthy again)
3066// 3. tap again -> block on ACTION_UP again -> receive ANR second time
3067TEST_F(InputDispatcherSingleWindowAnr, SameWindow_CanReceiveAnrTwice) {
3068 tapOnWindow();
3069
3070 mWindow->consumeMotionDown();
3071 // Block on ACTION_UP
3072 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3073 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3074 mWindow->consumeMotionUp(); // Now the connection should be healthy again
3075 mDispatcher->waitForIdle();
3076 mWindow->assertNoEvents();
3077
3078 tapOnWindow();
3079 mWindow->consumeMotionDown();
3080 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3081 mWindow->consumeMotionUp();
3082
3083 mDispatcher->waitForIdle();
3084 mWindow->assertNoEvents();
3085}
3086
3087// If the policy tells us to raise ANR again after some time, ensure that the timeout extension
3088// is honored
3089TEST_F(InputDispatcherSingleWindowAnr, Policy_CanExtendTimeout) {
3090 const std::chrono::duration timeout = 5ms;
3091 mFakePolicy->setAnrTimeout(timeout);
3092
3093 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3094 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3095 WINDOW_LOCATION));
3096
3097 const std::chrono::duration windowTimeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3098 mFakePolicy->assertNotifyAnrWasCalled(windowTimeout, nullptr /*application*/,
3099 mWindow->getToken());
3100
3101 // Since the policy wanted to extend ANR, make sure it is called again after the extension
3102 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3103 mFakePolicy->setAnrTimeout(0ms);
3104 std::this_thread::sleep_for(windowTimeout);
3105 // We are not checking if ANR has been called, because it may have been called again by the
3106 // time we set the timeout to 0
3107
3108 // When the policy finally says stop, we should get ACTION_CANCEL
3109 mWindow->consumeMotionDown();
3110 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
3111 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3112 mWindow->assertNoEvents();
3113}
3114
3115/**
3116 * If a window is processing a motion event, and then a key event comes in, the key event should
3117 * not to to the focused window until the motion is processed.
3118 *
3119 * Warning!!!
3120 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
3121 * and the injection timeout that we specify when injecting the key.
3122 * We must have the injection timeout (10ms) be smaller than
3123 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
3124 *
3125 * If that value changes, this test should also change.
3126 */
3127TEST_F(InputDispatcherSingleWindowAnr, Key_StaysPendingWhileMotionIsProcessed) {
3128 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
3129 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
3130
3131 tapOnWindow();
3132 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
3133 ASSERT_TRUE(downSequenceNum);
3134 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
3135 ASSERT_TRUE(upSequenceNum);
3136 // Don't finish the events yet, and send a key
3137 // Injection will "succeed" because we will eventually give up and send the key to the focused
3138 // window even if motions are still being processed. But because the injection timeout is short,
3139 // we will receive INJECTION_TIMED_OUT as the result.
3140
3141 int32_t result =
3142 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
3143 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
3144 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
3145 // Key will not be sent to the window, yet, because the window is still processing events
3146 // and the key remains pending, waiting for the touch events to be processed
3147 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
3148 ASSERT_FALSE(keySequenceNum);
3149
3150 std::this_thread::sleep_for(500ms);
3151 // if we wait long enough though, dispatcher will give up, and still send the key
3152 // to the focused window, even though we have not yet finished the motion event
3153 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3154 mWindow->finishEvent(*downSequenceNum);
3155 mWindow->finishEvent(*upSequenceNum);
3156}
3157
3158/**
3159 * If a window is processing a motion event, and then a key event comes in, the key event should
3160 * not go to the focused window until the motion is processed.
3161 * If then a new motion comes in, then the pending key event should be going to the currently
3162 * focused window right away.
3163 */
3164TEST_F(InputDispatcherSingleWindowAnr,
3165 PendingKey_IsDroppedWhileMotionIsProcessedAndNewTouchComesIn) {
3166 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
3167 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
3168
3169 tapOnWindow();
3170 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
3171 ASSERT_TRUE(downSequenceNum);
3172 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
3173 ASSERT_TRUE(upSequenceNum);
3174 // Don't finish the events yet, and send a key
3175 // Injection is async, so it will succeed
3176 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3177 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
3178 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
3179 // At this point, key is still pending, and should not be sent to the application yet.
3180 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
3181 ASSERT_FALSE(keySequenceNum);
3182
3183 // Now tap down again. It should cause the pending key to go to the focused window right away.
3184 tapOnWindow();
3185 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT); // it doesn't matter that we haven't ack'd
3186 // the other events yet. We can finish events in any order.
3187 mWindow->finishEvent(*downSequenceNum); // first tap's ACTION_DOWN
3188 mWindow->finishEvent(*upSequenceNum); // first tap's ACTION_UP
3189 mWindow->consumeMotionDown();
3190 mWindow->consumeMotionUp();
3191 mWindow->assertNoEvents();
3192}
3193
3194class InputDispatcherMultiWindowAnr : public InputDispatcherTest {
3195 virtual void SetUp() override {
3196 InputDispatcherTest::SetUp();
3197
Chris Yea209fde2020-07-22 13:54:51 -07003198 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003199 mApplication->setDispatchingTimeout(10ms);
3200 mUnfocusedWindow =
3201 new FakeWindowHandle(mApplication, mDispatcher, "Unfocused", ADISPLAY_ID_DEFAULT);
3202 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
3203 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
3204 // window.
3205 // Adding FLAG_WATCH_OUTSIDE_TOUCH to receive ACTION_OUTSIDE when another window is tapped
Michael Wright44753b12020-07-08 13:48:11 +01003206 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3207 InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
3208 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003209
3210 mFocusedWindow =
3211 new FakeWindowHandle(mApplication, mDispatcher, "Focused", ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05003212 mFocusedWindow->setDispatchingTimeout(30ms);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003213 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01003214 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3215 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003216
3217 // Set focused application.
3218 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
Vishnu Nair47074b82020-08-14 11:54:47 -07003219 mFocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003220
3221 // Expect one focus window exist in display.
3222 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07003223 setFocusedWindow(mFocusedWindow);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003224 mFocusedWindow->consumeFocusEvent(true);
3225 }
3226
3227 virtual void TearDown() override {
3228 InputDispatcherTest::TearDown();
3229
3230 mUnfocusedWindow.clear();
3231 mFocusedWindow.clear();
3232 }
3233
3234protected:
Chris Yea209fde2020-07-22 13:54:51 -07003235 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003236 sp<FakeWindowHandle> mUnfocusedWindow;
3237 sp<FakeWindowHandle> mFocusedWindow;
3238 static constexpr PointF UNFOCUSED_WINDOW_LOCATION = {20, 20};
3239 static constexpr PointF FOCUSED_WINDOW_LOCATION = {75, 75};
3240 static constexpr PointF LOCATION_OUTSIDE_ALL_WINDOWS = {40, 40};
3241
3242 void tapOnFocusedWindow() { tap(FOCUSED_WINDOW_LOCATION); }
3243
3244 void tapOnUnfocusedWindow() { tap(UNFOCUSED_WINDOW_LOCATION); }
3245
3246private:
3247 void tap(const PointF& location) {
3248 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3249 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3250 location));
3251 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3252 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3253 location));
3254 }
3255};
3256
3257// If we have 2 windows that are both unresponsive, the one with the shortest timeout
3258// should be ANR'd first.
3259TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsive) {
3260 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3261 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3262 FOCUSED_WINDOW_LOCATION))
3263 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3264 mFocusedWindow->consumeMotionDown();
3265 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3266 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3267 // We consumed all events, so no ANR
3268 ASSERT_TRUE(mDispatcher->waitForIdle());
3269 mFakePolicy->assertNotifyAnrWasNotCalled();
3270
3271 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3272 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3273 FOCUSED_WINDOW_LOCATION));
3274 std::optional<uint32_t> unfocusedSequenceNum = mUnfocusedWindow->receiveEvent();
3275 ASSERT_TRUE(unfocusedSequenceNum);
3276 std::optional<uint32_t> focusedSequenceNum = mFocusedWindow->receiveEvent();
3277 ASSERT_TRUE(focusedSequenceNum);
3278
3279 const std::chrono::duration timeout =
3280 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3281 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3282 mFocusedWindow->getToken());
3283
3284 mFocusedWindow->finishEvent(*focusedSequenceNum);
3285 mUnfocusedWindow->finishEvent(*unfocusedSequenceNum);
3286 ASSERT_TRUE(mDispatcher->waitForIdle());
3287}
3288
3289// If we have 2 windows with identical timeouts that are both unresponsive,
3290// it doesn't matter which order they should have ANR.
3291// But we should receive ANR for both.
3292TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsiveWithSameTimeout) {
3293 // Set the timeout for unfocused window to match the focused window
3294 mUnfocusedWindow->setDispatchingTimeout(10ms);
3295 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3296
3297 tapOnFocusedWindow();
3298 // we should have ACTION_DOWN/ACTION_UP on focused window and ACTION_OUTSIDE on unfocused window
Chris Yea209fde2020-07-22 13:54:51 -07003299 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData1 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003300 mFakePolicy->getNotifyAnrData(10ms);
Chris Yea209fde2020-07-22 13:54:51 -07003301 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData2 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003302 mFakePolicy->getNotifyAnrData(0ms);
3303
3304 // We don't know which window will ANR first. But both of them should happen eventually.
3305 ASSERT_TRUE(mFocusedWindow->getToken() == anrData1.second ||
3306 mFocusedWindow->getToken() == anrData2.second);
3307 ASSERT_TRUE(mUnfocusedWindow->getToken() == anrData1.second ||
3308 mUnfocusedWindow->getToken() == anrData2.second);
3309
3310 ASSERT_TRUE(mDispatcher->waitForIdle());
3311 mFakePolicy->assertNotifyAnrWasNotCalled();
3312}
3313
3314// If a window is already not responding, the second tap on the same window should be ignored.
3315// We should also log an error to account for the dropped event (not tested here).
3316// At the same time, FLAG_WATCH_OUTSIDE_TOUCH targets should not receive any events.
3317TEST_F(InputDispatcherMultiWindowAnr, DuringAnr_SecondTapIsIgnored) {
3318 tapOnFocusedWindow();
3319 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3320 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3321 // Receive the events, but don't respond
3322 std::optional<uint32_t> downEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_DOWN
3323 ASSERT_TRUE(downEventSequenceNum);
3324 std::optional<uint32_t> upEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_UP
3325 ASSERT_TRUE(upEventSequenceNum);
3326 const std::chrono::duration timeout =
3327 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3328 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3329 mFocusedWindow->getToken());
3330
3331 // Tap once again
3332 // We cannot use "tapOnFocusedWindow" because it asserts the injection result to be success
3333 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3334 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3335 FOCUSED_WINDOW_LOCATION));
3336 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3337 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3338 FOCUSED_WINDOW_LOCATION));
3339 // Unfocused window does not receive ACTION_OUTSIDE because the tapped window is not a
3340 // valid touch target
3341 mUnfocusedWindow->assertNoEvents();
3342
3343 // Consume the first tap
3344 mFocusedWindow->finishEvent(*downEventSequenceNum);
3345 mFocusedWindow->finishEvent(*upEventSequenceNum);
3346 ASSERT_TRUE(mDispatcher->waitForIdle());
3347 // The second tap did not go to the focused window
3348 mFocusedWindow->assertNoEvents();
3349 // should not have another ANR after the window just became healthy again
3350 mFakePolicy->assertNotifyAnrWasNotCalled();
3351}
3352
3353// If you tap outside of all windows, there will not be ANR
3354TEST_F(InputDispatcherMultiWindowAnr, TapOutsideAllWindows_DoesNotAnr) {
3355 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3356 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3357 LOCATION_OUTSIDE_ALL_WINDOWS));
3358 ASSERT_TRUE(mDispatcher->waitForIdle());
3359 mFakePolicy->assertNotifyAnrWasNotCalled();
3360}
3361
3362// Since the focused window is paused, tapping on it should not produce any events
3363TEST_F(InputDispatcherMultiWindowAnr, Window_CanBePaused) {
3364 mFocusedWindow->setPaused(true);
3365 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3366
3367 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3368 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3369 FOCUSED_WINDOW_LOCATION));
3370
3371 std::this_thread::sleep_for(mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT));
3372 ASSERT_TRUE(mDispatcher->waitForIdle());
3373 // Should not ANR because the window is paused, and touches shouldn't go to it
3374 mFakePolicy->assertNotifyAnrWasNotCalled();
3375
3376 mFocusedWindow->assertNoEvents();
3377 mUnfocusedWindow->assertNoEvents();
3378}
3379
3380/**
3381 * If a window is processing a motion event, and then a key event comes in, the key event should
3382 * not to to the focused window until the motion is processed.
3383 * If a different window becomes focused at this time, the key should go to that window instead.
3384 *
3385 * Warning!!!
3386 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
3387 * and the injection timeout that we specify when injecting the key.
3388 * We must have the injection timeout (10ms) be smaller than
3389 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
3390 *
3391 * If that value changes, this test should also change.
3392 */
3393TEST_F(InputDispatcherMultiWindowAnr, PendingKey_GoesToNewlyFocusedWindow) {
3394 // Set a long ANR timeout to prevent it from triggering
3395 mFocusedWindow->setDispatchingTimeout(2s);
3396 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3397
3398 tapOnUnfocusedWindow();
3399 std::optional<uint32_t> downSequenceNum = mUnfocusedWindow->receiveEvent();
3400 ASSERT_TRUE(downSequenceNum);
3401 std::optional<uint32_t> upSequenceNum = mUnfocusedWindow->receiveEvent();
3402 ASSERT_TRUE(upSequenceNum);
3403 // Don't finish the events yet, and send a key
3404 // Injection will succeed because we will eventually give up and send the key to the focused
3405 // window even if motions are still being processed.
3406
3407 int32_t result =
3408 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
3409 INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
3410 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
3411 // Key will not be sent to the window, yet, because the window is still processing events
3412 // and the key remains pending, waiting for the touch events to be processed
3413 std::optional<uint32_t> keySequenceNum = mFocusedWindow->receiveEvent();
3414 ASSERT_FALSE(keySequenceNum);
3415
3416 // Switch the focus to the "unfocused" window that we tapped. Expect the key to go there
Vishnu Nair47074b82020-08-14 11:54:47 -07003417 mFocusedWindow->setFocusable(false);
3418 mUnfocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003419 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07003420 setFocusedWindow(mUnfocusedWindow);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003421
3422 // Focus events should precede the key events
3423 mUnfocusedWindow->consumeFocusEvent(true);
3424 mFocusedWindow->consumeFocusEvent(false);
3425
3426 // Finish the tap events, which should unblock dispatcher
3427 mUnfocusedWindow->finishEvent(*downSequenceNum);
3428 mUnfocusedWindow->finishEvent(*upSequenceNum);
3429
3430 // Now that all queues are cleared and no backlog in the connections, the key event
3431 // can finally go to the newly focused "mUnfocusedWindow".
3432 mUnfocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3433 mFocusedWindow->assertNoEvents();
3434 mUnfocusedWindow->assertNoEvents();
3435}
3436
3437// When the touch stream is split across 2 windows, and one of them does not respond,
3438// then ANR should be raised and the touch should be canceled for the unresponsive window.
3439// The other window should not be affected by that.
3440TEST_F(InputDispatcherMultiWindowAnr, SplitTouch_SingleWindowAnr) {
3441 // Touch Window 1
3442 NotifyMotionArgs motionArgs =
3443 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3444 ADISPLAY_ID_DEFAULT, {FOCUSED_WINDOW_LOCATION});
3445 mDispatcher->notifyMotion(&motionArgs);
3446 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3447 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3448
3449 // Touch Window 2
3450 int32_t actionPointerDown =
3451 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
3452
3453 motionArgs =
3454 generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3455 {FOCUSED_WINDOW_LOCATION, UNFOCUSED_WINDOW_LOCATION});
3456 mDispatcher->notifyMotion(&motionArgs);
3457
3458 const std::chrono::duration timeout =
3459 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3460 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3461 mFocusedWindow->getToken());
3462
3463 mUnfocusedWindow->consumeMotionDown();
3464 mFocusedWindow->consumeMotionDown();
3465 // Focused window may or may not receive ACTION_MOVE
3466 // But it should definitely receive ACTION_CANCEL due to the ANR
3467 InputEvent* event;
3468 std::optional<int32_t> moveOrCancelSequenceNum = mFocusedWindow->receiveEvent(&event);
3469 ASSERT_TRUE(moveOrCancelSequenceNum);
3470 mFocusedWindow->finishEvent(*moveOrCancelSequenceNum);
3471 ASSERT_NE(nullptr, event);
3472 ASSERT_EQ(event->getType(), AINPUT_EVENT_TYPE_MOTION);
3473 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
3474 if (motionEvent.getAction() == AMOTION_EVENT_ACTION_MOVE) {
3475 mFocusedWindow->consumeMotionCancel();
3476 } else {
3477 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionEvent.getAction());
3478 }
3479
3480 ASSERT_TRUE(mDispatcher->waitForIdle());
3481 mUnfocusedWindow->assertNoEvents();
3482 mFocusedWindow->assertNoEvents();
3483}
3484
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003485// These tests ensure we cannot send touch events to a window that's positioned behind a window
3486// that has feature NO_INPUT_CHANNEL.
3487// Layout:
3488// Top (closest to user)
3489// mNoInputWindow (above all windows)
3490// mBottomWindow
3491// Bottom (furthest from user)
3492class InputDispatcherMultiWindowOcclusionTests : public InputDispatcherTest {
3493 virtual void SetUp() override {
3494 InputDispatcherTest::SetUp();
3495
3496 mApplication = std::make_shared<FakeApplicationHandle>();
3497 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3498 "Window without input channel", ADISPLAY_ID_DEFAULT,
3499 std::make_optional<sp<IBinder>>(nullptr) /*token*/);
3500
3501 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3502 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3503 // It's perfectly valid for this window to not have an associated input channel
3504
3505 mBottomWindow = new FakeWindowHandle(mApplication, mDispatcher, "Bottom window",
3506 ADISPLAY_ID_DEFAULT);
3507 mBottomWindow->setFrame(Rect(0, 0, 100, 100));
3508
3509 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3510 }
3511
3512protected:
3513 std::shared_ptr<FakeApplicationHandle> mApplication;
3514 sp<FakeWindowHandle> mNoInputWindow;
3515 sp<FakeWindowHandle> mBottomWindow;
3516};
3517
3518TEST_F(InputDispatcherMultiWindowOcclusionTests, NoInputChannelFeature_DropsTouches) {
3519 PointF touchedPoint = {10, 10};
3520
3521 NotifyMotionArgs motionArgs =
3522 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3523 ADISPLAY_ID_DEFAULT, {touchedPoint});
3524 mDispatcher->notifyMotion(&motionArgs);
3525
3526 mNoInputWindow->assertNoEvents();
3527 // Even though the window 'mNoInputWindow' positioned above 'mBottomWindow' does not have
3528 // an input channel, it is not marked as FLAG_NOT_TOUCHABLE,
3529 // and therefore should prevent mBottomWindow from receiving touches
3530 mBottomWindow->assertNoEvents();
3531}
3532
3533/**
3534 * If a window has feature NO_INPUT_CHANNEL, and somehow (by mistake) still has an input channel,
3535 * ensure that this window does not receive any touches, and blocks touches to windows underneath.
3536 */
3537TEST_F(InputDispatcherMultiWindowOcclusionTests,
3538 NoInputChannelFeature_DropsTouchesWithValidChannel) {
3539 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3540 "Window with input channel and NO_INPUT_CHANNEL",
3541 ADISPLAY_ID_DEFAULT);
3542
3543 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3544 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3545 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3546
3547 PointF touchedPoint = {10, 10};
3548
3549 NotifyMotionArgs motionArgs =
3550 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3551 ADISPLAY_ID_DEFAULT, {touchedPoint});
3552 mDispatcher->notifyMotion(&motionArgs);
3553
3554 mNoInputWindow->assertNoEvents();
3555 mBottomWindow->assertNoEvents();
3556}
3557
Vishnu Nair958da932020-08-21 17:12:37 -07003558class InputDispatcherMirrorWindowFocusTests : public InputDispatcherTest {
3559protected:
3560 std::shared_ptr<FakeApplicationHandle> mApp;
3561 sp<FakeWindowHandle> mWindow;
3562 sp<FakeWindowHandle> mMirror;
3563
3564 virtual void SetUp() override {
3565 InputDispatcherTest::SetUp();
3566 mApp = std::make_shared<FakeApplicationHandle>();
3567 mWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
3568 mMirror = new FakeWindowHandle(mApp, mDispatcher, "TestWindowMirror", ADISPLAY_ID_DEFAULT,
3569 mWindow->getToken());
3570 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
3571 mWindow->setFocusable(true);
3572 mMirror->setFocusable(true);
3573 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3574 }
3575};
3576
3577TEST_F(InputDispatcherMirrorWindowFocusTests, CanGetFocus) {
3578 // Request focus on a mirrored window
3579 setFocusedWindow(mMirror);
3580
3581 // window gets focused
3582 mWindow->consumeFocusEvent(true);
3583 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3584 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3585 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3586}
3587
3588// A focused & mirrored window remains focused only if the window and its mirror are both
3589// focusable.
3590TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAllWindowsFocusable) {
3591 setFocusedWindow(mMirror);
3592
3593 // window gets focused
3594 mWindow->consumeFocusEvent(true);
3595 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3596 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3597 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3598 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3599 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3600 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3601
3602 mMirror->setFocusable(false);
3603 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3604
3605 // window loses focus since one of the windows associated with the token in not focusable
3606 mWindow->consumeFocusEvent(false);
3607
3608 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3609 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3610 mWindow->assertNoEvents();
3611}
3612
3613// A focused & mirrored window remains focused until the window and its mirror both become
3614// invisible.
3615TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAnyWindowVisible) {
3616 setFocusedWindow(mMirror);
3617
3618 // window gets focused
3619 mWindow->consumeFocusEvent(true);
3620 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3621 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3622 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3623 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3624 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3625 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3626
3627 mMirror->setVisible(false);
3628 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3629
3630 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3631 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3632 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3633 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3634 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3635 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3636
3637 mWindow->setVisible(false);
3638 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3639
3640 // window loses focus only after all windows associated with the token become invisible.
3641 mWindow->consumeFocusEvent(false);
3642
3643 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3644 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3645 mWindow->assertNoEvents();
3646}
3647
3648// A focused & mirrored window remains focused until both windows are removed.
3649TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedWhileWindowsAlive) {
3650 setFocusedWindow(mMirror);
3651
3652 // window gets focused
3653 mWindow->consumeFocusEvent(true);
3654 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3655 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3656 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3657 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3658 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3659 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3660
3661 // single window is removed but the window token remains focused
3662 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mMirror}}});
3663
3664 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3665 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3666 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3667 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3668 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3669 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3670
3671 // Both windows are removed
3672 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {}}});
3673 mWindow->consumeFocusEvent(false);
3674
3675 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3676 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3677 mWindow->assertNoEvents();
3678}
3679
3680// Focus request can be pending until one window becomes visible.
3681TEST_F(InputDispatcherMirrorWindowFocusTests, DeferFocusWhenInvisible) {
3682 // Request focus on an invisible mirror.
3683 mWindow->setVisible(false);
3684 mMirror->setVisible(false);
3685 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3686 setFocusedWindow(mMirror);
3687
3688 // Injected key goes to pending queue.
3689 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3690 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
3691 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
3692
3693 mMirror->setVisible(true);
3694 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3695
3696 // window gets focused
3697 mWindow->consumeFocusEvent(true);
3698 // window gets the pending key event
3699 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3700}
Garfield Tane84e6f92019-08-29 17:28:41 -07003701} // namespace android::inputdispatcher