blob: 766dc90a5a16b34e1e2cfe5ec1b90009fc092257 [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
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700218 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800219 *outConfig = mConfig;
220 }
221
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800222 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700223 std::scoped_lock lock(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800224 switch (inputEvent->getType()) {
225 case AINPUT_EVENT_TYPE_KEY: {
226 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800227 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800228 break;
229 }
230
231 case AINPUT_EVENT_TYPE_MOTION: {
232 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800233 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800234 break;
235 }
236 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 return true;
238 }
239
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700240 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800241
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700242 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800243
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700244 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent*,
245 uint32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800246 return 0;
247 }
248
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700249 virtual bool dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent*, uint32_t,
250 KeyEvent*) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800251 return false;
252 }
253
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800254 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
255 uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700256 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800257 /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
258 * essentially a passthrough for notifySwitch.
259 */
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800260 mLastNotifySwitch = NotifySwitchArgs(1 /*id*/, when, policyFlags, switchValues, switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800261 }
262
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700263 virtual void pokeUserActivity(nsecs_t, int32_t) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800264
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700265 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800266 return false;
267 }
Jackal Guof9696682018-10-05 12:23:23 +0800268
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700269 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700270 std::scoped_lock lock(mLock);
chaviwfd6d3512019-03-25 13:23:49 -0700271 mOnPointerDownToken = newToken;
272 }
273
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800274 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
275 int32_t displayId) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700276 std::scoped_lock lock(mLock);
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800277 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
278 ASSERT_EQ(mFilteredEvent->getType(), type);
279
280 if (type == AINPUT_EVENT_TYPE_KEY) {
281 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
282 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
283 EXPECT_EQ(keyEvent.getAction(), action);
284 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
285 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
286 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
287 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
288 EXPECT_EQ(motionEvent.getAction(), action);
289 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
290 } else {
291 FAIL() << "Unknown type: " << type;
292 }
293
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800294 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800295 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800296};
297
Michael Wrightd02c5b62014-02-10 15:10:22 -0800298// --- InputDispatcherTest ---
299
300class InputDispatcherTest : public testing::Test {
301protected:
302 sp<FakeInputDispatcherPolicy> mFakePolicy;
303 sp<InputDispatcher> mDispatcher;
304
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700305 virtual void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800306 mFakePolicy = new FakeInputDispatcherPolicy();
307 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800308 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
309 //Start InputDispatcher thread
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700310 ASSERT_EQ(OK, mDispatcher->start());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800311 }
312
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700313 virtual void TearDown() override {
314 ASSERT_EQ(OK, mDispatcher->stop());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800315 mFakePolicy.clear();
316 mDispatcher.clear();
317 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700318
319 /**
320 * Used for debugging when writing the test
321 */
322 void dumpDispatcherState() {
323 std::string dump;
324 mDispatcher->dump(dump);
325 std::stringstream ss(dump);
326 std::string to;
327
328 while (std::getline(ss, to, '\n')) {
329 ALOGE("%s", to.c_str());
330 }
331 }
Vishnu Nair958da932020-08-21 17:12:37 -0700332
333 void setFocusedWindow(const sp<InputWindowHandle>& window,
334 const sp<InputWindowHandle>& focusedWindow = nullptr) {
335 FocusRequest request;
336 request.token = window->getToken();
337 if (focusedWindow) {
338 request.focusedToken = focusedWindow->getToken();
339 }
340 request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
341 request.displayId = window->getInfo()->displayId;
342 mDispatcher->setFocusedWindow(request);
343 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800344};
345
346
347TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
348 KeyEvent event;
349
350 // Rejects undefined key actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800351 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
352 INVALID_HMAC,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600353 /*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME,
354 ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700355 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
356 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
357 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800358 << "Should reject key events with undefined action.";
359
360 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800361 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
362 INVALID_HMAC, AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600363 ARBITRARY_TIME, ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700364 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
365 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
366 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800367 << "Should reject key events with ACTION_MULTIPLE.";
368}
369
370TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
371 MotionEvent event;
372 PointerProperties pointerProperties[MAX_POINTERS + 1];
373 PointerCoords pointerCoords[MAX_POINTERS + 1];
374 for (int i = 0; i <= MAX_POINTERS; i++) {
375 pointerProperties[i].clear();
376 pointerProperties[i].id = i;
377 pointerCoords[i].clear();
378 }
379
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800380 // Some constants commonly used below
381 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
382 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
383 constexpr int32_t metaState = AMETA_NONE;
384 constexpr MotionClassification classification = MotionClassification::NONE;
385
chaviw9eaa22c2020-07-01 16:21:27 -0700386 ui::Transform identityTransform;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800387 // Rejects undefined motion actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800388 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
chaviw9eaa22c2020-07-01 16:21:27 -0700389 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification,
390 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600391 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700392 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700393 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
394 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
395 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800396 << "Should reject motion events with undefined action.";
397
398 // Rejects pointer down with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800399 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700400 AMOTION_EVENT_ACTION_POINTER_DOWN |
401 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700402 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
403 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
404 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
405 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700406 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
407 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
408 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800409 << "Should reject motion events with pointer down index too large.";
410
Garfield Tanfbe732e2020-01-24 11:26:14 -0800411 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700412 AMOTION_EVENT_ACTION_POINTER_DOWN |
413 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700414 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
415 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
416 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
417 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700418 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
419 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
420 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800421 << "Should reject motion events with pointer down index too small.";
422
423 // Rejects pointer up with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800424 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700425 AMOTION_EVENT_ACTION_POINTER_UP |
426 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700427 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
428 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
429 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
430 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700431 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
432 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
433 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800434 << "Should reject motion events with pointer up index too large.";
435
Garfield Tanfbe732e2020-01-24 11:26:14 -0800436 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700437 AMOTION_EVENT_ACTION_POINTER_UP |
438 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700439 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
440 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
441 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
442 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700443 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
444 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
445 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800446 << "Should reject motion events with pointer up index too small.";
447
448 // Rejects motion events with invalid number of pointers.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800449 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
450 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700451 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
452 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700453 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700454 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
455 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
456 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800457 << "Should reject motion events with 0 pointers.";
458
Garfield Tanfbe732e2020-01-24 11:26:14 -0800459 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
460 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700461 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
462 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700463 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700464 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
465 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
466 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800467 << "Should reject motion events with more than MAX_POINTERS pointers.";
468
469 // Rejects motion events with invalid pointer ids.
470 pointerProperties[0].id = -1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800471 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
472 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700473 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
474 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700475 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700476 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
477 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
478 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800479 << "Should reject motion events with pointer ids less than 0.";
480
481 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800482 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
483 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700484 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
485 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700486 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700487 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
488 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
489 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800490 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
491
492 // Rejects motion events with duplicate pointer ids.
493 pointerProperties[0].id = 1;
494 pointerProperties[1].id = 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800495 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
496 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700497 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
498 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700499 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700500 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
501 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
502 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800503 << "Should reject motion events with duplicate pointer ids.";
504}
505
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800506/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
507
508TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
509 constexpr nsecs_t eventTime = 20;
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800510 NotifyConfigurationChangedArgs args(10 /*id*/, eventTime);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800511 mDispatcher->notifyConfigurationChanged(&args);
512 ASSERT_TRUE(mDispatcher->waitForIdle());
513
514 mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
515}
516
517TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800518 NotifySwitchArgs args(10 /*id*/, 20 /*eventTime*/, 0 /*policyFlags*/, 1 /*switchValues*/,
519 2 /*switchMask*/);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800520 mDispatcher->notifySwitch(&args);
521
522 // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener
523 args.policyFlags |= POLICY_FLAG_TRUSTED;
524 mFakePolicy->assertNotifySwitchWasCalled(args);
525}
526
Arthur Hungb92218b2018-08-14 12:00:21 +0800527// --- InputDispatcherTest SetInputWindowTest ---
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700528static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 500ms;
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700529static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
Arthur Hungb92218b2018-08-14 12:00:21 +0800530
531class FakeApplicationHandle : public InputApplicationHandle {
532public:
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700533 FakeApplicationHandle() {
534 mInfo.name = "Fake Application";
535 mInfo.token = new BBinder();
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500536 mInfo.dispatchingTimeoutMillis =
537 std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700538 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800539 virtual ~FakeApplicationHandle() {}
540
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700541 virtual bool updateInfo() override {
Arthur Hungb92218b2018-08-14 12:00:21 +0800542 return true;
543 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700544
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500545 void setDispatchingTimeout(std::chrono::milliseconds timeout) {
546 mInfo.dispatchingTimeoutMillis = timeout.count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700547 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800548};
549
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800550class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800551public:
Garfield Tan15601662020-09-22 15:32:38 -0700552 explicit FakeInputReceiver(std::unique_ptr<InputChannel> clientChannel, const std::string name)
chaviwd1c23182019-12-20 18:44:56 -0800553 : mName(name) {
Garfield Tan15601662020-09-22 15:32:38 -0700554 mConsumer = std::make_unique<InputConsumer>(std::move(clientChannel));
chaviwd1c23182019-12-20 18:44:56 -0800555 }
556
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800557 InputEvent* consume() {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700558 InputEvent* event;
559 std::optional<uint32_t> consumeSeq = receiveEvent(&event);
560 if (!consumeSeq) {
561 return nullptr;
562 }
563 finishEvent(*consumeSeq);
564 return event;
565 }
566
567 /**
568 * Receive an event without acknowledging it.
569 * Return the sequence number that could later be used to send finished signal.
570 */
571 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800572 uint32_t consumeSeq;
573 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800574
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800575 std::chrono::time_point start = std::chrono::steady_clock::now();
576 status_t status = WOULD_BLOCK;
577 while (status == WOULD_BLOCK) {
chaviw81e2bb92019-12-18 15:03:51 -0800578 status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq,
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800579 &event);
580 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
581 if (elapsed > 100ms) {
582 break;
583 }
584 }
585
586 if (status == WOULD_BLOCK) {
587 // Just means there's no event available.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700588 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800589 }
590
591 if (status != OK) {
592 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700593 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800594 }
595 if (event == nullptr) {
596 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700597 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800598 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700599 if (outEvent != nullptr) {
600 *outEvent = event;
601 }
602 return consumeSeq;
603 }
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800604
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700605 /**
606 * To be used together with "receiveEvent" to complete the consumption of an event.
607 */
608 void finishEvent(uint32_t consumeSeq) {
609 const status_t status = mConsumer->sendFinishedSignal(consumeSeq, true);
610 ASSERT_EQ(OK, status) << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800611 }
612
613 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
614 int32_t expectedFlags) {
615 InputEvent* event = consume();
616
617 ASSERT_NE(nullptr, event) << mName.c_str()
618 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800619 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700620 << mName.c_str() << " expected " << inputEventTypeToString(expectedEventType)
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800621 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800622
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800623 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800624
Tiger Huang8664f8c2018-10-11 19:14:35 +0800625 switch (expectedEventType) {
626 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800627 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
628 EXPECT_EQ(expectedAction, keyEvent.getAction());
629 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800630 break;
631 }
632 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800633 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
634 EXPECT_EQ(expectedAction, motionEvent.getAction());
635 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800636 break;
637 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100638 case AINPUT_EVENT_TYPE_FOCUS: {
639 FAIL() << "Use 'consumeFocusEvent' for FOCUS events";
640 }
Tiger Huang8664f8c2018-10-11 19:14:35 +0800641 default: {
642 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
643 }
644 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800645 }
646
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100647 void consumeFocusEvent(bool hasFocus, bool inTouchMode) {
648 InputEvent* event = consume();
649 ASSERT_NE(nullptr, event) << mName.c_str()
650 << ": consumer should have returned non-NULL event.";
651 ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, event->getType())
652 << "Got " << inputEventTypeToString(event->getType())
653 << " event instead of FOCUS event";
654
655 ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId())
656 << mName.c_str() << ": event displayId should always be NONE.";
657
658 FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
659 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
660 EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode());
661 }
662
chaviwd1c23182019-12-20 18:44:56 -0800663 void assertNoEvents() {
664 InputEvent* event = consume();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700665 if (event == nullptr) {
666 return;
667 }
668 if (event->getType() == AINPUT_EVENT_TYPE_KEY) {
669 KeyEvent& keyEvent = static_cast<KeyEvent&>(*event);
670 ADD_FAILURE() << "Received key event "
671 << KeyEvent::actionToString(keyEvent.getAction());
672 } else if (event->getType() == AINPUT_EVENT_TYPE_MOTION) {
673 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
674 ADD_FAILURE() << "Received motion event "
675 << MotionEvent::actionToString(motionEvent.getAction());
676 } else if (event->getType() == AINPUT_EVENT_TYPE_FOCUS) {
677 FocusEvent& focusEvent = static_cast<FocusEvent&>(*event);
678 ADD_FAILURE() << "Received focus event, hasFocus = "
679 << (focusEvent.getHasFocus() ? "true" : "false");
680 }
681 FAIL() << mName.c_str()
682 << ": should not have received any events, so consume() should return NULL";
chaviwd1c23182019-12-20 18:44:56 -0800683 }
684
685 sp<IBinder> getToken() { return mConsumer->getChannel()->getConnectionToken(); }
686
687protected:
688 std::unique_ptr<InputConsumer> mConsumer;
689 PreallocatedInputEventFactory mEventFactory;
690
691 std::string mName;
692};
693
694class FakeWindowHandle : public InputWindowHandle {
695public:
696 static const int32_t WIDTH = 600;
697 static const int32_t HEIGHT = 800;
chaviwd1c23182019-12-20 18:44:56 -0800698
Chris Yea209fde2020-07-22 13:54:51 -0700699 FakeWindowHandle(const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
chaviwd1c23182019-12-20 18:44:56 -0800700 const sp<InputDispatcher>& dispatcher, const std::string name,
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500701 int32_t displayId, std::optional<sp<IBinder>> token = std::nullopt)
chaviwd1c23182019-12-20 18:44:56 -0800702 : mName(name) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500703 if (token == std::nullopt) {
Garfield Tan15601662020-09-22 15:32:38 -0700704 base::Result<std::unique_ptr<InputChannel>> channel =
705 dispatcher->createInputChannel(name);
706 token = (*channel)->getConnectionToken();
707 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
chaviwd1c23182019-12-20 18:44:56 -0800708 }
709
710 inputApplicationHandle->updateInfo();
711 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
712
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500713 mInfo.token = *token;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700714 mInfo.id = sId++;
chaviwd1c23182019-12-20 18:44:56 -0800715 mInfo.name = name;
Michael Wright44753b12020-07-08 13:48:11 +0100716 mInfo.type = InputWindowInfo::Type::APPLICATION;
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500717 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwd1c23182019-12-20 18:44:56 -0800718 mInfo.frameLeft = 0;
719 mInfo.frameTop = 0;
720 mInfo.frameRight = WIDTH;
721 mInfo.frameBottom = HEIGHT;
chaviw1ff3d1e2020-07-01 15:53:47 -0700722 mInfo.transform.set(0, 0);
chaviwd1c23182019-12-20 18:44:56 -0800723 mInfo.globalScaleFactor = 1.0;
724 mInfo.touchableRegion.clear();
725 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
726 mInfo.visible = true;
Vishnu Nair47074b82020-08-14 11:54:47 -0700727 mInfo.focusable = false;
chaviwd1c23182019-12-20 18:44:56 -0800728 mInfo.hasWallpaper = false;
729 mInfo.paused = false;
chaviwd1c23182019-12-20 18:44:56 -0800730 mInfo.ownerPid = INJECTOR_PID;
731 mInfo.ownerUid = INJECTOR_UID;
chaviwd1c23182019-12-20 18:44:56 -0800732 mInfo.displayId = displayId;
733 }
734
735 virtual bool updateInfo() { return true; }
736
Vishnu Nair47074b82020-08-14 11:54:47 -0700737 void setFocusable(bool focusable) { mInfo.focusable = focusable; }
chaviwd1c23182019-12-20 18:44:56 -0800738
Vishnu Nair958da932020-08-21 17:12:37 -0700739 void setVisible(bool visible) { mInfo.visible = visible; }
740
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700741 void setDispatchingTimeout(std::chrono::nanoseconds timeout) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500742 mInfo.dispatchingTimeout = timeout;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700743 }
744
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700745 void setPaused(bool paused) { mInfo.paused = paused; }
746
chaviwd1c23182019-12-20 18:44:56 -0800747 void setFrame(const Rect& frame) {
748 mInfo.frameLeft = frame.left;
749 mInfo.frameTop = frame.top;
750 mInfo.frameRight = frame.right;
751 mInfo.frameBottom = frame.bottom;
chaviw1ff3d1e2020-07-01 15:53:47 -0700752 mInfo.transform.set(frame.left, frame.top);
chaviwd1c23182019-12-20 18:44:56 -0800753 mInfo.touchableRegion.clear();
754 mInfo.addTouchableRegion(frame);
755 }
756
Michael Wright44753b12020-07-08 13:48:11 +0100757 void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; }
chaviwd1c23182019-12-20 18:44:56 -0800758
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500759 void setInputFeatures(InputWindowInfo::Feature features) { mInfo.inputFeatures = features; }
760
chaviw9eaa22c2020-07-01 16:21:27 -0700761 void setWindowTransform(float dsdx, float dtdx, float dtdy, float dsdy) {
762 mInfo.transform.set(dsdx, dtdx, dtdy, dsdy);
763 }
764
765 void setWindowScale(float xScale, float yScale) { setWindowTransform(xScale, 0, 0, yScale); }
chaviwaf87b3e2019-10-01 16:59:28 -0700766
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800767 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
768 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
769 expectedFlags);
770 }
771
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700772 void consumeKeyUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
773 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, expectedDisplayId, expectedFlags);
774 }
775
Svet Ganov5d3bc372020-01-26 23:11:07 -0800776 void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
777 int32_t expectedFlags = 0) {
778 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId,
779 expectedFlags);
780 }
781
782 void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
783 int32_t expectedFlags = 0) {
784 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId,
785 expectedFlags);
786 }
787
788 void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
789 int32_t expectedFlags = 0) {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800790 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
791 expectedFlags);
792 }
793
Svet Ganov5d3bc372020-01-26 23:11:07 -0800794 void consumeMotionPointerDown(int32_t pointerIdx,
795 int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) {
796 int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN
797 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
798 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
799 }
800
801 void consumeMotionPointerUp(int32_t pointerIdx, int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
802 int32_t expectedFlags = 0) {
803 int32_t action = AMOTION_EVENT_ACTION_POINTER_UP
804 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
805 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
806 }
807
808 void consumeMotionUp(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
809 int32_t expectedFlags = 0) {
Michael Wright3a240c42019-12-10 20:53:41 +0000810 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
811 expectedFlags);
812 }
813
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100814 void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
815 ASSERT_NE(mInputReceiver, nullptr)
816 << "Cannot consume events from a window with no receiver";
817 mInputReceiver->consumeFocusEvent(hasFocus, inTouchMode);
818 }
819
chaviwd1c23182019-12-20 18:44:56 -0800820 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
821 int32_t expectedFlags) {
822 ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
823 mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
824 expectedFlags);
825 }
826
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700827 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700828 if (mInputReceiver == nullptr) {
829 ADD_FAILURE() << "Invalid receive event on window with no receiver";
830 return std::nullopt;
831 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700832 return mInputReceiver->receiveEvent(outEvent);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700833 }
834
835 void finishEvent(uint32_t sequenceNum) {
836 ASSERT_NE(mInputReceiver, nullptr) << "Invalid receive event on window with no receiver";
837 mInputReceiver->finishEvent(sequenceNum);
838 }
839
chaviwaf87b3e2019-10-01 16:59:28 -0700840 InputEvent* consume() {
841 if (mInputReceiver == nullptr) {
842 return nullptr;
843 }
844 return mInputReceiver->consume();
845 }
846
Arthur Hungb92218b2018-08-14 12:00:21 +0800847 void assertNoEvents() {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500848 if (mInputReceiver == nullptr &&
849 mInfo.inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL)) {
850 return; // Can't receive events if the window does not have input channel
851 }
852 ASSERT_NE(nullptr, mInputReceiver)
853 << "Window without InputReceiver must specify feature NO_INPUT_CHANNEL";
chaviwd1c23182019-12-20 18:44:56 -0800854 mInputReceiver->assertNoEvents();
Arthur Hungb92218b2018-08-14 12:00:21 +0800855 }
856
chaviwaf87b3e2019-10-01 16:59:28 -0700857 sp<IBinder> getToken() { return mInfo.token; }
858
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100859 const std::string& getName() { return mName; }
860
chaviwd1c23182019-12-20 18:44:56 -0800861private:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100862 const std::string mName;
chaviwd1c23182019-12-20 18:44:56 -0800863 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700864 static std::atomic<int32_t> sId; // each window gets a unique id, like in surfaceflinger
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800865};
866
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700867std::atomic<int32_t> FakeWindowHandle::sId{1};
868
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700869static int32_t injectKey(const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700870 int32_t displayId = ADISPLAY_ID_NONE,
871 int32_t syncMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
872 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800873 KeyEvent event;
874 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
875
876 // Define a valid key down event.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800877 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700878 INVALID_HMAC, action, /* flags */ 0, AKEYCODE_A, KEY_A, AMETA_NONE,
879 repeatCount, currentTime, currentTime);
Arthur Hungb92218b2018-08-14 12:00:21 +0800880
881 // Inject event until dispatch out.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700882 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, syncMode,
883 injectionTimeout,
884 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
Arthur Hungb92218b2018-08-14 12:00:21 +0800885}
886
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700887static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
888 int32_t displayId = ADISPLAY_ID_NONE) {
889 return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId);
890}
891
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700892static int32_t injectKeyUp(const sp<InputDispatcher>& dispatcher,
893 int32_t displayId = ADISPLAY_ID_NONE) {
894 return injectKey(dispatcher, AKEY_EVENT_ACTION_UP, /* repeatCount */ 0, displayId);
895}
896
Garfield Tandf26e862020-07-01 20:18:19 -0700897class PointerBuilder {
898public:
899 PointerBuilder(int32_t id, int32_t toolType) {
900 mProperties.clear();
901 mProperties.id = id;
902 mProperties.toolType = toolType;
903 mCoords.clear();
904 }
905
906 PointerBuilder& x(float x) { return axis(AMOTION_EVENT_AXIS_X, x); }
907
908 PointerBuilder& y(float y) { return axis(AMOTION_EVENT_AXIS_Y, y); }
909
910 PointerBuilder& axis(int32_t axis, float value) {
911 mCoords.setAxisValue(axis, value);
912 return *this;
913 }
914
915 PointerProperties buildProperties() const { return mProperties; }
916
917 PointerCoords buildCoords() const { return mCoords; }
918
919private:
920 PointerProperties mProperties;
921 PointerCoords mCoords;
922};
923
924class MotionEventBuilder {
925public:
926 MotionEventBuilder(int32_t action, int32_t source) {
927 mAction = action;
928 mSource = source;
929 mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
930 }
931
932 MotionEventBuilder& eventTime(nsecs_t eventTime) {
933 mEventTime = eventTime;
934 return *this;
935 }
936
937 MotionEventBuilder& displayId(int32_t displayId) {
938 mDisplayId = displayId;
939 return *this;
940 }
941
942 MotionEventBuilder& actionButton(int32_t actionButton) {
943 mActionButton = actionButton;
944 return *this;
945 }
946
947 MotionEventBuilder& buttonState(int32_t actionButton) {
948 mActionButton = actionButton;
949 return *this;
950 }
951
952 MotionEventBuilder& rawXCursorPosition(float rawXCursorPosition) {
953 mRawXCursorPosition = rawXCursorPosition;
954 return *this;
955 }
956
957 MotionEventBuilder& rawYCursorPosition(float rawYCursorPosition) {
958 mRawYCursorPosition = rawYCursorPosition;
959 return *this;
960 }
961
962 MotionEventBuilder& pointer(PointerBuilder pointer) {
963 mPointers.push_back(pointer);
964 return *this;
965 }
966
967 MotionEvent build() {
968 std::vector<PointerProperties> pointerProperties;
969 std::vector<PointerCoords> pointerCoords;
970 for (const PointerBuilder& pointer : mPointers) {
971 pointerProperties.push_back(pointer.buildProperties());
972 pointerCoords.push_back(pointer.buildCoords());
973 }
974
975 // Set mouse cursor position for the most common cases to avoid boilerplate.
976 if (mSource == AINPUT_SOURCE_MOUSE &&
977 !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition) &&
978 mPointers.size() == 1) {
979 mRawXCursorPosition = pointerCoords[0].getX();
980 mRawYCursorPosition = pointerCoords[0].getY();
981 }
982
983 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -0700984 ui::Transform identityTransform;
Garfield Tandf26e862020-07-01 20:18:19 -0700985 event.initialize(InputEvent::nextId(), DEVICE_ID, mSource, mDisplayId, INVALID_HMAC,
986 mAction, mActionButton, /* flags */ 0, /* edgeFlags */ 0, AMETA_NONE,
chaviw9eaa22c2020-07-01 16:21:27 -0700987 mButtonState, MotionClassification::NONE, identityTransform,
988 /* xPrecision */ 0, /* yPrecision */ 0, mRawXCursorPosition,
989 mRawYCursorPosition, mEventTime, mEventTime, mPointers.size(),
990 pointerProperties.data(), pointerCoords.data());
Garfield Tandf26e862020-07-01 20:18:19 -0700991
992 return event;
993 }
994
995private:
996 int32_t mAction;
997 int32_t mSource;
998 nsecs_t mEventTime;
999 int32_t mDisplayId{ADISPLAY_ID_DEFAULT};
1000 int32_t mActionButton{0};
1001 int32_t mButtonState{0};
1002 float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1003 float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1004
1005 std::vector<PointerBuilder> mPointers;
1006};
1007
1008static int32_t injectMotionEvent(
1009 const sp<InputDispatcher>& dispatcher, const MotionEvent& event,
1010 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
1011 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT) {
1012 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, injectionMode,
1013 injectionTimeout,
1014 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
1015}
1016
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001017static int32_t injectMotionEvent(
1018 const sp<InputDispatcher>& dispatcher, int32_t action, int32_t source, int32_t displayId,
1019 const PointF& position,
1020 const PointF& cursorPosition = {AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001021 AMOTION_EVENT_INVALID_CURSOR_POSITION},
1022 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
1023 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
1024 nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC)) {
Garfield Tandf26e862020-07-01 20:18:19 -07001025 MotionEvent event = MotionEventBuilder(action, source)
1026 .displayId(displayId)
1027 .eventTime(eventTime)
1028 .rawXCursorPosition(cursorPosition.x)
1029 .rawYCursorPosition(cursorPosition.y)
1030 .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER)
1031 .x(position.x)
1032 .y(position.y))
1033 .build();
Arthur Hungb92218b2018-08-14 12:00:21 +08001034
1035 // Inject event until dispatch out.
Garfield Tandf26e862020-07-01 20:18:19 -07001036 return injectMotionEvent(dispatcher, event);
Arthur Hungb92218b2018-08-14 12:00:21 +08001037}
1038
Garfield Tan00f511d2019-06-12 16:55:40 -07001039static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001040 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001041 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, location);
Garfield Tan00f511d2019-06-12 16:55:40 -07001042}
1043
Michael Wright3a240c42019-12-10 20:53:41 +00001044static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001045 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001046 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, location);
Michael Wright3a240c42019-12-10 20:53:41 +00001047}
1048
Jackal Guof9696682018-10-05 12:23:23 +08001049static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
1050 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1051 // Define a valid key event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001052 NotifyKeyArgs args(/* id */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
1053 POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0, AKEYCODE_A, KEY_A,
1054 AMETA_NONE, currentTime);
Jackal Guof9696682018-10-05 12:23:23 +08001055
1056 return args;
1057}
1058
chaviwd1c23182019-12-20 18:44:56 -08001059static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId,
1060 const std::vector<PointF>& points) {
1061 size_t pointerCount = points.size();
chaviwaf87b3e2019-10-01 16:59:28 -07001062 if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_UP) {
1063 EXPECT_EQ(1U, pointerCount) << "Actions DOWN and UP can only contain a single pointer";
1064 }
1065
chaviwd1c23182019-12-20 18:44:56 -08001066 PointerProperties pointerProperties[pointerCount];
1067 PointerCoords pointerCoords[pointerCount];
Jackal Guof9696682018-10-05 12:23:23 +08001068
chaviwd1c23182019-12-20 18:44:56 -08001069 for (size_t i = 0; i < pointerCount; i++) {
1070 pointerProperties[i].clear();
1071 pointerProperties[i].id = i;
1072 pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
Jackal Guof9696682018-10-05 12:23:23 +08001073
chaviwd1c23182019-12-20 18:44:56 -08001074 pointerCoords[i].clear();
1075 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
1076 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, points[i].y);
1077 }
Jackal Guof9696682018-10-05 12:23:23 +08001078
1079 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1080 // Define a valid motion event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001081 NotifyMotionArgs args(/* id */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -07001082 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
1083 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
chaviwd1c23182019-12-20 18:44:56 -08001084 AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, pointerProperties,
1085 pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -07001086 AMOTION_EVENT_INVALID_CURSOR_POSITION,
1087 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +08001088
1089 return args;
1090}
1091
chaviwd1c23182019-12-20 18:44:56 -08001092static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
1093 return generateMotionArgs(action, source, displayId, {PointF{100, 200}});
1094}
1095
Arthur Hungb92218b2018-08-14 12:00:21 +08001096TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001097 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001098 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
1099 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001100
Arthur Hung72d8dc32020-03-28 00:48:39 +00001101 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001102 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1103 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001104 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1105
1106 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001107 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001108}
1109
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001110/**
1111 * Calling setInputWindows once with FLAG_NOT_TOUCH_MODAL should not cause any issues.
1112 * To ensure that window receives only events that were directly inside of it, add
1113 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1114 * when finding touched windows.
1115 * This test serves as a sanity check for the next test, where setInputWindows is
1116 * called twice.
1117 */
1118TEST_F(InputDispatcherTest, SetInputWindowOnce_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001119 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001120 sp<FakeWindowHandle> window =
1121 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1122 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001123 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001124
1125 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1126 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1127 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1128 {50, 50}))
1129 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1130
1131 // Window should receive motion event.
1132 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1133}
1134
1135/**
1136 * Calling setInputWindows twice, with the same info, should not cause any issues.
1137 * To ensure that window receives only events that were directly inside of it, add
1138 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1139 * when finding touched windows.
1140 */
1141TEST_F(InputDispatcherTest, SetInputWindowTwice_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001142 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001143 sp<FakeWindowHandle> window =
1144 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1145 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001146 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001147
1148 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1149 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1150 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1151 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1152 {50, 50}))
1153 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1154
1155 // Window should receive motion event.
1156 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1157}
1158
Arthur Hungb92218b2018-08-14 12:00:21 +08001159// The foreground window should receive the first touch down event.
1160TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001161 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001162 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1163 ADISPLAY_ID_DEFAULT);
1164 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1165 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001166
Arthur Hung72d8dc32020-03-28 00:48:39 +00001167 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001168 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1169 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001170 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1171
1172 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001173 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001174 windowSecond->assertNoEvents();
1175}
1176
Garfield Tandf26e862020-07-01 20:18:19 -07001177TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001178 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001179 sp<FakeWindowHandle> windowLeft =
1180 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1181 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001182 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001183 sp<FakeWindowHandle> windowRight =
1184 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1185 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001186 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001187
1188 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1189
1190 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
1191
1192 // Start cursor position in right window so that we can move the cursor to left window.
1193 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1194 injectMotionEvent(mDispatcher,
1195 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1196 AINPUT_SOURCE_MOUSE)
1197 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1198 .x(900)
1199 .y(400))
1200 .build()));
1201 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1202 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1203 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1204 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1205
1206 // Move cursor into left window
1207 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1208 injectMotionEvent(mDispatcher,
1209 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1210 AINPUT_SOURCE_MOUSE)
1211 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1212 .x(300)
1213 .y(400))
1214 .build()));
1215 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1216 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1217 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1218 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1219 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1220 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1221
1222 // Inject a series of mouse events for a mouse click
1223 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1224 injectMotionEvent(mDispatcher,
1225 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1226 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1227 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1228 .x(300)
1229 .y(400))
1230 .build()));
1231 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1232
1233 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1234 injectMotionEvent(mDispatcher,
1235 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1236 AINPUT_SOURCE_MOUSE)
1237 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1238 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1239 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1240 .x(300)
1241 .y(400))
1242 .build()));
1243 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1244 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1245
1246 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1247 injectMotionEvent(mDispatcher,
1248 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1249 AINPUT_SOURCE_MOUSE)
1250 .buttonState(0)
1251 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1252 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1253 .x(300)
1254 .y(400))
1255 .build()));
1256 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1257 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1258
1259 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1260 injectMotionEvent(mDispatcher,
1261 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1262 .buttonState(0)
1263 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1264 .x(300)
1265 .y(400))
1266 .build()));
1267 windowLeft->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1268
1269 // Move mouse cursor back to right window
1270 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1271 injectMotionEvent(mDispatcher,
1272 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1273 AINPUT_SOURCE_MOUSE)
1274 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1275 .x(900)
1276 .y(400))
1277 .build()));
1278 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1279 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1280 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1281 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1282 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1283 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1284}
1285
1286// This test is different from the test above that HOVER_ENTER and HOVER_EXIT events are injected
1287// directly in this test.
1288TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001289 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001290 sp<FakeWindowHandle> window =
1291 new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
1292 window->setFrame(Rect(0, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001293 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001294
1295 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1296
1297 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1298
1299 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1300 injectMotionEvent(mDispatcher,
1301 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
1302 AINPUT_SOURCE_MOUSE)
1303 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1304 .x(300)
1305 .y(400))
1306 .build()));
1307 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1308 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1309
1310 // Inject a series of mouse events for a mouse click
1311 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1312 injectMotionEvent(mDispatcher,
1313 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1314 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1315 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1316 .x(300)
1317 .y(400))
1318 .build()));
1319 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1320
1321 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1322 injectMotionEvent(mDispatcher,
1323 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1324 AINPUT_SOURCE_MOUSE)
1325 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1326 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1327 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1328 .x(300)
1329 .y(400))
1330 .build()));
1331 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1332 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1333
1334 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1335 injectMotionEvent(mDispatcher,
1336 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1337 AINPUT_SOURCE_MOUSE)
1338 .buttonState(0)
1339 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1340 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1341 .x(300)
1342 .y(400))
1343 .build()));
1344 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1345 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1346
1347 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1348 injectMotionEvent(mDispatcher,
1349 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1350 .buttonState(0)
1351 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1352 .x(300)
1353 .y(400))
1354 .build()));
1355 window->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1356
1357 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1358 injectMotionEvent(mDispatcher,
1359 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
1360 AINPUT_SOURCE_MOUSE)
1361 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1362 .x(300)
1363 .y(400))
1364 .build()));
1365 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1366 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1367}
1368
Garfield Tan00f511d2019-06-12 16:55:40 -07001369TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
Chris Yea209fde2020-07-22 13:54:51 -07001370 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tan00f511d2019-06-12 16:55:40 -07001371
1372 sp<FakeWindowHandle> windowLeft =
1373 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1374 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001375 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001376 sp<FakeWindowHandle> windowRight =
1377 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1378 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001379 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001380
1381 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1382
Arthur Hung72d8dc32020-03-28 00:48:39 +00001383 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
Garfield Tan00f511d2019-06-12 16:55:40 -07001384
1385 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
1386 // left window. This event should be dispatched to the left window.
1387 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1388 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001389 ADISPLAY_ID_DEFAULT, {610, 400}, {599, 400}));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001390 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -07001391 windowRight->assertNoEvents();
1392}
1393
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001394TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001395 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001396 sp<FakeWindowHandle> window =
1397 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Vishnu Nair47074b82020-08-14 11:54:47 -07001398 window->setFocusable(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001399
Arthur Hung72d8dc32020-03-28 00:48:39 +00001400 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001401 setFocusedWindow(window);
1402
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001403 window->consumeFocusEvent(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001404
1405 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1406 mDispatcher->notifyKey(&keyArgs);
1407
1408 // Window should receive key down event.
1409 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1410
1411 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
1412 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001413 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001414 mDispatcher->notifyDeviceReset(&args);
1415 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
1416 AKEY_EVENT_FLAG_CANCELED);
1417}
1418
1419TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001420 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001421 sp<FakeWindowHandle> window =
1422 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1423
Arthur Hung72d8dc32020-03-28 00:48:39 +00001424 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001425
1426 NotifyMotionArgs motionArgs =
1427 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1428 ADISPLAY_ID_DEFAULT);
1429 mDispatcher->notifyMotion(&motionArgs);
1430
1431 // Window should receive motion down event.
1432 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1433
1434 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
1435 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001436 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001437 mDispatcher->notifyDeviceReset(&args);
1438 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
1439 0 /*expectedFlags*/);
1440}
1441
Svet Ganov5d3bc372020-01-26 23:11:07 -08001442TEST_F(InputDispatcherTest, TransferTouchFocus_OnePointer) {
Chris Yea209fde2020-07-22 13:54:51 -07001443 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001444
1445 // Create a couple of windows
1446 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1447 "First Window", ADISPLAY_ID_DEFAULT);
1448 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1449 "Second Window", ADISPLAY_ID_DEFAULT);
1450
1451 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001452 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001453
1454 // Send down to the first window
1455 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1456 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1457 mDispatcher->notifyMotion(&downMotionArgs);
1458 // Only the first window should get the down event
1459 firstWindow->consumeMotionDown();
1460 secondWindow->assertNoEvents();
1461
1462 // Transfer touch focus to the second window
1463 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1464 // The first window gets cancel and the second gets down
1465 firstWindow->consumeMotionCancel();
1466 secondWindow->consumeMotionDown();
1467
1468 // Send up event to the second window
1469 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1470 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1471 mDispatcher->notifyMotion(&upMotionArgs);
1472 // The first window gets no events and the second gets up
1473 firstWindow->assertNoEvents();
1474 secondWindow->consumeMotionUp();
1475}
1476
1477TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointerNoSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001478 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001479
1480 PointF touchPoint = {10, 10};
1481
1482 // Create a couple of windows
1483 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1484 "First Window", ADISPLAY_ID_DEFAULT);
1485 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1486 "Second Window", ADISPLAY_ID_DEFAULT);
1487
1488 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001489 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001490
1491 // Send down to the first window
1492 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1493 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint});
1494 mDispatcher->notifyMotion(&downMotionArgs);
1495 // Only the first window should get the down event
1496 firstWindow->consumeMotionDown();
1497 secondWindow->assertNoEvents();
1498
1499 // Send pointer down to the first window
1500 NotifyMotionArgs pointerDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1501 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1502 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1503 mDispatcher->notifyMotion(&pointerDownMotionArgs);
1504 // Only the first window should get the pointer down event
1505 firstWindow->consumeMotionPointerDown(1);
1506 secondWindow->assertNoEvents();
1507
1508 // Transfer touch focus to the second window
1509 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1510 // The first window gets cancel and the second gets down and pointer down
1511 firstWindow->consumeMotionCancel();
1512 secondWindow->consumeMotionDown();
1513 secondWindow->consumeMotionPointerDown(1);
1514
1515 // Send pointer up to the second window
1516 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1517 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1518 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1519 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1520 // The first window gets nothing and the second gets pointer up
1521 firstWindow->assertNoEvents();
1522 secondWindow->consumeMotionPointerUp(1);
1523
1524 // Send up event to the second window
1525 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1526 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1527 mDispatcher->notifyMotion(&upMotionArgs);
1528 // The first window gets nothing and the second gets up
1529 firstWindow->assertNoEvents();
1530 secondWindow->consumeMotionUp();
1531}
1532
1533TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointersSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001534 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001535
1536 // Create a non touch modal window that supports split touch
1537 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1538 "First Window", ADISPLAY_ID_DEFAULT);
1539 firstWindow->setFrame(Rect(0, 0, 600, 400));
Michael Wright44753b12020-07-08 13:48:11 +01001540 firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1541 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001542
1543 // Create a non touch modal window that supports split touch
1544 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1545 "Second Window", ADISPLAY_ID_DEFAULT);
1546 secondWindow->setFrame(Rect(0, 400, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001547 secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1548 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001549
1550 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001551 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001552
1553 PointF pointInFirst = {300, 200};
1554 PointF pointInSecond = {300, 600};
1555
1556 // Send down to the first window
1557 NotifyMotionArgs firstDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1558 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst});
1559 mDispatcher->notifyMotion(&firstDownMotionArgs);
1560 // Only the first window should get the down event
1561 firstWindow->consumeMotionDown();
1562 secondWindow->assertNoEvents();
1563
1564 // Send down to the second window
1565 NotifyMotionArgs secondDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1566 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1567 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1568 mDispatcher->notifyMotion(&secondDownMotionArgs);
1569 // The first window gets a move and the second a down
1570 firstWindow->consumeMotionMove();
1571 secondWindow->consumeMotionDown();
1572
1573 // Transfer touch focus to the second window
1574 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1575 // The first window gets cancel and the new gets pointer down (it already saw down)
1576 firstWindow->consumeMotionCancel();
1577 secondWindow->consumeMotionPointerDown(1);
1578
1579 // Send pointer up to the second window
1580 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1581 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1582 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1583 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1584 // The first window gets nothing and the second gets pointer up
1585 firstWindow->assertNoEvents();
1586 secondWindow->consumeMotionPointerUp(1);
1587
1588 // Send up event to the second window
1589 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1590 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1591 mDispatcher->notifyMotion(&upMotionArgs);
1592 // The first window gets nothing and the second gets up
1593 firstWindow->assertNoEvents();
1594 secondWindow->consumeMotionUp();
1595}
1596
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001597TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001598 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001599 sp<FakeWindowHandle> window =
1600 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1601
Vishnu Nair47074b82020-08-14 11:54:47 -07001602 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001603 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001604 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001605
1606 window->consumeFocusEvent(true);
1607
1608 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1609 mDispatcher->notifyKey(&keyArgs);
1610
1611 // Window should receive key down event.
1612 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1613}
1614
1615TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001616 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001617 sp<FakeWindowHandle> window =
1618 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1619
Arthur Hung72d8dc32020-03-28 00:48:39 +00001620 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001621
1622 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1623 mDispatcher->notifyKey(&keyArgs);
1624 mDispatcher->waitForIdle();
1625
1626 window->assertNoEvents();
1627}
1628
1629// If a window is touchable, but does not have focus, it should receive motion events, but not keys
1630TEST_F(InputDispatcherTest, UnfocusedWindow_ReceivesMotionsButNotKeys) {
Chris Yea209fde2020-07-22 13:54:51 -07001631 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001632 sp<FakeWindowHandle> window =
1633 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1634
Arthur Hung72d8dc32020-03-28 00:48:39 +00001635 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001636
1637 // Send key
1638 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1639 mDispatcher->notifyKey(&keyArgs);
1640 // Send motion
1641 NotifyMotionArgs motionArgs =
1642 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1643 ADISPLAY_ID_DEFAULT);
1644 mDispatcher->notifyMotion(&motionArgs);
1645
1646 // Window should receive only the motion event
1647 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1648 window->assertNoEvents(); // Key event or focus event will not be received
1649}
1650
chaviwd1c23182019-12-20 18:44:56 -08001651class FakeMonitorReceiver {
Michael Wright3a240c42019-12-10 20:53:41 +00001652public:
1653 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
chaviwd1c23182019-12-20 18:44:56 -08001654 int32_t displayId, bool isGestureMonitor = false) {
Garfield Tan15601662020-09-22 15:32:38 -07001655 base::Result<std::unique_ptr<InputChannel>> channel =
1656 dispatcher->createInputMonitor(displayId, isGestureMonitor, name);
1657 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
Michael Wright3a240c42019-12-10 20:53:41 +00001658 }
1659
chaviwd1c23182019-12-20 18:44:56 -08001660 sp<IBinder> getToken() { return mInputReceiver->getToken(); }
1661
1662 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1663 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN,
1664 expectedDisplayId, expectedFlags);
1665 }
1666
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001667 std::optional<int32_t> receiveEvent() { return mInputReceiver->receiveEvent(); }
1668
1669 void finishEvent(uint32_t consumeSeq) { return mInputReceiver->finishEvent(consumeSeq); }
1670
chaviwd1c23182019-12-20 18:44:56 -08001671 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1672 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN,
1673 expectedDisplayId, expectedFlags);
1674 }
1675
1676 void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1677 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP,
1678 expectedDisplayId, expectedFlags);
1679 }
1680
1681 void assertNoEvents() { mInputReceiver->assertNoEvents(); }
1682
1683private:
1684 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Michael Wright3a240c42019-12-10 20:53:41 +00001685};
1686
1687// Tests for gesture monitors
1688TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001689 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001690 sp<FakeWindowHandle> window =
1691 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001692 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001693
chaviwd1c23182019-12-20 18:44:56 -08001694 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1695 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001696
1697 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1698 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1699 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1700 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001701 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001702}
1703
1704TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001705 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001706 sp<FakeWindowHandle> window =
1707 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1708
1709 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001710 window->setFocusable(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001711
Arthur Hung72d8dc32020-03-28 00:48:39 +00001712 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001713 setFocusedWindow(window);
1714
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001715 window->consumeFocusEvent(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001716
chaviwd1c23182019-12-20 18:44:56 -08001717 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1718 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001719
1720 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1721 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1722 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001723 monitor.assertNoEvents();
Michael Wright3a240c42019-12-10 20:53:41 +00001724}
1725
1726TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001727 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001728 sp<FakeWindowHandle> window =
1729 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001730 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001731
chaviwd1c23182019-12-20 18:44:56 -08001732 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1733 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001734
1735 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1736 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1737 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1738 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001739 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001740
1741 window->releaseChannel();
1742
chaviwd1c23182019-12-20 18:44:56 -08001743 mDispatcher->pilferPointers(monitor.getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00001744
1745 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1746 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1747 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwd1c23182019-12-20 18:44:56 -08001748 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001749}
1750
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001751TEST_F(InputDispatcherTest, UnresponsiveGestureMonitor_GetsAnr) {
1752 FakeMonitorReceiver monitor =
1753 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
1754 true /*isGestureMonitor*/);
1755
1756 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1757 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT));
1758 std::optional<uint32_t> consumeSeq = monitor.receiveEvent();
1759 ASSERT_TRUE(consumeSeq);
1760
1761 mFakePolicy->assertNotifyAnrWasCalled(DISPATCHING_TIMEOUT, nullptr, monitor.getToken());
1762 monitor.finishEvent(*consumeSeq);
1763 ASSERT_TRUE(mDispatcher->waitForIdle());
1764}
1765
chaviw81e2bb92019-12-18 15:03:51 -08001766TEST_F(InputDispatcherTest, TestMoveEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001767 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
chaviw81e2bb92019-12-18 15:03:51 -08001768 sp<FakeWindowHandle> window =
1769 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1770
Arthur Hung72d8dc32020-03-28 00:48:39 +00001771 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
chaviw81e2bb92019-12-18 15:03:51 -08001772
1773 NotifyMotionArgs motionArgs =
1774 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1775 ADISPLAY_ID_DEFAULT);
1776
1777 mDispatcher->notifyMotion(&motionArgs);
1778 // Window should receive motion down event.
1779 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1780
1781 motionArgs.action = AMOTION_EVENT_ACTION_MOVE;
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001782 motionArgs.id += 1;
chaviw81e2bb92019-12-18 15:03:51 -08001783 motionArgs.eventTime = systemTime(SYSTEM_TIME_MONOTONIC);
1784 motionArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
1785 motionArgs.pointerCoords[0].getX() - 10);
1786
1787 mDispatcher->notifyMotion(&motionArgs);
1788 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, ADISPLAY_ID_DEFAULT,
1789 0 /*expectedFlags*/);
1790}
1791
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001792/**
1793 * Dispatcher has touch mode enabled by default. Typically, the policy overrides that value to
1794 * the device default right away. In the test scenario, we check both the default value,
1795 * and the action of enabling / disabling.
1796 */
1797TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
Chris Yea209fde2020-07-22 13:54:51 -07001798 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001799 sp<FakeWindowHandle> window =
1800 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1801
1802 // Set focused application.
1803 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001804 window->setFocusable(true);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001805
1806 SCOPED_TRACE("Check default value of touch mode");
Arthur Hung72d8dc32020-03-28 00:48:39 +00001807 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001808 setFocusedWindow(window);
1809
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001810 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1811
1812 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001813 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001814 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001815 window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
1816
1817 SCOPED_TRACE("Disable touch mode");
1818 mDispatcher->setInTouchMode(false);
Vishnu Nair47074b82020-08-14 11:54:47 -07001819 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001820 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001821 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001822 window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
1823
1824 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001825 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001826 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001827 window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
1828
1829 SCOPED_TRACE("Enable touch mode again");
1830 mDispatcher->setInTouchMode(true);
Vishnu Nair47074b82020-08-14 11:54:47 -07001831 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001832 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001833 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001834 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1835
1836 window->assertNoEvents();
1837}
1838
Gang Wange9087892020-01-07 12:17:14 -05001839TEST_F(InputDispatcherTest, VerifyInputEvent_KeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001840 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Gang Wange9087892020-01-07 12:17:14 -05001841 sp<FakeWindowHandle> window =
1842 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1843
1844 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001845 window->setFocusable(true);
Gang Wange9087892020-01-07 12:17:14 -05001846
Arthur Hung72d8dc32020-03-28 00:48:39 +00001847 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001848 setFocusedWindow(window);
1849
Gang Wange9087892020-01-07 12:17:14 -05001850 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1851
1852 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1853 mDispatcher->notifyKey(&keyArgs);
1854
1855 InputEvent* event = window->consume();
1856 ASSERT_NE(event, nullptr);
1857
1858 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1859 ASSERT_NE(verified, nullptr);
1860 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::KEY);
1861
1862 ASSERT_EQ(keyArgs.eventTime, verified->eventTimeNanos);
1863 ASSERT_EQ(keyArgs.deviceId, verified->deviceId);
1864 ASSERT_EQ(keyArgs.source, verified->source);
1865 ASSERT_EQ(keyArgs.displayId, verified->displayId);
1866
1867 const VerifiedKeyEvent& verifiedKey = static_cast<const VerifiedKeyEvent&>(*verified);
1868
1869 ASSERT_EQ(keyArgs.action, verifiedKey.action);
1870 ASSERT_EQ(keyArgs.downTime, verifiedKey.downTimeNanos);
Gang Wange9087892020-01-07 12:17:14 -05001871 ASSERT_EQ(keyArgs.flags & VERIFIED_KEY_EVENT_FLAGS, verifiedKey.flags);
1872 ASSERT_EQ(keyArgs.keyCode, verifiedKey.keyCode);
1873 ASSERT_EQ(keyArgs.scanCode, verifiedKey.scanCode);
1874 ASSERT_EQ(keyArgs.metaState, verifiedKey.metaState);
1875 ASSERT_EQ(0, verifiedKey.repeatCount);
1876}
1877
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001878TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001879 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001880 sp<FakeWindowHandle> window =
1881 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1882
1883 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1884
Arthur Hung72d8dc32020-03-28 00:48:39 +00001885 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001886
1887 NotifyMotionArgs motionArgs =
1888 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1889 ADISPLAY_ID_DEFAULT);
1890 mDispatcher->notifyMotion(&motionArgs);
1891
1892 InputEvent* event = window->consume();
1893 ASSERT_NE(event, nullptr);
1894
1895 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1896 ASSERT_NE(verified, nullptr);
1897 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::MOTION);
1898
1899 EXPECT_EQ(motionArgs.eventTime, verified->eventTimeNanos);
1900 EXPECT_EQ(motionArgs.deviceId, verified->deviceId);
1901 EXPECT_EQ(motionArgs.source, verified->source);
1902 EXPECT_EQ(motionArgs.displayId, verified->displayId);
1903
1904 const VerifiedMotionEvent& verifiedMotion = static_cast<const VerifiedMotionEvent&>(*verified);
1905
1906 EXPECT_EQ(motionArgs.pointerCoords[0].getX(), verifiedMotion.rawX);
1907 EXPECT_EQ(motionArgs.pointerCoords[0].getY(), verifiedMotion.rawY);
1908 EXPECT_EQ(motionArgs.action & AMOTION_EVENT_ACTION_MASK, verifiedMotion.actionMasked);
1909 EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos);
1910 EXPECT_EQ(motionArgs.flags & VERIFIED_MOTION_EVENT_FLAGS, verifiedMotion.flags);
1911 EXPECT_EQ(motionArgs.metaState, verifiedMotion.metaState);
1912 EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState);
1913}
1914
chaviw09c8d2d2020-08-24 15:48:26 -07001915/**
1916 * Ensure that separate calls to sign the same data are generating the same key.
1917 * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance
1918 * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky
1919 * tests.
1920 */
1921TEST_F(InputDispatcherTest, GeneratedHmac_IsConsistent) {
1922 KeyEvent event = getTestKeyEvent();
1923 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1924
1925 std::array<uint8_t, 32> hmac1 = mDispatcher->sign(verifiedEvent);
1926 std::array<uint8_t, 32> hmac2 = mDispatcher->sign(verifiedEvent);
1927 ASSERT_EQ(hmac1, hmac2);
1928}
1929
1930/**
1931 * Ensure that changes in VerifiedKeyEvent produce a different hmac.
1932 */
1933TEST_F(InputDispatcherTest, GeneratedHmac_ChangesWhenFieldsChange) {
1934 KeyEvent event = getTestKeyEvent();
1935 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1936 std::array<uint8_t, 32> initialHmac = mDispatcher->sign(verifiedEvent);
1937
1938 verifiedEvent.deviceId += 1;
1939 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1940
1941 verifiedEvent.source += 1;
1942 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1943
1944 verifiedEvent.eventTimeNanos += 1;
1945 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1946
1947 verifiedEvent.displayId += 1;
1948 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1949
1950 verifiedEvent.action += 1;
1951 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1952
1953 verifiedEvent.downTimeNanos += 1;
1954 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1955
1956 verifiedEvent.flags += 1;
1957 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1958
1959 verifiedEvent.keyCode += 1;
1960 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1961
1962 verifiedEvent.scanCode += 1;
1963 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1964
1965 verifiedEvent.metaState += 1;
1966 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1967
1968 verifiedEvent.repeatCount += 1;
1969 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1970}
1971
Vishnu Nair958da932020-08-21 17:12:37 -07001972TEST_F(InputDispatcherTest, SetFocusedWindow) {
1973 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
1974 sp<FakeWindowHandle> windowTop =
1975 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
1976 sp<FakeWindowHandle> windowSecond =
1977 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1978 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1979
1980 // Top window is also focusable but is not granted focus.
1981 windowTop->setFocusable(true);
1982 windowSecond->setFocusable(true);
1983 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
1984 setFocusedWindow(windowSecond);
1985
1986 windowSecond->consumeFocusEvent(true);
1987 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1988 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1989
1990 // Focused window should receive event.
1991 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
1992 windowTop->assertNoEvents();
1993}
1994
1995TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestInvalidChannel) {
1996 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
1997 sp<FakeWindowHandle> window =
1998 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
1999 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2000
2001 window->setFocusable(true);
2002 // Release channel for window is no longer valid.
2003 window->releaseChannel();
2004 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2005 setFocusedWindow(window);
2006
2007 // Test inject a key down, should timeout.
2008 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2009 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2010
2011 // window channel is invalid, so it should not receive any input event.
2012 window->assertNoEvents();
2013}
2014
2015TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestNoFocusableWindow) {
2016 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2017 sp<FakeWindowHandle> window =
2018 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2019 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2020
2021 // Window is not focusable.
2022 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2023 setFocusedWindow(window);
2024
2025 // Test inject a key down, should timeout.
2026 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2027 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2028
2029 // window is invalid, so it should not receive any input event.
2030 window->assertNoEvents();
2031}
2032
2033TEST_F(InputDispatcherTest, SetFocusedWindow_CheckFocusedToken) {
2034 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2035 sp<FakeWindowHandle> windowTop =
2036 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
2037 sp<FakeWindowHandle> windowSecond =
2038 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2039 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2040
2041 windowTop->setFocusable(true);
2042 windowSecond->setFocusable(true);
2043 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
2044 setFocusedWindow(windowTop);
2045 windowTop->consumeFocusEvent(true);
2046
2047 setFocusedWindow(windowSecond, windowTop);
2048 windowSecond->consumeFocusEvent(true);
2049 windowTop->consumeFocusEvent(false);
2050
2051 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2052 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2053
2054 // Focused window should receive event.
2055 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
2056}
2057
2058TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestFocusTokenNotFocused) {
2059 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2060 sp<FakeWindowHandle> windowTop =
2061 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
2062 sp<FakeWindowHandle> windowSecond =
2063 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2064 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2065
2066 windowTop->setFocusable(true);
2067 windowSecond->setFocusable(true);
2068 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
2069 setFocusedWindow(windowSecond, windowTop);
2070
2071 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2072 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2073
2074 // Event should be dropped.
2075 windowTop->assertNoEvents();
2076 windowSecond->assertNoEvents();
2077}
2078
2079TEST_F(InputDispatcherTest, SetFocusedWindow_DeferInvisibleWindow) {
2080 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2081 sp<FakeWindowHandle> window =
2082 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2083 sp<FakeWindowHandle> previousFocusedWindow =
2084 new FakeWindowHandle(application, mDispatcher, "previousFocusedWindow",
2085 ADISPLAY_ID_DEFAULT);
2086 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2087
2088 window->setFocusable(true);
2089 previousFocusedWindow->setFocusable(true);
2090 window->setVisible(false);
2091 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window, previousFocusedWindow}}});
2092 setFocusedWindow(previousFocusedWindow);
2093 previousFocusedWindow->consumeFocusEvent(true);
2094
2095 // Requesting focus on invisible window takes focus from currently focused window.
2096 setFocusedWindow(window);
2097 previousFocusedWindow->consumeFocusEvent(false);
2098
2099 // Injected key goes to pending queue.
2100 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2101 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
2102 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
2103
2104 // Window does not get focus event or key down.
2105 window->assertNoEvents();
2106
2107 // Window becomes visible.
2108 window->setVisible(true);
2109 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2110
2111 // Window receives focus event.
2112 window->consumeFocusEvent(true);
2113 // Focused window receives key down.
2114 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2115}
2116
Garfield Tan1c7bc862020-01-28 13:24:04 -08002117class InputDispatcherKeyRepeatTest : public InputDispatcherTest {
2118protected:
2119 static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms
2120 static constexpr nsecs_t KEY_REPEAT_DELAY = 40 * 1000000; // 40 ms
2121
Chris Yea209fde2020-07-22 13:54:51 -07002122 std::shared_ptr<FakeApplicationHandle> mApp;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002123 sp<FakeWindowHandle> mWindow;
2124
2125 virtual void SetUp() override {
2126 mFakePolicy = new FakeInputDispatcherPolicy();
2127 mFakePolicy->setKeyRepeatConfiguration(KEY_REPEAT_TIMEOUT, KEY_REPEAT_DELAY);
2128 mDispatcher = new InputDispatcher(mFakePolicy);
2129 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
2130 ASSERT_EQ(OK, mDispatcher->start());
2131
2132 setUpWindow();
2133 }
2134
2135 void setUpWindow() {
Chris Yea209fde2020-07-22 13:54:51 -07002136 mApp = std::make_shared<FakeApplicationHandle>();
Garfield Tan1c7bc862020-01-28 13:24:04 -08002137 mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
2138
Vishnu Nair47074b82020-08-14 11:54:47 -07002139 mWindow->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002140 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002141 setFocusedWindow(mWindow);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002142 mWindow->consumeFocusEvent(true);
2143 }
2144
Chris Ye2ad95392020-09-01 13:44:44 -07002145 void sendAndConsumeKeyDown(int32_t deviceId) {
Garfield Tan1c7bc862020-01-28 13:24:04 -08002146 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
Chris Ye2ad95392020-09-01 13:44:44 -07002147 keyArgs.deviceId = deviceId;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002148 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Otherwise it won't generate repeat event
2149 mDispatcher->notifyKey(&keyArgs);
2150
2151 // Window should receive key down event.
2152 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2153 }
2154
2155 void expectKeyRepeatOnce(int32_t repeatCount) {
2156 SCOPED_TRACE(StringPrintf("Checking event with repeat count %" PRId32, repeatCount));
2157 InputEvent* repeatEvent = mWindow->consume();
2158 ASSERT_NE(nullptr, repeatEvent);
2159
2160 uint32_t eventType = repeatEvent->getType();
2161 ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, eventType);
2162
2163 KeyEvent* repeatKeyEvent = static_cast<KeyEvent*>(repeatEvent);
2164 uint32_t eventAction = repeatKeyEvent->getAction();
2165 EXPECT_EQ(AKEY_EVENT_ACTION_DOWN, eventAction);
2166 EXPECT_EQ(repeatCount, repeatKeyEvent->getRepeatCount());
2167 }
2168
Chris Ye2ad95392020-09-01 13:44:44 -07002169 void sendAndConsumeKeyUp(int32_t deviceId) {
Garfield Tan1c7bc862020-01-28 13:24:04 -08002170 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
Chris Ye2ad95392020-09-01 13:44:44 -07002171 keyArgs.deviceId = deviceId;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002172 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Unless it won't generate repeat event
2173 mDispatcher->notifyKey(&keyArgs);
2174
2175 // Window should receive key down event.
2176 mWindow->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
2177 0 /*expectedFlags*/);
2178 }
2179};
2180
2181TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeat) {
Chris Ye2ad95392020-09-01 13:44:44 -07002182 sendAndConsumeKeyDown(1 /* deviceId */);
2183 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2184 expectKeyRepeatOnce(repeatCount);
2185 }
2186}
2187
2188TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeatFromTwoDevices) {
2189 sendAndConsumeKeyDown(1 /* deviceId */);
2190 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2191 expectKeyRepeatOnce(repeatCount);
2192 }
2193 sendAndConsumeKeyDown(2 /* deviceId */);
2194 /* repeatCount will start from 1 for deviceId 2 */
Garfield Tan1c7bc862020-01-28 13:24:04 -08002195 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2196 expectKeyRepeatOnce(repeatCount);
2197 }
2198}
2199
2200TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterUp) {
Chris Ye2ad95392020-09-01 13:44:44 -07002201 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002202 expectKeyRepeatOnce(1 /*repeatCount*/);
Chris Ye2ad95392020-09-01 13:44:44 -07002203 sendAndConsumeKeyUp(1 /* deviceId */);
2204 mWindow->assertNoEvents();
2205}
2206
2207TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_KeyRepeatAfterStaleDeviceKeyUp) {
2208 sendAndConsumeKeyDown(1 /* deviceId */);
2209 expectKeyRepeatOnce(1 /*repeatCount*/);
2210 sendAndConsumeKeyDown(2 /* deviceId */);
2211 expectKeyRepeatOnce(1 /*repeatCount*/);
2212 // Stale key up from device 1.
2213 sendAndConsumeKeyUp(1 /* deviceId */);
2214 // Device 2 is still down, keep repeating
2215 expectKeyRepeatOnce(2 /*repeatCount*/);
2216 expectKeyRepeatOnce(3 /*repeatCount*/);
2217 // Device 2 key up
2218 sendAndConsumeKeyUp(2 /* deviceId */);
2219 mWindow->assertNoEvents();
2220}
2221
2222TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_KeyRepeatStopsAfterRepeatingKeyUp) {
2223 sendAndConsumeKeyDown(1 /* deviceId */);
2224 expectKeyRepeatOnce(1 /*repeatCount*/);
2225 sendAndConsumeKeyDown(2 /* deviceId */);
2226 expectKeyRepeatOnce(1 /*repeatCount*/);
2227 // Device 2 which holds the key repeating goes up, expect the repeating to stop.
2228 sendAndConsumeKeyUp(2 /* deviceId */);
2229 // Device 1 still holds key down, but the repeating was already stopped
Garfield Tan1c7bc862020-01-28 13:24:04 -08002230 mWindow->assertNoEvents();
2231}
2232
2233TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseEventIdFromInputDispatcher) {
Chris Ye2ad95392020-09-01 13:44:44 -07002234 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002235 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2236 InputEvent* repeatEvent = mWindow->consume();
2237 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2238 EXPECT_EQ(IdGenerator::Source::INPUT_DISPATCHER,
2239 IdGenerator::getSource(repeatEvent->getId()));
2240 }
2241}
2242
2243TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseUniqueEventId) {
Chris Ye2ad95392020-09-01 13:44:44 -07002244 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002245
2246 std::unordered_set<int32_t> idSet;
2247 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2248 InputEvent* repeatEvent = mWindow->consume();
2249 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2250 int32_t id = repeatEvent->getId();
2251 EXPECT_EQ(idSet.end(), idSet.find(id));
2252 idSet.insert(id);
2253 }
2254}
2255
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002256/* Test InputDispatcher for MultiDisplay */
2257class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
2258public:
2259 static constexpr int32_t SECOND_DISPLAY_ID = 1;
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002260 virtual void SetUp() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002261 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +08002262
Chris Yea209fde2020-07-22 13:54:51 -07002263 application1 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002264 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
2265 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002266
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002267 // Set focus window for primary display, but focused display would be second one.
2268 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
Vishnu Nair47074b82020-08-14 11:54:47 -07002269 windowInPrimary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002270 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002271 setFocusedWindow(windowInPrimary);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002272 windowInPrimary->consumeFocusEvent(true);
Arthur Hungb92218b2018-08-14 12:00:21 +08002273
Chris Yea209fde2020-07-22 13:54:51 -07002274 application2 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002275 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
2276 SECOND_DISPLAY_ID);
2277 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002278 // Set focus display to second one.
2279 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
2280 // Set focus window for second display.
2281 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
Vishnu Nair47074b82020-08-14 11:54:47 -07002282 windowInSecondary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002283 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002284 setFocusedWindow(windowInSecondary);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002285 windowInSecondary->consumeFocusEvent(true);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002286 }
2287
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002288 virtual void TearDown() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002289 InputDispatcherTest::TearDown();
2290
Chris Yea209fde2020-07-22 13:54:51 -07002291 application1.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002292 windowInPrimary.clear();
Chris Yea209fde2020-07-22 13:54:51 -07002293 application2.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002294 windowInSecondary.clear();
2295 }
2296
2297protected:
Chris Yea209fde2020-07-22 13:54:51 -07002298 std::shared_ptr<FakeApplicationHandle> application1;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002299 sp<FakeWindowHandle> windowInPrimary;
Chris Yea209fde2020-07-22 13:54:51 -07002300 std::shared_ptr<FakeApplicationHandle> application2;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002301 sp<FakeWindowHandle> windowInSecondary;
2302};
2303
2304TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
2305 // Test touch down on primary display.
2306 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2307 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08002308 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002309 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08002310 windowInSecondary->assertNoEvents();
2311
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002312 // Test touch down on second display.
2313 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2314 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +08002315 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2316 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002317 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +08002318}
2319
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002320TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002321 // Test inject a key down with display id specified.
2322 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2323 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002324 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +08002325 windowInSecondary->assertNoEvents();
2326
2327 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +08002328 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2329 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2330 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002331 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +08002332
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002333 // Remove all windows in secondary display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002334 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
Arthur Hungb92218b2018-08-14 12:00:21 +08002335
2336 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002337 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
2338 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +08002339
2340 // Test inject a key down, should timeout because of no target window.
2341 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2342 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2343 windowInPrimary->assertNoEvents();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002344 windowInSecondary->consumeFocusEvent(false);
Arthur Hungb92218b2018-08-14 12:00:21 +08002345 windowInSecondary->assertNoEvents();
2346}
2347
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002348// Test per-display input monitors for motion event.
2349TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
chaviwd1c23182019-12-20 18:44:56 -08002350 FakeMonitorReceiver monitorInPrimary =
2351 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2352 FakeMonitorReceiver monitorInSecondary =
2353 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002354
2355 // Test touch down on primary display.
2356 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2357 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
2358 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002359 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08002360 monitorInPrimary.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002361 windowInSecondary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002362 monitorInSecondary.assertNoEvents();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002363
2364 // Test touch down on second display.
2365 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2366 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
2367 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2368 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002369 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002370 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
chaviwd1c23182019-12-20 18:44:56 -08002371 monitorInSecondary.consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002372
2373 // Test inject a non-pointer motion event.
2374 // If specific a display, it will dispatch to the focused window of particular display,
2375 // or it will dispatch to the focused window of focused display.
2376 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2377 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
2378 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2379 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002380 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002381 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002382 monitorInSecondary.consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002383}
2384
2385// Test per-display input monitors for key event.
2386TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
2387 //Input monitor per display.
chaviwd1c23182019-12-20 18:44:56 -08002388 FakeMonitorReceiver monitorInPrimary =
2389 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2390 FakeMonitorReceiver monitorInSecondary =
2391 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002392
2393 // Test inject a key down.
2394 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2395 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2396 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002397 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002398 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002399 monitorInSecondary.consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002400}
2401
Vishnu Nair958da932020-08-21 17:12:37 -07002402TEST_F(InputDispatcherFocusOnTwoDisplaysTest, CanFocusWindowOnUnfocusedDisplay) {
2403 sp<FakeWindowHandle> secondWindowInPrimary =
2404 new FakeWindowHandle(application1, mDispatcher, "D_1_W2", ADISPLAY_ID_DEFAULT);
2405 secondWindowInPrimary->setFocusable(true);
2406 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary, secondWindowInPrimary}}});
2407 setFocusedWindow(secondWindowInPrimary);
2408 windowInPrimary->consumeFocusEvent(false);
2409 secondWindowInPrimary->consumeFocusEvent(true);
2410
2411 // Test inject a key down.
2412 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2413 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2414 windowInPrimary->assertNoEvents();
2415 windowInSecondary->assertNoEvents();
2416 secondWindowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2417}
2418
Jackal Guof9696682018-10-05 12:23:23 +08002419class InputFilterTest : public InputDispatcherTest {
2420protected:
2421 static constexpr int32_t SECOND_DISPLAY_ID = 1;
2422
2423 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
2424 NotifyMotionArgs motionArgs;
2425
2426 motionArgs = generateMotionArgs(
2427 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2428 mDispatcher->notifyMotion(&motionArgs);
2429 motionArgs = generateMotionArgs(
2430 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2431 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002432 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002433 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002434 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002435 } else {
2436 mFakePolicy->assertFilterInputEventWasNotCalled();
2437 }
2438 }
2439
2440 void testNotifyKey(bool expectToBeFiltered) {
2441 NotifyKeyArgs keyArgs;
2442
2443 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
2444 mDispatcher->notifyKey(&keyArgs);
2445 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
2446 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002447 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002448
2449 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002450 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002451 } else {
2452 mFakePolicy->assertFilterInputEventWasNotCalled();
2453 }
2454 }
2455};
2456
2457// Test InputFilter for MotionEvent
2458TEST_F(InputFilterTest, MotionEvent_InputFilter) {
2459 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
2460 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2461 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2462
2463 // Enable InputFilter
2464 mDispatcher->setInputFilterEnabled(true);
2465 // Test touch on both primary and second display, and check if both events are filtered.
2466 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
2467 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
2468
2469 // Disable InputFilter
2470 mDispatcher->setInputFilterEnabled(false);
2471 // Test touch on both primary and second display, and check if both events aren't filtered.
2472 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2473 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2474}
2475
2476// Test InputFilter for KeyEvent
2477TEST_F(InputFilterTest, KeyEvent_InputFilter) {
2478 // Since the InputFilter is disabled by default, check if key event aren't filtered.
2479 testNotifyKey(/*expectToBeFiltered*/ false);
2480
2481 // Enable InputFilter
2482 mDispatcher->setInputFilterEnabled(true);
2483 // Send a key event, and check if it is filtered.
2484 testNotifyKey(/*expectToBeFiltered*/ true);
2485
2486 // Disable InputFilter
2487 mDispatcher->setInputFilterEnabled(false);
2488 // Send a key event, and check if it isn't filtered.
2489 testNotifyKey(/*expectToBeFiltered*/ false);
2490}
2491
chaviwfd6d3512019-03-25 13:23:49 -07002492class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002493 virtual void SetUp() override {
chaviwfd6d3512019-03-25 13:23:49 -07002494 InputDispatcherTest::SetUp();
2495
Chris Yea209fde2020-07-22 13:54:51 -07002496 std::shared_ptr<FakeApplicationHandle> application =
2497 std::make_shared<FakeApplicationHandle>();
chaviwfd6d3512019-03-25 13:23:49 -07002498 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
2499 ADISPLAY_ID_DEFAULT);
2500 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
2501 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2502 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002503 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002504
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002505 mFocusedWindow =
2506 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2507 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01002508 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002509
2510 // Set focused application.
2511 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07002512 mFocusedWindow->setFocusable(true);
chaviwfd6d3512019-03-25 13:23:49 -07002513
2514 // Expect one focus window exist in display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002515 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002516 setFocusedWindow(mFocusedWindow);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002517 mFocusedWindow->consumeFocusEvent(true);
chaviwfd6d3512019-03-25 13:23:49 -07002518 }
2519
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002520 virtual void TearDown() override {
chaviwfd6d3512019-03-25 13:23:49 -07002521 InputDispatcherTest::TearDown();
2522
2523 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002524 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07002525 }
2526
2527protected:
2528 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002529 sp<FakeWindowHandle> mFocusedWindow;
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002530 static constexpr PointF FOCUSED_WINDOW_TOUCH_POINT = {60, 60};
chaviwfd6d3512019-03-25 13:23:49 -07002531};
2532
2533// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2534// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
2535// the onPointerDownOutsideFocus callback.
2536TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002537 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2538 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2539 {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07002540 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002541 mUnfocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002542
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002543 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07002544 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
2545}
2546
2547// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
2548// DOWN on the window that doesn't have focus. Ensure no window received the
2549// onPointerDownOutsideFocus callback.
2550TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002551 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2552 injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07002553 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002554 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002555
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002556 ASSERT_TRUE(mDispatcher->waitForIdle());
2557 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002558}
2559
2560// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
2561// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
2562TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
2563 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2564 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002565 mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07002566
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002567 ASSERT_TRUE(mDispatcher->waitForIdle());
2568 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002569}
2570
2571// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2572// DOWN on the window that already has focus. Ensure no window received the
2573// onPointerDownOutsideFocus callback.
2574TEST_F(InputDispatcherOnPointerDownOutsideFocus,
2575 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002576 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2577 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002578 FOCUSED_WINDOW_TOUCH_POINT))
chaviwfd6d3512019-03-25 13:23:49 -07002579 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002580 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002581
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002582 ASSERT_TRUE(mDispatcher->waitForIdle());
2583 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002584}
2585
chaviwaf87b3e2019-10-01 16:59:28 -07002586// These tests ensures we can send touch events to a single client when there are multiple input
2587// windows that point to the same client token.
2588class InputDispatcherMultiWindowSameTokenTests : public InputDispatcherTest {
2589 virtual void SetUp() override {
2590 InputDispatcherTest::SetUp();
2591
Chris Yea209fde2020-07-22 13:54:51 -07002592 std::shared_ptr<FakeApplicationHandle> application =
2593 std::make_shared<FakeApplicationHandle>();
chaviwaf87b3e2019-10-01 16:59:28 -07002594 mWindow1 = new FakeWindowHandle(application, mDispatcher, "Fake Window 1",
2595 ADISPLAY_ID_DEFAULT);
2596 // Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
2597 // 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 +01002598 mWindow1->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2599 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002600 mWindow1->setFrame(Rect(0, 0, 100, 100));
2601
2602 mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
2603 ADISPLAY_ID_DEFAULT, mWindow1->getToken());
Michael Wright44753b12020-07-08 13:48:11 +01002604 mWindow2->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2605 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002606 mWindow2->setFrame(Rect(100, 100, 200, 200));
2607
Arthur Hung72d8dc32020-03-28 00:48:39 +00002608 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
chaviwaf87b3e2019-10-01 16:59:28 -07002609 }
2610
2611protected:
2612 sp<FakeWindowHandle> mWindow1;
2613 sp<FakeWindowHandle> mWindow2;
2614
2615 // Helper function to convert the point from screen coordinates into the window's space
2616 static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) {
chaviw1ff3d1e2020-07-01 15:53:47 -07002617 vec2 vals = windowInfo->transform.transform(point.x, point.y);
2618 return {vals.x, vals.y};
chaviwaf87b3e2019-10-01 16:59:28 -07002619 }
2620
2621 void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction,
2622 const std::vector<PointF>& points) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002623 const std::string name = window->getName();
chaviwaf87b3e2019-10-01 16:59:28 -07002624 InputEvent* event = window->consume();
2625
2626 ASSERT_NE(nullptr, event) << name.c_str()
2627 << ": consumer should have returned non-NULL event.";
2628
2629 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
2630 << name.c_str() << "expected " << inputEventTypeToString(AINPUT_EVENT_TYPE_MOTION)
2631 << " event, got " << inputEventTypeToString(event->getType()) << " event";
2632
2633 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
2634 EXPECT_EQ(expectedAction, motionEvent.getAction());
2635
2636 for (size_t i = 0; i < points.size(); i++) {
2637 float expectedX = points[i].x;
2638 float expectedY = points[i].y;
2639
2640 EXPECT_EQ(expectedX, motionEvent.getX(i))
2641 << "expected " << expectedX << " for x[" << i << "] coord of " << name.c_str()
2642 << ", got " << motionEvent.getX(i);
2643 EXPECT_EQ(expectedY, motionEvent.getY(i))
2644 << "expected " << expectedY << " for y[" << i << "] coord of " << name.c_str()
2645 << ", got " << motionEvent.getY(i);
2646 }
2647 }
chaviw9eaa22c2020-07-01 16:21:27 -07002648
2649 void touchAndAssertPositions(int32_t action, std::vector<PointF> touchedPoints,
2650 std::vector<PointF> expectedPoints) {
2651 NotifyMotionArgs motionArgs = generateMotionArgs(action, AINPUT_SOURCE_TOUCHSCREEN,
2652 ADISPLAY_ID_DEFAULT, touchedPoints);
2653 mDispatcher->notifyMotion(&motionArgs);
2654
2655 // Always consume from window1 since it's the window that has the InputReceiver
2656 consumeMotionEvent(mWindow1, action, expectedPoints);
2657 }
chaviwaf87b3e2019-10-01 16:59:28 -07002658};
2659
2660TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchSameScale) {
2661 // Touch Window 1
2662 PointF touchedPoint = {10, 10};
2663 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002664 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002665
2666 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002667 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002668
2669 // Touch Window 2
2670 touchedPoint = {150, 150};
2671 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002672 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002673}
2674
chaviw9eaa22c2020-07-01 16:21:27 -07002675TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchDifferentTransform) {
2676 // Set scale value for window2
chaviwaf87b3e2019-10-01 16:59:28 -07002677 mWindow2->setWindowScale(0.5f, 0.5f);
2678
2679 // Touch Window 1
2680 PointF touchedPoint = {10, 10};
2681 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002682 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002683 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002684 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002685
2686 // Touch Window 2
2687 touchedPoint = {150, 150};
2688 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002689 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
2690 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002691
chaviw9eaa22c2020-07-01 16:21:27 -07002692 // Update the transform so rotation is set
2693 mWindow2->setWindowTransform(0, -1, 1, 0);
2694 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
2695 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002696}
2697
chaviw9eaa22c2020-07-01 16:21:27 -07002698TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002699 mWindow2->setWindowScale(0.5f, 0.5f);
2700
2701 // Touch Window 1
2702 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2703 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002704 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002705
2706 // Touch Window 2
2707 int32_t actionPointerDown =
2708 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002709 touchedPoints.push_back(PointF{150, 150});
2710 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2711 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002712
chaviw9eaa22c2020-07-01 16:21:27 -07002713 // Release Window 2
2714 int32_t actionPointerUp =
2715 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2716 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2717 expectedPoints.pop_back();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002718
chaviw9eaa22c2020-07-01 16:21:27 -07002719 // Update the transform so rotation is set for Window 2
2720 mWindow2->setWindowTransform(0, -1, 1, 0);
2721 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2722 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002723}
2724
chaviw9eaa22c2020-07-01 16:21:27 -07002725TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchMoveDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002726 mWindow2->setWindowScale(0.5f, 0.5f);
2727
2728 // Touch Window 1
2729 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2730 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002731 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002732
2733 // Touch Window 2
2734 int32_t actionPointerDown =
2735 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002736 touchedPoints.push_back(PointF{150, 150});
2737 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002738
chaviw9eaa22c2020-07-01 16:21:27 -07002739 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002740
2741 // Move both windows
2742 touchedPoints = {{20, 20}, {175, 175}};
2743 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2744 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2745
chaviw9eaa22c2020-07-01 16:21:27 -07002746 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002747
chaviw9eaa22c2020-07-01 16:21:27 -07002748 // Release Window 2
2749 int32_t actionPointerUp =
2750 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2751 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2752 expectedPoints.pop_back();
2753
2754 // Touch Window 2
2755 mWindow2->setWindowTransform(0, -1, 1, 0);
2756 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2757 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
2758
2759 // Move both windows
2760 touchedPoints = {{20, 20}, {175, 175}};
2761 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2762 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2763
2764 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002765}
2766
2767TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithScale) {
2768 mWindow1->setWindowScale(0.5f, 0.5f);
2769
2770 // Touch Window 1
2771 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2772 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002773 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002774
2775 // Touch Window 2
2776 int32_t actionPointerDown =
2777 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002778 touchedPoints.push_back(PointF{150, 150});
2779 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002780
chaviw9eaa22c2020-07-01 16:21:27 -07002781 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002782
2783 // Move both windows
2784 touchedPoints = {{20, 20}, {175, 175}};
2785 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2786 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2787
chaviw9eaa22c2020-07-01 16:21:27 -07002788 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002789}
2790
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002791class InputDispatcherSingleWindowAnr : public InputDispatcherTest {
2792 virtual void SetUp() override {
2793 InputDispatcherTest::SetUp();
2794
Chris Yea209fde2020-07-22 13:54:51 -07002795 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002796 mApplication->setDispatchingTimeout(20ms);
2797 mWindow =
2798 new FakeWindowHandle(mApplication, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2799 mWindow->setFrame(Rect(0, 0, 30, 30));
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05002800 mWindow->setDispatchingTimeout(30ms);
Vishnu Nair47074b82020-08-14 11:54:47 -07002801 mWindow->setFocusable(true);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002802 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2803 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002804 mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002805
2806 // Set focused application.
2807 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
2808
2809 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002810 setFocusedWindow(mWindow);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002811 mWindow->consumeFocusEvent(true);
2812 }
2813
2814 virtual void TearDown() override {
2815 InputDispatcherTest::TearDown();
2816 mWindow.clear();
2817 }
2818
2819protected:
Chris Yea209fde2020-07-22 13:54:51 -07002820 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002821 sp<FakeWindowHandle> mWindow;
2822 static constexpr PointF WINDOW_LOCATION = {20, 20};
2823
2824 void tapOnWindow() {
2825 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2826 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2827 WINDOW_LOCATION));
2828 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2829 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2830 WINDOW_LOCATION));
2831 }
2832};
2833
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002834// Send a tap and respond, which should not cause an ANR.
2835TEST_F(InputDispatcherSingleWindowAnr, WhenTouchIsConsumed_NoAnr) {
2836 tapOnWindow();
2837 mWindow->consumeMotionDown();
2838 mWindow->consumeMotionUp();
2839 ASSERT_TRUE(mDispatcher->waitForIdle());
2840 mFakePolicy->assertNotifyAnrWasNotCalled();
2841}
2842
2843// Send a regular key and respond, which should not cause an ANR.
2844TEST_F(InputDispatcherSingleWindowAnr, WhenKeyIsConsumed_NoAnr) {
2845 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
2846 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
2847 ASSERT_TRUE(mDispatcher->waitForIdle());
2848 mFakePolicy->assertNotifyAnrWasNotCalled();
2849}
2850
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05002851TEST_F(InputDispatcherSingleWindowAnr, WhenFocusedApplicationChanges_NoAnr) {
2852 mWindow->setFocusable(false);
2853 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2854 mWindow->consumeFocusEvent(false);
2855
2856 int32_t result =
2857 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
2858 INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
2859 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
2860 // Key will not go to window because we have no focused window.
2861 // The 'no focused window' ANR timer should start instead.
2862
2863 // Now, the focused application goes away.
2864 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, nullptr);
2865 // The key should get dropped and there should be no ANR.
2866
2867 ASSERT_TRUE(mDispatcher->waitForIdle());
2868 mFakePolicy->assertNotifyAnrWasNotCalled();
2869}
2870
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002871// Send an event to the app and have the app not respond right away.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002872// When ANR is raised, policy will tell the dispatcher to cancel the events for that window.
2873// So InputDispatcher will enqueue ACTION_CANCEL event as well.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002874TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) {
2875 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2876 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2877 WINDOW_LOCATION));
2878
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002879 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent(); // ACTION_DOWN
2880 ASSERT_TRUE(sequenceNum);
2881 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2882 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002883
2884 // The remaining lines are not really needed for the test, but kept as a sanity check
2885 mWindow->finishEvent(*sequenceNum);
2886 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
2887 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002888 ASSERT_TRUE(mDispatcher->waitForIdle());
2889}
2890
2891// Send a key to the app and have the app not respond right away.
2892TEST_F(InputDispatcherSingleWindowAnr, OnKeyDown_BasicAnr) {
2893 // Inject a key, and don't respond - expect that ANR is called.
2894 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
2895 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent();
2896 ASSERT_TRUE(sequenceNum);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002897 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002898 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002899 ASSERT_TRUE(mDispatcher->waitForIdle());
2900}
2901
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002902// We have a focused application, but no focused window
2903TEST_F(InputDispatcherSingleWindowAnr, FocusedApplication_NoFocusedWindow) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002904 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002905 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2906 mWindow->consumeFocusEvent(false);
2907
2908 // taps on the window work as normal
2909 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2910 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2911 WINDOW_LOCATION));
2912 ASSERT_NO_FATAL_FAILURE(mWindow->consumeMotionDown());
2913 mDispatcher->waitForIdle();
2914 mFakePolicy->assertNotifyAnrWasNotCalled();
2915
2916 // Once a focused event arrives, we get an ANR for this application
2917 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2918 // injection times out (instead of failing).
2919 const int32_t result =
2920 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2921 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2922 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2923 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2924 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2925 ASSERT_TRUE(mDispatcher->waitForIdle());
2926}
2927
2928// We have a focused application, but no focused window
2929// If the policy wants to keep waiting on the focused window to be added, make sure
2930// that this timeout extension is honored and ANR is raised again.
2931TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_ExtendsAnr) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002932 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002933 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2934 mWindow->consumeFocusEvent(false);
2935 const std::chrono::duration timeout = 5ms;
2936 mFakePolicy->setAnrTimeout(timeout);
2937
2938 // Once a focused event arrives, we get an ANR for this application
2939 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2940 // injection times out (instead of failing).
2941 const int32_t result =
2942 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2943 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2944 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2945 const std::chrono::duration appTimeout =
2946 mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2947 mFakePolicy->assertNotifyAnrWasCalled(appTimeout, mApplication, nullptr /*windowToken*/);
2948
2949 // After the extended time has passed, ANR should be raised again
2950 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2951
2952 // If we stop extending the timeout, dispatcher should go to idle.
2953 // Another ANR may be raised during this time
2954 mFakePolicy->setAnrTimeout(0ms);
2955 ASSERT_TRUE(mDispatcher->waitForIdle());
2956}
2957
2958// We have a focused application, but no focused window
2959TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_DropsFocusedEvents) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002960 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002961 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2962 mWindow->consumeFocusEvent(false);
2963
2964 // Once a focused event arrives, we get an ANR for this application
2965 const int32_t result =
2966 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2967 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2968 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2969
2970 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2971 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2972
2973 // Future focused events get dropped right away
2974 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, injectKeyDown(mDispatcher));
2975 ASSERT_TRUE(mDispatcher->waitForIdle());
2976 mWindow->assertNoEvents();
2977}
2978
2979/**
2980 * Ensure that the implementation is valid. Since we are using multiset to keep track of the
2981 * ANR timeouts, we are allowing entries with identical timestamps in the same connection.
2982 * If we process 1 of the events, but ANR on the second event with the same timestamp,
2983 * the ANR mechanism should still work.
2984 *
2985 * In this test, we are injecting DOWN and UP events with the same timestamps, and acknowledging the
2986 * DOWN event, while not responding on the second one.
2987 */
2988TEST_F(InputDispatcherSingleWindowAnr, Anr_HandlesEventsWithIdenticalTimestamps) {
2989 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
2990 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2991 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
2992 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
2993 AMOTION_EVENT_INVALID_CURSOR_POSITION},
2994 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
2995
2996 // Now send ACTION_UP, with identical timestamp
2997 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
2998 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
2999 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
3000 AMOTION_EVENT_INVALID_CURSOR_POSITION},
3001 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
3002
3003 // We have now sent down and up. Let's consume first event and then ANR on the second.
3004 mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
3005 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3006 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3007}
3008
3009// If an app is not responding to a key event, gesture monitors should continue to receive
3010// new motion events
3011TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnKey) {
3012 FakeMonitorReceiver monitor =
3013 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
3014 true /*isGestureMonitor*/);
3015
3016 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT));
3017 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3018 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher, ADISPLAY_ID_DEFAULT));
3019
3020 // Stuck on the ACTION_UP
3021 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3022 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
3023
3024 // New tap will go to the gesture monitor, but not to the window
3025 tapOnWindow();
3026 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3027 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3028
3029 mWindow->consumeKeyUp(ADISPLAY_ID_DEFAULT); // still the previous motion
3030 mDispatcher->waitForIdle();
3031 mWindow->assertNoEvents();
3032 monitor.assertNoEvents();
3033}
3034
3035// If an app is not responding to a motion event, gesture monitors should continue to receive
3036// new motion events
3037TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnMotion) {
3038 FakeMonitorReceiver monitor =
3039 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
3040 true /*isGestureMonitor*/);
3041
3042 tapOnWindow();
3043 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3044 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3045
3046 mWindow->consumeMotionDown();
3047 // Stuck on the ACTION_UP
3048 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3049 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
3050
3051 // New tap will go to the gesture monitor, but not to the window
3052 tapOnWindow();
3053 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3054 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3055
3056 mWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT); // still the previous motion
3057 mDispatcher->waitForIdle();
3058 mWindow->assertNoEvents();
3059 monitor.assertNoEvents();
3060}
3061
3062// If a window is unresponsive, then you get anr. if the window later catches up and starts to
3063// process events, you don't get an anr. When the window later becomes unresponsive again, you
3064// get an ANR again.
3065// 1. tap -> block on ACTION_UP -> receive ANR
3066// 2. consume all pending events (= queue becomes healthy again)
3067// 3. tap again -> block on ACTION_UP again -> receive ANR second time
3068TEST_F(InputDispatcherSingleWindowAnr, SameWindow_CanReceiveAnrTwice) {
3069 tapOnWindow();
3070
3071 mWindow->consumeMotionDown();
3072 // Block on ACTION_UP
3073 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3074 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3075 mWindow->consumeMotionUp(); // Now the connection should be healthy again
3076 mDispatcher->waitForIdle();
3077 mWindow->assertNoEvents();
3078
3079 tapOnWindow();
3080 mWindow->consumeMotionDown();
3081 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3082 mWindow->consumeMotionUp();
3083
3084 mDispatcher->waitForIdle();
3085 mWindow->assertNoEvents();
3086}
3087
3088// If the policy tells us to raise ANR again after some time, ensure that the timeout extension
3089// is honored
3090TEST_F(InputDispatcherSingleWindowAnr, Policy_CanExtendTimeout) {
3091 const std::chrono::duration timeout = 5ms;
3092 mFakePolicy->setAnrTimeout(timeout);
3093
3094 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3095 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3096 WINDOW_LOCATION));
3097
3098 const std::chrono::duration windowTimeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3099 mFakePolicy->assertNotifyAnrWasCalled(windowTimeout, nullptr /*application*/,
3100 mWindow->getToken());
3101
3102 // Since the policy wanted to extend ANR, make sure it is called again after the extension
3103 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3104 mFakePolicy->setAnrTimeout(0ms);
3105 std::this_thread::sleep_for(windowTimeout);
3106 // We are not checking if ANR has been called, because it may have been called again by the
3107 // time we set the timeout to 0
3108
3109 // When the policy finally says stop, we should get ACTION_CANCEL
3110 mWindow->consumeMotionDown();
3111 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
3112 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3113 mWindow->assertNoEvents();
3114}
3115
3116/**
3117 * If a window is processing a motion event, and then a key event comes in, the key event should
3118 * not to to the focused window until the motion is processed.
3119 *
3120 * Warning!!!
3121 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
3122 * and the injection timeout that we specify when injecting the key.
3123 * We must have the injection timeout (10ms) be smaller than
3124 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
3125 *
3126 * If that value changes, this test should also change.
3127 */
3128TEST_F(InputDispatcherSingleWindowAnr, Key_StaysPendingWhileMotionIsProcessed) {
3129 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
3130 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
3131
3132 tapOnWindow();
3133 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
3134 ASSERT_TRUE(downSequenceNum);
3135 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
3136 ASSERT_TRUE(upSequenceNum);
3137 // Don't finish the events yet, and send a key
3138 // Injection will "succeed" because we will eventually give up and send the key to the focused
3139 // window even if motions are still being processed. But because the injection timeout is short,
3140 // we will receive INJECTION_TIMED_OUT as the result.
3141
3142 int32_t result =
3143 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
3144 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
3145 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
3146 // Key will not be sent to the window, yet, because the window is still processing events
3147 // and the key remains pending, waiting for the touch events to be processed
3148 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
3149 ASSERT_FALSE(keySequenceNum);
3150
3151 std::this_thread::sleep_for(500ms);
3152 // if we wait long enough though, dispatcher will give up, and still send the key
3153 // to the focused window, even though we have not yet finished the motion event
3154 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3155 mWindow->finishEvent(*downSequenceNum);
3156 mWindow->finishEvent(*upSequenceNum);
3157}
3158
3159/**
3160 * If a window is processing a motion event, and then a key event comes in, the key event should
3161 * not go to the focused window until the motion is processed.
3162 * If then a new motion comes in, then the pending key event should be going to the currently
3163 * focused window right away.
3164 */
3165TEST_F(InputDispatcherSingleWindowAnr,
3166 PendingKey_IsDroppedWhileMotionIsProcessedAndNewTouchComesIn) {
3167 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
3168 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
3169
3170 tapOnWindow();
3171 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
3172 ASSERT_TRUE(downSequenceNum);
3173 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
3174 ASSERT_TRUE(upSequenceNum);
3175 // Don't finish the events yet, and send a key
3176 // Injection is async, so it will succeed
3177 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3178 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
3179 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
3180 // At this point, key is still pending, and should not be sent to the application yet.
3181 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
3182 ASSERT_FALSE(keySequenceNum);
3183
3184 // Now tap down again. It should cause the pending key to go to the focused window right away.
3185 tapOnWindow();
3186 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT); // it doesn't matter that we haven't ack'd
3187 // the other events yet. We can finish events in any order.
3188 mWindow->finishEvent(*downSequenceNum); // first tap's ACTION_DOWN
3189 mWindow->finishEvent(*upSequenceNum); // first tap's ACTION_UP
3190 mWindow->consumeMotionDown();
3191 mWindow->consumeMotionUp();
3192 mWindow->assertNoEvents();
3193}
3194
3195class InputDispatcherMultiWindowAnr : public InputDispatcherTest {
3196 virtual void SetUp() override {
3197 InputDispatcherTest::SetUp();
3198
Chris Yea209fde2020-07-22 13:54:51 -07003199 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003200 mApplication->setDispatchingTimeout(10ms);
3201 mUnfocusedWindow =
3202 new FakeWindowHandle(mApplication, mDispatcher, "Unfocused", ADISPLAY_ID_DEFAULT);
3203 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
3204 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
3205 // window.
3206 // Adding FLAG_WATCH_OUTSIDE_TOUCH to receive ACTION_OUTSIDE when another window is tapped
Michael Wright44753b12020-07-08 13:48:11 +01003207 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3208 InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
3209 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003210
3211 mFocusedWindow =
3212 new FakeWindowHandle(mApplication, mDispatcher, "Focused", ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05003213 mFocusedWindow->setDispatchingTimeout(30ms);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003214 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01003215 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3216 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003217
3218 // Set focused application.
3219 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
Vishnu Nair47074b82020-08-14 11:54:47 -07003220 mFocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003221
3222 // Expect one focus window exist in display.
3223 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07003224 setFocusedWindow(mFocusedWindow);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003225 mFocusedWindow->consumeFocusEvent(true);
3226 }
3227
3228 virtual void TearDown() override {
3229 InputDispatcherTest::TearDown();
3230
3231 mUnfocusedWindow.clear();
3232 mFocusedWindow.clear();
3233 }
3234
3235protected:
Chris Yea209fde2020-07-22 13:54:51 -07003236 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003237 sp<FakeWindowHandle> mUnfocusedWindow;
3238 sp<FakeWindowHandle> mFocusedWindow;
3239 static constexpr PointF UNFOCUSED_WINDOW_LOCATION = {20, 20};
3240 static constexpr PointF FOCUSED_WINDOW_LOCATION = {75, 75};
3241 static constexpr PointF LOCATION_OUTSIDE_ALL_WINDOWS = {40, 40};
3242
3243 void tapOnFocusedWindow() { tap(FOCUSED_WINDOW_LOCATION); }
3244
3245 void tapOnUnfocusedWindow() { tap(UNFOCUSED_WINDOW_LOCATION); }
3246
3247private:
3248 void tap(const PointF& location) {
3249 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3250 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3251 location));
3252 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3253 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3254 location));
3255 }
3256};
3257
3258// If we have 2 windows that are both unresponsive, the one with the shortest timeout
3259// should be ANR'd first.
3260TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsive) {
3261 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3262 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3263 FOCUSED_WINDOW_LOCATION))
3264 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3265 mFocusedWindow->consumeMotionDown();
3266 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3267 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3268 // We consumed all events, so no ANR
3269 ASSERT_TRUE(mDispatcher->waitForIdle());
3270 mFakePolicy->assertNotifyAnrWasNotCalled();
3271
3272 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3273 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3274 FOCUSED_WINDOW_LOCATION));
3275 std::optional<uint32_t> unfocusedSequenceNum = mUnfocusedWindow->receiveEvent();
3276 ASSERT_TRUE(unfocusedSequenceNum);
3277 std::optional<uint32_t> focusedSequenceNum = mFocusedWindow->receiveEvent();
3278 ASSERT_TRUE(focusedSequenceNum);
3279
3280 const std::chrono::duration timeout =
3281 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3282 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3283 mFocusedWindow->getToken());
3284
3285 mFocusedWindow->finishEvent(*focusedSequenceNum);
3286 mUnfocusedWindow->finishEvent(*unfocusedSequenceNum);
3287 ASSERT_TRUE(mDispatcher->waitForIdle());
3288}
3289
3290// If we have 2 windows with identical timeouts that are both unresponsive,
3291// it doesn't matter which order they should have ANR.
3292// But we should receive ANR for both.
3293TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsiveWithSameTimeout) {
3294 // Set the timeout for unfocused window to match the focused window
3295 mUnfocusedWindow->setDispatchingTimeout(10ms);
3296 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3297
3298 tapOnFocusedWindow();
3299 // we should have ACTION_DOWN/ACTION_UP on focused window and ACTION_OUTSIDE on unfocused window
Chris Yea209fde2020-07-22 13:54:51 -07003300 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData1 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003301 mFakePolicy->getNotifyAnrData(10ms);
Chris Yea209fde2020-07-22 13:54:51 -07003302 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData2 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003303 mFakePolicy->getNotifyAnrData(0ms);
3304
3305 // We don't know which window will ANR first. But both of them should happen eventually.
3306 ASSERT_TRUE(mFocusedWindow->getToken() == anrData1.second ||
3307 mFocusedWindow->getToken() == anrData2.second);
3308 ASSERT_TRUE(mUnfocusedWindow->getToken() == anrData1.second ||
3309 mUnfocusedWindow->getToken() == anrData2.second);
3310
3311 ASSERT_TRUE(mDispatcher->waitForIdle());
3312 mFakePolicy->assertNotifyAnrWasNotCalled();
3313}
3314
3315// If a window is already not responding, the second tap on the same window should be ignored.
3316// We should also log an error to account for the dropped event (not tested here).
3317// At the same time, FLAG_WATCH_OUTSIDE_TOUCH targets should not receive any events.
3318TEST_F(InputDispatcherMultiWindowAnr, DuringAnr_SecondTapIsIgnored) {
3319 tapOnFocusedWindow();
3320 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3321 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3322 // Receive the events, but don't respond
3323 std::optional<uint32_t> downEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_DOWN
3324 ASSERT_TRUE(downEventSequenceNum);
3325 std::optional<uint32_t> upEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_UP
3326 ASSERT_TRUE(upEventSequenceNum);
3327 const std::chrono::duration timeout =
3328 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3329 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3330 mFocusedWindow->getToken());
3331
3332 // Tap once again
3333 // We cannot use "tapOnFocusedWindow" because it asserts the injection result to be success
3334 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3335 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3336 FOCUSED_WINDOW_LOCATION));
3337 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3338 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3339 FOCUSED_WINDOW_LOCATION));
3340 // Unfocused window does not receive ACTION_OUTSIDE because the tapped window is not a
3341 // valid touch target
3342 mUnfocusedWindow->assertNoEvents();
3343
3344 // Consume the first tap
3345 mFocusedWindow->finishEvent(*downEventSequenceNum);
3346 mFocusedWindow->finishEvent(*upEventSequenceNum);
3347 ASSERT_TRUE(mDispatcher->waitForIdle());
3348 // The second tap did not go to the focused window
3349 mFocusedWindow->assertNoEvents();
3350 // should not have another ANR after the window just became healthy again
3351 mFakePolicy->assertNotifyAnrWasNotCalled();
3352}
3353
3354// If you tap outside of all windows, there will not be ANR
3355TEST_F(InputDispatcherMultiWindowAnr, TapOutsideAllWindows_DoesNotAnr) {
3356 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3357 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3358 LOCATION_OUTSIDE_ALL_WINDOWS));
3359 ASSERT_TRUE(mDispatcher->waitForIdle());
3360 mFakePolicy->assertNotifyAnrWasNotCalled();
3361}
3362
3363// Since the focused window is paused, tapping on it should not produce any events
3364TEST_F(InputDispatcherMultiWindowAnr, Window_CanBePaused) {
3365 mFocusedWindow->setPaused(true);
3366 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3367
3368 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3369 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3370 FOCUSED_WINDOW_LOCATION));
3371
3372 std::this_thread::sleep_for(mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT));
3373 ASSERT_TRUE(mDispatcher->waitForIdle());
3374 // Should not ANR because the window is paused, and touches shouldn't go to it
3375 mFakePolicy->assertNotifyAnrWasNotCalled();
3376
3377 mFocusedWindow->assertNoEvents();
3378 mUnfocusedWindow->assertNoEvents();
3379}
3380
3381/**
3382 * If a window is processing a motion event, and then a key event comes in, the key event should
3383 * not to to the focused window until the motion is processed.
3384 * If a different window becomes focused at this time, the key should go to that window instead.
3385 *
3386 * Warning!!!
3387 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
3388 * and the injection timeout that we specify when injecting the key.
3389 * We must have the injection timeout (10ms) be smaller than
3390 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
3391 *
3392 * If that value changes, this test should also change.
3393 */
3394TEST_F(InputDispatcherMultiWindowAnr, PendingKey_GoesToNewlyFocusedWindow) {
3395 // Set a long ANR timeout to prevent it from triggering
3396 mFocusedWindow->setDispatchingTimeout(2s);
3397 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3398
3399 tapOnUnfocusedWindow();
3400 std::optional<uint32_t> downSequenceNum = mUnfocusedWindow->receiveEvent();
3401 ASSERT_TRUE(downSequenceNum);
3402 std::optional<uint32_t> upSequenceNum = mUnfocusedWindow->receiveEvent();
3403 ASSERT_TRUE(upSequenceNum);
3404 // Don't finish the events yet, and send a key
3405 // Injection will succeed because we will eventually give up and send the key to the focused
3406 // window even if motions are still being processed.
3407
3408 int32_t result =
3409 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
3410 INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
3411 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
3412 // Key will not be sent to the window, yet, because the window is still processing events
3413 // and the key remains pending, waiting for the touch events to be processed
3414 std::optional<uint32_t> keySequenceNum = mFocusedWindow->receiveEvent();
3415 ASSERT_FALSE(keySequenceNum);
3416
3417 // Switch the focus to the "unfocused" window that we tapped. Expect the key to go there
Vishnu Nair47074b82020-08-14 11:54:47 -07003418 mFocusedWindow->setFocusable(false);
3419 mUnfocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003420 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07003421 setFocusedWindow(mUnfocusedWindow);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003422
3423 // Focus events should precede the key events
3424 mUnfocusedWindow->consumeFocusEvent(true);
3425 mFocusedWindow->consumeFocusEvent(false);
3426
3427 // Finish the tap events, which should unblock dispatcher
3428 mUnfocusedWindow->finishEvent(*downSequenceNum);
3429 mUnfocusedWindow->finishEvent(*upSequenceNum);
3430
3431 // Now that all queues are cleared and no backlog in the connections, the key event
3432 // can finally go to the newly focused "mUnfocusedWindow".
3433 mUnfocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3434 mFocusedWindow->assertNoEvents();
3435 mUnfocusedWindow->assertNoEvents();
3436}
3437
3438// When the touch stream is split across 2 windows, and one of them does not respond,
3439// then ANR should be raised and the touch should be canceled for the unresponsive window.
3440// The other window should not be affected by that.
3441TEST_F(InputDispatcherMultiWindowAnr, SplitTouch_SingleWindowAnr) {
3442 // Touch Window 1
3443 NotifyMotionArgs motionArgs =
3444 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3445 ADISPLAY_ID_DEFAULT, {FOCUSED_WINDOW_LOCATION});
3446 mDispatcher->notifyMotion(&motionArgs);
3447 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3448 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3449
3450 // Touch Window 2
3451 int32_t actionPointerDown =
3452 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
3453
3454 motionArgs =
3455 generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3456 {FOCUSED_WINDOW_LOCATION, UNFOCUSED_WINDOW_LOCATION});
3457 mDispatcher->notifyMotion(&motionArgs);
3458
3459 const std::chrono::duration timeout =
3460 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3461 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3462 mFocusedWindow->getToken());
3463
3464 mUnfocusedWindow->consumeMotionDown();
3465 mFocusedWindow->consumeMotionDown();
3466 // Focused window may or may not receive ACTION_MOVE
3467 // But it should definitely receive ACTION_CANCEL due to the ANR
3468 InputEvent* event;
3469 std::optional<int32_t> moveOrCancelSequenceNum = mFocusedWindow->receiveEvent(&event);
3470 ASSERT_TRUE(moveOrCancelSequenceNum);
3471 mFocusedWindow->finishEvent(*moveOrCancelSequenceNum);
3472 ASSERT_NE(nullptr, event);
3473 ASSERT_EQ(event->getType(), AINPUT_EVENT_TYPE_MOTION);
3474 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
3475 if (motionEvent.getAction() == AMOTION_EVENT_ACTION_MOVE) {
3476 mFocusedWindow->consumeMotionCancel();
3477 } else {
3478 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionEvent.getAction());
3479 }
3480
3481 ASSERT_TRUE(mDispatcher->waitForIdle());
3482 mUnfocusedWindow->assertNoEvents();
3483 mFocusedWindow->assertNoEvents();
3484}
3485
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05003486/**
3487 * If we have no focused window, and a key comes in, we start the ANR timer.
3488 * The focused application should add a focused window before the timer runs out to prevent ANR.
3489 *
3490 * If the user touches another application during this time, the key should be dropped.
3491 * Next, if a new focused window comes in, without toggling the focused application,
3492 * then no ANR should occur.
3493 *
3494 * Normally, we would expect the new focused window to be accompanied by 'setFocusedApplication',
3495 * but in some cases the policy may not update the focused application.
3496 */
3497TEST_F(InputDispatcherMultiWindowAnr, FocusedWindowWithoutSetFocusedApplication_NoAnr) {
3498 std::shared_ptr<FakeApplicationHandle> focusedApplication =
3499 std::make_shared<FakeApplicationHandle>();
3500 focusedApplication->setDispatchingTimeout(60ms);
3501 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, focusedApplication);
3502 // The application that owns 'mFocusedWindow' and 'mUnfocusedWindow' is not focused.
3503 mFocusedWindow->setFocusable(false);
3504
3505 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3506 mFocusedWindow->consumeFocusEvent(false);
3507
3508 // Send a key. The ANR timer should start because there is no focused window.
3509 // 'focusedApplication' will get blamed if this timer completes.
3510 // Key will not be sent anywhere because we have no focused window. It will remain pending.
3511 int32_t result =
3512 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
3513 INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
3514 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
3515
3516 // Wait until dispatcher starts the "no focused window" timer. If we don't wait here,
3517 // then the injected touches won't cause the focused event to get dropped.
3518 // The dispatcher only checks for whether the queue should be pruned upon queueing.
3519 // If we inject the touch right away and the ANR timer hasn't started, the touch event would
3520 // simply be added to the queue without 'shouldPruneInboundQueueLocked' returning 'true'.
3521 // For this test, it means that the key would get delivered to the window once it becomes
3522 // focused.
3523 std::this_thread::sleep_for(10ms);
3524
3525 // Touch unfocused window. This should force the pending key to get dropped.
3526 NotifyMotionArgs motionArgs =
3527 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3528 ADISPLAY_ID_DEFAULT, {UNFOCUSED_WINDOW_LOCATION});
3529 mDispatcher->notifyMotion(&motionArgs);
3530
3531 // We do not consume the motion right away, because that would require dispatcher to first
3532 // process (== drop) the key event, and by that time, ANR will be raised.
3533 // Set the focused window first.
3534 mFocusedWindow->setFocusable(true);
3535 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3536 setFocusedWindow(mFocusedWindow);
3537 mFocusedWindow->consumeFocusEvent(true);
3538 // We do not call "setFocusedApplication" here, even though the newly focused window belongs
3539 // to another application. This could be a bug / behaviour in the policy.
3540
3541 mUnfocusedWindow->consumeMotionDown();
3542
3543 ASSERT_TRUE(mDispatcher->waitForIdle());
3544 // Should not ANR because we actually have a focused window. It was just added too slowly.
3545 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertNotifyAnrWasNotCalled());
3546}
3547
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003548// These tests ensure we cannot send touch events to a window that's positioned behind a window
3549// that has feature NO_INPUT_CHANNEL.
3550// Layout:
3551// Top (closest to user)
3552// mNoInputWindow (above all windows)
3553// mBottomWindow
3554// Bottom (furthest from user)
3555class InputDispatcherMultiWindowOcclusionTests : public InputDispatcherTest {
3556 virtual void SetUp() override {
3557 InputDispatcherTest::SetUp();
3558
3559 mApplication = std::make_shared<FakeApplicationHandle>();
3560 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3561 "Window without input channel", ADISPLAY_ID_DEFAULT,
3562 std::make_optional<sp<IBinder>>(nullptr) /*token*/);
3563
3564 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3565 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3566 // It's perfectly valid for this window to not have an associated input channel
3567
3568 mBottomWindow = new FakeWindowHandle(mApplication, mDispatcher, "Bottom window",
3569 ADISPLAY_ID_DEFAULT);
3570 mBottomWindow->setFrame(Rect(0, 0, 100, 100));
3571
3572 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3573 }
3574
3575protected:
3576 std::shared_ptr<FakeApplicationHandle> mApplication;
3577 sp<FakeWindowHandle> mNoInputWindow;
3578 sp<FakeWindowHandle> mBottomWindow;
3579};
3580
3581TEST_F(InputDispatcherMultiWindowOcclusionTests, NoInputChannelFeature_DropsTouches) {
3582 PointF touchedPoint = {10, 10};
3583
3584 NotifyMotionArgs motionArgs =
3585 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3586 ADISPLAY_ID_DEFAULT, {touchedPoint});
3587 mDispatcher->notifyMotion(&motionArgs);
3588
3589 mNoInputWindow->assertNoEvents();
3590 // Even though the window 'mNoInputWindow' positioned above 'mBottomWindow' does not have
3591 // an input channel, it is not marked as FLAG_NOT_TOUCHABLE,
3592 // and therefore should prevent mBottomWindow from receiving touches
3593 mBottomWindow->assertNoEvents();
3594}
3595
3596/**
3597 * If a window has feature NO_INPUT_CHANNEL, and somehow (by mistake) still has an input channel,
3598 * ensure that this window does not receive any touches, and blocks touches to windows underneath.
3599 */
3600TEST_F(InputDispatcherMultiWindowOcclusionTests,
3601 NoInputChannelFeature_DropsTouchesWithValidChannel) {
3602 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3603 "Window with input channel and NO_INPUT_CHANNEL",
3604 ADISPLAY_ID_DEFAULT);
3605
3606 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3607 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3608 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3609
3610 PointF touchedPoint = {10, 10};
3611
3612 NotifyMotionArgs motionArgs =
3613 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3614 ADISPLAY_ID_DEFAULT, {touchedPoint});
3615 mDispatcher->notifyMotion(&motionArgs);
3616
3617 mNoInputWindow->assertNoEvents();
3618 mBottomWindow->assertNoEvents();
3619}
3620
Vishnu Nair958da932020-08-21 17:12:37 -07003621class InputDispatcherMirrorWindowFocusTests : public InputDispatcherTest {
3622protected:
3623 std::shared_ptr<FakeApplicationHandle> mApp;
3624 sp<FakeWindowHandle> mWindow;
3625 sp<FakeWindowHandle> mMirror;
3626
3627 virtual void SetUp() override {
3628 InputDispatcherTest::SetUp();
3629 mApp = std::make_shared<FakeApplicationHandle>();
3630 mWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
3631 mMirror = new FakeWindowHandle(mApp, mDispatcher, "TestWindowMirror", ADISPLAY_ID_DEFAULT,
3632 mWindow->getToken());
3633 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
3634 mWindow->setFocusable(true);
3635 mMirror->setFocusable(true);
3636 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3637 }
3638};
3639
3640TEST_F(InputDispatcherMirrorWindowFocusTests, CanGetFocus) {
3641 // Request focus on a mirrored window
3642 setFocusedWindow(mMirror);
3643
3644 // window gets focused
3645 mWindow->consumeFocusEvent(true);
3646 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3647 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3648 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3649}
3650
3651// A focused & mirrored window remains focused only if the window and its mirror are both
3652// focusable.
3653TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAllWindowsFocusable) {
3654 setFocusedWindow(mMirror);
3655
3656 // window gets focused
3657 mWindow->consumeFocusEvent(true);
3658 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3659 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3660 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3661 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3662 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3663 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3664
3665 mMirror->setFocusable(false);
3666 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3667
3668 // window loses focus since one of the windows associated with the token in not focusable
3669 mWindow->consumeFocusEvent(false);
3670
3671 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3672 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3673 mWindow->assertNoEvents();
3674}
3675
3676// A focused & mirrored window remains focused until the window and its mirror both become
3677// invisible.
3678TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAnyWindowVisible) {
3679 setFocusedWindow(mMirror);
3680
3681 // window gets focused
3682 mWindow->consumeFocusEvent(true);
3683 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3684 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3685 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3686 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3687 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3688 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3689
3690 mMirror->setVisible(false);
3691 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3692
3693 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3694 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3695 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3696 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3697 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3698 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3699
3700 mWindow->setVisible(false);
3701 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3702
3703 // window loses focus only after all windows associated with the token become invisible.
3704 mWindow->consumeFocusEvent(false);
3705
3706 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3707 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3708 mWindow->assertNoEvents();
3709}
3710
3711// A focused & mirrored window remains focused until both windows are removed.
3712TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedWhileWindowsAlive) {
3713 setFocusedWindow(mMirror);
3714
3715 // window gets focused
3716 mWindow->consumeFocusEvent(true);
3717 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3718 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3719 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3720 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3721 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3722 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3723
3724 // single window is removed but the window token remains focused
3725 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mMirror}}});
3726
3727 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
3728 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3729 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3730 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
3731 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3732 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3733
3734 // Both windows are removed
3735 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {}}});
3736 mWindow->consumeFocusEvent(false);
3737
3738 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
3739 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
3740 mWindow->assertNoEvents();
3741}
3742
3743// Focus request can be pending until one window becomes visible.
3744TEST_F(InputDispatcherMirrorWindowFocusTests, DeferFocusWhenInvisible) {
3745 // Request focus on an invisible mirror.
3746 mWindow->setVisible(false);
3747 mMirror->setVisible(false);
3748 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3749 setFocusedWindow(mMirror);
3750
3751 // Injected key goes to pending queue.
3752 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3753 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
3754 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
3755
3756 mMirror->setVisible(true);
3757 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3758
3759 // window gets focused
3760 mWindow->consumeFocusEvent(true);
3761 // window gets the pending key event
3762 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3763}
Garfield Tane84e6f92019-08-29 17:28:41 -07003764} // namespace android::inputdispatcher