blob: b7e588c7100e65be959790619f090d69493f4856 [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 Tan400128f2020-09-22 21:53:55 +0000551 explicit FakeInputReceiver(const std::shared_ptr<InputChannel>& clientChannel,
552 const std::string name)
chaviwd1c23182019-12-20 18:44:56 -0800553 : mName(name) {
Garfield Tan400128f2020-09-22 21:53:55 +0000554 mConsumer = std::make_unique<InputConsumer>(clientChannel);
chaviwd1c23182019-12-20 18:44:56 -0800555 }
556
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800557 InputEvent* consume() {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700558 InputEvent* event;
559 std::optional<uint32_t> consumeSeq = receiveEvent(&event);
560 if (!consumeSeq) {
561 return nullptr;
562 }
563 finishEvent(*consumeSeq);
564 return event;
565 }
566
567 /**
568 * Receive an event without acknowledging it.
569 * Return the sequence number that could later be used to send finished signal.
570 */
571 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800572 uint32_t consumeSeq;
573 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800574
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800575 std::chrono::time_point start = std::chrono::steady_clock::now();
576 status_t status = WOULD_BLOCK;
577 while (status == WOULD_BLOCK) {
chaviw81e2bb92019-12-18 15:03:51 -0800578 status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq,
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800579 &event);
580 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
581 if (elapsed > 100ms) {
582 break;
583 }
584 }
585
586 if (status == WOULD_BLOCK) {
587 // Just means there's no event available.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700588 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800589 }
590
591 if (status != OK) {
592 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700593 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800594 }
595 if (event == nullptr) {
596 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700597 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800598 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700599 if (outEvent != nullptr) {
600 *outEvent = event;
601 }
602 return consumeSeq;
603 }
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800604
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700605 /**
606 * To be used together with "receiveEvent" to complete the consumption of an event.
607 */
608 void finishEvent(uint32_t consumeSeq) {
609 const status_t status = mConsumer->sendFinishedSignal(consumeSeq, true);
610 ASSERT_EQ(OK, status) << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800611 }
612
613 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
614 int32_t expectedFlags) {
615 InputEvent* event = consume();
616
617 ASSERT_NE(nullptr, event) << mName.c_str()
618 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800619 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700620 << mName.c_str() << " expected " << inputEventTypeToString(expectedEventType)
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800621 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800622
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800623 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800624
Tiger Huang8664f8c2018-10-11 19:14:35 +0800625 switch (expectedEventType) {
626 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800627 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
628 EXPECT_EQ(expectedAction, keyEvent.getAction());
629 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800630 break;
631 }
632 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800633 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
634 EXPECT_EQ(expectedAction, motionEvent.getAction());
635 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800636 break;
637 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100638 case AINPUT_EVENT_TYPE_FOCUS: {
639 FAIL() << "Use 'consumeFocusEvent' for FOCUS events";
640 }
Tiger Huang8664f8c2018-10-11 19:14:35 +0800641 default: {
642 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
643 }
644 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800645 }
646
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100647 void consumeFocusEvent(bool hasFocus, bool inTouchMode) {
648 InputEvent* event = consume();
649 ASSERT_NE(nullptr, event) << mName.c_str()
650 << ": consumer should have returned non-NULL event.";
651 ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, event->getType())
652 << "Got " << inputEventTypeToString(event->getType())
653 << " event instead of FOCUS event";
654
655 ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId())
656 << mName.c_str() << ": event displayId should always be NONE.";
657
658 FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
659 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
660 EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode());
661 }
662
chaviwd1c23182019-12-20 18:44:56 -0800663 void assertNoEvents() {
664 InputEvent* event = consume();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700665 if (event == nullptr) {
666 return;
667 }
668 if (event->getType() == AINPUT_EVENT_TYPE_KEY) {
669 KeyEvent& keyEvent = static_cast<KeyEvent&>(*event);
670 ADD_FAILURE() << "Received key event "
671 << KeyEvent::actionToString(keyEvent.getAction());
672 } else if (event->getType() == AINPUT_EVENT_TYPE_MOTION) {
673 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
674 ADD_FAILURE() << "Received motion event "
675 << MotionEvent::actionToString(motionEvent.getAction());
676 } else if (event->getType() == AINPUT_EVENT_TYPE_FOCUS) {
677 FocusEvent& focusEvent = static_cast<FocusEvent&>(*event);
678 ADD_FAILURE() << "Received focus event, hasFocus = "
679 << (focusEvent.getHasFocus() ? "true" : "false");
680 }
681 FAIL() << mName.c_str()
682 << ": should not have received any events, so consume() should return NULL";
chaviwd1c23182019-12-20 18:44:56 -0800683 }
684
685 sp<IBinder> getToken() { return mConsumer->getChannel()->getConnectionToken(); }
686
687protected:
688 std::unique_ptr<InputConsumer> mConsumer;
689 PreallocatedInputEventFactory mEventFactory;
690
691 std::string mName;
692};
693
694class FakeWindowHandle : public InputWindowHandle {
695public:
696 static const int32_t WIDTH = 600;
697 static const int32_t HEIGHT = 800;
chaviwd1c23182019-12-20 18:44:56 -0800698
Chris Yea209fde2020-07-22 13:54:51 -0700699 FakeWindowHandle(const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
chaviwd1c23182019-12-20 18:44:56 -0800700 const sp<InputDispatcher>& dispatcher, const std::string name,
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500701 int32_t displayId, std::optional<sp<IBinder>> token = std::nullopt)
chaviwd1c23182019-12-20 18:44:56 -0800702 : mName(name) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500703 if (token == std::nullopt) {
Garfield Tan400128f2020-09-22 21:53:55 +0000704 std::unique_ptr<InputChannel> serverChannel, clientChannel;
705 InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
706 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(clientChannel), name);
707 token = serverChannel->getConnectionToken();
708 dispatcher->registerInputChannel(std::move(serverChannel));
chaviwd1c23182019-12-20 18:44:56 -0800709 }
710
711 inputApplicationHandle->updateInfo();
712 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
713
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500714 mInfo.token = *token;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700715 mInfo.id = sId++;
chaviwd1c23182019-12-20 18:44:56 -0800716 mInfo.name = name;
Michael Wright44753b12020-07-08 13:48:11 +0100717 mInfo.type = InputWindowInfo::Type::APPLICATION;
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500718 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwd1c23182019-12-20 18:44:56 -0800719 mInfo.frameLeft = 0;
720 mInfo.frameTop = 0;
721 mInfo.frameRight = WIDTH;
722 mInfo.frameBottom = HEIGHT;
chaviw1ff3d1e2020-07-01 15:53:47 -0700723 mInfo.transform.set(0, 0);
chaviwd1c23182019-12-20 18:44:56 -0800724 mInfo.globalScaleFactor = 1.0;
725 mInfo.touchableRegion.clear();
726 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
727 mInfo.visible = true;
Vishnu Nair47074b82020-08-14 11:54:47 -0700728 mInfo.focusable = false;
chaviwd1c23182019-12-20 18:44:56 -0800729 mInfo.hasWallpaper = false;
730 mInfo.paused = false;
chaviwd1c23182019-12-20 18:44:56 -0800731 mInfo.ownerPid = INJECTOR_PID;
732 mInfo.ownerUid = INJECTOR_UID;
chaviwd1c23182019-12-20 18:44:56 -0800733 mInfo.displayId = displayId;
734 }
735
736 virtual bool updateInfo() { return true; }
737
Vishnu Nair47074b82020-08-14 11:54:47 -0700738 void setFocusable(bool focusable) { mInfo.focusable = focusable; }
chaviwd1c23182019-12-20 18:44:56 -0800739
Vishnu Nair958da932020-08-21 17:12:37 -0700740 void setVisible(bool visible) { mInfo.visible = visible; }
741
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700742 void setDispatchingTimeout(std::chrono::nanoseconds timeout) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500743 mInfo.dispatchingTimeout = timeout;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700744 }
745
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700746 void setPaused(bool paused) { mInfo.paused = paused; }
747
chaviwd1c23182019-12-20 18:44:56 -0800748 void setFrame(const Rect& frame) {
749 mInfo.frameLeft = frame.left;
750 mInfo.frameTop = frame.top;
751 mInfo.frameRight = frame.right;
752 mInfo.frameBottom = frame.bottom;
chaviw1ff3d1e2020-07-01 15:53:47 -0700753 mInfo.transform.set(frame.left, frame.top);
chaviwd1c23182019-12-20 18:44:56 -0800754 mInfo.touchableRegion.clear();
755 mInfo.addTouchableRegion(frame);
756 }
757
Michael Wright44753b12020-07-08 13:48:11 +0100758 void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; }
chaviwd1c23182019-12-20 18:44:56 -0800759
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500760 void setInputFeatures(InputWindowInfo::Feature features) { mInfo.inputFeatures = features; }
761
chaviw9eaa22c2020-07-01 16:21:27 -0700762 void setWindowTransform(float dsdx, float dtdx, float dtdy, float dsdy) {
763 mInfo.transform.set(dsdx, dtdx, dtdy, dsdy);
764 }
765
766 void setWindowScale(float xScale, float yScale) { setWindowTransform(xScale, 0, 0, yScale); }
chaviwaf87b3e2019-10-01 16:59:28 -0700767
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800768 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
769 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
770 expectedFlags);
771 }
772
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700773 void consumeKeyUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
774 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, expectedDisplayId, expectedFlags);
775 }
776
Svet Ganov5d3bc372020-01-26 23:11:07 -0800777 void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
778 int32_t expectedFlags = 0) {
779 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId,
780 expectedFlags);
781 }
782
783 void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
784 int32_t expectedFlags = 0) {
785 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId,
786 expectedFlags);
787 }
788
789 void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
790 int32_t expectedFlags = 0) {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800791 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
792 expectedFlags);
793 }
794
Svet Ganov5d3bc372020-01-26 23:11:07 -0800795 void consumeMotionPointerDown(int32_t pointerIdx,
796 int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) {
797 int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN
798 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
799 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
800 }
801
802 void consumeMotionPointerUp(int32_t pointerIdx, int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
803 int32_t expectedFlags = 0) {
804 int32_t action = AMOTION_EVENT_ACTION_POINTER_UP
805 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
806 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
807 }
808
809 void consumeMotionUp(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
810 int32_t expectedFlags = 0) {
Michael Wright3a240c42019-12-10 20:53:41 +0000811 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
812 expectedFlags);
813 }
814
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100815 void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
816 ASSERT_NE(mInputReceiver, nullptr)
817 << "Cannot consume events from a window with no receiver";
818 mInputReceiver->consumeFocusEvent(hasFocus, inTouchMode);
819 }
820
chaviwd1c23182019-12-20 18:44:56 -0800821 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
822 int32_t expectedFlags) {
823 ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
824 mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
825 expectedFlags);
826 }
827
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700828 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700829 if (mInputReceiver == nullptr) {
830 ADD_FAILURE() << "Invalid receive event on window with no receiver";
831 return std::nullopt;
832 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700833 return mInputReceiver->receiveEvent(outEvent);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700834 }
835
836 void finishEvent(uint32_t sequenceNum) {
837 ASSERT_NE(mInputReceiver, nullptr) << "Invalid receive event on window with no receiver";
838 mInputReceiver->finishEvent(sequenceNum);
839 }
840
chaviwaf87b3e2019-10-01 16:59:28 -0700841 InputEvent* consume() {
842 if (mInputReceiver == nullptr) {
843 return nullptr;
844 }
845 return mInputReceiver->consume();
846 }
847
Arthur Hungb92218b2018-08-14 12:00:21 +0800848 void assertNoEvents() {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500849 if (mInputReceiver == nullptr &&
850 mInfo.inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL)) {
851 return; // Can't receive events if the window does not have input channel
852 }
853 ASSERT_NE(nullptr, mInputReceiver)
854 << "Window without InputReceiver must specify feature NO_INPUT_CHANNEL";
chaviwd1c23182019-12-20 18:44:56 -0800855 mInputReceiver->assertNoEvents();
Arthur Hungb92218b2018-08-14 12:00:21 +0800856 }
857
chaviwaf87b3e2019-10-01 16:59:28 -0700858 sp<IBinder> getToken() { return mInfo.token; }
859
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100860 const std::string& getName() { return mName; }
861
chaviwd1c23182019-12-20 18:44:56 -0800862private:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100863 const std::string mName;
chaviwd1c23182019-12-20 18:44:56 -0800864 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700865 static std::atomic<int32_t> sId; // each window gets a unique id, like in surfaceflinger
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800866};
867
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700868std::atomic<int32_t> FakeWindowHandle::sId{1};
869
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700870static int32_t injectKey(const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700871 int32_t displayId = ADISPLAY_ID_NONE,
872 int32_t syncMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
873 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800874 KeyEvent event;
875 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
876
877 // Define a valid key down event.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800878 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700879 INVALID_HMAC, action, /* flags */ 0, AKEYCODE_A, KEY_A, AMETA_NONE,
880 repeatCount, currentTime, currentTime);
Arthur Hungb92218b2018-08-14 12:00:21 +0800881
882 // Inject event until dispatch out.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700883 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, syncMode,
884 injectionTimeout,
885 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
Arthur Hungb92218b2018-08-14 12:00:21 +0800886}
887
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700888static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
889 int32_t displayId = ADISPLAY_ID_NONE) {
890 return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId);
891}
892
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700893static int32_t injectKeyUp(const sp<InputDispatcher>& dispatcher,
894 int32_t displayId = ADISPLAY_ID_NONE) {
895 return injectKey(dispatcher, AKEY_EVENT_ACTION_UP, /* repeatCount */ 0, displayId);
896}
897
Garfield Tandf26e862020-07-01 20:18:19 -0700898class PointerBuilder {
899public:
900 PointerBuilder(int32_t id, int32_t toolType) {
901 mProperties.clear();
902 mProperties.id = id;
903 mProperties.toolType = toolType;
904 mCoords.clear();
905 }
906
907 PointerBuilder& x(float x) { return axis(AMOTION_EVENT_AXIS_X, x); }
908
909 PointerBuilder& y(float y) { return axis(AMOTION_EVENT_AXIS_Y, y); }
910
911 PointerBuilder& axis(int32_t axis, float value) {
912 mCoords.setAxisValue(axis, value);
913 return *this;
914 }
915
916 PointerProperties buildProperties() const { return mProperties; }
917
918 PointerCoords buildCoords() const { return mCoords; }
919
920private:
921 PointerProperties mProperties;
922 PointerCoords mCoords;
923};
924
925class MotionEventBuilder {
926public:
927 MotionEventBuilder(int32_t action, int32_t source) {
928 mAction = action;
929 mSource = source;
930 mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
931 }
932
933 MotionEventBuilder& eventTime(nsecs_t eventTime) {
934 mEventTime = eventTime;
935 return *this;
936 }
937
938 MotionEventBuilder& displayId(int32_t displayId) {
939 mDisplayId = displayId;
940 return *this;
941 }
942
943 MotionEventBuilder& actionButton(int32_t actionButton) {
944 mActionButton = actionButton;
945 return *this;
946 }
947
948 MotionEventBuilder& buttonState(int32_t actionButton) {
949 mActionButton = actionButton;
950 return *this;
951 }
952
953 MotionEventBuilder& rawXCursorPosition(float rawXCursorPosition) {
954 mRawXCursorPosition = rawXCursorPosition;
955 return *this;
956 }
957
958 MotionEventBuilder& rawYCursorPosition(float rawYCursorPosition) {
959 mRawYCursorPosition = rawYCursorPosition;
960 return *this;
961 }
962
963 MotionEventBuilder& pointer(PointerBuilder pointer) {
964 mPointers.push_back(pointer);
965 return *this;
966 }
967
968 MotionEvent build() {
969 std::vector<PointerProperties> pointerProperties;
970 std::vector<PointerCoords> pointerCoords;
971 for (const PointerBuilder& pointer : mPointers) {
972 pointerProperties.push_back(pointer.buildProperties());
973 pointerCoords.push_back(pointer.buildCoords());
974 }
975
976 // Set mouse cursor position for the most common cases to avoid boilerplate.
977 if (mSource == AINPUT_SOURCE_MOUSE &&
978 !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition) &&
979 mPointers.size() == 1) {
980 mRawXCursorPosition = pointerCoords[0].getX();
981 mRawYCursorPosition = pointerCoords[0].getY();
982 }
983
984 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -0700985 ui::Transform identityTransform;
Garfield Tandf26e862020-07-01 20:18:19 -0700986 event.initialize(InputEvent::nextId(), DEVICE_ID, mSource, mDisplayId, INVALID_HMAC,
987 mAction, mActionButton, /* flags */ 0, /* edgeFlags */ 0, AMETA_NONE,
chaviw9eaa22c2020-07-01 16:21:27 -0700988 mButtonState, MotionClassification::NONE, identityTransform,
989 /* xPrecision */ 0, /* yPrecision */ 0, mRawXCursorPosition,
990 mRawYCursorPosition, mEventTime, mEventTime, mPointers.size(),
991 pointerProperties.data(), pointerCoords.data());
Garfield Tandf26e862020-07-01 20:18:19 -0700992
993 return event;
994 }
995
996private:
997 int32_t mAction;
998 int32_t mSource;
999 nsecs_t mEventTime;
1000 int32_t mDisplayId{ADISPLAY_ID_DEFAULT};
1001 int32_t mActionButton{0};
1002 int32_t mButtonState{0};
1003 float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1004 float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1005
1006 std::vector<PointerBuilder> mPointers;
1007};
1008
1009static int32_t injectMotionEvent(
1010 const sp<InputDispatcher>& dispatcher, const MotionEvent& event,
1011 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
1012 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT) {
1013 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, injectionMode,
1014 injectionTimeout,
1015 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
1016}
1017
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001018static int32_t injectMotionEvent(
1019 const sp<InputDispatcher>& dispatcher, int32_t action, int32_t source, int32_t displayId,
1020 const PointF& position,
1021 const PointF& cursorPosition = {AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001022 AMOTION_EVENT_INVALID_CURSOR_POSITION},
1023 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
1024 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
1025 nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC)) {
Garfield Tandf26e862020-07-01 20:18:19 -07001026 MotionEvent event = MotionEventBuilder(action, source)
1027 .displayId(displayId)
1028 .eventTime(eventTime)
1029 .rawXCursorPosition(cursorPosition.x)
1030 .rawYCursorPosition(cursorPosition.y)
1031 .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER)
1032 .x(position.x)
1033 .y(position.y))
1034 .build();
Arthur Hungb92218b2018-08-14 12:00:21 +08001035
1036 // Inject event until dispatch out.
Garfield Tandf26e862020-07-01 20:18:19 -07001037 return injectMotionEvent(dispatcher, event);
Arthur Hungb92218b2018-08-14 12:00:21 +08001038}
1039
Garfield Tan00f511d2019-06-12 16:55:40 -07001040static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001041 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001042 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, location);
Garfield Tan00f511d2019-06-12 16:55:40 -07001043}
1044
Michael Wright3a240c42019-12-10 20:53:41 +00001045static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001046 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001047 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, location);
Michael Wright3a240c42019-12-10 20:53:41 +00001048}
1049
Jackal Guof9696682018-10-05 12:23:23 +08001050static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
1051 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1052 // Define a valid key event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001053 NotifyKeyArgs args(/* id */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
1054 POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0, AKEYCODE_A, KEY_A,
1055 AMETA_NONE, currentTime);
Jackal Guof9696682018-10-05 12:23:23 +08001056
1057 return args;
1058}
1059
chaviwd1c23182019-12-20 18:44:56 -08001060static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId,
1061 const std::vector<PointF>& points) {
1062 size_t pointerCount = points.size();
chaviwaf87b3e2019-10-01 16:59:28 -07001063 if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_UP) {
1064 EXPECT_EQ(1U, pointerCount) << "Actions DOWN and UP can only contain a single pointer";
1065 }
1066
chaviwd1c23182019-12-20 18:44:56 -08001067 PointerProperties pointerProperties[pointerCount];
1068 PointerCoords pointerCoords[pointerCount];
Jackal Guof9696682018-10-05 12:23:23 +08001069
chaviwd1c23182019-12-20 18:44:56 -08001070 for (size_t i = 0; i < pointerCount; i++) {
1071 pointerProperties[i].clear();
1072 pointerProperties[i].id = i;
1073 pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
Jackal Guof9696682018-10-05 12:23:23 +08001074
chaviwd1c23182019-12-20 18:44:56 -08001075 pointerCoords[i].clear();
1076 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
1077 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, points[i].y);
1078 }
Jackal Guof9696682018-10-05 12:23:23 +08001079
1080 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1081 // Define a valid motion event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001082 NotifyMotionArgs args(/* id */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -07001083 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
1084 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
chaviwd1c23182019-12-20 18:44:56 -08001085 AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, pointerProperties,
1086 pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -07001087 AMOTION_EVENT_INVALID_CURSOR_POSITION,
1088 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +08001089
1090 return args;
1091}
1092
chaviwd1c23182019-12-20 18:44:56 -08001093static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
1094 return generateMotionArgs(action, source, displayId, {PointF{100, 200}});
1095}
1096
Arthur Hungb92218b2018-08-14 12:00:21 +08001097TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001098 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001099 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
1100 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001101
Arthur Hung72d8dc32020-03-28 00:48:39 +00001102 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001103 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1104 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001105 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1106
1107 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001108 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001109}
1110
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001111/**
1112 * Calling setInputWindows once with FLAG_NOT_TOUCH_MODAL should not cause any issues.
1113 * To ensure that window receives only events that were directly inside of it, add
1114 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1115 * when finding touched windows.
1116 * This test serves as a sanity check for the next test, where setInputWindows is
1117 * called twice.
1118 */
1119TEST_F(InputDispatcherTest, SetInputWindowOnce_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001120 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001121 sp<FakeWindowHandle> window =
1122 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1123 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001124 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001125
1126 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1127 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1128 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1129 {50, 50}))
1130 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1131
1132 // Window should receive motion event.
1133 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1134}
1135
1136/**
1137 * Calling setInputWindows twice, with the same info, should not cause any issues.
1138 * To ensure that window receives only events that were directly inside of it, add
1139 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1140 * when finding touched windows.
1141 */
1142TEST_F(InputDispatcherTest, SetInputWindowTwice_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001143 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001144 sp<FakeWindowHandle> window =
1145 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1146 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001147 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001148
1149 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1150 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1151 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1152 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1153 {50, 50}))
1154 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1155
1156 // Window should receive motion event.
1157 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1158}
1159
Arthur Hungb92218b2018-08-14 12:00:21 +08001160// The foreground window should receive the first touch down event.
1161TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001162 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001163 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1164 ADISPLAY_ID_DEFAULT);
1165 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1166 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001167
Arthur Hung72d8dc32020-03-28 00:48:39 +00001168 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001169 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1170 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001171 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1172
1173 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001174 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001175 windowSecond->assertNoEvents();
1176}
1177
Garfield Tandf26e862020-07-01 20:18:19 -07001178TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001179 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001180 sp<FakeWindowHandle> windowLeft =
1181 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1182 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001183 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001184 sp<FakeWindowHandle> windowRight =
1185 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1186 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001187 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001188
1189 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1190
1191 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
1192
1193 // Start cursor position in right window so that we can move the cursor to left window.
1194 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1195 injectMotionEvent(mDispatcher,
1196 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1197 AINPUT_SOURCE_MOUSE)
1198 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1199 .x(900)
1200 .y(400))
1201 .build()));
1202 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1203 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1204 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1205 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1206
1207 // Move cursor into left window
1208 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1209 injectMotionEvent(mDispatcher,
1210 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1211 AINPUT_SOURCE_MOUSE)
1212 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1213 .x(300)
1214 .y(400))
1215 .build()));
1216 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1217 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1218 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1219 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1220 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1221 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1222
1223 // Inject a series of mouse events for a mouse click
1224 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1225 injectMotionEvent(mDispatcher,
1226 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1227 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1228 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1229 .x(300)
1230 .y(400))
1231 .build()));
1232 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1233
1234 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1235 injectMotionEvent(mDispatcher,
1236 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1237 AINPUT_SOURCE_MOUSE)
1238 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1239 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1240 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1241 .x(300)
1242 .y(400))
1243 .build()));
1244 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1245 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1246
1247 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1248 injectMotionEvent(mDispatcher,
1249 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1250 AINPUT_SOURCE_MOUSE)
1251 .buttonState(0)
1252 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1253 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1254 .x(300)
1255 .y(400))
1256 .build()));
1257 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1258 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1259
1260 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1261 injectMotionEvent(mDispatcher,
1262 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1263 .buttonState(0)
1264 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1265 .x(300)
1266 .y(400))
1267 .build()));
1268 windowLeft->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1269
1270 // Move mouse cursor back to right window
1271 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1272 injectMotionEvent(mDispatcher,
1273 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1274 AINPUT_SOURCE_MOUSE)
1275 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1276 .x(900)
1277 .y(400))
1278 .build()));
1279 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1280 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1281 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1282 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1283 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1284 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1285}
1286
1287// This test is different from the test above that HOVER_ENTER and HOVER_EXIT events are injected
1288// directly in this test.
1289TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001290 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001291 sp<FakeWindowHandle> window =
1292 new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
1293 window->setFrame(Rect(0, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001294 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001295
1296 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1297
1298 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1299
1300 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1301 injectMotionEvent(mDispatcher,
1302 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
1303 AINPUT_SOURCE_MOUSE)
1304 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1305 .x(300)
1306 .y(400))
1307 .build()));
1308 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1309 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1310
1311 // Inject a series of mouse events for a mouse click
1312 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1313 injectMotionEvent(mDispatcher,
1314 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1315 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1316 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1317 .x(300)
1318 .y(400))
1319 .build()));
1320 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1321
1322 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1323 injectMotionEvent(mDispatcher,
1324 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1325 AINPUT_SOURCE_MOUSE)
1326 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1327 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1328 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1329 .x(300)
1330 .y(400))
1331 .build()));
1332 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1333 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1334
1335 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1336 injectMotionEvent(mDispatcher,
1337 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1338 AINPUT_SOURCE_MOUSE)
1339 .buttonState(0)
1340 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1341 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1342 .x(300)
1343 .y(400))
1344 .build()));
1345 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1346 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1347
1348 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1349 injectMotionEvent(mDispatcher,
1350 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1351 .buttonState(0)
1352 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1353 .x(300)
1354 .y(400))
1355 .build()));
1356 window->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1357
1358 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1359 injectMotionEvent(mDispatcher,
1360 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
1361 AINPUT_SOURCE_MOUSE)
1362 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1363 .x(300)
1364 .y(400))
1365 .build()));
1366 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1367 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1368}
1369
Garfield Tan00f511d2019-06-12 16:55:40 -07001370TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
Chris Yea209fde2020-07-22 13:54:51 -07001371 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tan00f511d2019-06-12 16:55:40 -07001372
1373 sp<FakeWindowHandle> windowLeft =
1374 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1375 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001376 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001377 sp<FakeWindowHandle> windowRight =
1378 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1379 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001380 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001381
1382 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1383
Arthur Hung72d8dc32020-03-28 00:48:39 +00001384 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
Garfield Tan00f511d2019-06-12 16:55:40 -07001385
1386 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
1387 // left window. This event should be dispatched to the left window.
1388 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1389 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001390 ADISPLAY_ID_DEFAULT, {610, 400}, {599, 400}));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001391 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -07001392 windowRight->assertNoEvents();
1393}
1394
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001395TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001396 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001397 sp<FakeWindowHandle> window =
1398 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Vishnu Nair47074b82020-08-14 11:54:47 -07001399 window->setFocusable(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001400
Arthur Hung72d8dc32020-03-28 00:48:39 +00001401 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001402 setFocusedWindow(window);
1403
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001404 window->consumeFocusEvent(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001405
1406 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1407 mDispatcher->notifyKey(&keyArgs);
1408
1409 // Window should receive key down event.
1410 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1411
1412 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
1413 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001414 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001415 mDispatcher->notifyDeviceReset(&args);
1416 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
1417 AKEY_EVENT_FLAG_CANCELED);
1418}
1419
1420TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001421 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001422 sp<FakeWindowHandle> window =
1423 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1424
Arthur Hung72d8dc32020-03-28 00:48:39 +00001425 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001426
1427 NotifyMotionArgs motionArgs =
1428 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1429 ADISPLAY_ID_DEFAULT);
1430 mDispatcher->notifyMotion(&motionArgs);
1431
1432 // Window should receive motion down event.
1433 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1434
1435 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
1436 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001437 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001438 mDispatcher->notifyDeviceReset(&args);
1439 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
1440 0 /*expectedFlags*/);
1441}
1442
Svet Ganov5d3bc372020-01-26 23:11:07 -08001443TEST_F(InputDispatcherTest, TransferTouchFocus_OnePointer) {
Chris Yea209fde2020-07-22 13:54:51 -07001444 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001445
1446 // Create a couple of windows
1447 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1448 "First Window", ADISPLAY_ID_DEFAULT);
1449 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1450 "Second Window", ADISPLAY_ID_DEFAULT);
1451
1452 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001453 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001454
1455 // Send down to the first window
1456 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1457 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1458 mDispatcher->notifyMotion(&downMotionArgs);
1459 // Only the first window should get the down event
1460 firstWindow->consumeMotionDown();
1461 secondWindow->assertNoEvents();
1462
1463 // Transfer touch focus to the second window
1464 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1465 // The first window gets cancel and the second gets down
1466 firstWindow->consumeMotionCancel();
1467 secondWindow->consumeMotionDown();
1468
1469 // Send up event to the second window
1470 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1471 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1472 mDispatcher->notifyMotion(&upMotionArgs);
1473 // The first window gets no events and the second gets up
1474 firstWindow->assertNoEvents();
1475 secondWindow->consumeMotionUp();
1476}
1477
1478TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointerNoSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001479 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001480
1481 PointF touchPoint = {10, 10};
1482
1483 // Create a couple of windows
1484 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1485 "First Window", ADISPLAY_ID_DEFAULT);
1486 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1487 "Second Window", ADISPLAY_ID_DEFAULT);
1488
1489 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001490 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001491
1492 // Send down to the first window
1493 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1494 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint});
1495 mDispatcher->notifyMotion(&downMotionArgs);
1496 // Only the first window should get the down event
1497 firstWindow->consumeMotionDown();
1498 secondWindow->assertNoEvents();
1499
1500 // Send pointer down to the first window
1501 NotifyMotionArgs pointerDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1502 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1503 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1504 mDispatcher->notifyMotion(&pointerDownMotionArgs);
1505 // Only the first window should get the pointer down event
1506 firstWindow->consumeMotionPointerDown(1);
1507 secondWindow->assertNoEvents();
1508
1509 // Transfer touch focus to the second window
1510 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1511 // The first window gets cancel and the second gets down and pointer down
1512 firstWindow->consumeMotionCancel();
1513 secondWindow->consumeMotionDown();
1514 secondWindow->consumeMotionPointerDown(1);
1515
1516 // Send pointer up to the second window
1517 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1518 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1519 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1520 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1521 // The first window gets nothing and the second gets pointer up
1522 firstWindow->assertNoEvents();
1523 secondWindow->consumeMotionPointerUp(1);
1524
1525 // Send up event to the second window
1526 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1527 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1528 mDispatcher->notifyMotion(&upMotionArgs);
1529 // The first window gets nothing and the second gets up
1530 firstWindow->assertNoEvents();
1531 secondWindow->consumeMotionUp();
1532}
1533
1534TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointersSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001535 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001536
1537 // Create a non touch modal window that supports split touch
1538 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1539 "First Window", ADISPLAY_ID_DEFAULT);
1540 firstWindow->setFrame(Rect(0, 0, 600, 400));
Michael Wright44753b12020-07-08 13:48:11 +01001541 firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1542 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001543
1544 // Create a non touch modal window that supports split touch
1545 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1546 "Second Window", ADISPLAY_ID_DEFAULT);
1547 secondWindow->setFrame(Rect(0, 400, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001548 secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1549 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001550
1551 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001552 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001553
1554 PointF pointInFirst = {300, 200};
1555 PointF pointInSecond = {300, 600};
1556
1557 // Send down to the first window
1558 NotifyMotionArgs firstDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1559 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst});
1560 mDispatcher->notifyMotion(&firstDownMotionArgs);
1561 // Only the first window should get the down event
1562 firstWindow->consumeMotionDown();
1563 secondWindow->assertNoEvents();
1564
1565 // Send down to the second window
1566 NotifyMotionArgs secondDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1567 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1568 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1569 mDispatcher->notifyMotion(&secondDownMotionArgs);
1570 // The first window gets a move and the second a down
1571 firstWindow->consumeMotionMove();
1572 secondWindow->consumeMotionDown();
1573
1574 // Transfer touch focus to the second window
1575 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1576 // The first window gets cancel and the new gets pointer down (it already saw down)
1577 firstWindow->consumeMotionCancel();
1578 secondWindow->consumeMotionPointerDown(1);
1579
1580 // Send pointer up to the second window
1581 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1582 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1583 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1584 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1585 // The first window gets nothing and the second gets pointer up
1586 firstWindow->assertNoEvents();
1587 secondWindow->consumeMotionPointerUp(1);
1588
1589 // Send up event to the second window
1590 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1591 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1592 mDispatcher->notifyMotion(&upMotionArgs);
1593 // The first window gets nothing and the second gets up
1594 firstWindow->assertNoEvents();
1595 secondWindow->consumeMotionUp();
1596}
1597
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001598TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001599 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001600 sp<FakeWindowHandle> window =
1601 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1602
Vishnu Nair47074b82020-08-14 11:54:47 -07001603 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001604 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001605 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001606
1607 window->consumeFocusEvent(true);
1608
1609 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1610 mDispatcher->notifyKey(&keyArgs);
1611
1612 // Window should receive key down event.
1613 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1614}
1615
1616TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001617 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001618 sp<FakeWindowHandle> window =
1619 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1620
Arthur Hung72d8dc32020-03-28 00:48:39 +00001621 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001622
1623 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1624 mDispatcher->notifyKey(&keyArgs);
1625 mDispatcher->waitForIdle();
1626
1627 window->assertNoEvents();
1628}
1629
1630// If a window is touchable, but does not have focus, it should receive motion events, but not keys
1631TEST_F(InputDispatcherTest, UnfocusedWindow_ReceivesMotionsButNotKeys) {
Chris Yea209fde2020-07-22 13:54:51 -07001632 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001633 sp<FakeWindowHandle> window =
1634 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1635
Arthur Hung72d8dc32020-03-28 00:48:39 +00001636 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001637
1638 // Send key
1639 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1640 mDispatcher->notifyKey(&keyArgs);
1641 // Send motion
1642 NotifyMotionArgs motionArgs =
1643 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1644 ADISPLAY_ID_DEFAULT);
1645 mDispatcher->notifyMotion(&motionArgs);
1646
1647 // Window should receive only the motion event
1648 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1649 window->assertNoEvents(); // Key event or focus event will not be received
1650}
1651
chaviwd1c23182019-12-20 18:44:56 -08001652class FakeMonitorReceiver {
Michael Wright3a240c42019-12-10 20:53:41 +00001653public:
1654 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
chaviwd1c23182019-12-20 18:44:56 -08001655 int32_t displayId, bool isGestureMonitor = false) {
Garfield Tan400128f2020-09-22 21:53:55 +00001656 std::unique_ptr<InputChannel> serverChannel, clientChannel;
1657 InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
1658 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(clientChannel), name);
1659 dispatcher->registerInputMonitor(std::move(serverChannel), displayId, isGestureMonitor);
Michael Wright3a240c42019-12-10 20:53:41 +00001660 }
1661
chaviwd1c23182019-12-20 18:44:56 -08001662 sp<IBinder> getToken() { return mInputReceiver->getToken(); }
1663
1664 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1665 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN,
1666 expectedDisplayId, expectedFlags);
1667 }
1668
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001669 std::optional<int32_t> receiveEvent() { return mInputReceiver->receiveEvent(); }
1670
1671 void finishEvent(uint32_t consumeSeq) { return mInputReceiver->finishEvent(consumeSeq); }
1672
chaviwd1c23182019-12-20 18:44:56 -08001673 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1674 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN,
1675 expectedDisplayId, expectedFlags);
1676 }
1677
1678 void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1679 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP,
1680 expectedDisplayId, expectedFlags);
1681 }
1682
1683 void assertNoEvents() { mInputReceiver->assertNoEvents(); }
1684
1685private:
1686 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Michael Wright3a240c42019-12-10 20:53:41 +00001687};
1688
1689// Tests for gesture monitors
1690TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001691 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001692 sp<FakeWindowHandle> window =
1693 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001694 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001695
chaviwd1c23182019-12-20 18:44:56 -08001696 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1697 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001698
1699 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1700 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1701 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1702 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001703 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001704}
1705
1706TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001707 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001708 sp<FakeWindowHandle> window =
1709 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1710
1711 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001712 window->setFocusable(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001713
Arthur Hung72d8dc32020-03-28 00:48:39 +00001714 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001715 setFocusedWindow(window);
1716
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001717 window->consumeFocusEvent(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001718
chaviwd1c23182019-12-20 18:44:56 -08001719 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1720 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001721
1722 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1723 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1724 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001725 monitor.assertNoEvents();
Michael Wright3a240c42019-12-10 20:53:41 +00001726}
1727
1728TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001729 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001730 sp<FakeWindowHandle> window =
1731 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001732 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001733
chaviwd1c23182019-12-20 18:44:56 -08001734 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1735 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001736
1737 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1738 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1739 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1740 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001741 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001742
1743 window->releaseChannel();
1744
chaviwd1c23182019-12-20 18:44:56 -08001745 mDispatcher->pilferPointers(monitor.getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00001746
1747 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1748 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1749 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwd1c23182019-12-20 18:44:56 -08001750 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001751}
1752
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001753TEST_F(InputDispatcherTest, UnresponsiveGestureMonitor_GetsAnr) {
1754 FakeMonitorReceiver monitor =
1755 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
1756 true /*isGestureMonitor*/);
1757
1758 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1759 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT));
1760 std::optional<uint32_t> consumeSeq = monitor.receiveEvent();
1761 ASSERT_TRUE(consumeSeq);
1762
1763 mFakePolicy->assertNotifyAnrWasCalled(DISPATCHING_TIMEOUT, nullptr, monitor.getToken());
1764 monitor.finishEvent(*consumeSeq);
1765 ASSERT_TRUE(mDispatcher->waitForIdle());
1766}
1767
chaviw81e2bb92019-12-18 15:03:51 -08001768TEST_F(InputDispatcherTest, TestMoveEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001769 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
chaviw81e2bb92019-12-18 15:03:51 -08001770 sp<FakeWindowHandle> window =
1771 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1772
Arthur Hung72d8dc32020-03-28 00:48:39 +00001773 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
chaviw81e2bb92019-12-18 15:03:51 -08001774
1775 NotifyMotionArgs motionArgs =
1776 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1777 ADISPLAY_ID_DEFAULT);
1778
1779 mDispatcher->notifyMotion(&motionArgs);
1780 // Window should receive motion down event.
1781 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1782
1783 motionArgs.action = AMOTION_EVENT_ACTION_MOVE;
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001784 motionArgs.id += 1;
chaviw81e2bb92019-12-18 15:03:51 -08001785 motionArgs.eventTime = systemTime(SYSTEM_TIME_MONOTONIC);
1786 motionArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
1787 motionArgs.pointerCoords[0].getX() - 10);
1788
1789 mDispatcher->notifyMotion(&motionArgs);
1790 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, ADISPLAY_ID_DEFAULT,
1791 0 /*expectedFlags*/);
1792}
1793
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001794/**
1795 * Dispatcher has touch mode enabled by default. Typically, the policy overrides that value to
1796 * the device default right away. In the test scenario, we check both the default value,
1797 * and the action of enabling / disabling.
1798 */
1799TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
Chris Yea209fde2020-07-22 13:54:51 -07001800 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001801 sp<FakeWindowHandle> window =
1802 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1803
1804 // Set focused application.
1805 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001806 window->setFocusable(true);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001807
1808 SCOPED_TRACE("Check default value of touch mode");
Arthur Hung72d8dc32020-03-28 00:48:39 +00001809 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001810 setFocusedWindow(window);
1811
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001812 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1813
1814 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001815 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001816 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001817 window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
1818
1819 SCOPED_TRACE("Disable touch mode");
1820 mDispatcher->setInTouchMode(false);
Vishnu Nair47074b82020-08-14 11:54:47 -07001821 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001822 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001823 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001824 window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
1825
1826 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001827 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001828 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001829 window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
1830
1831 SCOPED_TRACE("Enable touch mode again");
1832 mDispatcher->setInTouchMode(true);
Vishnu Nair47074b82020-08-14 11:54:47 -07001833 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001834 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001835 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001836 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1837
1838 window->assertNoEvents();
1839}
1840
Gang Wange9087892020-01-07 12:17:14 -05001841TEST_F(InputDispatcherTest, VerifyInputEvent_KeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001842 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Gang Wange9087892020-01-07 12:17:14 -05001843 sp<FakeWindowHandle> window =
1844 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1845
1846 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001847 window->setFocusable(true);
Gang Wange9087892020-01-07 12:17:14 -05001848
Arthur Hung72d8dc32020-03-28 00:48:39 +00001849 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001850 setFocusedWindow(window);
1851
Gang Wange9087892020-01-07 12:17:14 -05001852 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1853
1854 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1855 mDispatcher->notifyKey(&keyArgs);
1856
1857 InputEvent* event = window->consume();
1858 ASSERT_NE(event, nullptr);
1859
1860 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1861 ASSERT_NE(verified, nullptr);
1862 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::KEY);
1863
1864 ASSERT_EQ(keyArgs.eventTime, verified->eventTimeNanos);
1865 ASSERT_EQ(keyArgs.deviceId, verified->deviceId);
1866 ASSERT_EQ(keyArgs.source, verified->source);
1867 ASSERT_EQ(keyArgs.displayId, verified->displayId);
1868
1869 const VerifiedKeyEvent& verifiedKey = static_cast<const VerifiedKeyEvent&>(*verified);
1870
1871 ASSERT_EQ(keyArgs.action, verifiedKey.action);
1872 ASSERT_EQ(keyArgs.downTime, verifiedKey.downTimeNanos);
Gang Wange9087892020-01-07 12:17:14 -05001873 ASSERT_EQ(keyArgs.flags & VERIFIED_KEY_EVENT_FLAGS, verifiedKey.flags);
1874 ASSERT_EQ(keyArgs.keyCode, verifiedKey.keyCode);
1875 ASSERT_EQ(keyArgs.scanCode, verifiedKey.scanCode);
1876 ASSERT_EQ(keyArgs.metaState, verifiedKey.metaState);
1877 ASSERT_EQ(0, verifiedKey.repeatCount);
1878}
1879
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001880TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001881 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001882 sp<FakeWindowHandle> window =
1883 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1884
1885 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1886
Arthur Hung72d8dc32020-03-28 00:48:39 +00001887 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001888
1889 NotifyMotionArgs motionArgs =
1890 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1891 ADISPLAY_ID_DEFAULT);
1892 mDispatcher->notifyMotion(&motionArgs);
1893
1894 InputEvent* event = window->consume();
1895 ASSERT_NE(event, nullptr);
1896
1897 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1898 ASSERT_NE(verified, nullptr);
1899 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::MOTION);
1900
1901 EXPECT_EQ(motionArgs.eventTime, verified->eventTimeNanos);
1902 EXPECT_EQ(motionArgs.deviceId, verified->deviceId);
1903 EXPECT_EQ(motionArgs.source, verified->source);
1904 EXPECT_EQ(motionArgs.displayId, verified->displayId);
1905
1906 const VerifiedMotionEvent& verifiedMotion = static_cast<const VerifiedMotionEvent&>(*verified);
1907
1908 EXPECT_EQ(motionArgs.pointerCoords[0].getX(), verifiedMotion.rawX);
1909 EXPECT_EQ(motionArgs.pointerCoords[0].getY(), verifiedMotion.rawY);
1910 EXPECT_EQ(motionArgs.action & AMOTION_EVENT_ACTION_MASK, verifiedMotion.actionMasked);
1911 EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos);
1912 EXPECT_EQ(motionArgs.flags & VERIFIED_MOTION_EVENT_FLAGS, verifiedMotion.flags);
1913 EXPECT_EQ(motionArgs.metaState, verifiedMotion.metaState);
1914 EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState);
1915}
1916
chaviw09c8d2d2020-08-24 15:48:26 -07001917/**
1918 * Ensure that separate calls to sign the same data are generating the same key.
1919 * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance
1920 * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky
1921 * tests.
1922 */
1923TEST_F(InputDispatcherTest, GeneratedHmac_IsConsistent) {
1924 KeyEvent event = getTestKeyEvent();
1925 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1926
1927 std::array<uint8_t, 32> hmac1 = mDispatcher->sign(verifiedEvent);
1928 std::array<uint8_t, 32> hmac2 = mDispatcher->sign(verifiedEvent);
1929 ASSERT_EQ(hmac1, hmac2);
1930}
1931
1932/**
1933 * Ensure that changes in VerifiedKeyEvent produce a different hmac.
1934 */
1935TEST_F(InputDispatcherTest, GeneratedHmac_ChangesWhenFieldsChange) {
1936 KeyEvent event = getTestKeyEvent();
1937 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1938 std::array<uint8_t, 32> initialHmac = mDispatcher->sign(verifiedEvent);
1939
1940 verifiedEvent.deviceId += 1;
1941 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1942
1943 verifiedEvent.source += 1;
1944 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1945
1946 verifiedEvent.eventTimeNanos += 1;
1947 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1948
1949 verifiedEvent.displayId += 1;
1950 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1951
1952 verifiedEvent.action += 1;
1953 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1954
1955 verifiedEvent.downTimeNanos += 1;
1956 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1957
1958 verifiedEvent.flags += 1;
1959 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1960
1961 verifiedEvent.keyCode += 1;
1962 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1963
1964 verifiedEvent.scanCode += 1;
1965 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1966
1967 verifiedEvent.metaState += 1;
1968 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1969
1970 verifiedEvent.repeatCount += 1;
1971 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1972}
1973
Vishnu Nair958da932020-08-21 17:12:37 -07001974TEST_F(InputDispatcherTest, SetFocusedWindow) {
1975 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
1976 sp<FakeWindowHandle> windowTop =
1977 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
1978 sp<FakeWindowHandle> windowSecond =
1979 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1980 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1981
1982 // Top window is also focusable but is not granted focus.
1983 windowTop->setFocusable(true);
1984 windowSecond->setFocusable(true);
1985 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
1986 setFocusedWindow(windowSecond);
1987
1988 windowSecond->consumeFocusEvent(true);
1989 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1990 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1991
1992 // Focused window should receive event.
1993 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
1994 windowTop->assertNoEvents();
1995}
1996
1997TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestInvalidChannel) {
1998 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
1999 sp<FakeWindowHandle> window =
2000 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2001 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2002
2003 window->setFocusable(true);
2004 // Release channel for window is no longer valid.
2005 window->releaseChannel();
2006 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2007 setFocusedWindow(window);
2008
2009 // Test inject a key down, should timeout.
2010 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2011 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2012
2013 // window channel is invalid, so it should not receive any input event.
2014 window->assertNoEvents();
2015}
2016
2017TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestNoFocusableWindow) {
2018 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2019 sp<FakeWindowHandle> window =
2020 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2021 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2022
2023 // Window is not focusable.
2024 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2025 setFocusedWindow(window);
2026
2027 // Test inject a key down, should timeout.
2028 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2029 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2030
2031 // window is invalid, so it should not receive any input event.
2032 window->assertNoEvents();
2033}
2034
2035TEST_F(InputDispatcherTest, SetFocusedWindow_CheckFocusedToken) {
2036 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2037 sp<FakeWindowHandle> windowTop =
2038 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
2039 sp<FakeWindowHandle> windowSecond =
2040 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2041 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2042
2043 windowTop->setFocusable(true);
2044 windowSecond->setFocusable(true);
2045 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
2046 setFocusedWindow(windowTop);
2047 windowTop->consumeFocusEvent(true);
2048
2049 setFocusedWindow(windowSecond, windowTop);
2050 windowSecond->consumeFocusEvent(true);
2051 windowTop->consumeFocusEvent(false);
2052
2053 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2054 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2055
2056 // Focused window should receive event.
2057 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
2058}
2059
2060TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestFocusTokenNotFocused) {
2061 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2062 sp<FakeWindowHandle> windowTop =
2063 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
2064 sp<FakeWindowHandle> windowSecond =
2065 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2066 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2067
2068 windowTop->setFocusable(true);
2069 windowSecond->setFocusable(true);
2070 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
2071 setFocusedWindow(windowSecond, windowTop);
2072
2073 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2074 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2075
2076 // Event should be dropped.
2077 windowTop->assertNoEvents();
2078 windowSecond->assertNoEvents();
2079}
2080
2081TEST_F(InputDispatcherTest, SetFocusedWindow_DeferInvisibleWindow) {
2082 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2083 sp<FakeWindowHandle> window =
2084 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2085 sp<FakeWindowHandle> previousFocusedWindow =
2086 new FakeWindowHandle(application, mDispatcher, "previousFocusedWindow",
2087 ADISPLAY_ID_DEFAULT);
2088 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2089
2090 window->setFocusable(true);
2091 previousFocusedWindow->setFocusable(true);
2092 window->setVisible(false);
2093 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window, previousFocusedWindow}}});
2094 setFocusedWindow(previousFocusedWindow);
2095 previousFocusedWindow->consumeFocusEvent(true);
2096
2097 // Requesting focus on invisible window takes focus from currently focused window.
2098 setFocusedWindow(window);
2099 previousFocusedWindow->consumeFocusEvent(false);
2100
2101 // Injected key goes to pending queue.
2102 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2103 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
2104 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
2105
2106 // Window does not get focus event or key down.
2107 window->assertNoEvents();
2108
2109 // Window becomes visible.
2110 window->setVisible(true);
2111 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2112
2113 // Window receives focus event.
2114 window->consumeFocusEvent(true);
2115 // Focused window receives key down.
2116 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2117}
2118
Garfield Tan1c7bc862020-01-28 13:24:04 -08002119class InputDispatcherKeyRepeatTest : public InputDispatcherTest {
2120protected:
2121 static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms
2122 static constexpr nsecs_t KEY_REPEAT_DELAY = 40 * 1000000; // 40 ms
2123
Chris Yea209fde2020-07-22 13:54:51 -07002124 std::shared_ptr<FakeApplicationHandle> mApp;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002125 sp<FakeWindowHandle> mWindow;
2126
2127 virtual void SetUp() override {
2128 mFakePolicy = new FakeInputDispatcherPolicy();
2129 mFakePolicy->setKeyRepeatConfiguration(KEY_REPEAT_TIMEOUT, KEY_REPEAT_DELAY);
2130 mDispatcher = new InputDispatcher(mFakePolicy);
2131 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
2132 ASSERT_EQ(OK, mDispatcher->start());
2133
2134 setUpWindow();
2135 }
2136
2137 void setUpWindow() {
Chris Yea209fde2020-07-22 13:54:51 -07002138 mApp = std::make_shared<FakeApplicationHandle>();
Garfield Tan1c7bc862020-01-28 13:24:04 -08002139 mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
2140
Vishnu Nair47074b82020-08-14 11:54:47 -07002141 mWindow->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002142 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002143 setFocusedWindow(mWindow);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002144 mWindow->consumeFocusEvent(true);
2145 }
2146
Chris Ye2ad95392020-09-01 13:44:44 -07002147 void sendAndConsumeKeyDown(int32_t deviceId) {
Garfield Tan1c7bc862020-01-28 13:24:04 -08002148 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
Chris Ye2ad95392020-09-01 13:44:44 -07002149 keyArgs.deviceId = deviceId;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002150 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Otherwise it won't generate repeat event
2151 mDispatcher->notifyKey(&keyArgs);
2152
2153 // Window should receive key down event.
2154 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2155 }
2156
2157 void expectKeyRepeatOnce(int32_t repeatCount) {
2158 SCOPED_TRACE(StringPrintf("Checking event with repeat count %" PRId32, repeatCount));
2159 InputEvent* repeatEvent = mWindow->consume();
2160 ASSERT_NE(nullptr, repeatEvent);
2161
2162 uint32_t eventType = repeatEvent->getType();
2163 ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, eventType);
2164
2165 KeyEvent* repeatKeyEvent = static_cast<KeyEvent*>(repeatEvent);
2166 uint32_t eventAction = repeatKeyEvent->getAction();
2167 EXPECT_EQ(AKEY_EVENT_ACTION_DOWN, eventAction);
2168 EXPECT_EQ(repeatCount, repeatKeyEvent->getRepeatCount());
2169 }
2170
Chris Ye2ad95392020-09-01 13:44:44 -07002171 void sendAndConsumeKeyUp(int32_t deviceId) {
Garfield Tan1c7bc862020-01-28 13:24:04 -08002172 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
Chris Ye2ad95392020-09-01 13:44:44 -07002173 keyArgs.deviceId = deviceId;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002174 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Unless it won't generate repeat event
2175 mDispatcher->notifyKey(&keyArgs);
2176
2177 // Window should receive key down event.
2178 mWindow->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
2179 0 /*expectedFlags*/);
2180 }
2181};
2182
2183TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeat) {
Chris Ye2ad95392020-09-01 13:44:44 -07002184 sendAndConsumeKeyDown(1 /* deviceId */);
2185 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2186 expectKeyRepeatOnce(repeatCount);
2187 }
2188}
2189
2190TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeatFromTwoDevices) {
2191 sendAndConsumeKeyDown(1 /* deviceId */);
2192 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2193 expectKeyRepeatOnce(repeatCount);
2194 }
2195 sendAndConsumeKeyDown(2 /* deviceId */);
2196 /* repeatCount will start from 1 for deviceId 2 */
Garfield Tan1c7bc862020-01-28 13:24:04 -08002197 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2198 expectKeyRepeatOnce(repeatCount);
2199 }
2200}
2201
2202TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterUp) {
Chris Ye2ad95392020-09-01 13:44:44 -07002203 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002204 expectKeyRepeatOnce(1 /*repeatCount*/);
Chris Ye2ad95392020-09-01 13:44:44 -07002205 sendAndConsumeKeyUp(1 /* deviceId */);
2206 mWindow->assertNoEvents();
2207}
2208
2209TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_KeyRepeatAfterStaleDeviceKeyUp) {
2210 sendAndConsumeKeyDown(1 /* deviceId */);
2211 expectKeyRepeatOnce(1 /*repeatCount*/);
2212 sendAndConsumeKeyDown(2 /* deviceId */);
2213 expectKeyRepeatOnce(1 /*repeatCount*/);
2214 // Stale key up from device 1.
2215 sendAndConsumeKeyUp(1 /* deviceId */);
2216 // Device 2 is still down, keep repeating
2217 expectKeyRepeatOnce(2 /*repeatCount*/);
2218 expectKeyRepeatOnce(3 /*repeatCount*/);
2219 // Device 2 key up
2220 sendAndConsumeKeyUp(2 /* deviceId */);
2221 mWindow->assertNoEvents();
2222}
2223
2224TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_KeyRepeatStopsAfterRepeatingKeyUp) {
2225 sendAndConsumeKeyDown(1 /* deviceId */);
2226 expectKeyRepeatOnce(1 /*repeatCount*/);
2227 sendAndConsumeKeyDown(2 /* deviceId */);
2228 expectKeyRepeatOnce(1 /*repeatCount*/);
2229 // Device 2 which holds the key repeating goes up, expect the repeating to stop.
2230 sendAndConsumeKeyUp(2 /* deviceId */);
2231 // Device 1 still holds key down, but the repeating was already stopped
Garfield Tan1c7bc862020-01-28 13:24:04 -08002232 mWindow->assertNoEvents();
2233}
2234
2235TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseEventIdFromInputDispatcher) {
Chris Ye2ad95392020-09-01 13:44:44 -07002236 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002237 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2238 InputEvent* repeatEvent = mWindow->consume();
2239 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2240 EXPECT_EQ(IdGenerator::Source::INPUT_DISPATCHER,
2241 IdGenerator::getSource(repeatEvent->getId()));
2242 }
2243}
2244
2245TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseUniqueEventId) {
Chris Ye2ad95392020-09-01 13:44:44 -07002246 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002247
2248 std::unordered_set<int32_t> idSet;
2249 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2250 InputEvent* repeatEvent = mWindow->consume();
2251 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2252 int32_t id = repeatEvent->getId();
2253 EXPECT_EQ(idSet.end(), idSet.find(id));
2254 idSet.insert(id);
2255 }
2256}
2257
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002258/* Test InputDispatcher for MultiDisplay */
2259class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
2260public:
2261 static constexpr int32_t SECOND_DISPLAY_ID = 1;
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002262 virtual void SetUp() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002263 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +08002264
Chris Yea209fde2020-07-22 13:54:51 -07002265 application1 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002266 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
2267 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002268
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002269 // Set focus window for primary display, but focused display would be second one.
2270 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
Vishnu Nair47074b82020-08-14 11:54:47 -07002271 windowInPrimary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002272 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002273 setFocusedWindow(windowInPrimary);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002274 windowInPrimary->consumeFocusEvent(true);
Arthur Hungb92218b2018-08-14 12:00:21 +08002275
Chris Yea209fde2020-07-22 13:54:51 -07002276 application2 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002277 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
2278 SECOND_DISPLAY_ID);
2279 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002280 // Set focus display to second one.
2281 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
2282 // Set focus window for second display.
2283 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
Vishnu Nair47074b82020-08-14 11:54:47 -07002284 windowInSecondary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002285 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002286 setFocusedWindow(windowInSecondary);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002287 windowInSecondary->consumeFocusEvent(true);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002288 }
2289
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002290 virtual void TearDown() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002291 InputDispatcherTest::TearDown();
2292
Chris Yea209fde2020-07-22 13:54:51 -07002293 application1.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002294 windowInPrimary.clear();
Chris Yea209fde2020-07-22 13:54:51 -07002295 application2.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002296 windowInSecondary.clear();
2297 }
2298
2299protected:
Chris Yea209fde2020-07-22 13:54:51 -07002300 std::shared_ptr<FakeApplicationHandle> application1;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002301 sp<FakeWindowHandle> windowInPrimary;
Chris Yea209fde2020-07-22 13:54:51 -07002302 std::shared_ptr<FakeApplicationHandle> application2;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002303 sp<FakeWindowHandle> windowInSecondary;
2304};
2305
2306TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
2307 // Test touch down on primary display.
2308 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2309 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08002310 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002311 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08002312 windowInSecondary->assertNoEvents();
2313
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002314 // Test touch down on second display.
2315 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2316 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +08002317 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2318 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002319 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +08002320}
2321
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002322TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002323 // Test inject a key down with display id specified.
2324 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2325 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002326 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +08002327 windowInSecondary->assertNoEvents();
2328
2329 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +08002330 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2331 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2332 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002333 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +08002334
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002335 // Remove all windows in secondary display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002336 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
Arthur Hungb92218b2018-08-14 12:00:21 +08002337
2338 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002339 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
2340 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +08002341
2342 // Test inject a key down, should timeout because of no target window.
2343 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2344 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2345 windowInPrimary->assertNoEvents();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002346 windowInSecondary->consumeFocusEvent(false);
Arthur Hungb92218b2018-08-14 12:00:21 +08002347 windowInSecondary->assertNoEvents();
2348}
2349
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002350// Test per-display input monitors for motion event.
2351TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
chaviwd1c23182019-12-20 18:44:56 -08002352 FakeMonitorReceiver monitorInPrimary =
2353 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2354 FakeMonitorReceiver monitorInSecondary =
2355 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002356
2357 // Test touch down on primary display.
2358 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2359 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
2360 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002361 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08002362 monitorInPrimary.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002363 windowInSecondary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002364 monitorInSecondary.assertNoEvents();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002365
2366 // Test touch down on second display.
2367 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2368 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
2369 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2370 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002371 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002372 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
chaviwd1c23182019-12-20 18:44:56 -08002373 monitorInSecondary.consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002374
2375 // Test inject a non-pointer motion event.
2376 // If specific a display, it will dispatch to the focused window of particular display,
2377 // or it will dispatch to the focused window of focused display.
2378 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2379 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
2380 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2381 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002382 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002383 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002384 monitorInSecondary.consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002385}
2386
2387// Test per-display input monitors for key event.
2388TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
2389 //Input monitor per display.
chaviwd1c23182019-12-20 18:44:56 -08002390 FakeMonitorReceiver monitorInPrimary =
2391 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2392 FakeMonitorReceiver monitorInSecondary =
2393 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002394
2395 // Test inject a key down.
2396 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2397 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2398 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002399 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002400 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002401 monitorInSecondary.consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002402}
2403
Vishnu Nair958da932020-08-21 17:12:37 -07002404TEST_F(InputDispatcherFocusOnTwoDisplaysTest, CanFocusWindowOnUnfocusedDisplay) {
2405 sp<FakeWindowHandle> secondWindowInPrimary =
2406 new FakeWindowHandle(application1, mDispatcher, "D_1_W2", ADISPLAY_ID_DEFAULT);
2407 secondWindowInPrimary->setFocusable(true);
2408 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary, secondWindowInPrimary}}});
2409 setFocusedWindow(secondWindowInPrimary);
2410 windowInPrimary->consumeFocusEvent(false);
2411 secondWindowInPrimary->consumeFocusEvent(true);
2412
2413 // Test inject a key down.
2414 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2415 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2416 windowInPrimary->assertNoEvents();
2417 windowInSecondary->assertNoEvents();
2418 secondWindowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2419}
2420
Jackal Guof9696682018-10-05 12:23:23 +08002421class InputFilterTest : public InputDispatcherTest {
2422protected:
2423 static constexpr int32_t SECOND_DISPLAY_ID = 1;
2424
2425 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
2426 NotifyMotionArgs motionArgs;
2427
2428 motionArgs = generateMotionArgs(
2429 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2430 mDispatcher->notifyMotion(&motionArgs);
2431 motionArgs = generateMotionArgs(
2432 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2433 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002434 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002435 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002436 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002437 } else {
2438 mFakePolicy->assertFilterInputEventWasNotCalled();
2439 }
2440 }
2441
2442 void testNotifyKey(bool expectToBeFiltered) {
2443 NotifyKeyArgs keyArgs;
2444
2445 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
2446 mDispatcher->notifyKey(&keyArgs);
2447 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
2448 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002449 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002450
2451 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002452 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002453 } else {
2454 mFakePolicy->assertFilterInputEventWasNotCalled();
2455 }
2456 }
2457};
2458
2459// Test InputFilter for MotionEvent
2460TEST_F(InputFilterTest, MotionEvent_InputFilter) {
2461 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
2462 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2463 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2464
2465 // Enable InputFilter
2466 mDispatcher->setInputFilterEnabled(true);
2467 // Test touch on both primary and second display, and check if both events are filtered.
2468 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
2469 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
2470
2471 // Disable InputFilter
2472 mDispatcher->setInputFilterEnabled(false);
2473 // Test touch on both primary and second display, and check if both events aren't filtered.
2474 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2475 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2476}
2477
2478// Test InputFilter for KeyEvent
2479TEST_F(InputFilterTest, KeyEvent_InputFilter) {
2480 // Since the InputFilter is disabled by default, check if key event aren't filtered.
2481 testNotifyKey(/*expectToBeFiltered*/ false);
2482
2483 // Enable InputFilter
2484 mDispatcher->setInputFilterEnabled(true);
2485 // Send a key event, and check if it is filtered.
2486 testNotifyKey(/*expectToBeFiltered*/ true);
2487
2488 // Disable InputFilter
2489 mDispatcher->setInputFilterEnabled(false);
2490 // Send a key event, and check if it isn't filtered.
2491 testNotifyKey(/*expectToBeFiltered*/ false);
2492}
2493
chaviwfd6d3512019-03-25 13:23:49 -07002494class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002495 virtual void SetUp() override {
chaviwfd6d3512019-03-25 13:23:49 -07002496 InputDispatcherTest::SetUp();
2497
Chris Yea209fde2020-07-22 13:54:51 -07002498 std::shared_ptr<FakeApplicationHandle> application =
2499 std::make_shared<FakeApplicationHandle>();
chaviwfd6d3512019-03-25 13:23:49 -07002500 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
2501 ADISPLAY_ID_DEFAULT);
2502 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
2503 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2504 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002505 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002506
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002507 mFocusedWindow =
2508 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2509 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01002510 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002511
2512 // Set focused application.
2513 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07002514 mFocusedWindow->setFocusable(true);
chaviwfd6d3512019-03-25 13:23:49 -07002515
2516 // Expect one focus window exist in display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002517 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002518 setFocusedWindow(mFocusedWindow);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002519 mFocusedWindow->consumeFocusEvent(true);
chaviwfd6d3512019-03-25 13:23:49 -07002520 }
2521
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002522 virtual void TearDown() override {
chaviwfd6d3512019-03-25 13:23:49 -07002523 InputDispatcherTest::TearDown();
2524
2525 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002526 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07002527 }
2528
2529protected:
2530 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002531 sp<FakeWindowHandle> mFocusedWindow;
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002532 static constexpr PointF FOCUSED_WINDOW_TOUCH_POINT = {60, 60};
chaviwfd6d3512019-03-25 13:23:49 -07002533};
2534
2535// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2536// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
2537// the onPointerDownOutsideFocus callback.
2538TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002539 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2540 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2541 {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07002542 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002543 mUnfocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002544
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002545 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07002546 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
2547}
2548
2549// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
2550// DOWN on the window that doesn't have focus. Ensure no window received the
2551// onPointerDownOutsideFocus callback.
2552TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002553 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2554 injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07002555 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002556 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002557
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002558 ASSERT_TRUE(mDispatcher->waitForIdle());
2559 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002560}
2561
2562// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
2563// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
2564TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
2565 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2566 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002567 mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07002568
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002569 ASSERT_TRUE(mDispatcher->waitForIdle());
2570 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002571}
2572
2573// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2574// DOWN on the window that already has focus. Ensure no window received the
2575// onPointerDownOutsideFocus callback.
2576TEST_F(InputDispatcherOnPointerDownOutsideFocus,
2577 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002578 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2579 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002580 FOCUSED_WINDOW_TOUCH_POINT))
chaviwfd6d3512019-03-25 13:23:49 -07002581 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002582 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002583
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002584 ASSERT_TRUE(mDispatcher->waitForIdle());
2585 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002586}
2587
chaviwaf87b3e2019-10-01 16:59:28 -07002588// These tests ensures we can send touch events to a single client when there are multiple input
2589// windows that point to the same client token.
2590class InputDispatcherMultiWindowSameTokenTests : public InputDispatcherTest {
2591 virtual void SetUp() override {
2592 InputDispatcherTest::SetUp();
2593
Chris Yea209fde2020-07-22 13:54:51 -07002594 std::shared_ptr<FakeApplicationHandle> application =
2595 std::make_shared<FakeApplicationHandle>();
chaviwaf87b3e2019-10-01 16:59:28 -07002596 mWindow1 = new FakeWindowHandle(application, mDispatcher, "Fake Window 1",
2597 ADISPLAY_ID_DEFAULT);
2598 // Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
2599 // 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 +01002600 mWindow1->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2601 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002602 mWindow1->setFrame(Rect(0, 0, 100, 100));
2603
2604 mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
2605 ADISPLAY_ID_DEFAULT, mWindow1->getToken());
Michael Wright44753b12020-07-08 13:48:11 +01002606 mWindow2->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2607 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002608 mWindow2->setFrame(Rect(100, 100, 200, 200));
2609
Arthur Hung72d8dc32020-03-28 00:48:39 +00002610 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
chaviwaf87b3e2019-10-01 16:59:28 -07002611 }
2612
2613protected:
2614 sp<FakeWindowHandle> mWindow1;
2615 sp<FakeWindowHandle> mWindow2;
2616
2617 // Helper function to convert the point from screen coordinates into the window's space
2618 static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) {
chaviw1ff3d1e2020-07-01 15:53:47 -07002619 vec2 vals = windowInfo->transform.transform(point.x, point.y);
2620 return {vals.x, vals.y};
chaviwaf87b3e2019-10-01 16:59:28 -07002621 }
2622
2623 void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction,
2624 const std::vector<PointF>& points) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002625 const std::string name = window->getName();
chaviwaf87b3e2019-10-01 16:59:28 -07002626 InputEvent* event = window->consume();
2627
2628 ASSERT_NE(nullptr, event) << name.c_str()
2629 << ": consumer should have returned non-NULL event.";
2630
2631 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
2632 << name.c_str() << "expected " << inputEventTypeToString(AINPUT_EVENT_TYPE_MOTION)
2633 << " event, got " << inputEventTypeToString(event->getType()) << " event";
2634
2635 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
2636 EXPECT_EQ(expectedAction, motionEvent.getAction());
2637
2638 for (size_t i = 0; i < points.size(); i++) {
2639 float expectedX = points[i].x;
2640 float expectedY = points[i].y;
2641
2642 EXPECT_EQ(expectedX, motionEvent.getX(i))
2643 << "expected " << expectedX << " for x[" << i << "] coord of " << name.c_str()
2644 << ", got " << motionEvent.getX(i);
2645 EXPECT_EQ(expectedY, motionEvent.getY(i))
2646 << "expected " << expectedY << " for y[" << i << "] coord of " << name.c_str()
2647 << ", got " << motionEvent.getY(i);
2648 }
2649 }
chaviw9eaa22c2020-07-01 16:21:27 -07002650
2651 void touchAndAssertPositions(int32_t action, std::vector<PointF> touchedPoints,
2652 std::vector<PointF> expectedPoints) {
2653 NotifyMotionArgs motionArgs = generateMotionArgs(action, AINPUT_SOURCE_TOUCHSCREEN,
2654 ADISPLAY_ID_DEFAULT, touchedPoints);
2655 mDispatcher->notifyMotion(&motionArgs);
2656
2657 // Always consume from window1 since it's the window that has the InputReceiver
2658 consumeMotionEvent(mWindow1, action, expectedPoints);
2659 }
chaviwaf87b3e2019-10-01 16:59:28 -07002660};
2661
2662TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchSameScale) {
2663 // Touch Window 1
2664 PointF touchedPoint = {10, 10};
2665 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002666 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002667
2668 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002669 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002670
2671 // Touch Window 2
2672 touchedPoint = {150, 150};
2673 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002674 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002675}
2676
chaviw9eaa22c2020-07-01 16:21:27 -07002677TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchDifferentTransform) {
2678 // Set scale value for window2
chaviwaf87b3e2019-10-01 16:59:28 -07002679 mWindow2->setWindowScale(0.5f, 0.5f);
2680
2681 // Touch Window 1
2682 PointF touchedPoint = {10, 10};
2683 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002684 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002685 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002686 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002687
2688 // Touch Window 2
2689 touchedPoint = {150, 150};
2690 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002691 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
2692 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002693
chaviw9eaa22c2020-07-01 16:21:27 -07002694 // Update the transform so rotation is set
2695 mWindow2->setWindowTransform(0, -1, 1, 0);
2696 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
2697 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002698}
2699
chaviw9eaa22c2020-07-01 16:21:27 -07002700TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002701 mWindow2->setWindowScale(0.5f, 0.5f);
2702
2703 // Touch Window 1
2704 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2705 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002706 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002707
2708 // Touch Window 2
2709 int32_t actionPointerDown =
2710 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002711 touchedPoints.push_back(PointF{150, 150});
2712 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2713 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002714
chaviw9eaa22c2020-07-01 16:21:27 -07002715 // Release Window 2
2716 int32_t actionPointerUp =
2717 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2718 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2719 expectedPoints.pop_back();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002720
chaviw9eaa22c2020-07-01 16:21:27 -07002721 // Update the transform so rotation is set for Window 2
2722 mWindow2->setWindowTransform(0, -1, 1, 0);
2723 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2724 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002725}
2726
chaviw9eaa22c2020-07-01 16:21:27 -07002727TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchMoveDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002728 mWindow2->setWindowScale(0.5f, 0.5f);
2729
2730 // Touch Window 1
2731 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2732 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002733 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002734
2735 // Touch Window 2
2736 int32_t actionPointerDown =
2737 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002738 touchedPoints.push_back(PointF{150, 150});
2739 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002740
chaviw9eaa22c2020-07-01 16:21:27 -07002741 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002742
2743 // Move both windows
2744 touchedPoints = {{20, 20}, {175, 175}};
2745 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2746 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2747
chaviw9eaa22c2020-07-01 16:21:27 -07002748 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002749
chaviw9eaa22c2020-07-01 16:21:27 -07002750 // Release Window 2
2751 int32_t actionPointerUp =
2752 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2753 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2754 expectedPoints.pop_back();
2755
2756 // Touch Window 2
2757 mWindow2->setWindowTransform(0, -1, 1, 0);
2758 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2759 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
2760
2761 // Move both windows
2762 touchedPoints = {{20, 20}, {175, 175}};
2763 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2764 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2765
2766 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002767}
2768
2769TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithScale) {
2770 mWindow1->setWindowScale(0.5f, 0.5f);
2771
2772 // Touch Window 1
2773 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2774 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002775 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002776
2777 // Touch Window 2
2778 int32_t actionPointerDown =
2779 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002780 touchedPoints.push_back(PointF{150, 150});
2781 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002782
chaviw9eaa22c2020-07-01 16:21:27 -07002783 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002784
2785 // Move both windows
2786 touchedPoints = {{20, 20}, {175, 175}};
2787 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2788 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2789
chaviw9eaa22c2020-07-01 16:21:27 -07002790 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002791}
2792
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002793class InputDispatcherSingleWindowAnr : public InputDispatcherTest {
2794 virtual void SetUp() override {
2795 InputDispatcherTest::SetUp();
2796
Chris Yea209fde2020-07-22 13:54:51 -07002797 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002798 mApplication->setDispatchingTimeout(20ms);
2799 mWindow =
2800 new FakeWindowHandle(mApplication, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2801 mWindow->setFrame(Rect(0, 0, 30, 30));
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05002802 mWindow->setDispatchingTimeout(30ms);
Vishnu Nair47074b82020-08-14 11:54:47 -07002803 mWindow->setFocusable(true);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002804 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2805 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002806 mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002807
2808 // Set focused application.
2809 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
2810
2811 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002812 setFocusedWindow(mWindow);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002813 mWindow->consumeFocusEvent(true);
2814 }
2815
2816 virtual void TearDown() override {
2817 InputDispatcherTest::TearDown();
2818 mWindow.clear();
2819 }
2820
2821protected:
Chris Yea209fde2020-07-22 13:54:51 -07002822 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002823 sp<FakeWindowHandle> mWindow;
2824 static constexpr PointF WINDOW_LOCATION = {20, 20};
2825
2826 void tapOnWindow() {
2827 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2828 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2829 WINDOW_LOCATION));
2830 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2831 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2832 WINDOW_LOCATION));
2833 }
2834};
2835
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002836// Send a tap and respond, which should not cause an ANR.
2837TEST_F(InputDispatcherSingleWindowAnr, WhenTouchIsConsumed_NoAnr) {
2838 tapOnWindow();
2839 mWindow->consumeMotionDown();
2840 mWindow->consumeMotionUp();
2841 ASSERT_TRUE(mDispatcher->waitForIdle());
2842 mFakePolicy->assertNotifyAnrWasNotCalled();
2843}
2844
2845// Send a regular key and respond, which should not cause an ANR.
2846TEST_F(InputDispatcherSingleWindowAnr, WhenKeyIsConsumed_NoAnr) {
2847 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
2848 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
2849 ASSERT_TRUE(mDispatcher->waitForIdle());
2850 mFakePolicy->assertNotifyAnrWasNotCalled();
2851}
2852
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05002853TEST_F(InputDispatcherSingleWindowAnr, WhenFocusedApplicationChanges_NoAnr) {
2854 mWindow->setFocusable(false);
2855 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2856 mWindow->consumeFocusEvent(false);
2857
2858 int32_t result =
2859 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
2860 INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
2861 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
2862 // Key will not go to window because we have no focused window.
2863 // The 'no focused window' ANR timer should start instead.
2864
2865 // Now, the focused application goes away.
2866 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, nullptr);
2867 // The key should get dropped and there should be no ANR.
2868
2869 ASSERT_TRUE(mDispatcher->waitForIdle());
2870 mFakePolicy->assertNotifyAnrWasNotCalled();
2871}
2872
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002873// Send an event to the app and have the app not respond right away.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002874// When ANR is raised, policy will tell the dispatcher to cancel the events for that window.
2875// So InputDispatcher will enqueue ACTION_CANCEL event as well.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002876TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) {
2877 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2878 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2879 WINDOW_LOCATION));
2880
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002881 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent(); // ACTION_DOWN
2882 ASSERT_TRUE(sequenceNum);
2883 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2884 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002885
2886 // The remaining lines are not really needed for the test, but kept as a sanity check
2887 mWindow->finishEvent(*sequenceNum);
2888 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
2889 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002890 ASSERT_TRUE(mDispatcher->waitForIdle());
2891}
2892
2893// Send a key to the app and have the app not respond right away.
2894TEST_F(InputDispatcherSingleWindowAnr, OnKeyDown_BasicAnr) {
2895 // Inject a key, and don't respond - expect that ANR is called.
2896 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
2897 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent();
2898 ASSERT_TRUE(sequenceNum);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002899 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002900 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002901 ASSERT_TRUE(mDispatcher->waitForIdle());
2902}
2903
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002904// We have a focused application, but no focused window
2905TEST_F(InputDispatcherSingleWindowAnr, FocusedApplication_NoFocusedWindow) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002906 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002907 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2908 mWindow->consumeFocusEvent(false);
2909
2910 // taps on the window work as normal
2911 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2912 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2913 WINDOW_LOCATION));
2914 ASSERT_NO_FATAL_FAILURE(mWindow->consumeMotionDown());
2915 mDispatcher->waitForIdle();
2916 mFakePolicy->assertNotifyAnrWasNotCalled();
2917
2918 // Once a focused event arrives, we get an ANR for this application
2919 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2920 // injection times out (instead of failing).
2921 const int32_t result =
2922 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2923 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2924 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2925 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2926 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2927 ASSERT_TRUE(mDispatcher->waitForIdle());
2928}
2929
2930// We have a focused application, but no focused window
2931// If the policy wants to keep waiting on the focused window to be added, make sure
2932// that this timeout extension is honored and ANR is raised again.
2933TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_ExtendsAnr) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002934 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002935 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2936 mWindow->consumeFocusEvent(false);
2937 const std::chrono::duration timeout = 5ms;
2938 mFakePolicy->setAnrTimeout(timeout);
2939
2940 // Once a focused event arrives, we get an ANR for this application
2941 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2942 // injection times out (instead of failing).
2943 const int32_t result =
2944 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2945 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2946 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2947 const std::chrono::duration appTimeout =
2948 mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2949 mFakePolicy->assertNotifyAnrWasCalled(appTimeout, mApplication, nullptr /*windowToken*/);
2950
2951 // After the extended time has passed, ANR should be raised again
2952 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2953
2954 // If we stop extending the timeout, dispatcher should go to idle.
2955 // Another ANR may be raised during this time
2956 mFakePolicy->setAnrTimeout(0ms);
2957 ASSERT_TRUE(mDispatcher->waitForIdle());
2958}
2959
2960// We have a focused application, but no focused window
2961TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_DropsFocusedEvents) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002962 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002963 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2964 mWindow->consumeFocusEvent(false);
2965
2966 // Once a focused event arrives, we get an ANR for this application
2967 const int32_t result =
2968 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2969 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2970 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2971
2972 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2973 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2974
2975 // Future focused events get dropped right away
2976 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, injectKeyDown(mDispatcher));
2977 ASSERT_TRUE(mDispatcher->waitForIdle());
2978 mWindow->assertNoEvents();
2979}
2980
2981/**
2982 * Ensure that the implementation is valid. Since we are using multiset to keep track of the
2983 * ANR timeouts, we are allowing entries with identical timestamps in the same connection.
2984 * If we process 1 of the events, but ANR on the second event with the same timestamp,
2985 * the ANR mechanism should still work.
2986 *
2987 * In this test, we are injecting DOWN and UP events with the same timestamps, and acknowledging the
2988 * DOWN event, while not responding on the second one.
2989 */
2990TEST_F(InputDispatcherSingleWindowAnr, Anr_HandlesEventsWithIdenticalTimestamps) {
2991 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
2992 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2993 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
2994 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
2995 AMOTION_EVENT_INVALID_CURSOR_POSITION},
2996 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
2997
2998 // Now send ACTION_UP, with identical timestamp
2999 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
3000 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
3001 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
3002 AMOTION_EVENT_INVALID_CURSOR_POSITION},
3003 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
3004
3005 // We have now sent down and up. Let's consume first event and then ANR on the second.
3006 mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
3007 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3008 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3009}
3010
3011// If an app is not responding to a key event, gesture monitors should continue to receive
3012// new motion events
3013TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnKey) {
3014 FakeMonitorReceiver monitor =
3015 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
3016 true /*isGestureMonitor*/);
3017
3018 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT));
3019 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3020 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher, ADISPLAY_ID_DEFAULT));
3021
3022 // Stuck on the ACTION_UP
3023 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3024 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
3025
3026 // New tap will go to the gesture monitor, but not to the window
3027 tapOnWindow();
3028 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3029 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3030
3031 mWindow->consumeKeyUp(ADISPLAY_ID_DEFAULT); // still the previous motion
3032 mDispatcher->waitForIdle();
3033 mWindow->assertNoEvents();
3034 monitor.assertNoEvents();
3035}
3036
3037// If an app is not responding to a motion event, gesture monitors should continue to receive
3038// new motion events
3039TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnMotion) {
3040 FakeMonitorReceiver monitor =
3041 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
3042 true /*isGestureMonitor*/);
3043
3044 tapOnWindow();
3045 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3046 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3047
3048 mWindow->consumeMotionDown();
3049 // Stuck on the ACTION_UP
3050 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3051 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
3052
3053 // New tap will go to the gesture monitor, but not to the window
3054 tapOnWindow();
3055 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3056 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3057
3058 mWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT); // still the previous motion
3059 mDispatcher->waitForIdle();
3060 mWindow->assertNoEvents();
3061 monitor.assertNoEvents();
3062}
3063
3064// If a window is unresponsive, then you get anr. if the window later catches up and starts to
3065// process events, you don't get an anr. When the window later becomes unresponsive again, you
3066// get an ANR again.
3067// 1. tap -> block on ACTION_UP -> receive ANR
3068// 2. consume all pending events (= queue becomes healthy again)
3069// 3. tap again -> block on ACTION_UP again -> receive ANR second time
3070TEST_F(InputDispatcherSingleWindowAnr, SameWindow_CanReceiveAnrTwice) {
3071 tapOnWindow();
3072
3073 mWindow->consumeMotionDown();
3074 // Block on ACTION_UP
3075 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3076 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3077 mWindow->consumeMotionUp(); // Now the connection should be healthy again
3078 mDispatcher->waitForIdle();
3079 mWindow->assertNoEvents();
3080
3081 tapOnWindow();
3082 mWindow->consumeMotionDown();
3083 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3084 mWindow->consumeMotionUp();
3085
3086 mDispatcher->waitForIdle();
3087 mWindow->assertNoEvents();
3088}
3089
3090// If the policy tells us to raise ANR again after some time, ensure that the timeout extension
3091// is honored
3092TEST_F(InputDispatcherSingleWindowAnr, Policy_CanExtendTimeout) {
3093 const std::chrono::duration timeout = 5ms;
3094 mFakePolicy->setAnrTimeout(timeout);
3095
3096 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3097 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3098 WINDOW_LOCATION));
3099
3100 const std::chrono::duration windowTimeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3101 mFakePolicy->assertNotifyAnrWasCalled(windowTimeout, nullptr /*application*/,
3102 mWindow->getToken());
3103
3104 // Since the policy wanted to extend ANR, make sure it is called again after the extension
3105 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3106 mFakePolicy->setAnrTimeout(0ms);
3107 std::this_thread::sleep_for(windowTimeout);
3108 // We are not checking if ANR has been called, because it may have been called again by the
3109 // time we set the timeout to 0
3110
3111 // When the policy finally says stop, we should get ACTION_CANCEL
3112 mWindow->consumeMotionDown();
3113 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
3114 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3115 mWindow->assertNoEvents();
3116}
3117
3118/**
3119 * If a window is processing a motion event, and then a key event comes in, the key event should
3120 * not to to the focused window until the motion is processed.
3121 *
3122 * Warning!!!
3123 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
3124 * and the injection timeout that we specify when injecting the key.
3125 * We must have the injection timeout (10ms) be smaller than
3126 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
3127 *
3128 * If that value changes, this test should also change.
3129 */
3130TEST_F(InputDispatcherSingleWindowAnr, Key_StaysPendingWhileMotionIsProcessed) {
3131 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
3132 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
3133
3134 tapOnWindow();
3135 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
3136 ASSERT_TRUE(downSequenceNum);
3137 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
3138 ASSERT_TRUE(upSequenceNum);
3139 // Don't finish the events yet, and send a key
3140 // Injection will "succeed" because we will eventually give up and send the key to the focused
3141 // window even if motions are still being processed. But because the injection timeout is short,
3142 // we will receive INJECTION_TIMED_OUT as the result.
3143
3144 int32_t result =
3145 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
3146 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
3147 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
3148 // Key will not be sent to the window, yet, because the window is still processing events
3149 // and the key remains pending, waiting for the touch events to be processed
3150 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
3151 ASSERT_FALSE(keySequenceNum);
3152
3153 std::this_thread::sleep_for(500ms);
3154 // if we wait long enough though, dispatcher will give up, and still send the key
3155 // to the focused window, even though we have not yet finished the motion event
3156 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3157 mWindow->finishEvent(*downSequenceNum);
3158 mWindow->finishEvent(*upSequenceNum);
3159}
3160
3161/**
3162 * If a window is processing a motion event, and then a key event comes in, the key event should
3163 * not go to the focused window until the motion is processed.
3164 * If then a new motion comes in, then the pending key event should be going to the currently
3165 * focused window right away.
3166 */
3167TEST_F(InputDispatcherSingleWindowAnr,
3168 PendingKey_IsDroppedWhileMotionIsProcessedAndNewTouchComesIn) {
3169 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
3170 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
3171
3172 tapOnWindow();
3173 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
3174 ASSERT_TRUE(downSequenceNum);
3175 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
3176 ASSERT_TRUE(upSequenceNum);
3177 // Don't finish the events yet, and send a key
3178 // Injection is async, so it will succeed
3179 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3180 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
3181 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
3182 // At this point, key is still pending, and should not be sent to the application yet.
3183 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
3184 ASSERT_FALSE(keySequenceNum);
3185
3186 // Now tap down again. It should cause the pending key to go to the focused window right away.
3187 tapOnWindow();
3188 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT); // it doesn't matter that we haven't ack'd
3189 // the other events yet. We can finish events in any order.
3190 mWindow->finishEvent(*downSequenceNum); // first tap's ACTION_DOWN
3191 mWindow->finishEvent(*upSequenceNum); // first tap's ACTION_UP
3192 mWindow->consumeMotionDown();
3193 mWindow->consumeMotionUp();
3194 mWindow->assertNoEvents();
3195}
3196
3197class InputDispatcherMultiWindowAnr : public InputDispatcherTest {
3198 virtual void SetUp() override {
3199 InputDispatcherTest::SetUp();
3200
Chris Yea209fde2020-07-22 13:54:51 -07003201 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003202 mApplication->setDispatchingTimeout(10ms);
3203 mUnfocusedWindow =
3204 new FakeWindowHandle(mApplication, mDispatcher, "Unfocused", ADISPLAY_ID_DEFAULT);
3205 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
3206 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
3207 // window.
3208 // Adding FLAG_WATCH_OUTSIDE_TOUCH to receive ACTION_OUTSIDE when another window is tapped
Michael Wright44753b12020-07-08 13:48:11 +01003209 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3210 InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
3211 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003212
3213 mFocusedWindow =
3214 new FakeWindowHandle(mApplication, mDispatcher, "Focused", ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05003215 mFocusedWindow->setDispatchingTimeout(30ms);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003216 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01003217 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3218 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003219
3220 // Set focused application.
3221 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
Vishnu Nair47074b82020-08-14 11:54:47 -07003222 mFocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003223
3224 // Expect one focus window exist in display.
3225 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07003226 setFocusedWindow(mFocusedWindow);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003227 mFocusedWindow->consumeFocusEvent(true);
3228 }
3229
3230 virtual void TearDown() override {
3231 InputDispatcherTest::TearDown();
3232
3233 mUnfocusedWindow.clear();
3234 mFocusedWindow.clear();
3235 }
3236
3237protected:
Chris Yea209fde2020-07-22 13:54:51 -07003238 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003239 sp<FakeWindowHandle> mUnfocusedWindow;
3240 sp<FakeWindowHandle> mFocusedWindow;
3241 static constexpr PointF UNFOCUSED_WINDOW_LOCATION = {20, 20};
3242 static constexpr PointF FOCUSED_WINDOW_LOCATION = {75, 75};
3243 static constexpr PointF LOCATION_OUTSIDE_ALL_WINDOWS = {40, 40};
3244
3245 void tapOnFocusedWindow() { tap(FOCUSED_WINDOW_LOCATION); }
3246
3247 void tapOnUnfocusedWindow() { tap(UNFOCUSED_WINDOW_LOCATION); }
3248
3249private:
3250 void tap(const PointF& location) {
3251 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3252 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3253 location));
3254 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3255 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3256 location));
3257 }
3258};
3259
3260// If we have 2 windows that are both unresponsive, the one with the shortest timeout
3261// should be ANR'd first.
3262TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsive) {
3263 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3264 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3265 FOCUSED_WINDOW_LOCATION))
3266 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3267 mFocusedWindow->consumeMotionDown();
3268 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3269 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3270 // We consumed all events, so no ANR
3271 ASSERT_TRUE(mDispatcher->waitForIdle());
3272 mFakePolicy->assertNotifyAnrWasNotCalled();
3273
3274 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3275 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3276 FOCUSED_WINDOW_LOCATION));
3277 std::optional<uint32_t> unfocusedSequenceNum = mUnfocusedWindow->receiveEvent();
3278 ASSERT_TRUE(unfocusedSequenceNum);
3279 std::optional<uint32_t> focusedSequenceNum = mFocusedWindow->receiveEvent();
3280 ASSERT_TRUE(focusedSequenceNum);
3281
3282 const std::chrono::duration timeout =
3283 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3284 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3285 mFocusedWindow->getToken());
3286
3287 mFocusedWindow->finishEvent(*focusedSequenceNum);
3288 mUnfocusedWindow->finishEvent(*unfocusedSequenceNum);
3289 ASSERT_TRUE(mDispatcher->waitForIdle());
3290}
3291
3292// If we have 2 windows with identical timeouts that are both unresponsive,
3293// it doesn't matter which order they should have ANR.
3294// But we should receive ANR for both.
3295TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsiveWithSameTimeout) {
3296 // Set the timeout for unfocused window to match the focused window
3297 mUnfocusedWindow->setDispatchingTimeout(10ms);
3298 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3299
3300 tapOnFocusedWindow();
3301 // we should have ACTION_DOWN/ACTION_UP on focused window and ACTION_OUTSIDE on unfocused window
Chris Yea209fde2020-07-22 13:54:51 -07003302 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData1 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003303 mFakePolicy->getNotifyAnrData(10ms);
Chris Yea209fde2020-07-22 13:54:51 -07003304 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData2 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003305 mFakePolicy->getNotifyAnrData(0ms);
3306
3307 // We don't know which window will ANR first. But both of them should happen eventually.
3308 ASSERT_TRUE(mFocusedWindow->getToken() == anrData1.second ||
3309 mFocusedWindow->getToken() == anrData2.second);
3310 ASSERT_TRUE(mUnfocusedWindow->getToken() == anrData1.second ||
3311 mUnfocusedWindow->getToken() == anrData2.second);
3312
3313 ASSERT_TRUE(mDispatcher->waitForIdle());
3314 mFakePolicy->assertNotifyAnrWasNotCalled();
3315}
3316
3317// If a window is already not responding, the second tap on the same window should be ignored.
3318// We should also log an error to account for the dropped event (not tested here).
3319// At the same time, FLAG_WATCH_OUTSIDE_TOUCH targets should not receive any events.
3320TEST_F(InputDispatcherMultiWindowAnr, DuringAnr_SecondTapIsIgnored) {
3321 tapOnFocusedWindow();
3322 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3323 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3324 // Receive the events, but don't respond
3325 std::optional<uint32_t> downEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_DOWN
3326 ASSERT_TRUE(downEventSequenceNum);
3327 std::optional<uint32_t> upEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_UP
3328 ASSERT_TRUE(upEventSequenceNum);
3329 const std::chrono::duration timeout =
3330 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3331 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3332 mFocusedWindow->getToken());
3333
3334 // Tap once again
3335 // We cannot use "tapOnFocusedWindow" because it asserts the injection result to be success
3336 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3337 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3338 FOCUSED_WINDOW_LOCATION));
3339 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3340 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3341 FOCUSED_WINDOW_LOCATION));
3342 // Unfocused window does not receive ACTION_OUTSIDE because the tapped window is not a
3343 // valid touch target
3344 mUnfocusedWindow->assertNoEvents();
3345
3346 // Consume the first tap
3347 mFocusedWindow->finishEvent(*downEventSequenceNum);
3348 mFocusedWindow->finishEvent(*upEventSequenceNum);
3349 ASSERT_TRUE(mDispatcher->waitForIdle());
3350 // The second tap did not go to the focused window
3351 mFocusedWindow->assertNoEvents();
3352 // should not have another ANR after the window just became healthy again
3353 mFakePolicy->assertNotifyAnrWasNotCalled();
3354}
3355
3356// If you tap outside of all windows, there will not be ANR
3357TEST_F(InputDispatcherMultiWindowAnr, TapOutsideAllWindows_DoesNotAnr) {
3358 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3359 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3360 LOCATION_OUTSIDE_ALL_WINDOWS));
3361 ASSERT_TRUE(mDispatcher->waitForIdle());
3362 mFakePolicy->assertNotifyAnrWasNotCalled();
3363}
3364
3365// Since the focused window is paused, tapping on it should not produce any events
3366TEST_F(InputDispatcherMultiWindowAnr, Window_CanBePaused) {
3367 mFocusedWindow->setPaused(true);
3368 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3369
3370 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3371 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3372 FOCUSED_WINDOW_LOCATION));
3373
3374 std::this_thread::sleep_for(mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT));
3375 ASSERT_TRUE(mDispatcher->waitForIdle());
3376 // Should not ANR because the window is paused, and touches shouldn't go to it
3377 mFakePolicy->assertNotifyAnrWasNotCalled();
3378
3379 mFocusedWindow->assertNoEvents();
3380 mUnfocusedWindow->assertNoEvents();
3381}
3382
3383/**
3384 * If a window is processing a motion event, and then a key event comes in, the key event should
3385 * not to to the focused window until the motion is processed.
3386 * If a different window becomes focused at this time, the key should go to that window instead.
3387 *
3388 * Warning!!!
3389 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
3390 * and the injection timeout that we specify when injecting the key.
3391 * We must have the injection timeout (10ms) be smaller than
3392 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
3393 *
3394 * If that value changes, this test should also change.
3395 */
3396TEST_F(InputDispatcherMultiWindowAnr, PendingKey_GoesToNewlyFocusedWindow) {
3397 // Set a long ANR timeout to prevent it from triggering
3398 mFocusedWindow->setDispatchingTimeout(2s);
3399 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3400
3401 tapOnUnfocusedWindow();
3402 std::optional<uint32_t> downSequenceNum = mUnfocusedWindow->receiveEvent();
3403 ASSERT_TRUE(downSequenceNum);
3404 std::optional<uint32_t> upSequenceNum = mUnfocusedWindow->receiveEvent();
3405 ASSERT_TRUE(upSequenceNum);
3406 // Don't finish the events yet, and send a key
3407 // Injection will succeed because we will eventually give up and send the key to the focused
3408 // window even if motions are still being processed.
3409
3410 int32_t result =
3411 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
3412 INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
3413 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
3414 // Key will not be sent to the window, yet, because the window is still processing events
3415 // and the key remains pending, waiting for the touch events to be processed
3416 std::optional<uint32_t> keySequenceNum = mFocusedWindow->receiveEvent();
3417 ASSERT_FALSE(keySequenceNum);
3418
3419 // Switch the focus to the "unfocused" window that we tapped. Expect the key to go there
Vishnu Nair47074b82020-08-14 11:54:47 -07003420 mFocusedWindow->setFocusable(false);
3421 mUnfocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003422 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07003423 setFocusedWindow(mUnfocusedWindow);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003424
3425 // Focus events should precede the key events
3426 mUnfocusedWindow->consumeFocusEvent(true);
3427 mFocusedWindow->consumeFocusEvent(false);
3428
3429 // Finish the tap events, which should unblock dispatcher
3430 mUnfocusedWindow->finishEvent(*downSequenceNum);
3431 mUnfocusedWindow->finishEvent(*upSequenceNum);
3432
3433 // Now that all queues are cleared and no backlog in the connections, the key event
3434 // can finally go to the newly focused "mUnfocusedWindow".
3435 mUnfocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3436 mFocusedWindow->assertNoEvents();
3437 mUnfocusedWindow->assertNoEvents();
3438}
3439
3440// When the touch stream is split across 2 windows, and one of them does not respond,
3441// then ANR should be raised and the touch should be canceled for the unresponsive window.
3442// The other window should not be affected by that.
3443TEST_F(InputDispatcherMultiWindowAnr, SplitTouch_SingleWindowAnr) {
3444 // Touch Window 1
3445 NotifyMotionArgs motionArgs =
3446 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3447 ADISPLAY_ID_DEFAULT, {FOCUSED_WINDOW_LOCATION});
3448 mDispatcher->notifyMotion(&motionArgs);
3449 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3450 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3451
3452 // Touch Window 2
3453 int32_t actionPointerDown =
3454 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
3455
3456 motionArgs =
3457 generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3458 {FOCUSED_WINDOW_LOCATION, UNFOCUSED_WINDOW_LOCATION});
3459 mDispatcher->notifyMotion(&motionArgs);
3460
3461 const std::chrono::duration timeout =
3462 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3463 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3464 mFocusedWindow->getToken());
3465
3466 mUnfocusedWindow->consumeMotionDown();
3467 mFocusedWindow->consumeMotionDown();
3468 // Focused window may or may not receive ACTION_MOVE
3469 // But it should definitely receive ACTION_CANCEL due to the ANR
3470 InputEvent* event;
3471 std::optional<int32_t> moveOrCancelSequenceNum = mFocusedWindow->receiveEvent(&event);
3472 ASSERT_TRUE(moveOrCancelSequenceNum);
3473 mFocusedWindow->finishEvent(*moveOrCancelSequenceNum);
3474 ASSERT_NE(nullptr, event);
3475 ASSERT_EQ(event->getType(), AINPUT_EVENT_TYPE_MOTION);
3476 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
3477 if (motionEvent.getAction() == AMOTION_EVENT_ACTION_MOVE) {
3478 mFocusedWindow->consumeMotionCancel();
3479 } else {
3480 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionEvent.getAction());
3481 }
3482
3483 ASSERT_TRUE(mDispatcher->waitForIdle());
3484 mUnfocusedWindow->assertNoEvents();
3485 mFocusedWindow->assertNoEvents();
3486}
3487
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003488// These tests ensure we cannot send touch events to a window that's positioned behind a window
3489// that has feature NO_INPUT_CHANNEL.
3490// Layout:
3491// Top (closest to user)
3492// mNoInputWindow (above all windows)
3493// mBottomWindow
3494// Bottom (furthest from user)
3495class InputDispatcherMultiWindowOcclusionTests : public InputDispatcherTest {
3496 virtual void SetUp() override {
3497 InputDispatcherTest::SetUp();
3498
3499 mApplication = std::make_shared<FakeApplicationHandle>();
3500 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3501 "Window without input channel", ADISPLAY_ID_DEFAULT,
3502 std::make_optional<sp<IBinder>>(nullptr) /*token*/);
3503
3504 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3505 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3506 // It's perfectly valid for this window to not have an associated input channel
3507
3508 mBottomWindow = new FakeWindowHandle(mApplication, mDispatcher, "Bottom window",
3509 ADISPLAY_ID_DEFAULT);
3510 mBottomWindow->setFrame(Rect(0, 0, 100, 100));
3511
3512 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3513 }
3514
3515protected:
3516 std::shared_ptr<FakeApplicationHandle> mApplication;
3517 sp<FakeWindowHandle> mNoInputWindow;
3518 sp<FakeWindowHandle> mBottomWindow;
3519};
3520
3521TEST_F(InputDispatcherMultiWindowOcclusionTests, NoInputChannelFeature_DropsTouches) {
3522 PointF touchedPoint = {10, 10};
3523
3524 NotifyMotionArgs motionArgs =
3525 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3526 ADISPLAY_ID_DEFAULT, {touchedPoint});
3527 mDispatcher->notifyMotion(&motionArgs);
3528
3529 mNoInputWindow->assertNoEvents();
3530 // Even though the window 'mNoInputWindow' positioned above 'mBottomWindow' does not have
3531 // an input channel, it is not marked as FLAG_NOT_TOUCHABLE,
3532 // and therefore should prevent mBottomWindow from receiving touches
3533 mBottomWindow->assertNoEvents();
3534}
3535
3536/**
3537 * If a window has feature NO_INPUT_CHANNEL, and somehow (by mistake) still has an input channel,
3538 * ensure that this window does not receive any touches, and blocks touches to windows underneath.
3539 */
3540TEST_F(InputDispatcherMultiWindowOcclusionTests,
3541 NoInputChannelFeature_DropsTouchesWithValidChannel) {
3542 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3543 "Window with input channel and NO_INPUT_CHANNEL",
3544 ADISPLAY_ID_DEFAULT);
3545
3546 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3547 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3548 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3549
3550 PointF touchedPoint = {10, 10};
3551
3552 NotifyMotionArgs motionArgs =
3553 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3554 ADISPLAY_ID_DEFAULT, {touchedPoint});
3555 mDispatcher->notifyMotion(&motionArgs);
3556
3557 mNoInputWindow->assertNoEvents();
3558 mBottomWindow->assertNoEvents();
3559}
3560
Vishnu Nair958da932020-08-21 17:12:37 -07003561class InputDispatcherMirrorWindowFocusTests : public InputDispatcherTest {
3562protected:
3563 std::shared_ptr<FakeApplicationHandle> mApp;
3564 sp<FakeWindowHandle> mWindow;
3565 sp<FakeWindowHandle> mMirror;
3566
3567 virtual void SetUp() override {
3568 InputDispatcherTest::SetUp();
3569 mApp = std::make_shared<FakeApplicationHandle>();
3570 mWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
3571 mMirror = new FakeWindowHandle(mApp, mDispatcher, "TestWindowMirror", ADISPLAY_ID_DEFAULT,
3572 mWindow->getToken());
3573 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
3574 mWindow->setFocusable(true);
3575 mMirror->setFocusable(true);
3576 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3577 }
3578};
3579
3580TEST_F(InputDispatcherMirrorWindowFocusTests, CanGetFocus) {
3581 // Request focus on a mirrored window
3582 setFocusedWindow(mMirror);
3583
3584 // window gets focused
3585 mWindow->consumeFocusEvent(true);
3586 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3587 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3588 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3589}
3590
3591// A focused & mirrored window remains focused only if the window and its mirror are both
3592// focusable.
3593TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAllWindowsFocusable) {
3594 setFocusedWindow(mMirror);
3595
3596 // window gets focused
3597 mWindow->consumeFocusEvent(true);
3598 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3599 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3600 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3601 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3602 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3603 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3604
3605 mMirror->setFocusable(false);
3606 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3607
3608 // window loses focus since one of the windows associated with the token in not focusable
3609 mWindow->consumeFocusEvent(false);
3610
3611 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3612 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3613 mWindow->assertNoEvents();
3614}
3615
3616// A focused & mirrored window remains focused until the window and its mirror both become
3617// invisible.
3618TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAnyWindowVisible) {
3619 setFocusedWindow(mMirror);
3620
3621 // window gets focused
3622 mWindow->consumeFocusEvent(true);
3623 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3624 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3625 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3626 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3627 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3628 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3629
3630 mMirror->setVisible(false);
3631 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3632
3633 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3634 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3635 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3636 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3637 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3638 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3639
3640 mWindow->setVisible(false);
3641 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3642
3643 // window loses focus only after all windows associated with the token become invisible.
3644 mWindow->consumeFocusEvent(false);
3645
3646 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3647 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3648 mWindow->assertNoEvents();
3649}
3650
3651// A focused & mirrored window remains focused until both windows are removed.
3652TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedWhileWindowsAlive) {
3653 setFocusedWindow(mMirror);
3654
3655 // window gets focused
3656 mWindow->consumeFocusEvent(true);
3657 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3658 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3659 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3660 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3661 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3662 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3663
3664 // single window is removed but the window token remains focused
3665 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mMirror}}});
3666
3667 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3668 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3669 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3670 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3671 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3672 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3673
3674 // Both windows are removed
3675 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {}}});
3676 mWindow->consumeFocusEvent(false);
3677
3678 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3679 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3680 mWindow->assertNoEvents();
3681}
3682
3683// Focus request can be pending until one window becomes visible.
3684TEST_F(InputDispatcherMirrorWindowFocusTests, DeferFocusWhenInvisible) {
3685 // Request focus on an invisible mirror.
3686 mWindow->setVisible(false);
3687 mMirror->setVisible(false);
3688 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3689 setFocusedWindow(mMirror);
3690
3691 // Injected key goes to pending queue.
3692 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3693 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
3694 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
3695
3696 mMirror->setVisible(true);
3697 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3698
3699 // window gets focused
3700 mWindow->consumeFocusEvent(true);
3701 // window gets the pending key event
3702 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3703}
Garfield Tane84e6f92019-08-29 17:28:41 -07003704} // namespace android::inputdispatcher