blob: 3e0b5e867d3de21d5338f1b5af57bfab0fb46931 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Garfield Tan0fc2fa72019-08-29 17:22:15 -070017#include "../dispatcher/InputDispatcher.h"
Michael Wrightd02c5b62014-02-10 15:10:22 -080018
Garfield Tan1c7bc862020-01-28 13:24:04 -080019#include <android-base/stringprintf.h>
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -070020#include <android-base/thread_annotations.h>
Robert Carr803535b2018-08-02 16:38:15 -070021#include <binder/Binder.h>
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -080022#include <input/Input.h>
Robert Carr803535b2018-08-02 16:38:15 -070023
Michael Wrightd02c5b62014-02-10 15:10:22 -080024#include <gtest/gtest.h>
25#include <linux/input.h>
Garfield Tan1c7bc862020-01-28 13:24:04 -080026#include <cinttypes>
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -070027#include <thread>
Garfield Tan1c7bc862020-01-28 13:24:04 -080028#include <unordered_set>
chaviwd1c23182019-12-20 18:44:56 -080029#include <vector>
Michael Wrightd02c5b62014-02-10 15:10:22 -080030
Garfield Tan1c7bc862020-01-28 13:24:04 -080031using android::base::StringPrintf;
Michael Wright44753b12020-07-08 13:48:11 +010032using namespace android::flag_operators;
Garfield Tan1c7bc862020-01-28 13:24:04 -080033
Garfield Tane84e6f92019-08-29 17:28:41 -070034namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080035
36// An arbitrary time value.
37static const nsecs_t ARBITRARY_TIME = 1234;
38
39// An arbitrary device id.
40static const int32_t DEVICE_ID = 1;
41
Jeff Brownf086ddb2014-02-11 14:28:48 -080042// An arbitrary display id.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -080043static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
Jeff Brownf086ddb2014-02-11 14:28:48 -080044
Michael Wrightd02c5b62014-02-10 15:10:22 -080045// An arbitrary injector pid / uid pair that has permission to inject events.
46static const int32_t INJECTOR_PID = 999;
47static const int32_t INJECTOR_UID = 1001;
48
chaviwd1c23182019-12-20 18:44:56 -080049struct PointF {
50 float x;
51 float y;
52};
Michael Wrightd02c5b62014-02-10 15:10:22 -080053
Gang Wang342c9272020-01-13 13:15:04 -050054/**
55 * Return a DOWN key event with KEYCODE_A.
56 */
57static KeyEvent getTestKeyEvent() {
58 KeyEvent event;
59
Garfield Tanfbe732e2020-01-24 11:26:14 -080060 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
61 INVALID_HMAC, AKEY_EVENT_ACTION_DOWN, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
62 ARBITRARY_TIME, ARBITRARY_TIME);
Gang Wang342c9272020-01-13 13:15:04 -050063 return event;
64}
65
Michael Wrightd02c5b62014-02-10 15:10:22 -080066// --- FakeInputDispatcherPolicy ---
67
68class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
69 InputDispatcherConfiguration mConfig;
70
71protected:
72 virtual ~FakeInputDispatcherPolicy() {
73 }
74
75public:
76 FakeInputDispatcherPolicy() {
Jackal Guof9696682018-10-05 12:23:23 +080077 }
78
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080079 void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080080 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_KEY, args.eventTime, args.action,
81 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080082 }
83
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080084 void assertFilterInputEventWasCalled(const NotifyMotionArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080085 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_MOTION, args.eventTime, args.action,
86 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080087 }
88
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070089 void assertFilterInputEventWasNotCalled() {
90 std::scoped_lock lock(mLock);
91 ASSERT_EQ(nullptr, mFilteredEvent);
92 }
Michael Wrightd02c5b62014-02-10 15:10:22 -080093
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080094 void assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070095 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080096 ASSERT_TRUE(mConfigurationChangedTime)
97 << "Timed out waiting for configuration changed call";
98 ASSERT_EQ(*mConfigurationChangedTime, when);
99 mConfigurationChangedTime = std::nullopt;
100 }
101
102 void assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700103 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800104 ASSERT_TRUE(mLastNotifySwitch);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800105 // We do not check id because it is not exposed to the policy
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800106 EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime);
107 EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags);
108 EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues);
109 EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask);
110 mLastNotifySwitch = std::nullopt;
111 }
112
chaviwfd6d3512019-03-25 13:23:49 -0700113 void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700114 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800115 ASSERT_EQ(touchedToken, mOnPointerDownToken);
116 mOnPointerDownToken.clear();
117 }
118
119 void assertOnPointerDownWasNotCalled() {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700120 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800121 ASSERT_TRUE(mOnPointerDownToken == nullptr)
122 << "Expected onPointerDownOutsideFocus to not have been called";
chaviwfd6d3512019-03-25 13:23:49 -0700123 }
124
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700125 // This function must be called soon after the expected ANR timer starts,
126 // because we are also checking how much time has passed.
Chris Yea209fde2020-07-22 13:54:51 -0700127 void assertNotifyAnrWasCalled(
128 std::chrono::nanoseconds timeout,
129 const std::shared_ptr<InputApplicationHandle>& expectedApplication,
130 const sp<IBinder>& expectedToken) {
131 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700132 ASSERT_NO_FATAL_FAILURE(anrData = getNotifyAnrData(timeout));
133 ASSERT_EQ(expectedApplication, anrData.first);
134 ASSERT_EQ(expectedToken, anrData.second);
135 }
136
Chris Yea209fde2020-07-22 13:54:51 -0700137 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> getNotifyAnrData(
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700138 std::chrono::nanoseconds timeout) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700139 const std::chrono::time_point start = std::chrono::steady_clock::now();
140 std::unique_lock lock(mLock);
141 std::chrono::duration timeToWait = timeout + 100ms; // provide some slack
142 android::base::ScopedLockAssertion assumeLocked(mLock);
143
144 // If there is an ANR, Dispatcher won't be idle because there are still events
145 // in the waitQueue that we need to check on. So we can't wait for dispatcher to be idle
146 // before checking if ANR was called.
147 // Since dispatcher is not guaranteed to call notifyAnr right away, we need to provide
148 // it some time to act. 100ms seems reasonable.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700149 mNotifyAnr.wait_for(lock, timeToWait, [this]() REQUIRES(mLock) {
150 return !mAnrApplications.empty() && !mAnrWindowTokens.empty();
151 });
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700152 const std::chrono::duration waited = std::chrono::steady_clock::now() - start;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700153 if (mAnrApplications.empty() || mAnrWindowTokens.empty()) {
154 ADD_FAILURE() << "Did not receive ANR callback";
155 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700156 // Ensure that the ANR didn't get raised too early. We can't be too strict here because
157 // the dispatcher started counting before this function was called
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700158 if (std::chrono::abs(timeout - waited) > 100ms) {
159 ADD_FAILURE() << "ANR was raised too early or too late. Expected "
160 << std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count()
161 << "ms, but waited "
162 << std::chrono::duration_cast<std::chrono::milliseconds>(waited).count()
163 << "ms instead";
164 }
Chris Yea209fde2020-07-22 13:54:51 -0700165 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> result =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700166 std::make_pair(mAnrApplications.front(), mAnrWindowTokens.front());
167 mAnrApplications.pop();
168 mAnrWindowTokens.pop();
169 return result;
170 }
171
172 void assertNotifyAnrWasNotCalled() {
173 std::scoped_lock lock(mLock);
174 ASSERT_TRUE(mAnrApplications.empty());
175 ASSERT_TRUE(mAnrWindowTokens.empty());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700176 }
177
Garfield Tan1c7bc862020-01-28 13:24:04 -0800178 void setKeyRepeatConfiguration(nsecs_t timeout, nsecs_t delay) {
179 mConfig.keyRepeatTimeout = timeout;
180 mConfig.keyRepeatDelay = delay;
181 }
182
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700183 void setAnrTimeout(std::chrono::nanoseconds timeout) { mAnrTimeout = timeout; }
184
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185private:
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700186 std::mutex mLock;
187 std::unique_ptr<InputEvent> mFilteredEvent GUARDED_BY(mLock);
188 std::optional<nsecs_t> mConfigurationChangedTime GUARDED_BY(mLock);
189 sp<IBinder> mOnPointerDownToken GUARDED_BY(mLock);
190 std::optional<NotifySwitchArgs> mLastNotifySwitch GUARDED_BY(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800191
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700192 // ANR handling
Chris Yea209fde2020-07-22 13:54:51 -0700193 std::queue<std::shared_ptr<InputApplicationHandle>> mAnrApplications GUARDED_BY(mLock);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700194 std::queue<sp<IBinder>> mAnrWindowTokens GUARDED_BY(mLock);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700195 std::condition_variable mNotifyAnr;
196 std::chrono::nanoseconds mAnrTimeout = 0ms;
197
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800198 virtual void notifyConfigurationChanged(nsecs_t when) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700199 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800200 mConfigurationChangedTime = when;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800201 }
202
Chris Yea209fde2020-07-22 13:54:51 -0700203 std::chrono::nanoseconds notifyAnr(const std::shared_ptr<InputApplicationHandle>& application,
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500204 const sp<IBinder>& windowToken,
205 const std::string&) override {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700206 std::scoped_lock lock(mLock);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700207 mAnrApplications.push(application);
208 mAnrWindowTokens.push(windowToken);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700209 mNotifyAnr.notify_all();
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500210 return mAnrTimeout;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 }
212
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700213 virtual void notifyInputChannelBroken(const sp<IBinder>&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700215 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) override {}
Robert Carr740167f2018-10-11 19:03:41 -0700216
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700217 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 *outConfig = mConfig;
219 }
220
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800221 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700222 std::scoped_lock lock(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800223 switch (inputEvent->getType()) {
224 case AINPUT_EVENT_TYPE_KEY: {
225 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800226 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800227 break;
228 }
229
230 case AINPUT_EVENT_TYPE_MOTION: {
231 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800232 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800233 break;
234 }
235 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800236 return true;
237 }
238
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700239 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800240
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700241 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700243 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent*,
244 uint32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800245 return 0;
246 }
247
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700248 virtual bool dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent*, uint32_t,
249 KeyEvent*) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 return false;
251 }
252
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800253 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
254 uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700255 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800256 /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
257 * essentially a passthrough for notifySwitch.
258 */
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800259 mLastNotifySwitch = NotifySwitchArgs(1 /*id*/, when, policyFlags, switchValues, switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800260 }
261
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700262 virtual void pokeUserActivity(nsecs_t, int32_t) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800263
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700264 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 return false;
266 }
Jackal Guof9696682018-10-05 12:23:23 +0800267
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700268 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700269 std::scoped_lock lock(mLock);
chaviwfd6d3512019-03-25 13:23:49 -0700270 mOnPointerDownToken = newToken;
271 }
272
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800273 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
274 int32_t displayId) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700275 std::scoped_lock lock(mLock);
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800276 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
277 ASSERT_EQ(mFilteredEvent->getType(), type);
278
279 if (type == AINPUT_EVENT_TYPE_KEY) {
280 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
281 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
282 EXPECT_EQ(keyEvent.getAction(), action);
283 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
284 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
285 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
286 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
287 EXPECT_EQ(motionEvent.getAction(), action);
288 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
289 } else {
290 FAIL() << "Unknown type: " << type;
291 }
292
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800293 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800294 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295};
296
Michael Wrightd02c5b62014-02-10 15:10:22 -0800297// --- InputDispatcherTest ---
298
299class InputDispatcherTest : public testing::Test {
300protected:
301 sp<FakeInputDispatcherPolicy> mFakePolicy;
302 sp<InputDispatcher> mDispatcher;
303
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700304 virtual void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800305 mFakePolicy = new FakeInputDispatcherPolicy();
306 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800307 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
308 //Start InputDispatcher thread
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700309 ASSERT_EQ(OK, mDispatcher->start());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800310 }
311
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700312 virtual void TearDown() override {
313 ASSERT_EQ(OK, mDispatcher->stop());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800314 mFakePolicy.clear();
315 mDispatcher.clear();
316 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700317
318 /**
319 * Used for debugging when writing the test
320 */
321 void dumpDispatcherState() {
322 std::string dump;
323 mDispatcher->dump(dump);
324 std::stringstream ss(dump);
325 std::string to;
326
327 while (std::getline(ss, to, '\n')) {
328 ALOGE("%s", to.c_str());
329 }
330 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800331};
332
333
334TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
335 KeyEvent event;
336
337 // Rejects undefined key actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800338 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
339 INVALID_HMAC,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600340 /*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME,
341 ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700342 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
343 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
344 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800345 << "Should reject key events with undefined action.";
346
347 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800348 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
349 INVALID_HMAC, AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600350 ARBITRARY_TIME, ARBITRARY_TIME);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700351 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
352 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
353 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800354 << "Should reject key events with ACTION_MULTIPLE.";
355}
356
357TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
358 MotionEvent event;
359 PointerProperties pointerProperties[MAX_POINTERS + 1];
360 PointerCoords pointerCoords[MAX_POINTERS + 1];
361 for (int i = 0; i <= MAX_POINTERS; i++) {
362 pointerProperties[i].clear();
363 pointerProperties[i].id = i;
364 pointerCoords[i].clear();
365 }
366
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800367 // Some constants commonly used below
368 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
369 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
370 constexpr int32_t metaState = AMETA_NONE;
371 constexpr MotionClassification classification = MotionClassification::NONE;
372
chaviw9eaa22c2020-07-01 16:21:27 -0700373 ui::Transform identityTransform;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800374 // Rejects undefined motion actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800375 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
chaviw9eaa22c2020-07-01 16:21:27 -0700376 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification,
377 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600378 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700379 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700380 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
381 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
382 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800383 << "Should reject motion events with undefined action.";
384
385 // Rejects pointer down with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800386 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700387 AMOTION_EVENT_ACTION_POINTER_DOWN |
388 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700389 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
390 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
391 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
392 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 pointer down index too large.";
397
Garfield Tanfbe732e2020-01-24 11:26:14 -0800398 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700399 AMOTION_EVENT_ACTION_POINTER_DOWN |
400 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700401 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
402 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
403 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
404 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700405 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
406 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
407 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800408 << "Should reject motion events with pointer down index too small.";
409
410 // Rejects pointer up with invalid index.
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_UP |
413 (1 << 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 up index too large.";
422
Garfield Tanfbe732e2020-01-24 11:26:14 -0800423 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700424 AMOTION_EVENT_ACTION_POINTER_UP |
425 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700426 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
427 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
428 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
429 pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700430 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
431 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
432 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800433 << "Should reject motion events with pointer up index too small.";
434
435 // Rejects motion events with invalid number of pointers.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800436 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
437 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700438 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
439 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700440 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700441 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
442 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
443 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800444 << "Should reject motion events with 0 pointers.";
445
Garfield Tanfbe732e2020-01-24 11:26:14 -0800446 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
447 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700448 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
449 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700450 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700451 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
452 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
453 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800454 << "Should reject motion events with more than MAX_POINTERS pointers.";
455
456 // Rejects motion events with invalid pointer ids.
457 pointerProperties[0].id = -1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800458 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
459 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700460 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
461 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700462 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700463 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
464 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
465 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800466 << "Should reject motion events with pointer ids less than 0.";
467
468 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800469 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
470 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700471 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
472 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700473 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700474 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
475 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
476 INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800477 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
478
479 // Rejects motion events with duplicate pointer ids.
480 pointerProperties[0].id = 1;
481 pointerProperties[1].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*/ 2, 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 duplicate pointer ids.";
491}
492
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800493/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
494
495TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
496 constexpr nsecs_t eventTime = 20;
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800497 NotifyConfigurationChangedArgs args(10 /*id*/, eventTime);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800498 mDispatcher->notifyConfigurationChanged(&args);
499 ASSERT_TRUE(mDispatcher->waitForIdle());
500
501 mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
502}
503
504TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800505 NotifySwitchArgs args(10 /*id*/, 20 /*eventTime*/, 0 /*policyFlags*/, 1 /*switchValues*/,
506 2 /*switchMask*/);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800507 mDispatcher->notifySwitch(&args);
508
509 // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener
510 args.policyFlags |= POLICY_FLAG_TRUSTED;
511 mFakePolicy->assertNotifySwitchWasCalled(args);
512}
513
Arthur Hungb92218b2018-08-14 12:00:21 +0800514// --- InputDispatcherTest SetInputWindowTest ---
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700515static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 500ms;
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700516static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
Arthur Hungb92218b2018-08-14 12:00:21 +0800517
518class FakeApplicationHandle : public InputApplicationHandle {
519public:
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700520 FakeApplicationHandle() {
521 mInfo.name = "Fake Application";
522 mInfo.token = new BBinder();
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500523 mInfo.dispatchingTimeoutMillis =
524 std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700525 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800526 virtual ~FakeApplicationHandle() {}
527
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700528 virtual bool updateInfo() override {
Arthur Hungb92218b2018-08-14 12:00:21 +0800529 return true;
530 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700531
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500532 void setDispatchingTimeout(std::chrono::milliseconds timeout) {
533 mInfo.dispatchingTimeoutMillis = timeout.count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700534 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800535};
536
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800537class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800538public:
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500539 explicit FakeInputReceiver(const std::shared_ptr<InputChannel>& clientChannel,
540 const std::string name)
chaviwd1c23182019-12-20 18:44:56 -0800541 : mName(name) {
542 mConsumer = std::make_unique<InputConsumer>(clientChannel);
543 }
544
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800545 InputEvent* consume() {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700546 InputEvent* event;
547 std::optional<uint32_t> consumeSeq = receiveEvent(&event);
548 if (!consumeSeq) {
549 return nullptr;
550 }
551 finishEvent(*consumeSeq);
552 return event;
553 }
554
555 /**
556 * Receive an event without acknowledging it.
557 * Return the sequence number that could later be used to send finished signal.
558 */
559 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800560 uint32_t consumeSeq;
561 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800562
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800563 std::chrono::time_point start = std::chrono::steady_clock::now();
564 status_t status = WOULD_BLOCK;
565 while (status == WOULD_BLOCK) {
chaviw81e2bb92019-12-18 15:03:51 -0800566 status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq,
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800567 &event);
568 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
569 if (elapsed > 100ms) {
570 break;
571 }
572 }
573
574 if (status == WOULD_BLOCK) {
575 // Just means there's no event available.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700576 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800577 }
578
579 if (status != OK) {
580 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700581 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800582 }
583 if (event == nullptr) {
584 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700585 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800586 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700587 if (outEvent != nullptr) {
588 *outEvent = event;
589 }
590 return consumeSeq;
591 }
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800592
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700593 /**
594 * To be used together with "receiveEvent" to complete the consumption of an event.
595 */
596 void finishEvent(uint32_t consumeSeq) {
597 const status_t status = mConsumer->sendFinishedSignal(consumeSeq, true);
598 ASSERT_EQ(OK, status) << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800599 }
600
601 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
602 int32_t expectedFlags) {
603 InputEvent* event = consume();
604
605 ASSERT_NE(nullptr, event) << mName.c_str()
606 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800607 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700608 << mName.c_str() << " expected " << inputEventTypeToString(expectedEventType)
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800609 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800610
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800611 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800612
Tiger Huang8664f8c2018-10-11 19:14:35 +0800613 switch (expectedEventType) {
614 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800615 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
616 EXPECT_EQ(expectedAction, keyEvent.getAction());
617 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800618 break;
619 }
620 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800621 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
622 EXPECT_EQ(expectedAction, motionEvent.getAction());
623 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800624 break;
625 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100626 case AINPUT_EVENT_TYPE_FOCUS: {
627 FAIL() << "Use 'consumeFocusEvent' for FOCUS events";
628 }
Tiger Huang8664f8c2018-10-11 19:14:35 +0800629 default: {
630 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
631 }
632 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800633 }
634
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100635 void consumeFocusEvent(bool hasFocus, bool inTouchMode) {
636 InputEvent* event = consume();
637 ASSERT_NE(nullptr, event) << mName.c_str()
638 << ": consumer should have returned non-NULL event.";
639 ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, event->getType())
640 << "Got " << inputEventTypeToString(event->getType())
641 << " event instead of FOCUS event";
642
643 ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId())
644 << mName.c_str() << ": event displayId should always be NONE.";
645
646 FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
647 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
648 EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode());
649 }
650
chaviwd1c23182019-12-20 18:44:56 -0800651 void assertNoEvents() {
652 InputEvent* event = consume();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700653 if (event == nullptr) {
654 return;
655 }
656 if (event->getType() == AINPUT_EVENT_TYPE_KEY) {
657 KeyEvent& keyEvent = static_cast<KeyEvent&>(*event);
658 ADD_FAILURE() << "Received key event "
659 << KeyEvent::actionToString(keyEvent.getAction());
660 } else if (event->getType() == AINPUT_EVENT_TYPE_MOTION) {
661 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
662 ADD_FAILURE() << "Received motion event "
663 << MotionEvent::actionToString(motionEvent.getAction());
664 } else if (event->getType() == AINPUT_EVENT_TYPE_FOCUS) {
665 FocusEvent& focusEvent = static_cast<FocusEvent&>(*event);
666 ADD_FAILURE() << "Received focus event, hasFocus = "
667 << (focusEvent.getHasFocus() ? "true" : "false");
668 }
669 FAIL() << mName.c_str()
670 << ": should not have received any events, so consume() should return NULL";
chaviwd1c23182019-12-20 18:44:56 -0800671 }
672
673 sp<IBinder> getToken() { return mConsumer->getChannel()->getConnectionToken(); }
674
675protected:
676 std::unique_ptr<InputConsumer> mConsumer;
677 PreallocatedInputEventFactory mEventFactory;
678
679 std::string mName;
680};
681
682class FakeWindowHandle : public InputWindowHandle {
683public:
684 static const int32_t WIDTH = 600;
685 static const int32_t HEIGHT = 800;
chaviwd1c23182019-12-20 18:44:56 -0800686
Chris Yea209fde2020-07-22 13:54:51 -0700687 FakeWindowHandle(const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
chaviwd1c23182019-12-20 18:44:56 -0800688 const sp<InputDispatcher>& dispatcher, const std::string name,
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500689 int32_t displayId, std::optional<sp<IBinder>> token = std::nullopt)
chaviwd1c23182019-12-20 18:44:56 -0800690 : mName(name) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500691 if (token == std::nullopt) {
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500692 std::unique_ptr<InputChannel> serverChannel, clientChannel;
chaviwd1c23182019-12-20 18:44:56 -0800693 InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500694 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(clientChannel), name);
chaviwd1c23182019-12-20 18:44:56 -0800695 token = serverChannel->getConnectionToken();
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500696 dispatcher->registerInputChannel(std::move(serverChannel));
chaviwd1c23182019-12-20 18:44:56 -0800697 }
698
699 inputApplicationHandle->updateInfo();
700 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
701
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500702 mInfo.token = *token;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700703 mInfo.id = sId++;
chaviwd1c23182019-12-20 18:44:56 -0800704 mInfo.name = name;
Michael Wright44753b12020-07-08 13:48:11 +0100705 mInfo.type = InputWindowInfo::Type::APPLICATION;
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500706 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwd1c23182019-12-20 18:44:56 -0800707 mInfo.frameLeft = 0;
708 mInfo.frameTop = 0;
709 mInfo.frameRight = WIDTH;
710 mInfo.frameBottom = HEIGHT;
chaviw1ff3d1e2020-07-01 15:53:47 -0700711 mInfo.transform.set(0, 0);
chaviwd1c23182019-12-20 18:44:56 -0800712 mInfo.globalScaleFactor = 1.0;
713 mInfo.touchableRegion.clear();
714 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
715 mInfo.visible = true;
Vishnu Nair47074b82020-08-14 11:54:47 -0700716 mInfo.focusable = false;
chaviwd1c23182019-12-20 18:44:56 -0800717 mInfo.hasWallpaper = false;
718 mInfo.paused = false;
chaviwd1c23182019-12-20 18:44:56 -0800719 mInfo.ownerPid = INJECTOR_PID;
720 mInfo.ownerUid = INJECTOR_UID;
chaviwd1c23182019-12-20 18:44:56 -0800721 mInfo.displayId = displayId;
722 }
723
724 virtual bool updateInfo() { return true; }
725
Vishnu Nair47074b82020-08-14 11:54:47 -0700726 void setFocusable(bool focusable) { mInfo.focusable = focusable; }
chaviwd1c23182019-12-20 18:44:56 -0800727
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700728 void setDispatchingTimeout(std::chrono::nanoseconds timeout) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500729 mInfo.dispatchingTimeout = timeout;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700730 }
731
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700732 void setPaused(bool paused) { mInfo.paused = paused; }
733
chaviwd1c23182019-12-20 18:44:56 -0800734 void setFrame(const Rect& frame) {
735 mInfo.frameLeft = frame.left;
736 mInfo.frameTop = frame.top;
737 mInfo.frameRight = frame.right;
738 mInfo.frameBottom = frame.bottom;
chaviw1ff3d1e2020-07-01 15:53:47 -0700739 mInfo.transform.set(frame.left, frame.top);
chaviwd1c23182019-12-20 18:44:56 -0800740 mInfo.touchableRegion.clear();
741 mInfo.addTouchableRegion(frame);
742 }
743
Michael Wright44753b12020-07-08 13:48:11 +0100744 void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; }
chaviwd1c23182019-12-20 18:44:56 -0800745
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500746 void setInputFeatures(InputWindowInfo::Feature features) { mInfo.inputFeatures = features; }
747
chaviw9eaa22c2020-07-01 16:21:27 -0700748 void setWindowTransform(float dsdx, float dtdx, float dtdy, float dsdy) {
749 mInfo.transform.set(dsdx, dtdx, dtdy, dsdy);
750 }
751
752 void setWindowScale(float xScale, float yScale) { setWindowTransform(xScale, 0, 0, yScale); }
chaviwaf87b3e2019-10-01 16:59:28 -0700753
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800754 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
755 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
756 expectedFlags);
757 }
758
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700759 void consumeKeyUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
760 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, expectedDisplayId, expectedFlags);
761 }
762
Svet Ganov5d3bc372020-01-26 23:11:07 -0800763 void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
764 int32_t expectedFlags = 0) {
765 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId,
766 expectedFlags);
767 }
768
769 void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
770 int32_t expectedFlags = 0) {
771 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId,
772 expectedFlags);
773 }
774
775 void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
776 int32_t expectedFlags = 0) {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800777 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
778 expectedFlags);
779 }
780
Svet Ganov5d3bc372020-01-26 23:11:07 -0800781 void consumeMotionPointerDown(int32_t pointerIdx,
782 int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) {
783 int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN
784 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
785 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
786 }
787
788 void consumeMotionPointerUp(int32_t pointerIdx, int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
789 int32_t expectedFlags = 0) {
790 int32_t action = AMOTION_EVENT_ACTION_POINTER_UP
791 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
792 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
793 }
794
795 void consumeMotionUp(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
796 int32_t expectedFlags = 0) {
Michael Wright3a240c42019-12-10 20:53:41 +0000797 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
798 expectedFlags);
799 }
800
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100801 void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
802 ASSERT_NE(mInputReceiver, nullptr)
803 << "Cannot consume events from a window with no receiver";
804 mInputReceiver->consumeFocusEvent(hasFocus, inTouchMode);
805 }
806
chaviwd1c23182019-12-20 18:44:56 -0800807 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
808 int32_t expectedFlags) {
809 ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
810 mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
811 expectedFlags);
812 }
813
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700814 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700815 if (mInputReceiver == nullptr) {
816 ADD_FAILURE() << "Invalid receive event on window with no receiver";
817 return std::nullopt;
818 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700819 return mInputReceiver->receiveEvent(outEvent);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700820 }
821
822 void finishEvent(uint32_t sequenceNum) {
823 ASSERT_NE(mInputReceiver, nullptr) << "Invalid receive event on window with no receiver";
824 mInputReceiver->finishEvent(sequenceNum);
825 }
826
chaviwaf87b3e2019-10-01 16:59:28 -0700827 InputEvent* consume() {
828 if (mInputReceiver == nullptr) {
829 return nullptr;
830 }
831 return mInputReceiver->consume();
832 }
833
Arthur Hungb92218b2018-08-14 12:00:21 +0800834 void assertNoEvents() {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500835 if (mInputReceiver == nullptr &&
836 mInfo.inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL)) {
837 return; // Can't receive events if the window does not have input channel
838 }
839 ASSERT_NE(nullptr, mInputReceiver)
840 << "Window without InputReceiver must specify feature NO_INPUT_CHANNEL";
chaviwd1c23182019-12-20 18:44:56 -0800841 mInputReceiver->assertNoEvents();
Arthur Hungb92218b2018-08-14 12:00:21 +0800842 }
843
chaviwaf87b3e2019-10-01 16:59:28 -0700844 sp<IBinder> getToken() { return mInfo.token; }
845
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100846 const std::string& getName() { return mName; }
847
chaviwd1c23182019-12-20 18:44:56 -0800848private:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100849 const std::string mName;
chaviwd1c23182019-12-20 18:44:56 -0800850 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700851 static std::atomic<int32_t> sId; // each window gets a unique id, like in surfaceflinger
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800852};
853
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700854std::atomic<int32_t> FakeWindowHandle::sId{1};
855
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700856static int32_t injectKey(const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700857 int32_t displayId = ADISPLAY_ID_NONE,
858 int32_t syncMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
859 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800860 KeyEvent event;
861 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
862
863 // Define a valid key down event.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800864 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700865 INVALID_HMAC, action, /* flags */ 0, AKEYCODE_A, KEY_A, AMETA_NONE,
866 repeatCount, currentTime, currentTime);
Arthur Hungb92218b2018-08-14 12:00:21 +0800867
868 // Inject event until dispatch out.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700869 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, syncMode,
870 injectionTimeout,
871 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
Arthur Hungb92218b2018-08-14 12:00:21 +0800872}
873
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700874static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
875 int32_t displayId = ADISPLAY_ID_NONE) {
876 return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId);
877}
878
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700879static int32_t injectKeyUp(const sp<InputDispatcher>& dispatcher,
880 int32_t displayId = ADISPLAY_ID_NONE) {
881 return injectKey(dispatcher, AKEY_EVENT_ACTION_UP, /* repeatCount */ 0, displayId);
882}
883
Garfield Tandf26e862020-07-01 20:18:19 -0700884class PointerBuilder {
885public:
886 PointerBuilder(int32_t id, int32_t toolType) {
887 mProperties.clear();
888 mProperties.id = id;
889 mProperties.toolType = toolType;
890 mCoords.clear();
891 }
892
893 PointerBuilder& x(float x) { return axis(AMOTION_EVENT_AXIS_X, x); }
894
895 PointerBuilder& y(float y) { return axis(AMOTION_EVENT_AXIS_Y, y); }
896
897 PointerBuilder& axis(int32_t axis, float value) {
898 mCoords.setAxisValue(axis, value);
899 return *this;
900 }
901
902 PointerProperties buildProperties() const { return mProperties; }
903
904 PointerCoords buildCoords() const { return mCoords; }
905
906private:
907 PointerProperties mProperties;
908 PointerCoords mCoords;
909};
910
911class MotionEventBuilder {
912public:
913 MotionEventBuilder(int32_t action, int32_t source) {
914 mAction = action;
915 mSource = source;
916 mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
917 }
918
919 MotionEventBuilder& eventTime(nsecs_t eventTime) {
920 mEventTime = eventTime;
921 return *this;
922 }
923
924 MotionEventBuilder& displayId(int32_t displayId) {
925 mDisplayId = displayId;
926 return *this;
927 }
928
929 MotionEventBuilder& actionButton(int32_t actionButton) {
930 mActionButton = actionButton;
931 return *this;
932 }
933
934 MotionEventBuilder& buttonState(int32_t actionButton) {
935 mActionButton = actionButton;
936 return *this;
937 }
938
939 MotionEventBuilder& rawXCursorPosition(float rawXCursorPosition) {
940 mRawXCursorPosition = rawXCursorPosition;
941 return *this;
942 }
943
944 MotionEventBuilder& rawYCursorPosition(float rawYCursorPosition) {
945 mRawYCursorPosition = rawYCursorPosition;
946 return *this;
947 }
948
949 MotionEventBuilder& pointer(PointerBuilder pointer) {
950 mPointers.push_back(pointer);
951 return *this;
952 }
953
954 MotionEvent build() {
955 std::vector<PointerProperties> pointerProperties;
956 std::vector<PointerCoords> pointerCoords;
957 for (const PointerBuilder& pointer : mPointers) {
958 pointerProperties.push_back(pointer.buildProperties());
959 pointerCoords.push_back(pointer.buildCoords());
960 }
961
962 // Set mouse cursor position for the most common cases to avoid boilerplate.
963 if (mSource == AINPUT_SOURCE_MOUSE &&
964 !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition) &&
965 mPointers.size() == 1) {
966 mRawXCursorPosition = pointerCoords[0].getX();
967 mRawYCursorPosition = pointerCoords[0].getY();
968 }
969
970 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -0700971 ui::Transform identityTransform;
Garfield Tandf26e862020-07-01 20:18:19 -0700972 event.initialize(InputEvent::nextId(), DEVICE_ID, mSource, mDisplayId, INVALID_HMAC,
973 mAction, mActionButton, /* flags */ 0, /* edgeFlags */ 0, AMETA_NONE,
chaviw9eaa22c2020-07-01 16:21:27 -0700974 mButtonState, MotionClassification::NONE, identityTransform,
975 /* xPrecision */ 0, /* yPrecision */ 0, mRawXCursorPosition,
976 mRawYCursorPosition, mEventTime, mEventTime, mPointers.size(),
977 pointerProperties.data(), pointerCoords.data());
Garfield Tandf26e862020-07-01 20:18:19 -0700978
979 return event;
980 }
981
982private:
983 int32_t mAction;
984 int32_t mSource;
985 nsecs_t mEventTime;
986 int32_t mDisplayId{ADISPLAY_ID_DEFAULT};
987 int32_t mActionButton{0};
988 int32_t mButtonState{0};
989 float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
990 float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
991
992 std::vector<PointerBuilder> mPointers;
993};
994
995static int32_t injectMotionEvent(
996 const sp<InputDispatcher>& dispatcher, const MotionEvent& event,
997 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
998 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT) {
999 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, injectionMode,
1000 injectionTimeout,
1001 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
1002}
1003
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001004static int32_t injectMotionEvent(
1005 const sp<InputDispatcher>& dispatcher, int32_t action, int32_t source, int32_t displayId,
1006 const PointF& position,
1007 const PointF& cursorPosition = {AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001008 AMOTION_EVENT_INVALID_CURSOR_POSITION},
1009 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
1010 int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
1011 nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC)) {
Garfield Tandf26e862020-07-01 20:18:19 -07001012 MotionEvent event = MotionEventBuilder(action, source)
1013 .displayId(displayId)
1014 .eventTime(eventTime)
1015 .rawXCursorPosition(cursorPosition.x)
1016 .rawYCursorPosition(cursorPosition.y)
1017 .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER)
1018 .x(position.x)
1019 .y(position.y))
1020 .build();
Arthur Hungb92218b2018-08-14 12:00:21 +08001021
1022 // Inject event until dispatch out.
Garfield Tandf26e862020-07-01 20:18:19 -07001023 return injectMotionEvent(dispatcher, event);
Arthur Hungb92218b2018-08-14 12:00:21 +08001024}
1025
Garfield Tan00f511d2019-06-12 16:55:40 -07001026static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001027 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001028 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, location);
Garfield Tan00f511d2019-06-12 16:55:40 -07001029}
1030
Michael Wright3a240c42019-12-10 20:53:41 +00001031static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001032 int32_t displayId, const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001033 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, location);
Michael Wright3a240c42019-12-10 20:53:41 +00001034}
1035
Jackal Guof9696682018-10-05 12:23:23 +08001036static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
1037 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1038 // Define a valid key event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001039 NotifyKeyArgs args(/* id */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
1040 POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0, AKEYCODE_A, KEY_A,
1041 AMETA_NONE, currentTime);
Jackal Guof9696682018-10-05 12:23:23 +08001042
1043 return args;
1044}
1045
chaviwd1c23182019-12-20 18:44:56 -08001046static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId,
1047 const std::vector<PointF>& points) {
1048 size_t pointerCount = points.size();
chaviwaf87b3e2019-10-01 16:59:28 -07001049 if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_UP) {
1050 EXPECT_EQ(1U, pointerCount) << "Actions DOWN and UP can only contain a single pointer";
1051 }
1052
chaviwd1c23182019-12-20 18:44:56 -08001053 PointerProperties pointerProperties[pointerCount];
1054 PointerCoords pointerCoords[pointerCount];
Jackal Guof9696682018-10-05 12:23:23 +08001055
chaviwd1c23182019-12-20 18:44:56 -08001056 for (size_t i = 0; i < pointerCount; i++) {
1057 pointerProperties[i].clear();
1058 pointerProperties[i].id = i;
1059 pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
Jackal Guof9696682018-10-05 12:23:23 +08001060
chaviwd1c23182019-12-20 18:44:56 -08001061 pointerCoords[i].clear();
1062 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
1063 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, points[i].y);
1064 }
Jackal Guof9696682018-10-05 12:23:23 +08001065
1066 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1067 // Define a valid motion event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001068 NotifyMotionArgs args(/* id */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -07001069 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
1070 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
chaviwd1c23182019-12-20 18:44:56 -08001071 AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, pointerProperties,
1072 pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -07001073 AMOTION_EVENT_INVALID_CURSOR_POSITION,
1074 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +08001075
1076 return args;
1077}
1078
chaviwd1c23182019-12-20 18:44:56 -08001079static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
1080 return generateMotionArgs(action, source, displayId, {PointF{100, 200}});
1081}
1082
Arthur Hungb92218b2018-08-14 12:00:21 +08001083TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001084 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001085 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
1086 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001087
Arthur Hung72d8dc32020-03-28 00:48:39 +00001088 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001089 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1090 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001091 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1092
1093 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001094 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001095}
1096
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001097/**
1098 * Calling setInputWindows once with FLAG_NOT_TOUCH_MODAL should not cause any issues.
1099 * To ensure that window receives only events that were directly inside of it, add
1100 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1101 * when finding touched windows.
1102 * This test serves as a sanity check for the next test, where setInputWindows is
1103 * called twice.
1104 */
1105TEST_F(InputDispatcherTest, SetInputWindowOnce_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001106 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001107 sp<FakeWindowHandle> window =
1108 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1109 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001110 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001111
1112 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1113 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1114 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1115 {50, 50}))
1116 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1117
1118 // Window should receive motion event.
1119 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1120}
1121
1122/**
1123 * Calling setInputWindows twice, with the same info, should not cause any issues.
1124 * To ensure that window receives only events that were directly inside of it, add
1125 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1126 * when finding touched windows.
1127 */
1128TEST_F(InputDispatcherTest, SetInputWindowTwice_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001129 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001130 sp<FakeWindowHandle> window =
1131 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1132 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001133 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001134
1135 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1136 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1137 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1138 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1139 {50, 50}))
1140 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1141
1142 // Window should receive motion event.
1143 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1144}
1145
Arthur Hungb92218b2018-08-14 12:00:21 +08001146// The foreground window should receive the first touch down event.
1147TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001148 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001149 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1150 ADISPLAY_ID_DEFAULT);
1151 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1152 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001153
Arthur Hung72d8dc32020-03-28 00:48:39 +00001154 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001155 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
1156 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08001157 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1158
1159 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001160 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001161 windowSecond->assertNoEvents();
1162}
1163
1164TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) {
Chris Yea209fde2020-07-22 13:54:51 -07001165 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001166 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1167 ADISPLAY_ID_DEFAULT);
1168 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1169 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001170
Arthur Hung7ab76b12019-01-09 19:17:20 +08001171 // Set focused application.
Tiger Huang721e26f2018-07-24 22:26:19 +08001172 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hungb92218b2018-08-14 12:00:21 +08001173
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001174 // Display should have only one focused window
Vishnu Nair47074b82020-08-14 11:54:47 -07001175 windowSecond->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001176 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001177
1178 windowSecond->consumeFocusEvent(true);
Arthur Hungb92218b2018-08-14 12:00:21 +08001179 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1180 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1181
1182 // Focused window should receive event.
1183 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001184 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +08001185}
1186
Arthur Hung7ab76b12019-01-09 19:17:20 +08001187TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) {
Chris Yea209fde2020-07-22 13:54:51 -07001188 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung7ab76b12019-01-09 19:17:20 +08001189 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1190 ADISPLAY_ID_DEFAULT);
1191 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1192 ADISPLAY_ID_DEFAULT);
1193
1194 // Set focused application.
1195 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1196
1197 // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first)
Vishnu Nair47074b82020-08-14 11:54:47 -07001198 windowTop->setFocusable(true);
1199 windowSecond->setFocusable(true);
Arthur Hung7ab76b12019-01-09 19:17:20 +08001200
Arthur Hung72d8dc32020-03-28 00:48:39 +00001201 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001202 windowTop->consumeFocusEvent(true);
Arthur Hung7ab76b12019-01-09 19:17:20 +08001203 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1204 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1205
1206 // Top focused window should receive event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001207 windowTop->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung7ab76b12019-01-09 19:17:20 +08001208 windowSecond->assertNoEvents();
1209}
1210
Arthur Hung3b413f22018-10-26 18:05:34 +08001211TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) {
Chris Yea209fde2020-07-22 13:54:51 -07001212 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung3b413f22018-10-26 18:05:34 +08001213
1214 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1215 ADISPLAY_ID_DEFAULT);
1216 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1217 ADISPLAY_ID_DEFAULT);
1218
Arthur Hung832bc4a2019-01-28 11:43:17 +08001219 // Set focused application.
1220 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Arthur Hung3b413f22018-10-26 18:05:34 +08001221
Vishnu Nair47074b82020-08-14 11:54:47 -07001222 windowTop->setFocusable(true);
1223 windowSecond->setFocusable(true);
Arthur Hung3b413f22018-10-26 18:05:34 +08001224 // Release channel for window is no longer valid.
1225 windowTop->releaseChannel();
Arthur Hung72d8dc32020-03-28 00:48:39 +00001226 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001227 windowSecond->consumeFocusEvent(true);
Arthur Hung3b413f22018-10-26 18:05:34 +08001228
Arthur Hung832bc4a2019-01-28 11:43:17 +08001229 // Test inject a key down, should dispatch to a valid window.
1230 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
1231 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Arthur Hung3b413f22018-10-26 18:05:34 +08001232
1233 // Top window is invalid, so it should not receive any input event.
1234 windowTop->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001235 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung3b413f22018-10-26 18:05:34 +08001236}
1237
Garfield Tandf26e862020-07-01 20:18:19 -07001238TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001239 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001240 sp<FakeWindowHandle> windowLeft =
1241 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1242 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001243 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001244 sp<FakeWindowHandle> windowRight =
1245 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1246 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001247 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001248
1249 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1250
1251 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
1252
1253 // Start cursor position in right window so that we can move the cursor to left window.
1254 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1255 injectMotionEvent(mDispatcher,
1256 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1257 AINPUT_SOURCE_MOUSE)
1258 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1259 .x(900)
1260 .y(400))
1261 .build()));
1262 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1263 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1264 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1265 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1266
1267 // Move cursor into left window
1268 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1269 injectMotionEvent(mDispatcher,
1270 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1271 AINPUT_SOURCE_MOUSE)
1272 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1273 .x(300)
1274 .y(400))
1275 .build()));
1276 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1277 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1278 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1279 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1280 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1281 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1282
1283 // Inject a series of mouse events for a mouse click
1284 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1285 injectMotionEvent(mDispatcher,
1286 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1287 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1288 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1289 .x(300)
1290 .y(400))
1291 .build()));
1292 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1293
1294 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1295 injectMotionEvent(mDispatcher,
1296 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1297 AINPUT_SOURCE_MOUSE)
1298 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1299 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1300 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1301 .x(300)
1302 .y(400))
1303 .build()));
1304 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1305 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1306
1307 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1308 injectMotionEvent(mDispatcher,
1309 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1310 AINPUT_SOURCE_MOUSE)
1311 .buttonState(0)
1312 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1313 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1314 .x(300)
1315 .y(400))
1316 .build()));
1317 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1318 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1319
1320 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1321 injectMotionEvent(mDispatcher,
1322 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1323 .buttonState(0)
1324 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1325 .x(300)
1326 .y(400))
1327 .build()));
1328 windowLeft->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1329
1330 // Move mouse cursor back to right window
1331 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1332 injectMotionEvent(mDispatcher,
1333 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1334 AINPUT_SOURCE_MOUSE)
1335 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1336 .x(900)
1337 .y(400))
1338 .build()));
1339 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1340 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1341 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1342 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1343 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1344 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1345}
1346
1347// This test is different from the test above that HOVER_ENTER and HOVER_EXIT events are injected
1348// directly in this test.
1349TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001350 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001351 sp<FakeWindowHandle> window =
1352 new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
1353 window->setFrame(Rect(0, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001354 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001355
1356 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1357
1358 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1359
1360 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1361 injectMotionEvent(mDispatcher,
1362 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
1363 AINPUT_SOURCE_MOUSE)
1364 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1365 .x(300)
1366 .y(400))
1367 .build()));
1368 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1369 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1370
1371 // Inject a series of mouse events for a mouse click
1372 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1373 injectMotionEvent(mDispatcher,
1374 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1375 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1376 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1377 .x(300)
1378 .y(400))
1379 .build()));
1380 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1381
1382 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1383 injectMotionEvent(mDispatcher,
1384 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1385 AINPUT_SOURCE_MOUSE)
1386 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1387 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1388 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1389 .x(300)
1390 .y(400))
1391 .build()));
1392 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1393 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1394
1395 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1396 injectMotionEvent(mDispatcher,
1397 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1398 AINPUT_SOURCE_MOUSE)
1399 .buttonState(0)
1400 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1401 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1402 .x(300)
1403 .y(400))
1404 .build()));
1405 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1406 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1407
1408 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1409 injectMotionEvent(mDispatcher,
1410 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1411 .buttonState(0)
1412 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1413 .x(300)
1414 .y(400))
1415 .build()));
1416 window->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1417
1418 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1419 injectMotionEvent(mDispatcher,
1420 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
1421 AINPUT_SOURCE_MOUSE)
1422 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1423 .x(300)
1424 .y(400))
1425 .build()));
1426 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1427 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1428}
1429
Garfield Tan00f511d2019-06-12 16:55:40 -07001430TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
Chris Yea209fde2020-07-22 13:54:51 -07001431 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tan00f511d2019-06-12 16:55:40 -07001432
1433 sp<FakeWindowHandle> windowLeft =
1434 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1435 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001436 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001437 sp<FakeWindowHandle> windowRight =
1438 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1439 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001440 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001441
1442 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1443
Arthur Hung72d8dc32020-03-28 00:48:39 +00001444 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
Garfield Tan00f511d2019-06-12 16:55:40 -07001445
1446 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
1447 // left window. This event should be dispatched to the left window.
1448 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1449 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001450 ADISPLAY_ID_DEFAULT, {610, 400}, {599, 400}));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001451 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -07001452 windowRight->assertNoEvents();
1453}
1454
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001455TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001456 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001457 sp<FakeWindowHandle> window =
1458 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Vishnu Nair47074b82020-08-14 11:54:47 -07001459 window->setFocusable(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001460
Arthur Hung72d8dc32020-03-28 00:48:39 +00001461 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001462 window->consumeFocusEvent(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001463
1464 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1465 mDispatcher->notifyKey(&keyArgs);
1466
1467 // Window should receive key down event.
1468 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1469
1470 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
1471 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001472 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001473 mDispatcher->notifyDeviceReset(&args);
1474 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
1475 AKEY_EVENT_FLAG_CANCELED);
1476}
1477
1478TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001479 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001480 sp<FakeWindowHandle> window =
1481 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1482
Arthur Hung72d8dc32020-03-28 00:48:39 +00001483 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001484
1485 NotifyMotionArgs motionArgs =
1486 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1487 ADISPLAY_ID_DEFAULT);
1488 mDispatcher->notifyMotion(&motionArgs);
1489
1490 // Window should receive motion down event.
1491 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1492
1493 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
1494 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001495 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001496 mDispatcher->notifyDeviceReset(&args);
1497 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
1498 0 /*expectedFlags*/);
1499}
1500
Svet Ganov5d3bc372020-01-26 23:11:07 -08001501TEST_F(InputDispatcherTest, TransferTouchFocus_OnePointer) {
Chris Yea209fde2020-07-22 13:54:51 -07001502 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001503
1504 // Create a couple of windows
1505 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1506 "First Window", ADISPLAY_ID_DEFAULT);
1507 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1508 "Second Window", ADISPLAY_ID_DEFAULT);
1509
1510 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001511 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001512
1513 // Send down to the first window
1514 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1515 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1516 mDispatcher->notifyMotion(&downMotionArgs);
1517 // Only the first window should get the down event
1518 firstWindow->consumeMotionDown();
1519 secondWindow->assertNoEvents();
1520
1521 // Transfer touch focus to the second window
1522 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1523 // The first window gets cancel and the second gets down
1524 firstWindow->consumeMotionCancel();
1525 secondWindow->consumeMotionDown();
1526
1527 // Send up event to the second window
1528 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1529 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1530 mDispatcher->notifyMotion(&upMotionArgs);
1531 // The first window gets no events and the second gets up
1532 firstWindow->assertNoEvents();
1533 secondWindow->consumeMotionUp();
1534}
1535
1536TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointerNoSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001537 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001538
1539 PointF touchPoint = {10, 10};
1540
1541 // Create a couple of windows
1542 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1543 "First Window", ADISPLAY_ID_DEFAULT);
1544 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1545 "Second Window", ADISPLAY_ID_DEFAULT);
1546
1547 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001548 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001549
1550 // Send down to the first window
1551 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1552 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint});
1553 mDispatcher->notifyMotion(&downMotionArgs);
1554 // Only the first window should get the down event
1555 firstWindow->consumeMotionDown();
1556 secondWindow->assertNoEvents();
1557
1558 // Send pointer down to the first window
1559 NotifyMotionArgs pointerDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1560 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1561 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1562 mDispatcher->notifyMotion(&pointerDownMotionArgs);
1563 // Only the first window should get the pointer down event
1564 firstWindow->consumeMotionPointerDown(1);
1565 secondWindow->assertNoEvents();
1566
1567 // Transfer touch focus to the second window
1568 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1569 // The first window gets cancel and the second gets down and pointer down
1570 firstWindow->consumeMotionCancel();
1571 secondWindow->consumeMotionDown();
1572 secondWindow->consumeMotionPointerDown(1);
1573
1574 // Send pointer up to the second window
1575 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1576 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1577 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1578 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1579 // The first window gets nothing and the second gets pointer up
1580 firstWindow->assertNoEvents();
1581 secondWindow->consumeMotionPointerUp(1);
1582
1583 // Send up event to the second window
1584 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1585 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1586 mDispatcher->notifyMotion(&upMotionArgs);
1587 // The first window gets nothing and the second gets up
1588 firstWindow->assertNoEvents();
1589 secondWindow->consumeMotionUp();
1590}
1591
1592TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointersSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001593 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001594
1595 // Create a non touch modal window that supports split touch
1596 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1597 "First Window", ADISPLAY_ID_DEFAULT);
1598 firstWindow->setFrame(Rect(0, 0, 600, 400));
Michael Wright44753b12020-07-08 13:48:11 +01001599 firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1600 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001601
1602 // Create a non touch modal window that supports split touch
1603 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1604 "Second Window", ADISPLAY_ID_DEFAULT);
1605 secondWindow->setFrame(Rect(0, 400, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001606 secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1607 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001608
1609 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001610 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001611
1612 PointF pointInFirst = {300, 200};
1613 PointF pointInSecond = {300, 600};
1614
1615 // Send down to the first window
1616 NotifyMotionArgs firstDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1617 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst});
1618 mDispatcher->notifyMotion(&firstDownMotionArgs);
1619 // Only the first window should get the down event
1620 firstWindow->consumeMotionDown();
1621 secondWindow->assertNoEvents();
1622
1623 // Send down to the second window
1624 NotifyMotionArgs secondDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1625 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1626 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1627 mDispatcher->notifyMotion(&secondDownMotionArgs);
1628 // The first window gets a move and the second a down
1629 firstWindow->consumeMotionMove();
1630 secondWindow->consumeMotionDown();
1631
1632 // Transfer touch focus to the second window
1633 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1634 // The first window gets cancel and the new gets pointer down (it already saw down)
1635 firstWindow->consumeMotionCancel();
1636 secondWindow->consumeMotionPointerDown(1);
1637
1638 // Send pointer up to the second window
1639 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1640 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1641 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1642 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1643 // The first window gets nothing and the second gets pointer up
1644 firstWindow->assertNoEvents();
1645 secondWindow->consumeMotionPointerUp(1);
1646
1647 // Send up event to the second window
1648 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1649 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1650 mDispatcher->notifyMotion(&upMotionArgs);
1651 // The first window gets nothing and the second gets up
1652 firstWindow->assertNoEvents();
1653 secondWindow->consumeMotionUp();
1654}
1655
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001656TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001657 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001658 sp<FakeWindowHandle> window =
1659 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1660
Vishnu Nair47074b82020-08-14 11:54:47 -07001661 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001662 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001663
1664 window->consumeFocusEvent(true);
1665
1666 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1667 mDispatcher->notifyKey(&keyArgs);
1668
1669 // Window should receive key down event.
1670 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1671}
1672
1673TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001674 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001675 sp<FakeWindowHandle> window =
1676 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1677
Arthur Hung72d8dc32020-03-28 00:48:39 +00001678 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001679
1680 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1681 mDispatcher->notifyKey(&keyArgs);
1682 mDispatcher->waitForIdle();
1683
1684 window->assertNoEvents();
1685}
1686
1687// If a window is touchable, but does not have focus, it should receive motion events, but not keys
1688TEST_F(InputDispatcherTest, UnfocusedWindow_ReceivesMotionsButNotKeys) {
Chris Yea209fde2020-07-22 13:54:51 -07001689 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001690 sp<FakeWindowHandle> window =
1691 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1692
Arthur Hung72d8dc32020-03-28 00:48:39 +00001693 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001694
1695 // Send key
1696 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1697 mDispatcher->notifyKey(&keyArgs);
1698 // Send motion
1699 NotifyMotionArgs motionArgs =
1700 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1701 ADISPLAY_ID_DEFAULT);
1702 mDispatcher->notifyMotion(&motionArgs);
1703
1704 // Window should receive only the motion event
1705 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1706 window->assertNoEvents(); // Key event or focus event will not be received
1707}
1708
chaviwd1c23182019-12-20 18:44:56 -08001709class FakeMonitorReceiver {
Michael Wright3a240c42019-12-10 20:53:41 +00001710public:
1711 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
chaviwd1c23182019-12-20 18:44:56 -08001712 int32_t displayId, bool isGestureMonitor = false) {
Siarhei Vishniakoud2588272020-07-10 11:15:40 -05001713 std::unique_ptr<InputChannel> serverChannel, clientChannel;
chaviwd1c23182019-12-20 18:44:56 -08001714 InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Siarhei Vishniakoud2588272020-07-10 11:15:40 -05001715 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(clientChannel), name);
1716 dispatcher->registerInputMonitor(std::move(serverChannel), displayId, isGestureMonitor);
Michael Wright3a240c42019-12-10 20:53:41 +00001717 }
1718
chaviwd1c23182019-12-20 18:44:56 -08001719 sp<IBinder> getToken() { return mInputReceiver->getToken(); }
1720
1721 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1722 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN,
1723 expectedDisplayId, expectedFlags);
1724 }
1725
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001726 std::optional<int32_t> receiveEvent() { return mInputReceiver->receiveEvent(); }
1727
1728 void finishEvent(uint32_t consumeSeq) { return mInputReceiver->finishEvent(consumeSeq); }
1729
chaviwd1c23182019-12-20 18:44:56 -08001730 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1731 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN,
1732 expectedDisplayId, expectedFlags);
1733 }
1734
1735 void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1736 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP,
1737 expectedDisplayId, expectedFlags);
1738 }
1739
1740 void assertNoEvents() { mInputReceiver->assertNoEvents(); }
1741
1742private:
1743 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Michael Wright3a240c42019-12-10 20:53:41 +00001744};
1745
1746// Tests for gesture monitors
1747TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001748 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001749 sp<FakeWindowHandle> window =
1750 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001751 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001752
chaviwd1c23182019-12-20 18:44:56 -08001753 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1754 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001755
1756 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1757 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1758 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1759 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001760 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001761}
1762
1763TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001764 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001765 sp<FakeWindowHandle> window =
1766 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1767
1768 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001769 window->setFocusable(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001770
Arthur Hung72d8dc32020-03-28 00:48:39 +00001771 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001772 window->consumeFocusEvent(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001773
chaviwd1c23182019-12-20 18:44:56 -08001774 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1775 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001776
1777 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1778 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1779 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001780 monitor.assertNoEvents();
Michael Wright3a240c42019-12-10 20:53:41 +00001781}
1782
1783TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001784 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001785 sp<FakeWindowHandle> window =
1786 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001787 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001788
chaviwd1c23182019-12-20 18:44:56 -08001789 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1790 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001791
1792 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1793 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1794 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
1795 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001796 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001797
1798 window->releaseChannel();
1799
chaviwd1c23182019-12-20 18:44:56 -08001800 mDispatcher->pilferPointers(monitor.getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00001801
1802 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1803 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1804 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
chaviwd1c23182019-12-20 18:44:56 -08001805 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001806}
1807
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001808TEST_F(InputDispatcherTest, UnresponsiveGestureMonitor_GetsAnr) {
1809 FakeMonitorReceiver monitor =
1810 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
1811 true /*isGestureMonitor*/);
1812
1813 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
1814 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT));
1815 std::optional<uint32_t> consumeSeq = monitor.receiveEvent();
1816 ASSERT_TRUE(consumeSeq);
1817
1818 mFakePolicy->assertNotifyAnrWasCalled(DISPATCHING_TIMEOUT, nullptr, monitor.getToken());
1819 monitor.finishEvent(*consumeSeq);
1820 ASSERT_TRUE(mDispatcher->waitForIdle());
1821}
1822
chaviw81e2bb92019-12-18 15:03:51 -08001823TEST_F(InputDispatcherTest, TestMoveEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001824 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
chaviw81e2bb92019-12-18 15:03:51 -08001825 sp<FakeWindowHandle> window =
1826 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1827
Arthur Hung72d8dc32020-03-28 00:48:39 +00001828 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
chaviw81e2bb92019-12-18 15:03:51 -08001829
1830 NotifyMotionArgs motionArgs =
1831 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1832 ADISPLAY_ID_DEFAULT);
1833
1834 mDispatcher->notifyMotion(&motionArgs);
1835 // Window should receive motion down event.
1836 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1837
1838 motionArgs.action = AMOTION_EVENT_ACTION_MOVE;
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001839 motionArgs.id += 1;
chaviw81e2bb92019-12-18 15:03:51 -08001840 motionArgs.eventTime = systemTime(SYSTEM_TIME_MONOTONIC);
1841 motionArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
1842 motionArgs.pointerCoords[0].getX() - 10);
1843
1844 mDispatcher->notifyMotion(&motionArgs);
1845 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, ADISPLAY_ID_DEFAULT,
1846 0 /*expectedFlags*/);
1847}
1848
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001849/**
1850 * Dispatcher has touch mode enabled by default. Typically, the policy overrides that value to
1851 * the device default right away. In the test scenario, we check both the default value,
1852 * and the action of enabling / disabling.
1853 */
1854TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
Chris Yea209fde2020-07-22 13:54:51 -07001855 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001856 sp<FakeWindowHandle> window =
1857 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1858
1859 // Set focused application.
1860 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001861 window->setFocusable(true);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001862
1863 SCOPED_TRACE("Check default value of touch mode");
Arthur Hung72d8dc32020-03-28 00:48:39 +00001864 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001865 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1866
1867 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001868 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001869 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001870 window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
1871
1872 SCOPED_TRACE("Disable touch mode");
1873 mDispatcher->setInTouchMode(false);
Vishnu Nair47074b82020-08-14 11:54:47 -07001874 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001875 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001876 window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
1877
1878 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001879 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001880 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001881 window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
1882
1883 SCOPED_TRACE("Enable touch mode again");
1884 mDispatcher->setInTouchMode(true);
Vishnu Nair47074b82020-08-14 11:54:47 -07001885 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001886 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001887 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1888
1889 window->assertNoEvents();
1890}
1891
Gang Wange9087892020-01-07 12:17:14 -05001892TEST_F(InputDispatcherTest, VerifyInputEvent_KeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001893 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Gang Wange9087892020-01-07 12:17:14 -05001894 sp<FakeWindowHandle> window =
1895 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1896
1897 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001898 window->setFocusable(true);
Gang Wange9087892020-01-07 12:17:14 -05001899
Arthur Hung72d8dc32020-03-28 00:48:39 +00001900 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Gang Wange9087892020-01-07 12:17:14 -05001901 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1902
1903 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1904 mDispatcher->notifyKey(&keyArgs);
1905
1906 InputEvent* event = window->consume();
1907 ASSERT_NE(event, nullptr);
1908
1909 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1910 ASSERT_NE(verified, nullptr);
1911 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::KEY);
1912
1913 ASSERT_EQ(keyArgs.eventTime, verified->eventTimeNanos);
1914 ASSERT_EQ(keyArgs.deviceId, verified->deviceId);
1915 ASSERT_EQ(keyArgs.source, verified->source);
1916 ASSERT_EQ(keyArgs.displayId, verified->displayId);
1917
1918 const VerifiedKeyEvent& verifiedKey = static_cast<const VerifiedKeyEvent&>(*verified);
1919
1920 ASSERT_EQ(keyArgs.action, verifiedKey.action);
1921 ASSERT_EQ(keyArgs.downTime, verifiedKey.downTimeNanos);
Gang Wange9087892020-01-07 12:17:14 -05001922 ASSERT_EQ(keyArgs.flags & VERIFIED_KEY_EVENT_FLAGS, verifiedKey.flags);
1923 ASSERT_EQ(keyArgs.keyCode, verifiedKey.keyCode);
1924 ASSERT_EQ(keyArgs.scanCode, verifiedKey.scanCode);
1925 ASSERT_EQ(keyArgs.metaState, verifiedKey.metaState);
1926 ASSERT_EQ(0, verifiedKey.repeatCount);
1927}
1928
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001929TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001930 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001931 sp<FakeWindowHandle> window =
1932 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1933
1934 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1935
Arthur Hung72d8dc32020-03-28 00:48:39 +00001936 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001937
1938 NotifyMotionArgs motionArgs =
1939 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1940 ADISPLAY_ID_DEFAULT);
1941 mDispatcher->notifyMotion(&motionArgs);
1942
1943 InputEvent* event = window->consume();
1944 ASSERT_NE(event, nullptr);
1945
1946 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1947 ASSERT_NE(verified, nullptr);
1948 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::MOTION);
1949
1950 EXPECT_EQ(motionArgs.eventTime, verified->eventTimeNanos);
1951 EXPECT_EQ(motionArgs.deviceId, verified->deviceId);
1952 EXPECT_EQ(motionArgs.source, verified->source);
1953 EXPECT_EQ(motionArgs.displayId, verified->displayId);
1954
1955 const VerifiedMotionEvent& verifiedMotion = static_cast<const VerifiedMotionEvent&>(*verified);
1956
1957 EXPECT_EQ(motionArgs.pointerCoords[0].getX(), verifiedMotion.rawX);
1958 EXPECT_EQ(motionArgs.pointerCoords[0].getY(), verifiedMotion.rawY);
1959 EXPECT_EQ(motionArgs.action & AMOTION_EVENT_ACTION_MASK, verifiedMotion.actionMasked);
1960 EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos);
1961 EXPECT_EQ(motionArgs.flags & VERIFIED_MOTION_EVENT_FLAGS, verifiedMotion.flags);
1962 EXPECT_EQ(motionArgs.metaState, verifiedMotion.metaState);
1963 EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState);
1964}
1965
chaviw09c8d2d2020-08-24 15:48:26 -07001966/**
1967 * Ensure that separate calls to sign the same data are generating the same key.
1968 * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance
1969 * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky
1970 * tests.
1971 */
1972TEST_F(InputDispatcherTest, GeneratedHmac_IsConsistent) {
1973 KeyEvent event = getTestKeyEvent();
1974 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1975
1976 std::array<uint8_t, 32> hmac1 = mDispatcher->sign(verifiedEvent);
1977 std::array<uint8_t, 32> hmac2 = mDispatcher->sign(verifiedEvent);
1978 ASSERT_EQ(hmac1, hmac2);
1979}
1980
1981/**
1982 * Ensure that changes in VerifiedKeyEvent produce a different hmac.
1983 */
1984TEST_F(InputDispatcherTest, GeneratedHmac_ChangesWhenFieldsChange) {
1985 KeyEvent event = getTestKeyEvent();
1986 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1987 std::array<uint8_t, 32> initialHmac = mDispatcher->sign(verifiedEvent);
1988
1989 verifiedEvent.deviceId += 1;
1990 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1991
1992 verifiedEvent.source += 1;
1993 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1994
1995 verifiedEvent.eventTimeNanos += 1;
1996 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1997
1998 verifiedEvent.displayId += 1;
1999 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
2000
2001 verifiedEvent.action += 1;
2002 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
2003
2004 verifiedEvent.downTimeNanos += 1;
2005 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
2006
2007 verifiedEvent.flags += 1;
2008 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
2009
2010 verifiedEvent.keyCode += 1;
2011 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
2012
2013 verifiedEvent.scanCode += 1;
2014 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
2015
2016 verifiedEvent.metaState += 1;
2017 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
2018
2019 verifiedEvent.repeatCount += 1;
2020 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
2021}
2022
Garfield Tan1c7bc862020-01-28 13:24:04 -08002023class InputDispatcherKeyRepeatTest : public InputDispatcherTest {
2024protected:
2025 static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms
2026 static constexpr nsecs_t KEY_REPEAT_DELAY = 40 * 1000000; // 40 ms
2027
Chris Yea209fde2020-07-22 13:54:51 -07002028 std::shared_ptr<FakeApplicationHandle> mApp;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002029 sp<FakeWindowHandle> mWindow;
2030
2031 virtual void SetUp() override {
2032 mFakePolicy = new FakeInputDispatcherPolicy();
2033 mFakePolicy->setKeyRepeatConfiguration(KEY_REPEAT_TIMEOUT, KEY_REPEAT_DELAY);
2034 mDispatcher = new InputDispatcher(mFakePolicy);
2035 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
2036 ASSERT_EQ(OK, mDispatcher->start());
2037
2038 setUpWindow();
2039 }
2040
2041 void setUpWindow() {
Chris Yea209fde2020-07-22 13:54:51 -07002042 mApp = std::make_shared<FakeApplicationHandle>();
Garfield Tan1c7bc862020-01-28 13:24:04 -08002043 mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
2044
Vishnu Nair47074b82020-08-14 11:54:47 -07002045 mWindow->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002046 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Garfield Tan1c7bc862020-01-28 13:24:04 -08002047
2048 mWindow->consumeFocusEvent(true);
2049 }
2050
2051 void sendAndConsumeKeyDown() {
2052 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
2053 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Otherwise it won't generate repeat event
2054 mDispatcher->notifyKey(&keyArgs);
2055
2056 // Window should receive key down event.
2057 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2058 }
2059
2060 void expectKeyRepeatOnce(int32_t repeatCount) {
2061 SCOPED_TRACE(StringPrintf("Checking event with repeat count %" PRId32, repeatCount));
2062 InputEvent* repeatEvent = mWindow->consume();
2063 ASSERT_NE(nullptr, repeatEvent);
2064
2065 uint32_t eventType = repeatEvent->getType();
2066 ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, eventType);
2067
2068 KeyEvent* repeatKeyEvent = static_cast<KeyEvent*>(repeatEvent);
2069 uint32_t eventAction = repeatKeyEvent->getAction();
2070 EXPECT_EQ(AKEY_EVENT_ACTION_DOWN, eventAction);
2071 EXPECT_EQ(repeatCount, repeatKeyEvent->getRepeatCount());
2072 }
2073
2074 void sendAndConsumeKeyUp() {
2075 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
2076 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Unless it won't generate repeat event
2077 mDispatcher->notifyKey(&keyArgs);
2078
2079 // Window should receive key down event.
2080 mWindow->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
2081 0 /*expectedFlags*/);
2082 }
2083};
2084
2085TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeat) {
2086 sendAndConsumeKeyDown();
2087 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2088 expectKeyRepeatOnce(repeatCount);
2089 }
2090}
2091
2092TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterUp) {
2093 sendAndConsumeKeyDown();
2094 expectKeyRepeatOnce(1 /*repeatCount*/);
2095 sendAndConsumeKeyUp();
2096 mWindow->assertNoEvents();
2097}
2098
2099TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseEventIdFromInputDispatcher) {
2100 sendAndConsumeKeyDown();
2101 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2102 InputEvent* repeatEvent = mWindow->consume();
2103 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2104 EXPECT_EQ(IdGenerator::Source::INPUT_DISPATCHER,
2105 IdGenerator::getSource(repeatEvent->getId()));
2106 }
2107}
2108
2109TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseUniqueEventId) {
2110 sendAndConsumeKeyDown();
2111
2112 std::unordered_set<int32_t> idSet;
2113 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2114 InputEvent* repeatEvent = mWindow->consume();
2115 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2116 int32_t id = repeatEvent->getId();
2117 EXPECT_EQ(idSet.end(), idSet.find(id));
2118 idSet.insert(id);
2119 }
2120}
2121
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002122/* Test InputDispatcher for MultiDisplay */
2123class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
2124public:
2125 static constexpr int32_t SECOND_DISPLAY_ID = 1;
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002126 virtual void SetUp() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002127 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +08002128
Chris Yea209fde2020-07-22 13:54:51 -07002129 application1 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002130 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
2131 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002132
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002133 // Set focus window for primary display, but focused display would be second one.
2134 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
Vishnu Nair47074b82020-08-14 11:54:47 -07002135 windowInPrimary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002136 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002137 windowInPrimary->consumeFocusEvent(true);
Arthur Hungb92218b2018-08-14 12:00:21 +08002138
Chris Yea209fde2020-07-22 13:54:51 -07002139 application2 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002140 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
2141 SECOND_DISPLAY_ID);
2142 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002143 // Set focus display to second one.
2144 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
2145 // Set focus window for second display.
2146 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
Vishnu Nair47074b82020-08-14 11:54:47 -07002147 windowInSecondary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002148 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002149 windowInSecondary->consumeFocusEvent(true);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002150 }
2151
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002152 virtual void TearDown() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002153 InputDispatcherTest::TearDown();
2154
Chris Yea209fde2020-07-22 13:54:51 -07002155 application1.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002156 windowInPrimary.clear();
Chris Yea209fde2020-07-22 13:54:51 -07002157 application2.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002158 windowInSecondary.clear();
2159 }
2160
2161protected:
Chris Yea209fde2020-07-22 13:54:51 -07002162 std::shared_ptr<FakeApplicationHandle> application1;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002163 sp<FakeWindowHandle> windowInPrimary;
Chris Yea209fde2020-07-22 13:54:51 -07002164 std::shared_ptr<FakeApplicationHandle> application2;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002165 sp<FakeWindowHandle> windowInSecondary;
2166};
2167
2168TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
2169 // Test touch down on primary display.
2170 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2171 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Arthur Hungb92218b2018-08-14 12:00:21 +08002172 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002173 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08002174 windowInSecondary->assertNoEvents();
2175
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002176 // Test touch down on second display.
2177 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2178 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
Arthur Hungb92218b2018-08-14 12:00:21 +08002179 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2180 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002181 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +08002182}
2183
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002184TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002185 // Test inject a key down with display id specified.
2186 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2187 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002188 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +08002189 windowInSecondary->assertNoEvents();
2190
2191 // Test inject a key down without display id specified.
Arthur Hungb92218b2018-08-14 12:00:21 +08002192 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2193 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2194 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002195 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +08002196
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002197 // Remove all windows in secondary display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002198 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
Arthur Hungb92218b2018-08-14 12:00:21 +08002199
2200 // Expect old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002201 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
2202 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +08002203
2204 // Test inject a key down, should timeout because of no target window.
2205 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
2206 << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
2207 windowInPrimary->assertNoEvents();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002208 windowInSecondary->consumeFocusEvent(false);
Arthur Hungb92218b2018-08-14 12:00:21 +08002209 windowInSecondary->assertNoEvents();
2210}
2211
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002212// Test per-display input monitors for motion event.
2213TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
chaviwd1c23182019-12-20 18:44:56 -08002214 FakeMonitorReceiver monitorInPrimary =
2215 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2216 FakeMonitorReceiver monitorInSecondary =
2217 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002218
2219 // Test touch down on primary display.
2220 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2221 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
2222 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002223 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08002224 monitorInPrimary.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002225 windowInSecondary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002226 monitorInSecondary.assertNoEvents();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002227
2228 // Test touch down on second display.
2229 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2230 AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
2231 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2232 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002233 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002234 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
chaviwd1c23182019-12-20 18:44:56 -08002235 monitorInSecondary.consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002236
2237 // Test inject a non-pointer motion event.
2238 // If specific a display, it will dispatch to the focused window of particular display,
2239 // or it will dispatch to the focused window of focused display.
2240 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
2241 AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
2242 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2243 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002244 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002245 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002246 monitorInSecondary.consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002247}
2248
2249// Test per-display input monitors for key event.
2250TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
2251 //Input monitor per display.
chaviwd1c23182019-12-20 18:44:56 -08002252 FakeMonitorReceiver monitorInPrimary =
2253 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2254 FakeMonitorReceiver monitorInSecondary =
2255 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002256
2257 // Test inject a key down.
2258 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
2259 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
2260 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002261 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002262 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002263 monitorInSecondary.consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002264}
2265
Jackal Guof9696682018-10-05 12:23:23 +08002266class InputFilterTest : public InputDispatcherTest {
2267protected:
2268 static constexpr int32_t SECOND_DISPLAY_ID = 1;
2269
2270 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
2271 NotifyMotionArgs motionArgs;
2272
2273 motionArgs = generateMotionArgs(
2274 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2275 mDispatcher->notifyMotion(&motionArgs);
2276 motionArgs = generateMotionArgs(
2277 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2278 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002279 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002280 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002281 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002282 } else {
2283 mFakePolicy->assertFilterInputEventWasNotCalled();
2284 }
2285 }
2286
2287 void testNotifyKey(bool expectToBeFiltered) {
2288 NotifyKeyArgs keyArgs;
2289
2290 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
2291 mDispatcher->notifyKey(&keyArgs);
2292 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
2293 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002294 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002295
2296 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002297 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002298 } else {
2299 mFakePolicy->assertFilterInputEventWasNotCalled();
2300 }
2301 }
2302};
2303
2304// Test InputFilter for MotionEvent
2305TEST_F(InputFilterTest, MotionEvent_InputFilter) {
2306 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
2307 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2308 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2309
2310 // Enable InputFilter
2311 mDispatcher->setInputFilterEnabled(true);
2312 // Test touch on both primary and second display, and check if both events are filtered.
2313 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
2314 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
2315
2316 // Disable InputFilter
2317 mDispatcher->setInputFilterEnabled(false);
2318 // Test touch on both primary and second display, and check if both events aren't filtered.
2319 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2320 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2321}
2322
2323// Test InputFilter for KeyEvent
2324TEST_F(InputFilterTest, KeyEvent_InputFilter) {
2325 // Since the InputFilter is disabled by default, check if key event aren't filtered.
2326 testNotifyKey(/*expectToBeFiltered*/ false);
2327
2328 // Enable InputFilter
2329 mDispatcher->setInputFilterEnabled(true);
2330 // Send a key event, and check if it is filtered.
2331 testNotifyKey(/*expectToBeFiltered*/ true);
2332
2333 // Disable InputFilter
2334 mDispatcher->setInputFilterEnabled(false);
2335 // Send a key event, and check if it isn't filtered.
2336 testNotifyKey(/*expectToBeFiltered*/ false);
2337}
2338
chaviwfd6d3512019-03-25 13:23:49 -07002339class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002340 virtual void SetUp() override {
chaviwfd6d3512019-03-25 13:23:49 -07002341 InputDispatcherTest::SetUp();
2342
Chris Yea209fde2020-07-22 13:54:51 -07002343 std::shared_ptr<FakeApplicationHandle> application =
2344 std::make_shared<FakeApplicationHandle>();
chaviwfd6d3512019-03-25 13:23:49 -07002345 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
2346 ADISPLAY_ID_DEFAULT);
2347 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
2348 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2349 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002350 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002351
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002352 mFocusedWindow =
2353 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2354 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01002355 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002356
2357 // Set focused application.
2358 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07002359 mFocusedWindow->setFocusable(true);
chaviwfd6d3512019-03-25 13:23:49 -07002360
2361 // Expect one focus window exist in display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002362 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002363 mFocusedWindow->consumeFocusEvent(true);
chaviwfd6d3512019-03-25 13:23:49 -07002364 }
2365
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002366 virtual void TearDown() override {
chaviwfd6d3512019-03-25 13:23:49 -07002367 InputDispatcherTest::TearDown();
2368
2369 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002370 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07002371 }
2372
2373protected:
2374 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002375 sp<FakeWindowHandle> mFocusedWindow;
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002376 static constexpr PointF FOCUSED_WINDOW_TOUCH_POINT = {60, 60};
chaviwfd6d3512019-03-25 13:23:49 -07002377};
2378
2379// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2380// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
2381// the onPointerDownOutsideFocus callback.
2382TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002383 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2384 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2385 {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07002386 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002387 mUnfocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002388
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002389 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07002390 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
2391}
2392
2393// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
2394// DOWN on the window that doesn't have focus. Ensure no window received the
2395// onPointerDownOutsideFocus callback.
2396TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002397 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2398 injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, {20, 20}))
chaviwfd6d3512019-03-25 13:23:49 -07002399 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002400 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002401
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002402 ASSERT_TRUE(mDispatcher->waitForIdle());
2403 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002404}
2405
2406// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
2407// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
2408TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
2409 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2410 << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002411 mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07002412
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002413 ASSERT_TRUE(mDispatcher->waitForIdle());
2414 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002415}
2416
2417// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2418// DOWN on the window that already has focus. Ensure no window received the
2419// onPointerDownOutsideFocus callback.
2420TEST_F(InputDispatcherOnPointerDownOutsideFocus,
2421 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002422 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2423 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002424 FOCUSED_WINDOW_TOUCH_POINT))
chaviwfd6d3512019-03-25 13:23:49 -07002425 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002426 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002427
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002428 ASSERT_TRUE(mDispatcher->waitForIdle());
2429 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002430}
2431
chaviwaf87b3e2019-10-01 16:59:28 -07002432// These tests ensures we can send touch events to a single client when there are multiple input
2433// windows that point to the same client token.
2434class InputDispatcherMultiWindowSameTokenTests : public InputDispatcherTest {
2435 virtual void SetUp() override {
2436 InputDispatcherTest::SetUp();
2437
Chris Yea209fde2020-07-22 13:54:51 -07002438 std::shared_ptr<FakeApplicationHandle> application =
2439 std::make_shared<FakeApplicationHandle>();
chaviwaf87b3e2019-10-01 16:59:28 -07002440 mWindow1 = new FakeWindowHandle(application, mDispatcher, "Fake Window 1",
2441 ADISPLAY_ID_DEFAULT);
2442 // Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
2443 // 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 +01002444 mWindow1->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2445 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002446 mWindow1->setFrame(Rect(0, 0, 100, 100));
2447
2448 mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
2449 ADISPLAY_ID_DEFAULT, mWindow1->getToken());
Michael Wright44753b12020-07-08 13:48:11 +01002450 mWindow2->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2451 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002452 mWindow2->setFrame(Rect(100, 100, 200, 200));
2453
Arthur Hung72d8dc32020-03-28 00:48:39 +00002454 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
chaviwaf87b3e2019-10-01 16:59:28 -07002455 }
2456
2457protected:
2458 sp<FakeWindowHandle> mWindow1;
2459 sp<FakeWindowHandle> mWindow2;
2460
2461 // Helper function to convert the point from screen coordinates into the window's space
2462 static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) {
chaviw1ff3d1e2020-07-01 15:53:47 -07002463 vec2 vals = windowInfo->transform.transform(point.x, point.y);
2464 return {vals.x, vals.y};
chaviwaf87b3e2019-10-01 16:59:28 -07002465 }
2466
2467 void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction,
2468 const std::vector<PointF>& points) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002469 const std::string name = window->getName();
chaviwaf87b3e2019-10-01 16:59:28 -07002470 InputEvent* event = window->consume();
2471
2472 ASSERT_NE(nullptr, event) << name.c_str()
2473 << ": consumer should have returned non-NULL event.";
2474
2475 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
2476 << name.c_str() << "expected " << inputEventTypeToString(AINPUT_EVENT_TYPE_MOTION)
2477 << " event, got " << inputEventTypeToString(event->getType()) << " event";
2478
2479 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
2480 EXPECT_EQ(expectedAction, motionEvent.getAction());
2481
2482 for (size_t i = 0; i < points.size(); i++) {
2483 float expectedX = points[i].x;
2484 float expectedY = points[i].y;
2485
2486 EXPECT_EQ(expectedX, motionEvent.getX(i))
2487 << "expected " << expectedX << " for x[" << i << "] coord of " << name.c_str()
2488 << ", got " << motionEvent.getX(i);
2489 EXPECT_EQ(expectedY, motionEvent.getY(i))
2490 << "expected " << expectedY << " for y[" << i << "] coord of " << name.c_str()
2491 << ", got " << motionEvent.getY(i);
2492 }
2493 }
chaviw9eaa22c2020-07-01 16:21:27 -07002494
2495 void touchAndAssertPositions(int32_t action, std::vector<PointF> touchedPoints,
2496 std::vector<PointF> expectedPoints) {
2497 NotifyMotionArgs motionArgs = generateMotionArgs(action, AINPUT_SOURCE_TOUCHSCREEN,
2498 ADISPLAY_ID_DEFAULT, touchedPoints);
2499 mDispatcher->notifyMotion(&motionArgs);
2500
2501 // Always consume from window1 since it's the window that has the InputReceiver
2502 consumeMotionEvent(mWindow1, action, expectedPoints);
2503 }
chaviwaf87b3e2019-10-01 16:59:28 -07002504};
2505
2506TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchSameScale) {
2507 // Touch Window 1
2508 PointF touchedPoint = {10, 10};
2509 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002510 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002511
2512 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002513 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002514
2515 // Touch Window 2
2516 touchedPoint = {150, 150};
2517 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002518 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002519}
2520
chaviw9eaa22c2020-07-01 16:21:27 -07002521TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchDifferentTransform) {
2522 // Set scale value for window2
chaviwaf87b3e2019-10-01 16:59:28 -07002523 mWindow2->setWindowScale(0.5f, 0.5f);
2524
2525 // Touch Window 1
2526 PointF touchedPoint = {10, 10};
2527 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002528 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002529 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002530 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002531
2532 // Touch Window 2
2533 touchedPoint = {150, 150};
2534 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002535 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
2536 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002537
chaviw9eaa22c2020-07-01 16:21:27 -07002538 // Update the transform so rotation is set
2539 mWindow2->setWindowTransform(0, -1, 1, 0);
2540 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
2541 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002542}
2543
chaviw9eaa22c2020-07-01 16:21:27 -07002544TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002545 mWindow2->setWindowScale(0.5f, 0.5f);
2546
2547 // Touch Window 1
2548 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2549 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002550 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002551
2552 // Touch Window 2
2553 int32_t actionPointerDown =
2554 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002555 touchedPoints.push_back(PointF{150, 150});
2556 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2557 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002558
chaviw9eaa22c2020-07-01 16:21:27 -07002559 // Release Window 2
2560 int32_t actionPointerUp =
2561 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2562 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2563 expectedPoints.pop_back();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002564
chaviw9eaa22c2020-07-01 16:21:27 -07002565 // Update the transform so rotation is set for Window 2
2566 mWindow2->setWindowTransform(0, -1, 1, 0);
2567 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2568 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002569}
2570
chaviw9eaa22c2020-07-01 16:21:27 -07002571TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchMoveDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002572 mWindow2->setWindowScale(0.5f, 0.5f);
2573
2574 // Touch Window 1
2575 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2576 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002577 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002578
2579 // Touch Window 2
2580 int32_t actionPointerDown =
2581 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002582 touchedPoints.push_back(PointF{150, 150});
2583 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002584
chaviw9eaa22c2020-07-01 16:21:27 -07002585 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002586
2587 // Move both windows
2588 touchedPoints = {{20, 20}, {175, 175}};
2589 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2590 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2591
chaviw9eaa22c2020-07-01 16:21:27 -07002592 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002593
chaviw9eaa22c2020-07-01 16:21:27 -07002594 // Release Window 2
2595 int32_t actionPointerUp =
2596 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2597 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2598 expectedPoints.pop_back();
2599
2600 // Touch Window 2
2601 mWindow2->setWindowTransform(0, -1, 1, 0);
2602 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2603 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
2604
2605 // Move both windows
2606 touchedPoints = {{20, 20}, {175, 175}};
2607 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2608 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2609
2610 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002611}
2612
2613TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithScale) {
2614 mWindow1->setWindowScale(0.5f, 0.5f);
2615
2616 // Touch Window 1
2617 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2618 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002619 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002620
2621 // Touch Window 2
2622 int32_t actionPointerDown =
2623 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002624 touchedPoints.push_back(PointF{150, 150});
2625 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002626
chaviw9eaa22c2020-07-01 16:21:27 -07002627 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002628
2629 // Move both windows
2630 touchedPoints = {{20, 20}, {175, 175}};
2631 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2632 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2633
chaviw9eaa22c2020-07-01 16:21:27 -07002634 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002635}
2636
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002637class InputDispatcherSingleWindowAnr : public InputDispatcherTest {
2638 virtual void SetUp() override {
2639 InputDispatcherTest::SetUp();
2640
Chris Yea209fde2020-07-22 13:54:51 -07002641 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002642 mApplication->setDispatchingTimeout(20ms);
2643 mWindow =
2644 new FakeWindowHandle(mApplication, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2645 mWindow->setFrame(Rect(0, 0, 30, 30));
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05002646 mWindow->setDispatchingTimeout(30ms);
Vishnu Nair47074b82020-08-14 11:54:47 -07002647 mWindow->setFocusable(true);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002648 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2649 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002650 mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002651
2652 // Set focused application.
2653 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
2654
2655 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2656 mWindow->consumeFocusEvent(true);
2657 }
2658
2659 virtual void TearDown() override {
2660 InputDispatcherTest::TearDown();
2661 mWindow.clear();
2662 }
2663
2664protected:
Chris Yea209fde2020-07-22 13:54:51 -07002665 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002666 sp<FakeWindowHandle> mWindow;
2667 static constexpr PointF WINDOW_LOCATION = {20, 20};
2668
2669 void tapOnWindow() {
2670 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2671 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2672 WINDOW_LOCATION));
2673 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2674 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2675 WINDOW_LOCATION));
2676 }
2677};
2678
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002679// Send a tap and respond, which should not cause an ANR.
2680TEST_F(InputDispatcherSingleWindowAnr, WhenTouchIsConsumed_NoAnr) {
2681 tapOnWindow();
2682 mWindow->consumeMotionDown();
2683 mWindow->consumeMotionUp();
2684 ASSERT_TRUE(mDispatcher->waitForIdle());
2685 mFakePolicy->assertNotifyAnrWasNotCalled();
2686}
2687
2688// Send a regular key and respond, which should not cause an ANR.
2689TEST_F(InputDispatcherSingleWindowAnr, WhenKeyIsConsumed_NoAnr) {
2690 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
2691 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
2692 ASSERT_TRUE(mDispatcher->waitForIdle());
2693 mFakePolicy->assertNotifyAnrWasNotCalled();
2694}
2695
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002696// Send an event to the app and have the app not respond right away.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002697// When ANR is raised, policy will tell the dispatcher to cancel the events for that window.
2698// So InputDispatcher will enqueue ACTION_CANCEL event as well.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002699TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) {
2700 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2701 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2702 WINDOW_LOCATION));
2703
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002704 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent(); // ACTION_DOWN
2705 ASSERT_TRUE(sequenceNum);
2706 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2707 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002708
2709 // The remaining lines are not really needed for the test, but kept as a sanity check
2710 mWindow->finishEvent(*sequenceNum);
2711 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
2712 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002713 ASSERT_TRUE(mDispatcher->waitForIdle());
2714}
2715
2716// Send a key to the app and have the app not respond right away.
2717TEST_F(InputDispatcherSingleWindowAnr, OnKeyDown_BasicAnr) {
2718 // Inject a key, and don't respond - expect that ANR is called.
2719 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
2720 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent();
2721 ASSERT_TRUE(sequenceNum);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002722 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002723 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002724 ASSERT_TRUE(mDispatcher->waitForIdle());
2725}
2726
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002727// We have a focused application, but no focused window
2728TEST_F(InputDispatcherSingleWindowAnr, FocusedApplication_NoFocusedWindow) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002729 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002730 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2731 mWindow->consumeFocusEvent(false);
2732
2733 // taps on the window work as normal
2734 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2735 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2736 WINDOW_LOCATION));
2737 ASSERT_NO_FATAL_FAILURE(mWindow->consumeMotionDown());
2738 mDispatcher->waitForIdle();
2739 mFakePolicy->assertNotifyAnrWasNotCalled();
2740
2741 // Once a focused event arrives, we get an ANR for this application
2742 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2743 // injection times out (instead of failing).
2744 const int32_t result =
2745 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2746 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2747 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2748 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2749 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2750 ASSERT_TRUE(mDispatcher->waitForIdle());
2751}
2752
2753// We have a focused application, but no focused window
2754// If the policy wants to keep waiting on the focused window to be added, make sure
2755// that this timeout extension is honored and ANR is raised again.
2756TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_ExtendsAnr) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002757 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002758 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2759 mWindow->consumeFocusEvent(false);
2760 const std::chrono::duration timeout = 5ms;
2761 mFakePolicy->setAnrTimeout(timeout);
2762
2763 // Once a focused event arrives, we get an ANR for this application
2764 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2765 // injection times out (instead of failing).
2766 const int32_t result =
2767 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2768 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2769 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2770 const std::chrono::duration appTimeout =
2771 mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2772 mFakePolicy->assertNotifyAnrWasCalled(appTimeout, mApplication, nullptr /*windowToken*/);
2773
2774 // After the extended time has passed, ANR should be raised again
2775 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2776
2777 // If we stop extending the timeout, dispatcher should go to idle.
2778 // Another ANR may be raised during this time
2779 mFakePolicy->setAnrTimeout(0ms);
2780 ASSERT_TRUE(mDispatcher->waitForIdle());
2781}
2782
2783// We have a focused application, but no focused window
2784TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_DropsFocusedEvents) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002785 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002786 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2787 mWindow->consumeFocusEvent(false);
2788
2789 // Once a focused event arrives, we get an ANR for this application
2790 const int32_t result =
2791 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2792 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2793 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2794
2795 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2796 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2797
2798 // Future focused events get dropped right away
2799 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, injectKeyDown(mDispatcher));
2800 ASSERT_TRUE(mDispatcher->waitForIdle());
2801 mWindow->assertNoEvents();
2802}
2803
2804/**
2805 * Ensure that the implementation is valid. Since we are using multiset to keep track of the
2806 * ANR timeouts, we are allowing entries with identical timestamps in the same connection.
2807 * If we process 1 of the events, but ANR on the second event with the same timestamp,
2808 * the ANR mechanism should still work.
2809 *
2810 * In this test, we are injecting DOWN and UP events with the same timestamps, and acknowledging the
2811 * DOWN event, while not responding on the second one.
2812 */
2813TEST_F(InputDispatcherSingleWindowAnr, Anr_HandlesEventsWithIdenticalTimestamps) {
2814 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
2815 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2816 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
2817 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
2818 AMOTION_EVENT_INVALID_CURSOR_POSITION},
2819 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
2820
2821 // Now send ACTION_UP, with identical timestamp
2822 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
2823 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
2824 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
2825 AMOTION_EVENT_INVALID_CURSOR_POSITION},
2826 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
2827
2828 // We have now sent down and up. Let's consume first event and then ANR on the second.
2829 mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
2830 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2831 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
2832}
2833
2834// If an app is not responding to a key event, gesture monitors should continue to receive
2835// new motion events
2836TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnKey) {
2837 FakeMonitorReceiver monitor =
2838 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
2839 true /*isGestureMonitor*/);
2840
2841 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT));
2842 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2843 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher, ADISPLAY_ID_DEFAULT));
2844
2845 // Stuck on the ACTION_UP
2846 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2847 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
2848
2849 // New tap will go to the gesture monitor, but not to the window
2850 tapOnWindow();
2851 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
2852 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
2853
2854 mWindow->consumeKeyUp(ADISPLAY_ID_DEFAULT); // still the previous motion
2855 mDispatcher->waitForIdle();
2856 mWindow->assertNoEvents();
2857 monitor.assertNoEvents();
2858}
2859
2860// If an app is not responding to a motion event, gesture monitors should continue to receive
2861// new motion events
2862TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnMotion) {
2863 FakeMonitorReceiver monitor =
2864 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
2865 true /*isGestureMonitor*/);
2866
2867 tapOnWindow();
2868 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
2869 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
2870
2871 mWindow->consumeMotionDown();
2872 // Stuck on the ACTION_UP
2873 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2874 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
2875
2876 // New tap will go to the gesture monitor, but not to the window
2877 tapOnWindow();
2878 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
2879 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
2880
2881 mWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT); // still the previous motion
2882 mDispatcher->waitForIdle();
2883 mWindow->assertNoEvents();
2884 monitor.assertNoEvents();
2885}
2886
2887// If a window is unresponsive, then you get anr. if the window later catches up and starts to
2888// process events, you don't get an anr. When the window later becomes unresponsive again, you
2889// get an ANR again.
2890// 1. tap -> block on ACTION_UP -> receive ANR
2891// 2. consume all pending events (= queue becomes healthy again)
2892// 3. tap again -> block on ACTION_UP again -> receive ANR second time
2893TEST_F(InputDispatcherSingleWindowAnr, SameWindow_CanReceiveAnrTwice) {
2894 tapOnWindow();
2895
2896 mWindow->consumeMotionDown();
2897 // Block on ACTION_UP
2898 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2899 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
2900 mWindow->consumeMotionUp(); // Now the connection should be healthy again
2901 mDispatcher->waitForIdle();
2902 mWindow->assertNoEvents();
2903
2904 tapOnWindow();
2905 mWindow->consumeMotionDown();
2906 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
2907 mWindow->consumeMotionUp();
2908
2909 mDispatcher->waitForIdle();
2910 mWindow->assertNoEvents();
2911}
2912
2913// If the policy tells us to raise ANR again after some time, ensure that the timeout extension
2914// is honored
2915TEST_F(InputDispatcherSingleWindowAnr, Policy_CanExtendTimeout) {
2916 const std::chrono::duration timeout = 5ms;
2917 mFakePolicy->setAnrTimeout(timeout);
2918
2919 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
2920 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2921 WINDOW_LOCATION));
2922
2923 const std::chrono::duration windowTimeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2924 mFakePolicy->assertNotifyAnrWasCalled(windowTimeout, nullptr /*application*/,
2925 mWindow->getToken());
2926
2927 // Since the policy wanted to extend ANR, make sure it is called again after the extension
2928 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
2929 mFakePolicy->setAnrTimeout(0ms);
2930 std::this_thread::sleep_for(windowTimeout);
2931 // We are not checking if ANR has been called, because it may have been called again by the
2932 // time we set the timeout to 0
2933
2934 // When the policy finally says stop, we should get ACTION_CANCEL
2935 mWindow->consumeMotionDown();
2936 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
2937 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
2938 mWindow->assertNoEvents();
2939}
2940
2941/**
2942 * If a window is processing a motion event, and then a key event comes in, the key event should
2943 * not to to the focused window until the motion is processed.
2944 *
2945 * Warning!!!
2946 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
2947 * and the injection timeout that we specify when injecting the key.
2948 * We must have the injection timeout (10ms) be smaller than
2949 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
2950 *
2951 * If that value changes, this test should also change.
2952 */
2953TEST_F(InputDispatcherSingleWindowAnr, Key_StaysPendingWhileMotionIsProcessed) {
2954 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
2955 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2956
2957 tapOnWindow();
2958 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
2959 ASSERT_TRUE(downSequenceNum);
2960 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
2961 ASSERT_TRUE(upSequenceNum);
2962 // Don't finish the events yet, and send a key
2963 // Injection will "succeed" because we will eventually give up and send the key to the focused
2964 // window even if motions are still being processed. But because the injection timeout is short,
2965 // we will receive INJECTION_TIMED_OUT as the result.
2966
2967 int32_t result =
2968 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
2969 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
2970 ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
2971 // Key will not be sent to the window, yet, because the window is still processing events
2972 // and the key remains pending, waiting for the touch events to be processed
2973 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
2974 ASSERT_FALSE(keySequenceNum);
2975
2976 std::this_thread::sleep_for(500ms);
2977 // if we wait long enough though, dispatcher will give up, and still send the key
2978 // to the focused window, even though we have not yet finished the motion event
2979 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2980 mWindow->finishEvent(*downSequenceNum);
2981 mWindow->finishEvent(*upSequenceNum);
2982}
2983
2984/**
2985 * If a window is processing a motion event, and then a key event comes in, the key event should
2986 * not go to the focused window until the motion is processed.
2987 * If then a new motion comes in, then the pending key event should be going to the currently
2988 * focused window right away.
2989 */
2990TEST_F(InputDispatcherSingleWindowAnr,
2991 PendingKey_IsDroppedWhileMotionIsProcessedAndNewTouchComesIn) {
2992 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
2993 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2994
2995 tapOnWindow();
2996 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
2997 ASSERT_TRUE(downSequenceNum);
2998 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
2999 ASSERT_TRUE(upSequenceNum);
3000 // Don't finish the events yet, and send a key
3001 // Injection is async, so it will succeed
3002 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3003 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
3004 ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
3005 // At this point, key is still pending, and should not be sent to the application yet.
3006 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
3007 ASSERT_FALSE(keySequenceNum);
3008
3009 // Now tap down again. It should cause the pending key to go to the focused window right away.
3010 tapOnWindow();
3011 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT); // it doesn't matter that we haven't ack'd
3012 // the other events yet. We can finish events in any order.
3013 mWindow->finishEvent(*downSequenceNum); // first tap's ACTION_DOWN
3014 mWindow->finishEvent(*upSequenceNum); // first tap's ACTION_UP
3015 mWindow->consumeMotionDown();
3016 mWindow->consumeMotionUp();
3017 mWindow->assertNoEvents();
3018}
3019
3020class InputDispatcherMultiWindowAnr : public InputDispatcherTest {
3021 virtual void SetUp() override {
3022 InputDispatcherTest::SetUp();
3023
Chris Yea209fde2020-07-22 13:54:51 -07003024 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003025 mApplication->setDispatchingTimeout(10ms);
3026 mUnfocusedWindow =
3027 new FakeWindowHandle(mApplication, mDispatcher, "Unfocused", ADISPLAY_ID_DEFAULT);
3028 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
3029 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
3030 // window.
3031 // Adding FLAG_WATCH_OUTSIDE_TOUCH to receive ACTION_OUTSIDE when another window is tapped
Michael Wright44753b12020-07-08 13:48:11 +01003032 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3033 InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
3034 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003035
3036 mFocusedWindow =
3037 new FakeWindowHandle(mApplication, mDispatcher, "Focused", ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05003038 mFocusedWindow->setDispatchingTimeout(30ms);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003039 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01003040 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3041 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003042
3043 // Set focused application.
3044 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
Vishnu Nair47074b82020-08-14 11:54:47 -07003045 mFocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003046
3047 // Expect one focus window exist in display.
3048 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3049 mFocusedWindow->consumeFocusEvent(true);
3050 }
3051
3052 virtual void TearDown() override {
3053 InputDispatcherTest::TearDown();
3054
3055 mUnfocusedWindow.clear();
3056 mFocusedWindow.clear();
3057 }
3058
3059protected:
Chris Yea209fde2020-07-22 13:54:51 -07003060 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003061 sp<FakeWindowHandle> mUnfocusedWindow;
3062 sp<FakeWindowHandle> mFocusedWindow;
3063 static constexpr PointF UNFOCUSED_WINDOW_LOCATION = {20, 20};
3064 static constexpr PointF FOCUSED_WINDOW_LOCATION = {75, 75};
3065 static constexpr PointF LOCATION_OUTSIDE_ALL_WINDOWS = {40, 40};
3066
3067 void tapOnFocusedWindow() { tap(FOCUSED_WINDOW_LOCATION); }
3068
3069 void tapOnUnfocusedWindow() { tap(UNFOCUSED_WINDOW_LOCATION); }
3070
3071private:
3072 void tap(const PointF& location) {
3073 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3074 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3075 location));
3076 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3077 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3078 location));
3079 }
3080};
3081
3082// If we have 2 windows that are both unresponsive, the one with the shortest timeout
3083// should be ANR'd first.
3084TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsive) {
3085 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3086 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3087 FOCUSED_WINDOW_LOCATION))
3088 << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
3089 mFocusedWindow->consumeMotionDown();
3090 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3091 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3092 // We consumed all events, so no ANR
3093 ASSERT_TRUE(mDispatcher->waitForIdle());
3094 mFakePolicy->assertNotifyAnrWasNotCalled();
3095
3096 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
3097 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3098 FOCUSED_WINDOW_LOCATION));
3099 std::optional<uint32_t> unfocusedSequenceNum = mUnfocusedWindow->receiveEvent();
3100 ASSERT_TRUE(unfocusedSequenceNum);
3101 std::optional<uint32_t> focusedSequenceNum = mFocusedWindow->receiveEvent();
3102 ASSERT_TRUE(focusedSequenceNum);
3103
3104 const std::chrono::duration timeout =
3105 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3106 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3107 mFocusedWindow->getToken());
3108
3109 mFocusedWindow->finishEvent(*focusedSequenceNum);
3110 mUnfocusedWindow->finishEvent(*unfocusedSequenceNum);
3111 ASSERT_TRUE(mDispatcher->waitForIdle());
3112}
3113
3114// If we have 2 windows with identical timeouts that are both unresponsive,
3115// it doesn't matter which order they should have ANR.
3116// But we should receive ANR for both.
3117TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsiveWithSameTimeout) {
3118 // Set the timeout for unfocused window to match the focused window
3119 mUnfocusedWindow->setDispatchingTimeout(10ms);
3120 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3121
3122 tapOnFocusedWindow();
3123 // we should have ACTION_DOWN/ACTION_UP on focused window and ACTION_OUTSIDE on unfocused window
Chris Yea209fde2020-07-22 13:54:51 -07003124 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData1 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003125 mFakePolicy->getNotifyAnrData(10ms);
Chris Yea209fde2020-07-22 13:54:51 -07003126 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData2 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003127 mFakePolicy->getNotifyAnrData(0ms);
3128
3129 // We don't know which window will ANR first. But both of them should happen eventually.
3130 ASSERT_TRUE(mFocusedWindow->getToken() == anrData1.second ||
3131 mFocusedWindow->getToken() == anrData2.second);
3132 ASSERT_TRUE(mUnfocusedWindow->getToken() == anrData1.second ||
3133 mUnfocusedWindow->getToken() == anrData2.second);
3134
3135 ASSERT_TRUE(mDispatcher->waitForIdle());
3136 mFakePolicy->assertNotifyAnrWasNotCalled();
3137}
3138
3139// If a window is already not responding, the second tap on the same window should be ignored.
3140// We should also log an error to account for the dropped event (not tested here).
3141// At the same time, FLAG_WATCH_OUTSIDE_TOUCH targets should not receive any events.
3142TEST_F(InputDispatcherMultiWindowAnr, DuringAnr_SecondTapIsIgnored) {
3143 tapOnFocusedWindow();
3144 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3145 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3146 // Receive the events, but don't respond
3147 std::optional<uint32_t> downEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_DOWN
3148 ASSERT_TRUE(downEventSequenceNum);
3149 std::optional<uint32_t> upEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_UP
3150 ASSERT_TRUE(upEventSequenceNum);
3151 const std::chrono::duration timeout =
3152 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3153 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3154 mFocusedWindow->getToken());
3155
3156 // Tap once again
3157 // We cannot use "tapOnFocusedWindow" because it asserts the injection result to be success
3158 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3159 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3160 FOCUSED_WINDOW_LOCATION));
3161 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3162 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3163 FOCUSED_WINDOW_LOCATION));
3164 // Unfocused window does not receive ACTION_OUTSIDE because the tapped window is not a
3165 // valid touch target
3166 mUnfocusedWindow->assertNoEvents();
3167
3168 // Consume the first tap
3169 mFocusedWindow->finishEvent(*downEventSequenceNum);
3170 mFocusedWindow->finishEvent(*upEventSequenceNum);
3171 ASSERT_TRUE(mDispatcher->waitForIdle());
3172 // The second tap did not go to the focused window
3173 mFocusedWindow->assertNoEvents();
3174 // should not have another ANR after the window just became healthy again
3175 mFakePolicy->assertNotifyAnrWasNotCalled();
3176}
3177
3178// If you tap outside of all windows, there will not be ANR
3179TEST_F(InputDispatcherMultiWindowAnr, TapOutsideAllWindows_DoesNotAnr) {
3180 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3181 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3182 LOCATION_OUTSIDE_ALL_WINDOWS));
3183 ASSERT_TRUE(mDispatcher->waitForIdle());
3184 mFakePolicy->assertNotifyAnrWasNotCalled();
3185}
3186
3187// Since the focused window is paused, tapping on it should not produce any events
3188TEST_F(InputDispatcherMultiWindowAnr, Window_CanBePaused) {
3189 mFocusedWindow->setPaused(true);
3190 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3191
3192 ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
3193 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3194 FOCUSED_WINDOW_LOCATION));
3195
3196 std::this_thread::sleep_for(mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT));
3197 ASSERT_TRUE(mDispatcher->waitForIdle());
3198 // Should not ANR because the window is paused, and touches shouldn't go to it
3199 mFakePolicy->assertNotifyAnrWasNotCalled();
3200
3201 mFocusedWindow->assertNoEvents();
3202 mUnfocusedWindow->assertNoEvents();
3203}
3204
3205/**
3206 * If a window is processing a motion event, and then a key event comes in, the key event should
3207 * not to to the focused window until the motion is processed.
3208 * If a different window becomes focused at this time, the key should go to that window instead.
3209 *
3210 * Warning!!!
3211 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
3212 * and the injection timeout that we specify when injecting the key.
3213 * We must have the injection timeout (10ms) be smaller than
3214 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
3215 *
3216 * If that value changes, this test should also change.
3217 */
3218TEST_F(InputDispatcherMultiWindowAnr, PendingKey_GoesToNewlyFocusedWindow) {
3219 // Set a long ANR timeout to prevent it from triggering
3220 mFocusedWindow->setDispatchingTimeout(2s);
3221 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3222
3223 tapOnUnfocusedWindow();
3224 std::optional<uint32_t> downSequenceNum = mUnfocusedWindow->receiveEvent();
3225 ASSERT_TRUE(downSequenceNum);
3226 std::optional<uint32_t> upSequenceNum = mUnfocusedWindow->receiveEvent();
3227 ASSERT_TRUE(upSequenceNum);
3228 // Don't finish the events yet, and send a key
3229 // Injection will succeed because we will eventually give up and send the key to the focused
3230 // window even if motions are still being processed.
3231
3232 int32_t result =
3233 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
3234 INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
3235 ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
3236 // Key will not be sent to the window, yet, because the window is still processing events
3237 // and the key remains pending, waiting for the touch events to be processed
3238 std::optional<uint32_t> keySequenceNum = mFocusedWindow->receiveEvent();
3239 ASSERT_FALSE(keySequenceNum);
3240
3241 // Switch the focus to the "unfocused" window that we tapped. Expect the key to go there
Vishnu Nair47074b82020-08-14 11:54:47 -07003242 mFocusedWindow->setFocusable(false);
3243 mUnfocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003244 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3245
3246 // Focus events should precede the key events
3247 mUnfocusedWindow->consumeFocusEvent(true);
3248 mFocusedWindow->consumeFocusEvent(false);
3249
3250 // Finish the tap events, which should unblock dispatcher
3251 mUnfocusedWindow->finishEvent(*downSequenceNum);
3252 mUnfocusedWindow->finishEvent(*upSequenceNum);
3253
3254 // Now that all queues are cleared and no backlog in the connections, the key event
3255 // can finally go to the newly focused "mUnfocusedWindow".
3256 mUnfocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3257 mFocusedWindow->assertNoEvents();
3258 mUnfocusedWindow->assertNoEvents();
3259}
3260
3261// When the touch stream is split across 2 windows, and one of them does not respond,
3262// then ANR should be raised and the touch should be canceled for the unresponsive window.
3263// The other window should not be affected by that.
3264TEST_F(InputDispatcherMultiWindowAnr, SplitTouch_SingleWindowAnr) {
3265 // Touch Window 1
3266 NotifyMotionArgs motionArgs =
3267 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3268 ADISPLAY_ID_DEFAULT, {FOCUSED_WINDOW_LOCATION});
3269 mDispatcher->notifyMotion(&motionArgs);
3270 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3271 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3272
3273 // Touch Window 2
3274 int32_t actionPointerDown =
3275 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
3276
3277 motionArgs =
3278 generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3279 {FOCUSED_WINDOW_LOCATION, UNFOCUSED_WINDOW_LOCATION});
3280 mDispatcher->notifyMotion(&motionArgs);
3281
3282 const std::chrono::duration timeout =
3283 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3284 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3285 mFocusedWindow->getToken());
3286
3287 mUnfocusedWindow->consumeMotionDown();
3288 mFocusedWindow->consumeMotionDown();
3289 // Focused window may or may not receive ACTION_MOVE
3290 // But it should definitely receive ACTION_CANCEL due to the ANR
3291 InputEvent* event;
3292 std::optional<int32_t> moveOrCancelSequenceNum = mFocusedWindow->receiveEvent(&event);
3293 ASSERT_TRUE(moveOrCancelSequenceNum);
3294 mFocusedWindow->finishEvent(*moveOrCancelSequenceNum);
3295 ASSERT_NE(nullptr, event);
3296 ASSERT_EQ(event->getType(), AINPUT_EVENT_TYPE_MOTION);
3297 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
3298 if (motionEvent.getAction() == AMOTION_EVENT_ACTION_MOVE) {
3299 mFocusedWindow->consumeMotionCancel();
3300 } else {
3301 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionEvent.getAction());
3302 }
3303
3304 ASSERT_TRUE(mDispatcher->waitForIdle());
3305 mUnfocusedWindow->assertNoEvents();
3306 mFocusedWindow->assertNoEvents();
3307}
3308
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003309// These tests ensure we cannot send touch events to a window that's positioned behind a window
3310// that has feature NO_INPUT_CHANNEL.
3311// Layout:
3312// Top (closest to user)
3313// mNoInputWindow (above all windows)
3314// mBottomWindow
3315// Bottom (furthest from user)
3316class InputDispatcherMultiWindowOcclusionTests : public InputDispatcherTest {
3317 virtual void SetUp() override {
3318 InputDispatcherTest::SetUp();
3319
3320 mApplication = std::make_shared<FakeApplicationHandle>();
3321 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3322 "Window without input channel", ADISPLAY_ID_DEFAULT,
3323 std::make_optional<sp<IBinder>>(nullptr) /*token*/);
3324
3325 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3326 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3327 // It's perfectly valid for this window to not have an associated input channel
3328
3329 mBottomWindow = new FakeWindowHandle(mApplication, mDispatcher, "Bottom window",
3330 ADISPLAY_ID_DEFAULT);
3331 mBottomWindow->setFrame(Rect(0, 0, 100, 100));
3332
3333 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3334 }
3335
3336protected:
3337 std::shared_ptr<FakeApplicationHandle> mApplication;
3338 sp<FakeWindowHandle> mNoInputWindow;
3339 sp<FakeWindowHandle> mBottomWindow;
3340};
3341
3342TEST_F(InputDispatcherMultiWindowOcclusionTests, NoInputChannelFeature_DropsTouches) {
3343 PointF touchedPoint = {10, 10};
3344
3345 NotifyMotionArgs motionArgs =
3346 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3347 ADISPLAY_ID_DEFAULT, {touchedPoint});
3348 mDispatcher->notifyMotion(&motionArgs);
3349
3350 mNoInputWindow->assertNoEvents();
3351 // Even though the window 'mNoInputWindow' positioned above 'mBottomWindow' does not have
3352 // an input channel, it is not marked as FLAG_NOT_TOUCHABLE,
3353 // and therefore should prevent mBottomWindow from receiving touches
3354 mBottomWindow->assertNoEvents();
3355}
3356
3357/**
3358 * If a window has feature NO_INPUT_CHANNEL, and somehow (by mistake) still has an input channel,
3359 * ensure that this window does not receive any touches, and blocks touches to windows underneath.
3360 */
3361TEST_F(InputDispatcherMultiWindowOcclusionTests,
3362 NoInputChannelFeature_DropsTouchesWithValidChannel) {
3363 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3364 "Window with input channel and NO_INPUT_CHANNEL",
3365 ADISPLAY_ID_DEFAULT);
3366
3367 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3368 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3369 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3370
3371 PointF touchedPoint = {10, 10};
3372
3373 NotifyMotionArgs motionArgs =
3374 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3375 ADISPLAY_ID_DEFAULT, {touchedPoint});
3376 mDispatcher->notifyMotion(&motionArgs);
3377
3378 mNoInputWindow->assertNoEvents();
3379 mBottomWindow->assertNoEvents();
3380}
3381
Garfield Tane84e6f92019-08-29 17:28:41 -07003382} // namespace android::inputdispatcher