blob: 662b8d0d05d0cc32f7e5bc258127f9c7fdde05e7 [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";
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500155 return {};
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700156 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700157 // Ensure that the ANR didn't get raised too early. We can't be too strict here because
158 // the dispatcher started counting before this function was called
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700159 if (std::chrono::abs(timeout - waited) > 100ms) {
160 ADD_FAILURE() << "ANR was raised too early or too late. Expected "
161 << std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count()
162 << "ms, but waited "
163 << std::chrono::duration_cast<std::chrono::milliseconds>(waited).count()
164 << "ms instead";
165 }
Chris Yea209fde2020-07-22 13:54:51 -0700166 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> result =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700167 std::make_pair(mAnrApplications.front(), mAnrWindowTokens.front());
168 mAnrApplications.pop();
169 mAnrWindowTokens.pop();
170 return result;
171 }
172
173 void assertNotifyAnrWasNotCalled() {
174 std::scoped_lock lock(mLock);
175 ASSERT_TRUE(mAnrApplications.empty());
176 ASSERT_TRUE(mAnrWindowTokens.empty());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700177 }
178
Garfield Tan1c7bc862020-01-28 13:24:04 -0800179 void setKeyRepeatConfiguration(nsecs_t timeout, nsecs_t delay) {
180 mConfig.keyRepeatTimeout = timeout;
181 mConfig.keyRepeatDelay = delay;
182 }
183
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700184 void setAnrTimeout(std::chrono::nanoseconds timeout) { mAnrTimeout = timeout; }
185
Michael Wrightd02c5b62014-02-10 15:10:22 -0800186private:
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700187 std::mutex mLock;
188 std::unique_ptr<InputEvent> mFilteredEvent GUARDED_BY(mLock);
189 std::optional<nsecs_t> mConfigurationChangedTime GUARDED_BY(mLock);
190 sp<IBinder> mOnPointerDownToken GUARDED_BY(mLock);
191 std::optional<NotifySwitchArgs> mLastNotifySwitch GUARDED_BY(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800192
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700193 // ANR handling
Chris Yea209fde2020-07-22 13:54:51 -0700194 std::queue<std::shared_ptr<InputApplicationHandle>> mAnrApplications GUARDED_BY(mLock);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700195 std::queue<sp<IBinder>> mAnrWindowTokens GUARDED_BY(mLock);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700196 std::condition_variable mNotifyAnr;
197 std::chrono::nanoseconds mAnrTimeout = 0ms;
198
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800199 virtual void notifyConfigurationChanged(nsecs_t when) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700200 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800201 mConfigurationChangedTime = when;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202 }
203
Chris Yea209fde2020-07-22 13:54:51 -0700204 std::chrono::nanoseconds notifyAnr(const std::shared_ptr<InputApplicationHandle>& application,
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500205 const sp<IBinder>& windowToken,
206 const std::string&) override {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700207 std::scoped_lock lock(mLock);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700208 mAnrApplications.push(application);
209 mAnrWindowTokens.push(windowToken);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700210 mNotifyAnr.notify_all();
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500211 return mAnrTimeout;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800212 }
213
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700214 virtual void notifyInputChannelBroken(const sp<IBinder>&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800215
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700216 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) override {}
Robert Carr740167f2018-10-11 19:03:41 -0700217
Bernardo Rufino2e1f6512020-10-08 13:42:07 +0000218 virtual void notifyUntrustedTouch(const std::string& obscuringPackage) override {}
219
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700220 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 *outConfig = mConfig;
222 }
223
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800224 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700225 std::scoped_lock lock(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800226 switch (inputEvent->getType()) {
227 case AINPUT_EVENT_TYPE_KEY: {
228 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800229 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800230 break;
231 }
232
233 case AINPUT_EVENT_TYPE_MOTION: {
234 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800235 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800236 break;
237 }
238 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800239 return true;
240 }
241
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700242 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800243
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700244 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800245
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700246 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent*,
247 uint32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800248 return 0;
249 }
250
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700251 virtual bool dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent*, uint32_t,
252 KeyEvent*) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800253 return false;
254 }
255
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800256 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
257 uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700258 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800259 /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
260 * essentially a passthrough for notifySwitch.
261 */
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800262 mLastNotifySwitch = NotifySwitchArgs(1 /*id*/, when, policyFlags, switchValues, switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800263 }
264
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700265 virtual void pokeUserActivity(nsecs_t, int32_t) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800266
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700267 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800268 return false;
269 }
Jackal Guof9696682018-10-05 12:23:23 +0800270
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700271 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700272 std::scoped_lock lock(mLock);
chaviwfd6d3512019-03-25 13:23:49 -0700273 mOnPointerDownToken = newToken;
274 }
275
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800276 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
277 int32_t displayId) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700278 std::scoped_lock lock(mLock);
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800279 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
280 ASSERT_EQ(mFilteredEvent->getType(), type);
281
282 if (type == AINPUT_EVENT_TYPE_KEY) {
283 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
284 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
285 EXPECT_EQ(keyEvent.getAction(), action);
286 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
287 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
288 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
289 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
290 EXPECT_EQ(motionEvent.getAction(), action);
291 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
292 } else {
293 FAIL() << "Unknown type: " << type;
294 }
295
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800296 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800297 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800298};
299
Michael Wrightd02c5b62014-02-10 15:10:22 -0800300// --- InputDispatcherTest ---
301
302class InputDispatcherTest : public testing::Test {
303protected:
304 sp<FakeInputDispatcherPolicy> mFakePolicy;
305 sp<InputDispatcher> mDispatcher;
306
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700307 virtual void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800308 mFakePolicy = new FakeInputDispatcherPolicy();
309 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800310 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
311 //Start InputDispatcher thread
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700312 ASSERT_EQ(OK, mDispatcher->start());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800313 }
314
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700315 virtual void TearDown() override {
316 ASSERT_EQ(OK, mDispatcher->stop());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800317 mFakePolicy.clear();
318 mDispatcher.clear();
319 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700320
321 /**
322 * Used for debugging when writing the test
323 */
324 void dumpDispatcherState() {
325 std::string dump;
326 mDispatcher->dump(dump);
327 std::stringstream ss(dump);
328 std::string to;
329
330 while (std::getline(ss, to, '\n')) {
331 ALOGE("%s", to.c_str());
332 }
333 }
Vishnu Nair958da932020-08-21 17:12:37 -0700334
335 void setFocusedWindow(const sp<InputWindowHandle>& window,
336 const sp<InputWindowHandle>& focusedWindow = nullptr) {
337 FocusRequest request;
338 request.token = window->getToken();
339 if (focusedWindow) {
340 request.focusedToken = focusedWindow->getToken();
341 }
342 request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
343 request.displayId = window->getInfo()->displayId;
344 mDispatcher->setFocusedWindow(request);
345 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800346};
347
348
349TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
350 KeyEvent event;
351
352 // Rejects undefined key actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800353 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
354 INVALID_HMAC,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600355 /*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME,
356 ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700357 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
358 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
359 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800360 << "Should reject key events with undefined action.";
361
362 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800363 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
364 INVALID_HMAC, AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600365 ARBITRARY_TIME, ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700366 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
367 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
368 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800369 << "Should reject key events with ACTION_MULTIPLE.";
370}
371
372TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
373 MotionEvent event;
374 PointerProperties pointerProperties[MAX_POINTERS + 1];
375 PointerCoords pointerCoords[MAX_POINTERS + 1];
376 for (int i = 0; i <= MAX_POINTERS; i++) {
377 pointerProperties[i].clear();
378 pointerProperties[i].id = i;
379 pointerCoords[i].clear();
380 }
381
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800382 // Some constants commonly used below
383 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
384 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
385 constexpr int32_t metaState = AMETA_NONE;
386 constexpr MotionClassification classification = MotionClassification::NONE;
387
chaviw9eaa22c2020-07-01 16:21:27 -0700388 ui::Transform identityTransform;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800389 // Rejects undefined motion actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800390 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
chaviw9eaa22c2020-07-01 16:21:27 -0700391 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification,
392 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600393 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700394 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700395 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
396 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
397 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800398 << "Should reject motion events with undefined action.";
399
400 // Rejects pointer down with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800401 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700402 AMOTION_EVENT_ACTION_POINTER_DOWN |
403 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700404 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
405 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
406 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
407 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700408 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
409 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
410 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800411 << "Should reject motion events with pointer down index too large.";
412
Garfield Tanfbe732e2020-01-24 11:26:14 -0800413 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700414 AMOTION_EVENT_ACTION_POINTER_DOWN |
415 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700416 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
417 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
418 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
419 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700420 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
421 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
422 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800423 << "Should reject motion events with pointer down index too small.";
424
425 // Rejects pointer up with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800426 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700427 AMOTION_EVENT_ACTION_POINTER_UP |
428 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700429 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
430 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
431 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
432 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700433 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
434 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
435 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800436 << "Should reject motion events with pointer up index too large.";
437
Garfield Tanfbe732e2020-01-24 11:26:14 -0800438 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700439 AMOTION_EVENT_ACTION_POINTER_UP |
440 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700441 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
442 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
443 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
444 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700445 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
446 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
447 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800448 << "Should reject motion events with pointer up index too small.";
449
450 // Rejects motion events with invalid number of pointers.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800451 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
452 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700453 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
454 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700455 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700456 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
457 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
458 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800459 << "Should reject motion events with 0 pointers.";
460
Garfield Tanfbe732e2020-01-24 11:26:14 -0800461 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
462 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700463 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
464 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700465 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700466 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
467 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
468 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800469 << "Should reject motion events with more than MAX_POINTERS pointers.";
470
471 // Rejects motion events with invalid pointer ids.
472 pointerProperties[0].id = -1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800473 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
474 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700475 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
476 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700477 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700478 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
479 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
480 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800481 << "Should reject motion events with pointer ids less than 0.";
482
483 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800484 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
485 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700486 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
487 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700488 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700489 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
490 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
491 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800492 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
493
494 // Rejects motion events with duplicate pointer ids.
495 pointerProperties[0].id = 1;
496 pointerProperties[1].id = 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800497 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
498 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700499 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
500 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700501 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700502 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
503 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
504 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800505 << "Should reject motion events with duplicate pointer ids.";
506}
507
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800508/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
509
510TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
511 constexpr nsecs_t eventTime = 20;
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800512 NotifyConfigurationChangedArgs args(10 /*id*/, eventTime);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800513 mDispatcher->notifyConfigurationChanged(&args);
514 ASSERT_TRUE(mDispatcher->waitForIdle());
515
516 mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
517}
518
519TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800520 NotifySwitchArgs args(10 /*id*/, 20 /*eventTime*/, 0 /*policyFlags*/, 1 /*switchValues*/,
521 2 /*switchMask*/);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800522 mDispatcher->notifySwitch(&args);
523
524 // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener
525 args.policyFlags |= POLICY_FLAG_TRUSTED;
526 mFakePolicy->assertNotifySwitchWasCalled(args);
527}
528
Arthur Hungb92218b2018-08-14 12:00:21 +0800529// --- InputDispatcherTest SetInputWindowTest ---
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700530static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 500ms;
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700531static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
Arthur Hungb92218b2018-08-14 12:00:21 +0800532
533class FakeApplicationHandle : public InputApplicationHandle {
534public:
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700535 FakeApplicationHandle() {
536 mInfo.name = "Fake Application";
537 mInfo.token = new BBinder();
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500538 mInfo.dispatchingTimeoutMillis =
539 std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700540 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800541 virtual ~FakeApplicationHandle() {}
542
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700543 virtual bool updateInfo() override {
Arthur Hungb92218b2018-08-14 12:00:21 +0800544 return true;
545 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700546
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500547 void setDispatchingTimeout(std::chrono::milliseconds timeout) {
548 mInfo.dispatchingTimeoutMillis = timeout.count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700549 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800550};
551
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800552class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800553public:
Garfield Tan15601662020-09-22 15:32:38 -0700554 explicit FakeInputReceiver(std::unique_ptr<InputChannel> clientChannel, const std::string name)
chaviwd1c23182019-12-20 18:44:56 -0800555 : mName(name) {
Garfield Tan15601662020-09-22 15:32:38 -0700556 mConsumer = std::make_unique<InputConsumer>(std::move(clientChannel));
chaviwd1c23182019-12-20 18:44:56 -0800557 }
558
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800559 InputEvent* consume() {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700560 InputEvent* event;
561 std::optional<uint32_t> consumeSeq = receiveEvent(&event);
562 if (!consumeSeq) {
563 return nullptr;
564 }
565 finishEvent(*consumeSeq);
566 return event;
567 }
568
569 /**
570 * Receive an event without acknowledging it.
571 * Return the sequence number that could later be used to send finished signal.
572 */
573 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800574 uint32_t consumeSeq;
575 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800576
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800577 std::chrono::time_point start = std::chrono::steady_clock::now();
578 status_t status = WOULD_BLOCK;
579 while (status == WOULD_BLOCK) {
chaviw81e2bb92019-12-18 15:03:51 -0800580 status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq,
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800581 &event);
582 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
583 if (elapsed > 100ms) {
584 break;
585 }
586 }
587
588 if (status == WOULD_BLOCK) {
589 // Just means there's no event available.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700590 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800591 }
592
593 if (status != OK) {
594 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700595 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800596 }
597 if (event == nullptr) {
598 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700599 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800600 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700601 if (outEvent != nullptr) {
602 *outEvent = event;
603 }
604 return consumeSeq;
605 }
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800606
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700607 /**
608 * To be used together with "receiveEvent" to complete the consumption of an event.
609 */
610 void finishEvent(uint32_t consumeSeq) {
611 const status_t status = mConsumer->sendFinishedSignal(consumeSeq, true);
612 ASSERT_EQ(OK, status) << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800613 }
614
615 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
616 int32_t expectedFlags) {
617 InputEvent* event = consume();
618
619 ASSERT_NE(nullptr, event) << mName.c_str()
620 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800621 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700622 << mName.c_str() << " expected " << inputEventTypeToString(expectedEventType)
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800623 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800624
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800625 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800626
Tiger Huang8664f8c2018-10-11 19:14:35 +0800627 switch (expectedEventType) {
628 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800629 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
630 EXPECT_EQ(expectedAction, keyEvent.getAction());
631 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800632 break;
633 }
634 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800635 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
636 EXPECT_EQ(expectedAction, motionEvent.getAction());
637 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800638 break;
639 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100640 case AINPUT_EVENT_TYPE_FOCUS: {
641 FAIL() << "Use 'consumeFocusEvent' for FOCUS events";
642 }
Tiger Huang8664f8c2018-10-11 19:14:35 +0800643 default: {
644 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
645 }
646 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800647 }
648
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100649 void consumeFocusEvent(bool hasFocus, bool inTouchMode) {
650 InputEvent* event = consume();
651 ASSERT_NE(nullptr, event) << mName.c_str()
652 << ": consumer should have returned non-NULL event.";
653 ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, event->getType())
654 << "Got " << inputEventTypeToString(event->getType())
655 << " event instead of FOCUS event";
656
657 ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId())
658 << mName.c_str() << ": event displayId should always be NONE.";
659
660 FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
661 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
662 EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode());
663 }
664
chaviwd1c23182019-12-20 18:44:56 -0800665 void assertNoEvents() {
666 InputEvent* event = consume();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700667 if (event == nullptr) {
668 return;
669 }
670 if (event->getType() == AINPUT_EVENT_TYPE_KEY) {
671 KeyEvent& keyEvent = static_cast<KeyEvent&>(*event);
672 ADD_FAILURE() << "Received key event "
673 << KeyEvent::actionToString(keyEvent.getAction());
674 } else if (event->getType() == AINPUT_EVENT_TYPE_MOTION) {
675 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
676 ADD_FAILURE() << "Received motion event "
677 << MotionEvent::actionToString(motionEvent.getAction());
678 } else if (event->getType() == AINPUT_EVENT_TYPE_FOCUS) {
679 FocusEvent& focusEvent = static_cast<FocusEvent&>(*event);
680 ADD_FAILURE() << "Received focus event, hasFocus = "
681 << (focusEvent.getHasFocus() ? "true" : "false");
682 }
683 FAIL() << mName.c_str()
684 << ": should not have received any events, so consume() should return NULL";
chaviwd1c23182019-12-20 18:44:56 -0800685 }
686
687 sp<IBinder> getToken() { return mConsumer->getChannel()->getConnectionToken(); }
688
689protected:
690 std::unique_ptr<InputConsumer> mConsumer;
691 PreallocatedInputEventFactory mEventFactory;
692
693 std::string mName;
694};
695
696class FakeWindowHandle : public InputWindowHandle {
697public:
698 static const int32_t WIDTH = 600;
699 static const int32_t HEIGHT = 800;
chaviwd1c23182019-12-20 18:44:56 -0800700
Chris Yea209fde2020-07-22 13:54:51 -0700701 FakeWindowHandle(const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
chaviwd1c23182019-12-20 18:44:56 -0800702 const sp<InputDispatcher>& dispatcher, const std::string name,
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500703 int32_t displayId, std::optional<sp<IBinder>> token = std::nullopt)
chaviwd1c23182019-12-20 18:44:56 -0800704 : mName(name) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500705 if (token == std::nullopt) {
Garfield Tan15601662020-09-22 15:32:38 -0700706 base::Result<std::unique_ptr<InputChannel>> channel =
707 dispatcher->createInputChannel(name);
708 token = (*channel)->getConnectionToken();
709 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
chaviwd1c23182019-12-20 18:44:56 -0800710 }
711
712 inputApplicationHandle->updateInfo();
713 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
714
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500715 mInfo.token = *token;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700716 mInfo.id = sId++;
chaviwd1c23182019-12-20 18:44:56 -0800717 mInfo.name = name;
Michael Wright44753b12020-07-08 13:48:11 +0100718 mInfo.type = InputWindowInfo::Type::APPLICATION;
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500719 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwd1c23182019-12-20 18:44:56 -0800720 mInfo.frameLeft = 0;
721 mInfo.frameTop = 0;
722 mInfo.frameRight = WIDTH;
723 mInfo.frameBottom = HEIGHT;
chaviw1ff3d1e2020-07-01 15:53:47 -0700724 mInfo.transform.set(0, 0);
chaviwd1c23182019-12-20 18:44:56 -0800725 mInfo.globalScaleFactor = 1.0;
726 mInfo.touchableRegion.clear();
727 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
728 mInfo.visible = true;
Vishnu Nair47074b82020-08-14 11:54:47 -0700729 mInfo.focusable = false;
chaviwd1c23182019-12-20 18:44:56 -0800730 mInfo.hasWallpaper = false;
731 mInfo.paused = false;
chaviwd1c23182019-12-20 18:44:56 -0800732 mInfo.ownerPid = INJECTOR_PID;
733 mInfo.ownerUid = INJECTOR_UID;
chaviwd1c23182019-12-20 18:44:56 -0800734 mInfo.displayId = displayId;
735 }
736
737 virtual bool updateInfo() { return true; }
738
Vishnu Nair47074b82020-08-14 11:54:47 -0700739 void setFocusable(bool focusable) { mInfo.focusable = focusable; }
chaviwd1c23182019-12-20 18:44:56 -0800740
Vishnu Nair958da932020-08-21 17:12:37 -0700741 void setVisible(bool visible) { mInfo.visible = visible; }
742
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700743 void setDispatchingTimeout(std::chrono::nanoseconds timeout) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500744 mInfo.dispatchingTimeout = timeout;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700745 }
746
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700747 void setPaused(bool paused) { mInfo.paused = paused; }
748
chaviwd1c23182019-12-20 18:44:56 -0800749 void setFrame(const Rect& frame) {
750 mInfo.frameLeft = frame.left;
751 mInfo.frameTop = frame.top;
752 mInfo.frameRight = frame.right;
753 mInfo.frameBottom = frame.bottom;
chaviw1ff3d1e2020-07-01 15:53:47 -0700754 mInfo.transform.set(frame.left, frame.top);
chaviwd1c23182019-12-20 18:44:56 -0800755 mInfo.touchableRegion.clear();
756 mInfo.addTouchableRegion(frame);
757 }
758
Michael Wright44753b12020-07-08 13:48:11 +0100759 void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; }
chaviwd1c23182019-12-20 18:44:56 -0800760
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500761 void setInputFeatures(InputWindowInfo::Feature features) { mInfo.inputFeatures = features; }
762
chaviw9eaa22c2020-07-01 16:21:27 -0700763 void setWindowTransform(float dsdx, float dtdx, float dtdy, float dsdy) {
764 mInfo.transform.set(dsdx, dtdx, dtdy, dsdy);
765 }
766
767 void setWindowScale(float xScale, float yScale) { setWindowTransform(xScale, 0, 0, yScale); }
chaviwaf87b3e2019-10-01 16:59:28 -0700768
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800769 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
770 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
771 expectedFlags);
772 }
773
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700774 void consumeKeyUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
775 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, expectedDisplayId, expectedFlags);
776 }
777
Svet Ganov5d3bc372020-01-26 23:11:07 -0800778 void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
779 int32_t expectedFlags = 0) {
780 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId,
781 expectedFlags);
782 }
783
784 void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
785 int32_t expectedFlags = 0) {
786 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId,
787 expectedFlags);
788 }
789
790 void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
791 int32_t expectedFlags = 0) {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800792 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
793 expectedFlags);
794 }
795
Svet Ganov5d3bc372020-01-26 23:11:07 -0800796 void consumeMotionPointerDown(int32_t pointerIdx,
797 int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) {
798 int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN
799 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
800 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
801 }
802
803 void consumeMotionPointerUp(int32_t pointerIdx, int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
804 int32_t expectedFlags = 0) {
805 int32_t action = AMOTION_EVENT_ACTION_POINTER_UP
806 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
807 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
808 }
809
810 void consumeMotionUp(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
811 int32_t expectedFlags = 0) {
Michael Wright3a240c42019-12-10 20:53:41 +0000812 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
813 expectedFlags);
814 }
815
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100816 void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
817 ASSERT_NE(mInputReceiver, nullptr)
818 << "Cannot consume events from a window with no receiver";
819 mInputReceiver->consumeFocusEvent(hasFocus, inTouchMode);
820 }
821
chaviwd1c23182019-12-20 18:44:56 -0800822 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
823 int32_t expectedFlags) {
824 ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
825 mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
826 expectedFlags);
827 }
828
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700829 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700830 if (mInputReceiver == nullptr) {
831 ADD_FAILURE() << "Invalid receive event on window with no receiver";
832 return std::nullopt;
833 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700834 return mInputReceiver->receiveEvent(outEvent);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700835 }
836
837 void finishEvent(uint32_t sequenceNum) {
838 ASSERT_NE(mInputReceiver, nullptr) << "Invalid receive event on window with no receiver";
839 mInputReceiver->finishEvent(sequenceNum);
840 }
841
chaviwaf87b3e2019-10-01 16:59:28 -0700842 InputEvent* consume() {
843 if (mInputReceiver == nullptr) {
844 return nullptr;
845 }
846 return mInputReceiver->consume();
847 }
848
Arthur Hungb92218b2018-08-14 12:00:21 +0800849 void assertNoEvents() {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500850 if (mInputReceiver == nullptr &&
851 mInfo.inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL)) {
852 return; // Can't receive events if the window does not have input channel
853 }
854 ASSERT_NE(nullptr, mInputReceiver)
855 << "Window without InputReceiver must specify feature NO_INPUT_CHANNEL";
chaviwd1c23182019-12-20 18:44:56 -0800856 mInputReceiver->assertNoEvents();
Arthur Hungb92218b2018-08-14 12:00:21 +0800857 }
858
chaviwaf87b3e2019-10-01 16:59:28 -0700859 sp<IBinder> getToken() { return mInfo.token; }
860
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100861 const std::string& getName() { return mName; }
862
chaviwd1c23182019-12-20 18:44:56 -0800863private:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100864 const std::string mName;
chaviwd1c23182019-12-20 18:44:56 -0800865 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700866 static std::atomic<int32_t> sId; // each window gets a unique id, like in surfaceflinger
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800867};
868
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700869std::atomic<int32_t> FakeWindowHandle::sId{1};
870
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700871static int32_t injectKey(const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700872 int32_t displayId = ADISPLAY_ID_NONE,
873 int32_t syncMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
874 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800875 KeyEvent event;
876 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
877
878 // Define a valid key down event.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800879 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700880 INVALID_HMAC, action, /* flags */ 0, AKEYCODE_A, KEY_A, AMETA_NONE,
881 repeatCount, currentTime, currentTime);
Arthur Hungb92218b2018-08-14 12:00:21 +0800882
883 // Inject event until dispatch out.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700884 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, syncMode,
885 injectionTimeout,
886 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
Arthur Hungb92218b2018-08-14 12:00:21 +0800887}
888
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700889static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
890 int32_t displayId = ADISPLAY_ID_NONE) {
891 return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId);
892}
893
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700894static int32_t injectKeyUp(const sp<InputDispatcher>& dispatcher,
895 int32_t displayId = ADISPLAY_ID_NONE) {
896 return injectKey(dispatcher, AKEY_EVENT_ACTION_UP, /* repeatCount */ 0, displayId);
897}
898
Garfield Tandf26e862020-07-01 20:18:19 -0700899class PointerBuilder {
900public:
901 PointerBuilder(int32_t id, int32_t toolType) {
902 mProperties.clear();
903 mProperties.id = id;
904 mProperties.toolType = toolType;
905 mCoords.clear();
906 }
907
908 PointerBuilder& x(float x) { return axis(AMOTION_EVENT_AXIS_X, x); }
909
910 PointerBuilder& y(float y) { return axis(AMOTION_EVENT_AXIS_Y, y); }
911
912 PointerBuilder& axis(int32_t axis, float value) {
913 mCoords.setAxisValue(axis, value);
914 return *this;
915 }
916
917 PointerProperties buildProperties() const { return mProperties; }
918
919 PointerCoords buildCoords() const { return mCoords; }
920
921private:
922 PointerProperties mProperties;
923 PointerCoords mCoords;
924};
925
926class MotionEventBuilder {
927public:
928 MotionEventBuilder(int32_t action, int32_t source) {
929 mAction = action;
930 mSource = source;
931 mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
932 }
933
934 MotionEventBuilder& eventTime(nsecs_t eventTime) {
935 mEventTime = eventTime;
936 return *this;
937 }
938
939 MotionEventBuilder& displayId(int32_t displayId) {
940 mDisplayId = displayId;
941 return *this;
942 }
943
944 MotionEventBuilder& actionButton(int32_t actionButton) {
945 mActionButton = actionButton;
946 return *this;
947 }
948
949 MotionEventBuilder& buttonState(int32_t actionButton) {
950 mActionButton = actionButton;
951 return *this;
952 }
953
954 MotionEventBuilder& rawXCursorPosition(float rawXCursorPosition) {
955 mRawXCursorPosition = rawXCursorPosition;
956 return *this;
957 }
958
959 MotionEventBuilder& rawYCursorPosition(float rawYCursorPosition) {
960 mRawYCursorPosition = rawYCursorPosition;
961 return *this;
962 }
963
964 MotionEventBuilder& pointer(PointerBuilder pointer) {
965 mPointers.push_back(pointer);
966 return *this;
967 }
968
969 MotionEvent build() {
970 std::vector<PointerProperties> pointerProperties;
971 std::vector<PointerCoords> pointerCoords;
972 for (const PointerBuilder& pointer : mPointers) {
973 pointerProperties.push_back(pointer.buildProperties());
974 pointerCoords.push_back(pointer.buildCoords());
975 }
976
977 // Set mouse cursor position for the most common cases to avoid boilerplate.
978 if (mSource == AINPUT_SOURCE_MOUSE &&
979 !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition) &&
980 mPointers.size() == 1) {
981 mRawXCursorPosition = pointerCoords[0].getX();
982 mRawYCursorPosition = pointerCoords[0].getY();
983 }
984
985 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -0700986 ui::Transform identityTransform;
Garfield Tandf26e862020-07-01 20:18:19 -0700987 event.initialize(InputEvent::nextId(), DEVICE_ID, mSource, mDisplayId, INVALID_HMAC,
988 mAction, mActionButton, /* flags */ 0, /* edgeFlags */ 0, AMETA_NONE,
chaviw9eaa22c2020-07-01 16:21:27 -0700989 mButtonState, MotionClassification::NONE, identityTransform,
990 /* xPrecision */ 0, /* yPrecision */ 0, mRawXCursorPosition,
991 mRawYCursorPosition, mEventTime, mEventTime, mPointers.size(),
992 pointerProperties.data(), pointerCoords.data());
Garfield Tandf26e862020-07-01 20:18:19 -0700993
994 return event;
995 }
996
997private:
998 int32_t mAction;
999 int32_t mSource;
1000 nsecs_t mEventTime;
1001 int32_t mDisplayId{ADISPLAY_ID_DEFAULT};
1002 int32_t mActionButton{0};
1003 int32_t mButtonState{0};
1004 float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1005 float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1006
1007 std::vector<PointerBuilder> mPointers;
1008};
1009
1010static int32_t injectMotionEvent(
1011 const sp<InputDispatcher>& dispatcher, const MotionEvent& event,
1012 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
1013 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT) {
1014 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, injectionMode,
1015 injectionTimeout,
1016 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
1017}
1018
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001019static int32_t injectMotionEvent(
1020 const sp<InputDispatcher>& dispatcher, int32_t action, int32_t source, int32_t displayId,
1021 const PointF& position,
1022 const PointF& cursorPosition = {AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001023 AMOTION_EVENT_INVALID_CURSOR_POSITION},
1024 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
1025 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
1026 nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC)) {
Garfield Tandf26e862020-07-01 20:18:19 -07001027 MotionEvent event = MotionEventBuilder(action, source)
1028 .displayId(displayId)
1029 .eventTime(eventTime)
1030 .rawXCursorPosition(cursorPosition.x)
1031 .rawYCursorPosition(cursorPosition.y)
1032 .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER)
1033 .x(position.x)
1034 .y(position.y))
1035 .build();
Arthur Hungb92218b2018-08-14 12:00:21 +08001036
1037 // Inject event until dispatch out.
Garfield Tandf26e862020-07-01 20:18:19 -07001038 return injectMotionEvent(dispatcher, event);
Arthur Hungb92218b2018-08-14 12:00:21 +08001039}
1040
Garfield Tan00f511d2019-06-12 16:55:40 -07001041static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001042 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001043 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, location);
Garfield Tan00f511d2019-06-12 16:55:40 -07001044}
1045
Michael Wright3a240c42019-12-10 20:53:41 +00001046static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001047 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001048 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, location);
Michael Wright3a240c42019-12-10 20:53:41 +00001049}
1050
Jackal Guof9696682018-10-05 12:23:23 +08001051static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
1052 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1053 // Define a valid key event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001054 NotifyKeyArgs args(/* id */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
1055 POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0, AKEYCODE_A, KEY_A,
1056 AMETA_NONE, currentTime);
Jackal Guof9696682018-10-05 12:23:23 +08001057
1058 return args;
1059}
1060
chaviwd1c23182019-12-20 18:44:56 -08001061static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId,
1062 const std::vector<PointF>& points) {
1063 size_t pointerCount = points.size();
chaviwaf87b3e2019-10-01 16:59:28 -07001064 if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_UP) {
1065 EXPECT_EQ(1U, pointerCount) << "Actions DOWN and UP can only contain a single pointer";
1066 }
1067
chaviwd1c23182019-12-20 18:44:56 -08001068 PointerProperties pointerProperties[pointerCount];
1069 PointerCoords pointerCoords[pointerCount];
Jackal Guof9696682018-10-05 12:23:23 +08001070
chaviwd1c23182019-12-20 18:44:56 -08001071 for (size_t i = 0; i < pointerCount; i++) {
1072 pointerProperties[i].clear();
1073 pointerProperties[i].id = i;
1074 pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
Jackal Guof9696682018-10-05 12:23:23 +08001075
chaviwd1c23182019-12-20 18:44:56 -08001076 pointerCoords[i].clear();
1077 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
1078 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, points[i].y);
1079 }
Jackal Guof9696682018-10-05 12:23:23 +08001080
1081 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1082 // Define a valid motion event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001083 NotifyMotionArgs args(/* id */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -07001084 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
1085 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
chaviwd1c23182019-12-20 18:44:56 -08001086 AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, pointerProperties,
1087 pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -07001088 AMOTION_EVENT_INVALID_CURSOR_POSITION,
1089 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +08001090
1091 return args;
1092}
1093
chaviwd1c23182019-12-20 18:44:56 -08001094static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
1095 return generateMotionArgs(action, source, displayId, {PointF{100, 200}});
1096}
1097
Arthur Hungb92218b2018-08-14 12:00:21 +08001098TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001099 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001100 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
1101 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001102
Arthur Hung72d8dc32020-03-28 00:48:39 +00001103 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001104 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1105 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001106 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1107
1108 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001109 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001110}
1111
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001112/**
1113 * Calling setInputWindows once with FLAG_NOT_TOUCH_MODAL should not cause any issues.
1114 * To ensure that window receives only events that were directly inside of it, add
1115 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1116 * when finding touched windows.
1117 * This test serves as a sanity check for the next test, where setInputWindows is
1118 * called twice.
1119 */
1120TEST_F(InputDispatcherTest, SetInputWindowOnce_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001121 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001122 sp<FakeWindowHandle> window =
1123 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1124 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001125 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001126
1127 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1128 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1129 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1130 {50, 50}))
1131 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1132
1133 // Window should receive motion event.
1134 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1135}
1136
1137/**
1138 * Calling setInputWindows twice, with the same info, should not cause any issues.
1139 * To ensure that window receives only events that were directly inside of it, add
1140 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1141 * when finding touched windows.
1142 */
1143TEST_F(InputDispatcherTest, SetInputWindowTwice_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001144 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001145 sp<FakeWindowHandle> window =
1146 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1147 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001148 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001149
1150 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1151 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1152 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1153 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1154 {50, 50}))
1155 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1156
1157 // Window should receive motion event.
1158 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1159}
1160
Arthur Hungb92218b2018-08-14 12:00:21 +08001161// The foreground window should receive the first touch down event.
1162TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001163 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001164 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1165 ADISPLAY_ID_DEFAULT);
1166 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1167 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001168
Arthur Hung72d8dc32020-03-28 00:48:39 +00001169 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001170 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1171 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001172 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1173
1174 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001175 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001176 windowSecond->assertNoEvents();
1177}
1178
Garfield Tandf26e862020-07-01 20:18:19 -07001179TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001180 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001181 sp<FakeWindowHandle> windowLeft =
1182 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1183 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001184 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001185 sp<FakeWindowHandle> windowRight =
1186 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1187 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001188 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001189
1190 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1191
1192 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
1193
1194 // Start cursor position in right window so that we can move the cursor to left window.
1195 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1196 injectMotionEvent(mDispatcher,
1197 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1198 AINPUT_SOURCE_MOUSE)
1199 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1200 .x(900)
1201 .y(400))
1202 .build()));
1203 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1204 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1205 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1206 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1207
1208 // Move cursor into left window
1209 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1210 injectMotionEvent(mDispatcher,
1211 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1212 AINPUT_SOURCE_MOUSE)
1213 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1214 .x(300)
1215 .y(400))
1216 .build()));
1217 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1218 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1219 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1220 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1221 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1222 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1223
1224 // Inject a series of mouse events for a mouse click
1225 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1226 injectMotionEvent(mDispatcher,
1227 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1228 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1229 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1230 .x(300)
1231 .y(400))
1232 .build()));
1233 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1234
1235 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1236 injectMotionEvent(mDispatcher,
1237 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1238 AINPUT_SOURCE_MOUSE)
1239 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1240 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1241 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1242 .x(300)
1243 .y(400))
1244 .build()));
1245 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1246 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1247
1248 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1249 injectMotionEvent(mDispatcher,
1250 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1251 AINPUT_SOURCE_MOUSE)
1252 .buttonState(0)
1253 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1254 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1255 .x(300)
1256 .y(400))
1257 .build()));
1258 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1259 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1260
1261 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1262 injectMotionEvent(mDispatcher,
1263 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1264 .buttonState(0)
1265 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1266 .x(300)
1267 .y(400))
1268 .build()));
1269 windowLeft->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1270
1271 // Move mouse cursor back to right window
1272 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1273 injectMotionEvent(mDispatcher,
1274 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1275 AINPUT_SOURCE_MOUSE)
1276 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1277 .x(900)
1278 .y(400))
1279 .build()));
1280 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1281 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1282 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1283 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1284 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1285 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1286}
1287
1288// This test is different from the test above that HOVER_ENTER and HOVER_EXIT events are injected
1289// directly in this test.
1290TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001291 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001292 sp<FakeWindowHandle> window =
1293 new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
1294 window->setFrame(Rect(0, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001295 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001296
1297 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1298
1299 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1300
1301 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1302 injectMotionEvent(mDispatcher,
1303 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
1304 AINPUT_SOURCE_MOUSE)
1305 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1306 .x(300)
1307 .y(400))
1308 .build()));
1309 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1310 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1311
1312 // Inject a series of mouse events for a mouse click
1313 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1314 injectMotionEvent(mDispatcher,
1315 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1316 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1317 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1318 .x(300)
1319 .y(400))
1320 .build()));
1321 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1322
1323 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1324 injectMotionEvent(mDispatcher,
1325 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1326 AINPUT_SOURCE_MOUSE)
1327 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1328 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1329 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1330 .x(300)
1331 .y(400))
1332 .build()));
1333 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1334 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1335
1336 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1337 injectMotionEvent(mDispatcher,
1338 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1339 AINPUT_SOURCE_MOUSE)
1340 .buttonState(0)
1341 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1342 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1343 .x(300)
1344 .y(400))
1345 .build()));
1346 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1347 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1348
1349 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1350 injectMotionEvent(mDispatcher,
1351 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1352 .buttonState(0)
1353 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1354 .x(300)
1355 .y(400))
1356 .build()));
1357 window->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1358
1359 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1360 injectMotionEvent(mDispatcher,
1361 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
1362 AINPUT_SOURCE_MOUSE)
1363 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1364 .x(300)
1365 .y(400))
1366 .build()));
1367 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1368 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1369}
1370
Garfield Tan00f511d2019-06-12 16:55:40 -07001371TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
Chris Yea209fde2020-07-22 13:54:51 -07001372 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tan00f511d2019-06-12 16:55:40 -07001373
1374 sp<FakeWindowHandle> windowLeft =
1375 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1376 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001377 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001378 sp<FakeWindowHandle> windowRight =
1379 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1380 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001381 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001382
1383 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1384
Arthur Hung72d8dc32020-03-28 00:48:39 +00001385 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
Garfield Tan00f511d2019-06-12 16:55:40 -07001386
1387 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
1388 // left window. This event should be dispatched to the left window.
1389 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1390 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001391 ADISPLAY_ID_DEFAULT, {610, 400}, {599, 400}));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001392 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -07001393 windowRight->assertNoEvents();
1394}
1395
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001396TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001397 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001398 sp<FakeWindowHandle> window =
1399 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Vishnu Nair47074b82020-08-14 11:54:47 -07001400 window->setFocusable(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001401
Arthur Hung72d8dc32020-03-28 00:48:39 +00001402 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001403 setFocusedWindow(window);
1404
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001405 window->consumeFocusEvent(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001406
1407 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1408 mDispatcher->notifyKey(&keyArgs);
1409
1410 // Window should receive key down event.
1411 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1412
1413 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
1414 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001415 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001416 mDispatcher->notifyDeviceReset(&args);
1417 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
1418 AKEY_EVENT_FLAG_CANCELED);
1419}
1420
1421TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001422 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001423 sp<FakeWindowHandle> window =
1424 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1425
Arthur Hung72d8dc32020-03-28 00:48:39 +00001426 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001427
1428 NotifyMotionArgs motionArgs =
1429 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1430 ADISPLAY_ID_DEFAULT);
1431 mDispatcher->notifyMotion(&motionArgs);
1432
1433 // Window should receive motion down event.
1434 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1435
1436 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
1437 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001438 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001439 mDispatcher->notifyDeviceReset(&args);
1440 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
1441 0 /*expectedFlags*/);
1442}
1443
Svet Ganov5d3bc372020-01-26 23:11:07 -08001444TEST_F(InputDispatcherTest, TransferTouchFocus_OnePointer) {
Chris Yea209fde2020-07-22 13:54:51 -07001445 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001446
1447 // Create a couple of windows
1448 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1449 "First Window", ADISPLAY_ID_DEFAULT);
1450 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1451 "Second Window", ADISPLAY_ID_DEFAULT);
1452
1453 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001454 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001455
1456 // Send down to the first window
1457 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1458 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1459 mDispatcher->notifyMotion(&downMotionArgs);
1460 // Only the first window should get the down event
1461 firstWindow->consumeMotionDown();
1462 secondWindow->assertNoEvents();
1463
1464 // Transfer touch focus to the second window
1465 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1466 // The first window gets cancel and the second gets down
1467 firstWindow->consumeMotionCancel();
1468 secondWindow->consumeMotionDown();
1469
1470 // Send up event to the second window
1471 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1472 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1473 mDispatcher->notifyMotion(&upMotionArgs);
1474 // The first window gets no events and the second gets up
1475 firstWindow->assertNoEvents();
1476 secondWindow->consumeMotionUp();
1477}
1478
1479TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointerNoSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001480 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001481
1482 PointF touchPoint = {10, 10};
1483
1484 // Create a couple of windows
1485 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1486 "First Window", ADISPLAY_ID_DEFAULT);
1487 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1488 "Second Window", ADISPLAY_ID_DEFAULT);
1489
1490 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001491 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001492
1493 // Send down to the first window
1494 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1495 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint});
1496 mDispatcher->notifyMotion(&downMotionArgs);
1497 // Only the first window should get the down event
1498 firstWindow->consumeMotionDown();
1499 secondWindow->assertNoEvents();
1500
1501 // Send pointer down to the first window
1502 NotifyMotionArgs pointerDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1503 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1504 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1505 mDispatcher->notifyMotion(&pointerDownMotionArgs);
1506 // Only the first window should get the pointer down event
1507 firstWindow->consumeMotionPointerDown(1);
1508 secondWindow->assertNoEvents();
1509
1510 // Transfer touch focus to the second window
1511 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1512 // The first window gets cancel and the second gets down and pointer down
1513 firstWindow->consumeMotionCancel();
1514 secondWindow->consumeMotionDown();
1515 secondWindow->consumeMotionPointerDown(1);
1516
1517 // Send pointer up to the second window
1518 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1519 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1520 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1521 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1522 // The first window gets nothing and the second gets pointer up
1523 firstWindow->assertNoEvents();
1524 secondWindow->consumeMotionPointerUp(1);
1525
1526 // Send up event to the second window
1527 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1528 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1529 mDispatcher->notifyMotion(&upMotionArgs);
1530 // The first window gets nothing and the second gets up
1531 firstWindow->assertNoEvents();
1532 secondWindow->consumeMotionUp();
1533}
1534
1535TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointersSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001536 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001537
1538 // Create a non touch modal window that supports split touch
1539 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1540 "First Window", ADISPLAY_ID_DEFAULT);
1541 firstWindow->setFrame(Rect(0, 0, 600, 400));
Michael Wright44753b12020-07-08 13:48:11 +01001542 firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1543 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001544
1545 // Create a non touch modal window that supports split touch
1546 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1547 "Second Window", ADISPLAY_ID_DEFAULT);
1548 secondWindow->setFrame(Rect(0, 400, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001549 secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1550 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001551
1552 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001553 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001554
1555 PointF pointInFirst = {300, 200};
1556 PointF pointInSecond = {300, 600};
1557
1558 // Send down to the first window
1559 NotifyMotionArgs firstDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1560 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst});
1561 mDispatcher->notifyMotion(&firstDownMotionArgs);
1562 // Only the first window should get the down event
1563 firstWindow->consumeMotionDown();
1564 secondWindow->assertNoEvents();
1565
1566 // Send down to the second window
1567 NotifyMotionArgs secondDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1568 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1569 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1570 mDispatcher->notifyMotion(&secondDownMotionArgs);
1571 // The first window gets a move and the second a down
1572 firstWindow->consumeMotionMove();
1573 secondWindow->consumeMotionDown();
1574
1575 // Transfer touch focus to the second window
1576 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1577 // The first window gets cancel and the new gets pointer down (it already saw down)
1578 firstWindow->consumeMotionCancel();
1579 secondWindow->consumeMotionPointerDown(1);
1580
1581 // Send pointer up to the second window
1582 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1583 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1584 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1585 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1586 // The first window gets nothing and the second gets pointer up
1587 firstWindow->assertNoEvents();
1588 secondWindow->consumeMotionPointerUp(1);
1589
1590 // Send up event to the second window
1591 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1592 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1593 mDispatcher->notifyMotion(&upMotionArgs);
1594 // The first window gets nothing and the second gets up
1595 firstWindow->assertNoEvents();
1596 secondWindow->consumeMotionUp();
1597}
1598
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001599TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001600 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001601 sp<FakeWindowHandle> window =
1602 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1603
Vishnu Nair47074b82020-08-14 11:54:47 -07001604 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001605 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001606 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001607
1608 window->consumeFocusEvent(true);
1609
1610 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1611 mDispatcher->notifyKey(&keyArgs);
1612
1613 // Window should receive key down event.
1614 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1615}
1616
1617TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001618 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001619 sp<FakeWindowHandle> window =
1620 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1621
Arthur Hung72d8dc32020-03-28 00:48:39 +00001622 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001623
1624 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1625 mDispatcher->notifyKey(&keyArgs);
1626 mDispatcher->waitForIdle();
1627
1628 window->assertNoEvents();
1629}
1630
1631// If a window is touchable, but does not have focus, it should receive motion events, but not keys
1632TEST_F(InputDispatcherTest, UnfocusedWindow_ReceivesMotionsButNotKeys) {
Chris Yea209fde2020-07-22 13:54:51 -07001633 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001634 sp<FakeWindowHandle> window =
1635 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1636
Arthur Hung72d8dc32020-03-28 00:48:39 +00001637 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001638
1639 // Send key
1640 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1641 mDispatcher->notifyKey(&keyArgs);
1642 // Send motion
1643 NotifyMotionArgs motionArgs =
1644 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1645 ADISPLAY_ID_DEFAULT);
1646 mDispatcher->notifyMotion(&motionArgs);
1647
1648 // Window should receive only the motion event
1649 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1650 window->assertNoEvents(); // Key event or focus event will not be received
1651}
1652
chaviwd1c23182019-12-20 18:44:56 -08001653class FakeMonitorReceiver {
Michael Wright3a240c42019-12-10 20:53:41 +00001654public:
1655 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
chaviwd1c23182019-12-20 18:44:56 -08001656 int32_t displayId, bool isGestureMonitor = false) {
Garfield Tan15601662020-09-22 15:32:38 -07001657 base::Result<std::unique_ptr<InputChannel>> channel =
1658 dispatcher->createInputMonitor(displayId, isGestureMonitor, name);
1659 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
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 Vishniakouf56b2692020-09-08 19:43:33 -05003488/**
3489 * If we have no focused window, and a key comes in, we start the ANR timer.
3490 * The focused application should add a focused window before the timer runs out to prevent ANR.
3491 *
3492 * If the user touches another application during this time, the key should be dropped.
3493 * Next, if a new focused window comes in, without toggling the focused application,
3494 * then no ANR should occur.
3495 *
3496 * Normally, we would expect the new focused window to be accompanied by 'setFocusedApplication',
3497 * but in some cases the policy may not update the focused application.
3498 */
3499TEST_F(InputDispatcherMultiWindowAnr, FocusedWindowWithoutSetFocusedApplication_NoAnr) {
3500 std::shared_ptr<FakeApplicationHandle> focusedApplication =
3501 std::make_shared<FakeApplicationHandle>();
3502 focusedApplication->setDispatchingTimeout(60ms);
3503 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, focusedApplication);
3504 // The application that owns 'mFocusedWindow' and 'mUnfocusedWindow' is not focused.
3505 mFocusedWindow->setFocusable(false);
3506
3507 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3508 mFocusedWindow->consumeFocusEvent(false);
3509
3510 // Send a key. The ANR timer should start because there is no focused window.
3511 // 'focusedApplication' will get blamed if this timer completes.
3512 // Key will not be sent anywhere because we have no focused window. It will remain pending.
3513 int32_t result =
3514 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
3515 INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
3516 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
3517
3518 // Wait until dispatcher starts the "no focused window" timer. If we don't wait here,
3519 // then the injected touches won't cause the focused event to get dropped.
3520 // The dispatcher only checks for whether the queue should be pruned upon queueing.
3521 // If we inject the touch right away and the ANR timer hasn't started, the touch event would
3522 // simply be added to the queue without 'shouldPruneInboundQueueLocked' returning 'true'.
3523 // For this test, it means that the key would get delivered to the window once it becomes
3524 // focused.
3525 std::this_thread::sleep_for(10ms);
3526
3527 // Touch unfocused window. This should force the pending key to get dropped.
3528 NotifyMotionArgs motionArgs =
3529 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3530 ADISPLAY_ID_DEFAULT, {UNFOCUSED_WINDOW_LOCATION});
3531 mDispatcher->notifyMotion(&motionArgs);
3532
3533 // We do not consume the motion right away, because that would require dispatcher to first
3534 // process (== drop) the key event, and by that time, ANR will be raised.
3535 // Set the focused window first.
3536 mFocusedWindow->setFocusable(true);
3537 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3538 setFocusedWindow(mFocusedWindow);
3539 mFocusedWindow->consumeFocusEvent(true);
3540 // We do not call "setFocusedApplication" here, even though the newly focused window belongs
3541 // to another application. This could be a bug / behaviour in the policy.
3542
3543 mUnfocusedWindow->consumeMotionDown();
3544
3545 ASSERT_TRUE(mDispatcher->waitForIdle());
3546 // Should not ANR because we actually have a focused window. It was just added too slowly.
3547 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertNotifyAnrWasNotCalled());
3548}
3549
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003550// These tests ensure we cannot send touch events to a window that's positioned behind a window
3551// that has feature NO_INPUT_CHANNEL.
3552// Layout:
3553// Top (closest to user)
3554// mNoInputWindow (above all windows)
3555// mBottomWindow
3556// Bottom (furthest from user)
3557class InputDispatcherMultiWindowOcclusionTests : public InputDispatcherTest {
3558 virtual void SetUp() override {
3559 InputDispatcherTest::SetUp();
3560
3561 mApplication = std::make_shared<FakeApplicationHandle>();
3562 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3563 "Window without input channel", ADISPLAY_ID_DEFAULT,
3564 std::make_optional<sp<IBinder>>(nullptr) /*token*/);
3565
3566 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3567 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3568 // It's perfectly valid for this window to not have an associated input channel
3569
3570 mBottomWindow = new FakeWindowHandle(mApplication, mDispatcher, "Bottom window",
3571 ADISPLAY_ID_DEFAULT);
3572 mBottomWindow->setFrame(Rect(0, 0, 100, 100));
3573
3574 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3575 }
3576
3577protected:
3578 std::shared_ptr<FakeApplicationHandle> mApplication;
3579 sp<FakeWindowHandle> mNoInputWindow;
3580 sp<FakeWindowHandle> mBottomWindow;
3581};
3582
3583TEST_F(InputDispatcherMultiWindowOcclusionTests, NoInputChannelFeature_DropsTouches) {
3584 PointF touchedPoint = {10, 10};
3585
3586 NotifyMotionArgs motionArgs =
3587 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3588 ADISPLAY_ID_DEFAULT, {touchedPoint});
3589 mDispatcher->notifyMotion(&motionArgs);
3590
3591 mNoInputWindow->assertNoEvents();
3592 // Even though the window 'mNoInputWindow' positioned above 'mBottomWindow' does not have
3593 // an input channel, it is not marked as FLAG_NOT_TOUCHABLE,
3594 // and therefore should prevent mBottomWindow from receiving touches
3595 mBottomWindow->assertNoEvents();
3596}
3597
3598/**
3599 * If a window has feature NO_INPUT_CHANNEL, and somehow (by mistake) still has an input channel,
3600 * ensure that this window does not receive any touches, and blocks touches to windows underneath.
3601 */
3602TEST_F(InputDispatcherMultiWindowOcclusionTests,
3603 NoInputChannelFeature_DropsTouchesWithValidChannel) {
3604 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3605 "Window with input channel and NO_INPUT_CHANNEL",
3606 ADISPLAY_ID_DEFAULT);
3607
3608 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3609 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3610 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3611
3612 PointF touchedPoint = {10, 10};
3613
3614 NotifyMotionArgs motionArgs =
3615 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3616 ADISPLAY_ID_DEFAULT, {touchedPoint});
3617 mDispatcher->notifyMotion(&motionArgs);
3618
3619 mNoInputWindow->assertNoEvents();
3620 mBottomWindow->assertNoEvents();
3621}
3622
Vishnu Nair958da932020-08-21 17:12:37 -07003623class InputDispatcherMirrorWindowFocusTests : public InputDispatcherTest {
3624protected:
3625 std::shared_ptr<FakeApplicationHandle> mApp;
3626 sp<FakeWindowHandle> mWindow;
3627 sp<FakeWindowHandle> mMirror;
3628
3629 virtual void SetUp() override {
3630 InputDispatcherTest::SetUp();
3631 mApp = std::make_shared<FakeApplicationHandle>();
3632 mWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
3633 mMirror = new FakeWindowHandle(mApp, mDispatcher, "TestWindowMirror", ADISPLAY_ID_DEFAULT,
3634 mWindow->getToken());
3635 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
3636 mWindow->setFocusable(true);
3637 mMirror->setFocusable(true);
3638 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3639 }
3640};
3641
3642TEST_F(InputDispatcherMirrorWindowFocusTests, CanGetFocus) {
3643 // Request focus on a mirrored window
3644 setFocusedWindow(mMirror);
3645
3646 // window gets focused
3647 mWindow->consumeFocusEvent(true);
3648 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3649 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3650 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3651}
3652
3653// A focused & mirrored window remains focused only if the window and its mirror are both
3654// focusable.
3655TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAllWindowsFocusable) {
3656 setFocusedWindow(mMirror);
3657
3658 // window gets focused
3659 mWindow->consumeFocusEvent(true);
3660 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3661 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3662 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3663 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3664 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3665 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3666
3667 mMirror->setFocusable(false);
3668 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3669
3670 // window loses focus since one of the windows associated with the token in not focusable
3671 mWindow->consumeFocusEvent(false);
3672
3673 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3674 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3675 mWindow->assertNoEvents();
3676}
3677
3678// A focused & mirrored window remains focused until the window and its mirror both become
3679// invisible.
3680TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAnyWindowVisible) {
3681 setFocusedWindow(mMirror);
3682
3683 // window gets focused
3684 mWindow->consumeFocusEvent(true);
3685 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3686 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3687 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3688 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3689 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3690 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3691
3692 mMirror->setVisible(false);
3693 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3694
3695 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3696 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3697 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3698 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3699 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3700 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3701
3702 mWindow->setVisible(false);
3703 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3704
3705 // window loses focus only after all windows associated with the token become invisible.
3706 mWindow->consumeFocusEvent(false);
3707
3708 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3709 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3710 mWindow->assertNoEvents();
3711}
3712
3713// A focused & mirrored window remains focused until both windows are removed.
3714TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedWhileWindowsAlive) {
3715 setFocusedWindow(mMirror);
3716
3717 // window gets focused
3718 mWindow->consumeFocusEvent(true);
3719 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3720 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3721 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3722 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3723 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3724 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3725
3726 // single window is removed but the window token remains focused
3727 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mMirror}}});
3728
3729 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3730 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3731 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3732 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3733 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3734 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3735
3736 // Both windows are removed
3737 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {}}});
3738 mWindow->consumeFocusEvent(false);
3739
3740 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3741 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3742 mWindow->assertNoEvents();
3743}
3744
3745// Focus request can be pending until one window becomes visible.
3746TEST_F(InputDispatcherMirrorWindowFocusTests, DeferFocusWhenInvisible) {
3747 // Request focus on an invisible mirror.
3748 mWindow->setVisible(false);
3749 mMirror->setVisible(false);
3750 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3751 setFocusedWindow(mMirror);
3752
3753 // Injected key goes to pending queue.
3754 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3755 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
3756 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
3757
3758 mMirror->setVisible(true);
3759 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3760
3761 // window gets focused
3762 mWindow->consumeFocusEvent(true);
3763 // window gets the pending key event
3764 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3765}
Garfield Tane84e6f92019-08-29 17:28:41 -07003766} // namespace android::inputdispatcher