blob: dc320036f182aba71fee298d72e5f696f2703c7a [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;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080032using android::os::InputEventInjectionResult;
33using android::os::InputEventInjectionSync;
Michael Wright44753b12020-07-08 13:48:11 +010034using namespace android::flag_operators;
Garfield Tan1c7bc862020-01-28 13:24:04 -080035
Garfield Tane84e6f92019-08-29 17:28:41 -070036namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080037
38// An arbitrary time value.
39static const nsecs_t ARBITRARY_TIME = 1234;
40
41// An arbitrary device id.
42static const int32_t DEVICE_ID = 1;
43
Jeff Brownf086ddb2014-02-11 14:28:48 -080044// An arbitrary display id.
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -080045static const int32_t DISPLAY_ID = ADISPLAY_ID_DEFAULT;
Jeff Brownf086ddb2014-02-11 14:28:48 -080046
Michael Wrightd02c5b62014-02-10 15:10:22 -080047// An arbitrary injector pid / uid pair that has permission to inject events.
48static const int32_t INJECTOR_PID = 999;
49static const int32_t INJECTOR_UID = 1001;
50
chaviwd1c23182019-12-20 18:44:56 -080051struct PointF {
52 float x;
53 float y;
54};
Michael Wrightd02c5b62014-02-10 15:10:22 -080055
Gang Wang342c9272020-01-13 13:15:04 -050056/**
57 * Return a DOWN key event with KEYCODE_A.
58 */
59static KeyEvent getTestKeyEvent() {
60 KeyEvent event;
61
Garfield Tanfbe732e2020-01-24 11:26:14 -080062 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
63 INVALID_HMAC, AKEY_EVENT_ACTION_DOWN, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
64 ARBITRARY_TIME, ARBITRARY_TIME);
Gang Wang342c9272020-01-13 13:15:04 -050065 return event;
66}
67
Michael Wrightd02c5b62014-02-10 15:10:22 -080068// --- FakeInputDispatcherPolicy ---
69
70class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
71 InputDispatcherConfiguration mConfig;
72
73protected:
74 virtual ~FakeInputDispatcherPolicy() {
75 }
76
77public:
78 FakeInputDispatcherPolicy() {
Jackal Guof9696682018-10-05 12:23:23 +080079 }
80
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080081 void assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080082 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_KEY, args.eventTime, args.action,
83 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080084 }
85
Siarhei Vishniakou8935a802019-11-15 16:41:44 -080086 void assertFilterInputEventWasCalled(const NotifyMotionArgs& args) {
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -080087 assertFilterInputEventWasCalled(AINPUT_EVENT_TYPE_MOTION, args.eventTime, args.action,
88 args.displayId);
Jackal Guof9696682018-10-05 12:23:23 +080089 }
90
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070091 void assertFilterInputEventWasNotCalled() {
92 std::scoped_lock lock(mLock);
93 ASSERT_EQ(nullptr, mFilteredEvent);
94 }
Michael Wrightd02c5b62014-02-10 15:10:22 -080095
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080096 void assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -070097 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -080098 ASSERT_TRUE(mConfigurationChangedTime)
99 << "Timed out waiting for configuration changed call";
100 ASSERT_EQ(*mConfigurationChangedTime, when);
101 mConfigurationChangedTime = std::nullopt;
102 }
103
104 void assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700105 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800106 ASSERT_TRUE(mLastNotifySwitch);
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800107 // We do not check id because it is not exposed to the policy
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800108 EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime);
109 EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags);
110 EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues);
111 EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask);
112 mLastNotifySwitch = std::nullopt;
113 }
114
chaviwfd6d3512019-03-25 13:23:49 -0700115 void assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700116 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800117 ASSERT_EQ(touchedToken, mOnPointerDownToken);
118 mOnPointerDownToken.clear();
119 }
120
121 void assertOnPointerDownWasNotCalled() {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700122 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800123 ASSERT_TRUE(mOnPointerDownToken == nullptr)
124 << "Expected onPointerDownOutsideFocus to not have been called";
chaviwfd6d3512019-03-25 13:23:49 -0700125 }
126
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700127 // This function must be called soon after the expected ANR timer starts,
128 // because we are also checking how much time has passed.
Chris Yea209fde2020-07-22 13:54:51 -0700129 void assertNotifyAnrWasCalled(
130 std::chrono::nanoseconds timeout,
131 const std::shared_ptr<InputApplicationHandle>& expectedApplication,
132 const sp<IBinder>& expectedToken) {
133 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700134 ASSERT_NO_FATAL_FAILURE(anrData = getNotifyAnrData(timeout));
135 ASSERT_EQ(expectedApplication, anrData.first);
136 ASSERT_EQ(expectedToken, anrData.second);
137 }
138
Chris Yea209fde2020-07-22 13:54:51 -0700139 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> getNotifyAnrData(
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700140 std::chrono::nanoseconds timeout) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700141 const std::chrono::time_point start = std::chrono::steady_clock::now();
142 std::unique_lock lock(mLock);
143 std::chrono::duration timeToWait = timeout + 100ms; // provide some slack
144 android::base::ScopedLockAssertion assumeLocked(mLock);
145
146 // If there is an ANR, Dispatcher won't be idle because there are still events
147 // in the waitQueue that we need to check on. So we can't wait for dispatcher to be idle
148 // before checking if ANR was called.
149 // Since dispatcher is not guaranteed to call notifyAnr right away, we need to provide
150 // it some time to act. 100ms seems reasonable.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700151 mNotifyAnr.wait_for(lock, timeToWait, [this]() REQUIRES(mLock) {
152 return !mAnrApplications.empty() && !mAnrWindowTokens.empty();
153 });
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700154 const std::chrono::duration waited = std::chrono::steady_clock::now() - start;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700155 if (mAnrApplications.empty() || mAnrWindowTokens.empty()) {
156 ADD_FAILURE() << "Did not receive ANR callback";
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500157 return {};
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700158 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700159 // Ensure that the ANR didn't get raised too early. We can't be too strict here because
160 // the dispatcher started counting before this function was called
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700161 if (std::chrono::abs(timeout - waited) > 100ms) {
162 ADD_FAILURE() << "ANR was raised too early or too late. Expected "
163 << std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count()
164 << "ms, but waited "
165 << std::chrono::duration_cast<std::chrono::milliseconds>(waited).count()
166 << "ms instead";
167 }
Chris Yea209fde2020-07-22 13:54:51 -0700168 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> result =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700169 std::make_pair(mAnrApplications.front(), mAnrWindowTokens.front());
170 mAnrApplications.pop();
171 mAnrWindowTokens.pop();
172 return result;
173 }
174
175 void assertNotifyAnrWasNotCalled() {
176 std::scoped_lock lock(mLock);
177 ASSERT_TRUE(mAnrApplications.empty());
178 ASSERT_TRUE(mAnrWindowTokens.empty());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700179 }
180
Garfield Tan1c7bc862020-01-28 13:24:04 -0800181 void setKeyRepeatConfiguration(nsecs_t timeout, nsecs_t delay) {
182 mConfig.keyRepeatTimeout = timeout;
183 mConfig.keyRepeatDelay = delay;
184 }
185
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700186 void setAnrTimeout(std::chrono::nanoseconds timeout) { mAnrTimeout = timeout; }
187
Michael Wrightd02c5b62014-02-10 15:10:22 -0800188private:
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700189 std::mutex mLock;
190 std::unique_ptr<InputEvent> mFilteredEvent GUARDED_BY(mLock);
191 std::optional<nsecs_t> mConfigurationChangedTime GUARDED_BY(mLock);
192 sp<IBinder> mOnPointerDownToken GUARDED_BY(mLock);
193 std::optional<NotifySwitchArgs> mLastNotifySwitch GUARDED_BY(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800194
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700195 // ANR handling
Chris Yea209fde2020-07-22 13:54:51 -0700196 std::queue<std::shared_ptr<InputApplicationHandle>> mAnrApplications GUARDED_BY(mLock);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700197 std::queue<sp<IBinder>> mAnrWindowTokens GUARDED_BY(mLock);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700198 std::condition_variable mNotifyAnr;
199 std::chrono::nanoseconds mAnrTimeout = 0ms;
200
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800201 virtual void notifyConfigurationChanged(nsecs_t when) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700202 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800203 mConfigurationChangedTime = when;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800204 }
205
Chris Yea209fde2020-07-22 13:54:51 -0700206 std::chrono::nanoseconds notifyAnr(const std::shared_ptr<InputApplicationHandle>& application,
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500207 const sp<IBinder>& windowToken,
208 const std::string&) override {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700209 std::scoped_lock lock(mLock);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700210 mAnrApplications.push(application);
211 mAnrWindowTokens.push(windowToken);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700212 mNotifyAnr.notify_all();
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500213 return mAnrTimeout;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800214 }
215
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700216 virtual void notifyInputChannelBroken(const sp<IBinder>&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700218 virtual void notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) override {}
Robert Carr740167f2018-10-11 19:03:41 -0700219
Bernardo Rufino2e1f6512020-10-08 13:42:07 +0000220 virtual void notifyUntrustedTouch(const std::string& obscuringPackage) override {}
221
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700222 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 *outConfig = mConfig;
224 }
225
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800226 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700227 std::scoped_lock lock(mLock);
Jackal Guof9696682018-10-05 12:23:23 +0800228 switch (inputEvent->getType()) {
229 case AINPUT_EVENT_TYPE_KEY: {
230 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800231 mFilteredEvent = std::make_unique<KeyEvent>(*keyEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800232 break;
233 }
234
235 case AINPUT_EVENT_TYPE_MOTION: {
236 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(inputEvent);
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800237 mFilteredEvent = std::make_unique<MotionEvent>(*motionEvent);
Jackal Guof9696682018-10-05 12:23:23 +0800238 break;
239 }
240 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800241 return true;
242 }
243
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700244 virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800245
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700246 virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800247
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700248 virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&, const KeyEvent*,
249 uint32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800250 return 0;
251 }
252
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700253 virtual bool dispatchUnhandledKey(const sp<IBinder>&, const KeyEvent*, uint32_t,
254 KeyEvent*) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800255 return false;
256 }
257
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800258 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
259 uint32_t policyFlags) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700260 std::scoped_lock lock(mLock);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800261 /** We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
262 * essentially a passthrough for notifySwitch.
263 */
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800264 mLastNotifySwitch = NotifySwitchArgs(1 /*id*/, when, policyFlags, switchValues, switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265 }
266
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700267 virtual void pokeUserActivity(nsecs_t, int32_t) override {}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800268
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700269 virtual bool checkInjectEventsPermissionNonReentrant(int32_t, int32_t) override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800270 return false;
271 }
Jackal Guof9696682018-10-05 12:23:23 +0800272
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -0700273 virtual void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700274 std::scoped_lock lock(mLock);
chaviwfd6d3512019-03-25 13:23:49 -0700275 mOnPointerDownToken = newToken;
276 }
277
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800278 void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
279 int32_t displayId) {
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700280 std::scoped_lock lock(mLock);
Siarhei Vishniakoud99e1b62019-11-26 11:01:06 -0800281 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
282 ASSERT_EQ(mFilteredEvent->getType(), type);
283
284 if (type == AINPUT_EVENT_TYPE_KEY) {
285 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*mFilteredEvent);
286 EXPECT_EQ(keyEvent.getEventTime(), eventTime);
287 EXPECT_EQ(keyEvent.getAction(), action);
288 EXPECT_EQ(keyEvent.getDisplayId(), displayId);
289 } else if (type == AINPUT_EVENT_TYPE_MOTION) {
290 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*mFilteredEvent);
291 EXPECT_EQ(motionEvent.getEventTime(), eventTime);
292 EXPECT_EQ(motionEvent.getAction(), action);
293 EXPECT_EQ(motionEvent.getDisplayId(), displayId);
294 } else {
295 FAIL() << "Unknown type: " << type;
296 }
297
Siarhei Vishniakou8935a802019-11-15 16:41:44 -0800298 mFilteredEvent = nullptr;
Jackal Guof9696682018-10-05 12:23:23 +0800299 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800300};
301
Michael Wrightd02c5b62014-02-10 15:10:22 -0800302// --- InputDispatcherTest ---
303
304class InputDispatcherTest : public testing::Test {
305protected:
306 sp<FakeInputDispatcherPolicy> mFakePolicy;
307 sp<InputDispatcher> mDispatcher;
308
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700309 virtual void SetUp() override {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800310 mFakePolicy = new FakeInputDispatcherPolicy();
311 mDispatcher = new InputDispatcher(mFakePolicy);
Arthur Hungb92218b2018-08-14 12:00:21 +0800312 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
313 //Start InputDispatcher thread
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700314 ASSERT_EQ(OK, mDispatcher->start());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800315 }
316
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700317 virtual void TearDown() override {
318 ASSERT_EQ(OK, mDispatcher->stop());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800319 mFakePolicy.clear();
320 mDispatcher.clear();
321 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700322
323 /**
324 * Used for debugging when writing the test
325 */
326 void dumpDispatcherState() {
327 std::string dump;
328 mDispatcher->dump(dump);
329 std::stringstream ss(dump);
330 std::string to;
331
332 while (std::getline(ss, to, '\n')) {
333 ALOGE("%s", to.c_str());
334 }
335 }
Vishnu Nair958da932020-08-21 17:12:37 -0700336
337 void setFocusedWindow(const sp<InputWindowHandle>& window,
338 const sp<InputWindowHandle>& focusedWindow = nullptr) {
339 FocusRequest request;
340 request.token = window->getToken();
341 if (focusedWindow) {
342 request.focusedToken = focusedWindow->getToken();
343 }
344 request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
345 request.displayId = window->getInfo()->displayId;
346 mDispatcher->setFocusedWindow(request);
347 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800348};
349
350
351TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
352 KeyEvent event;
353
354 // Rejects undefined key actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800355 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
356 INVALID_HMAC,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600357 /*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME,
358 ARBITRARY_TIME);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800359 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700360 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800361 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800362 << "Should reject key events with undefined action.";
363
364 // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800365 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
366 INVALID_HMAC, AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600367 ARBITRARY_TIME, ARBITRARY_TIME);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800368 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700369 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800370 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800371 << "Should reject key events with ACTION_MULTIPLE.";
372}
373
374TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
375 MotionEvent event;
376 PointerProperties pointerProperties[MAX_POINTERS + 1];
377 PointerCoords pointerCoords[MAX_POINTERS + 1];
378 for (int i = 0; i <= MAX_POINTERS; i++) {
379 pointerProperties[i].clear();
380 pointerProperties[i].id = i;
381 pointerCoords[i].clear();
382 }
383
Siarhei Vishniakou49e59222018-12-28 18:17:15 -0800384 // Some constants commonly used below
385 constexpr int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
386 constexpr int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
387 constexpr int32_t metaState = AMETA_NONE;
388 constexpr MotionClassification classification = MotionClassification::NONE;
389
chaviw9eaa22c2020-07-01 16:21:27 -0700390 ui::Transform identityTransform;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800391 // Rejects undefined motion actions.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800392 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
chaviw9eaa22c2020-07-01 16:21:27 -0700393 /*action*/ -1, 0, 0, edgeFlags, metaState, 0, classification,
394 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600395 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700396 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800397 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700398 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800399 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800400 << "Should reject motion events with undefined action.";
401
402 // Rejects pointer down with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800403 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700404 AMOTION_EVENT_ACTION_POINTER_DOWN |
405 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700406 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
407 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
408 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
409 pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800410 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700411 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800412 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800413 << "Should reject motion events with pointer down index too large.";
414
Garfield Tanfbe732e2020-01-24 11:26:14 -0800415 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700416 AMOTION_EVENT_ACTION_POINTER_DOWN |
417 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700418 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
419 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
420 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
421 pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800422 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700423 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800424 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800425 << "Should reject motion events with pointer down index too small.";
426
427 // Rejects pointer up with invalid index.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800428 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700429 AMOTION_EVENT_ACTION_POINTER_UP |
430 (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700431 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
432 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
433 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
434 pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800435 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700436 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800437 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800438 << "Should reject motion events with pointer up index too large.";
439
Garfield Tanfbe732e2020-01-24 11:26:14 -0800440 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
Garfield Tan00f511d2019-06-12 16:55:40 -0700441 AMOTION_EVENT_ACTION_POINTER_UP |
442 (~0U << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
chaviw9eaa22c2020-07-01 16:21:27 -0700443 0, 0, edgeFlags, metaState, 0, classification, identityTransform, 0, 0,
444 AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
445 ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
446 pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800447 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700448 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800449 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800450 << "Should reject motion events with pointer up index too small.";
451
452 // Rejects motion events with invalid number of pointers.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800453 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
454 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700455 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
456 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700457 /*pointerCount*/ 0, pointerProperties, pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800458 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700459 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800460 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800461 << "Should reject motion events with 0 pointers.";
462
Garfield Tanfbe732e2020-01-24 11:26:14 -0800463 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
464 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700465 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
466 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700467 /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800468 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700469 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800470 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800471 << "Should reject motion events with more than MAX_POINTERS pointers.";
472
473 // Rejects motion events with invalid pointer ids.
474 pointerProperties[0].id = -1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800475 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
476 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700477 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
478 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700479 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800480 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700481 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800482 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800483 << "Should reject motion events with pointer ids less than 0.";
484
485 pointerProperties[0].id = MAX_POINTER_ID + 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800486 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
487 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700488 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
489 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700490 /*pointerCount*/ 1, pointerProperties, pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800491 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700492 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800493 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800494 << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
495
496 // Rejects motion events with duplicate pointer ids.
497 pointerProperties[0].id = 1;
498 pointerProperties[1].id = 1;
Garfield Tanfbe732e2020-01-24 11:26:14 -0800499 event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
500 AMOTION_EVENT_ACTION_DOWN, 0, 0, edgeFlags, metaState, 0, classification,
chaviw9eaa22c2020-07-01 16:21:27 -0700501 identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
502 AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
Garfield Tan00f511d2019-06-12 16:55:40 -0700503 /*pointerCount*/ 2, pointerProperties, pointerCoords);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800504 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700505 mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800506 InputEventInjectionSync::NONE, 0ms, 0))
Michael Wrightd02c5b62014-02-10 15:10:22 -0800507 << "Should reject motion events with duplicate pointer ids.";
508}
509
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800510/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
511
512TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
513 constexpr nsecs_t eventTime = 20;
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800514 NotifyConfigurationChangedArgs args(10 /*id*/, eventTime);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800515 mDispatcher->notifyConfigurationChanged(&args);
516 ASSERT_TRUE(mDispatcher->waitForIdle());
517
518 mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
519}
520
521TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
Garfield Tanc51d1ba2020-01-28 13:24:04 -0800522 NotifySwitchArgs args(10 /*id*/, 20 /*eventTime*/, 0 /*policyFlags*/, 1 /*switchValues*/,
523 2 /*switchMask*/);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800524 mDispatcher->notifySwitch(&args);
525
526 // InputDispatcher adds POLICY_FLAG_TRUSTED because the event went through InputListener
527 args.policyFlags |= POLICY_FLAG_TRUSTED;
528 mFakePolicy->assertNotifySwitchWasCalled(args);
529}
530
Arthur Hungb92218b2018-08-14 12:00:21 +0800531// --- InputDispatcherTest SetInputWindowTest ---
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700532static constexpr std::chrono::duration INJECT_EVENT_TIMEOUT = 500ms;
Siarhei Vishniakoucd899e82020-05-08 09:24:29 -0700533static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
Arthur Hungb92218b2018-08-14 12:00:21 +0800534
535class FakeApplicationHandle : public InputApplicationHandle {
536public:
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700537 FakeApplicationHandle() {
538 mInfo.name = "Fake Application";
539 mInfo.token = new BBinder();
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500540 mInfo.dispatchingTimeoutMillis =
541 std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700542 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800543 virtual ~FakeApplicationHandle() {}
544
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -0700545 virtual bool updateInfo() override {
Arthur Hungb92218b2018-08-14 12:00:21 +0800546 return true;
547 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700548
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500549 void setDispatchingTimeout(std::chrono::milliseconds timeout) {
550 mInfo.dispatchingTimeoutMillis = timeout.count();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700551 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800552};
553
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800554class FakeInputReceiver {
Arthur Hungb92218b2018-08-14 12:00:21 +0800555public:
Garfield Tan15601662020-09-22 15:32:38 -0700556 explicit FakeInputReceiver(std::unique_ptr<InputChannel> clientChannel, const std::string name)
chaviwd1c23182019-12-20 18:44:56 -0800557 : mName(name) {
Garfield Tan15601662020-09-22 15:32:38 -0700558 mConsumer = std::make_unique<InputConsumer>(std::move(clientChannel));
chaviwd1c23182019-12-20 18:44:56 -0800559 }
560
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800561 InputEvent* consume() {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700562 InputEvent* event;
563 std::optional<uint32_t> consumeSeq = receiveEvent(&event);
564 if (!consumeSeq) {
565 return nullptr;
566 }
567 finishEvent(*consumeSeq);
568 return event;
569 }
570
571 /**
572 * Receive an event without acknowledging it.
573 * Return the sequence number that could later be used to send finished signal.
574 */
575 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800576 uint32_t consumeSeq;
577 InputEvent* event;
Arthur Hungb92218b2018-08-14 12:00:21 +0800578
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800579 std::chrono::time_point start = std::chrono::steady_clock::now();
580 status_t status = WOULD_BLOCK;
581 while (status == WOULD_BLOCK) {
chaviw81e2bb92019-12-18 15:03:51 -0800582 status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq,
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800583 &event);
584 std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
585 if (elapsed > 100ms) {
586 break;
587 }
588 }
589
590 if (status == WOULD_BLOCK) {
591 // Just means there's no event available.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700592 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800593 }
594
595 if (status != OK) {
596 ADD_FAILURE() << mName.c_str() << ": consumer consume should return OK.";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700597 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800598 }
599 if (event == nullptr) {
600 ADD_FAILURE() << "Consumed correctly, but received NULL event from consumer";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700601 return std::nullopt;
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800602 }
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700603 if (outEvent != nullptr) {
604 *outEvent = event;
605 }
606 return consumeSeq;
607 }
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800608
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700609 /**
610 * To be used together with "receiveEvent" to complete the consumption of an event.
611 */
612 void finishEvent(uint32_t consumeSeq) {
613 const status_t status = mConsumer->sendFinishedSignal(consumeSeq, true);
614 ASSERT_EQ(OK, status) << mName.c_str() << ": consumer sendFinishedSignal should return OK.";
Siarhei Vishniakou08b574f2019-11-15 18:05:52 -0800615 }
616
617 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
618 int32_t expectedFlags) {
619 InputEvent* event = consume();
620
621 ASSERT_NE(nullptr, event) << mName.c_str()
622 << ": consumer should have returned non-NULL event.";
Arthur Hungb92218b2018-08-14 12:00:21 +0800623 ASSERT_EQ(expectedEventType, event->getType())
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700624 << mName.c_str() << " expected " << inputEventTypeToString(expectedEventType)
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800625 << " event, got " << inputEventTypeToString(event->getType()) << " event";
Arthur Hungb92218b2018-08-14 12:00:21 +0800626
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800627 EXPECT_EQ(expectedDisplayId, event->getDisplayId());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800628
Tiger Huang8664f8c2018-10-11 19:14:35 +0800629 switch (expectedEventType) {
630 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800631 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(*event);
632 EXPECT_EQ(expectedAction, keyEvent.getAction());
633 EXPECT_EQ(expectedFlags, keyEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800634 break;
635 }
636 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800637 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
638 EXPECT_EQ(expectedAction, motionEvent.getAction());
639 EXPECT_EQ(expectedFlags, motionEvent.getFlags());
Tiger Huang8664f8c2018-10-11 19:14:35 +0800640 break;
641 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100642 case AINPUT_EVENT_TYPE_FOCUS: {
643 FAIL() << "Use 'consumeFocusEvent' for FOCUS events";
644 }
Tiger Huang8664f8c2018-10-11 19:14:35 +0800645 default: {
646 FAIL() << mName.c_str() << ": invalid event type: " << expectedEventType;
647 }
648 }
Arthur Hungb92218b2018-08-14 12:00:21 +0800649 }
650
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100651 void consumeFocusEvent(bool hasFocus, bool inTouchMode) {
652 InputEvent* event = consume();
653 ASSERT_NE(nullptr, event) << mName.c_str()
654 << ": consumer should have returned non-NULL event.";
655 ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, event->getType())
656 << "Got " << inputEventTypeToString(event->getType())
657 << " event instead of FOCUS event";
658
659 ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId())
660 << mName.c_str() << ": event displayId should always be NONE.";
661
662 FocusEvent* focusEvent = static_cast<FocusEvent*>(event);
663 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
664 EXPECT_EQ(inTouchMode, focusEvent->getInTouchMode());
665 }
666
chaviwd1c23182019-12-20 18:44:56 -0800667 void assertNoEvents() {
668 InputEvent* event = consume();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700669 if (event == nullptr) {
670 return;
671 }
672 if (event->getType() == AINPUT_EVENT_TYPE_KEY) {
673 KeyEvent& keyEvent = static_cast<KeyEvent&>(*event);
674 ADD_FAILURE() << "Received key event "
675 << KeyEvent::actionToString(keyEvent.getAction());
676 } else if (event->getType() == AINPUT_EVENT_TYPE_MOTION) {
677 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
678 ADD_FAILURE() << "Received motion event "
679 << MotionEvent::actionToString(motionEvent.getAction());
680 } else if (event->getType() == AINPUT_EVENT_TYPE_FOCUS) {
681 FocusEvent& focusEvent = static_cast<FocusEvent&>(*event);
682 ADD_FAILURE() << "Received focus event, hasFocus = "
683 << (focusEvent.getHasFocus() ? "true" : "false");
684 }
685 FAIL() << mName.c_str()
686 << ": should not have received any events, so consume() should return NULL";
chaviwd1c23182019-12-20 18:44:56 -0800687 }
688
689 sp<IBinder> getToken() { return mConsumer->getChannel()->getConnectionToken(); }
690
691protected:
692 std::unique_ptr<InputConsumer> mConsumer;
693 PreallocatedInputEventFactory mEventFactory;
694
695 std::string mName;
696};
697
698class FakeWindowHandle : public InputWindowHandle {
699public:
700 static const int32_t WIDTH = 600;
701 static const int32_t HEIGHT = 800;
chaviwd1c23182019-12-20 18:44:56 -0800702
Chris Yea209fde2020-07-22 13:54:51 -0700703 FakeWindowHandle(const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle,
chaviwd1c23182019-12-20 18:44:56 -0800704 const sp<InputDispatcher>& dispatcher, const std::string name,
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500705 int32_t displayId, std::optional<sp<IBinder>> token = std::nullopt)
chaviwd1c23182019-12-20 18:44:56 -0800706 : mName(name) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500707 if (token == std::nullopt) {
Garfield Tan15601662020-09-22 15:32:38 -0700708 base::Result<std::unique_ptr<InputChannel>> channel =
709 dispatcher->createInputChannel(name);
710 token = (*channel)->getConnectionToken();
711 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
chaviwd1c23182019-12-20 18:44:56 -0800712 }
713
714 inputApplicationHandle->updateInfo();
715 mInfo.applicationInfo = *inputApplicationHandle->getInfo();
716
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500717 mInfo.token = *token;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700718 mInfo.id = sId++;
chaviwd1c23182019-12-20 18:44:56 -0800719 mInfo.name = name;
Michael Wright44753b12020-07-08 13:48:11 +0100720 mInfo.type = InputWindowInfo::Type::APPLICATION;
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500721 mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
chaviwd1c23182019-12-20 18:44:56 -0800722 mInfo.frameLeft = 0;
723 mInfo.frameTop = 0;
724 mInfo.frameRight = WIDTH;
725 mInfo.frameBottom = HEIGHT;
chaviw1ff3d1e2020-07-01 15:53:47 -0700726 mInfo.transform.set(0, 0);
chaviwd1c23182019-12-20 18:44:56 -0800727 mInfo.globalScaleFactor = 1.0;
728 mInfo.touchableRegion.clear();
729 mInfo.addTouchableRegion(Rect(0, 0, WIDTH, HEIGHT));
730 mInfo.visible = true;
Vishnu Nair47074b82020-08-14 11:54:47 -0700731 mInfo.focusable = false;
chaviwd1c23182019-12-20 18:44:56 -0800732 mInfo.hasWallpaper = false;
733 mInfo.paused = false;
chaviwd1c23182019-12-20 18:44:56 -0800734 mInfo.ownerPid = INJECTOR_PID;
735 mInfo.ownerUid = INJECTOR_UID;
chaviwd1c23182019-12-20 18:44:56 -0800736 mInfo.displayId = displayId;
737 }
738
739 virtual bool updateInfo() { return true; }
740
Vishnu Nair47074b82020-08-14 11:54:47 -0700741 void setFocusable(bool focusable) { mInfo.focusable = focusable; }
chaviwd1c23182019-12-20 18:44:56 -0800742
Vishnu Nair958da932020-08-21 17:12:37 -0700743 void setVisible(bool visible) { mInfo.visible = visible; }
744
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700745 void setDispatchingTimeout(std::chrono::nanoseconds timeout) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500746 mInfo.dispatchingTimeout = timeout;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700747 }
748
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700749 void setPaused(bool paused) { mInfo.paused = paused; }
750
chaviwd1c23182019-12-20 18:44:56 -0800751 void setFrame(const Rect& frame) {
752 mInfo.frameLeft = frame.left;
753 mInfo.frameTop = frame.top;
754 mInfo.frameRight = frame.right;
755 mInfo.frameBottom = frame.bottom;
chaviw1ff3d1e2020-07-01 15:53:47 -0700756 mInfo.transform.set(frame.left, frame.top);
chaviwd1c23182019-12-20 18:44:56 -0800757 mInfo.touchableRegion.clear();
758 mInfo.addTouchableRegion(frame);
759 }
760
Michael Wright44753b12020-07-08 13:48:11 +0100761 void setFlags(Flags<InputWindowInfo::Flag> flags) { mInfo.flags = flags; }
chaviwd1c23182019-12-20 18:44:56 -0800762
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500763 void setInputFeatures(InputWindowInfo::Feature features) { mInfo.inputFeatures = features; }
764
chaviw9eaa22c2020-07-01 16:21:27 -0700765 void setWindowTransform(float dsdx, float dtdx, float dtdy, float dsdy) {
766 mInfo.transform.set(dsdx, dtdx, dtdy, dsdy);
767 }
768
769 void setWindowScale(float xScale, float yScale) { setWindowTransform(xScale, 0, 0, yScale); }
chaviwaf87b3e2019-10-01 16:59:28 -0700770
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800771 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
772 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
773 expectedFlags);
774 }
775
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700776 void consumeKeyUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
777 consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, expectedDisplayId, expectedFlags);
778 }
779
Svet Ganov5d3bc372020-01-26 23:11:07 -0800780 void consumeMotionCancel(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
781 int32_t expectedFlags = 0) {
782 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, expectedDisplayId,
783 expectedFlags);
784 }
785
786 void consumeMotionMove(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
787 int32_t expectedFlags = 0) {
788 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, expectedDisplayId,
789 expectedFlags);
790 }
791
792 void consumeMotionDown(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
793 int32_t expectedFlags = 0) {
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -0800794 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, expectedDisplayId,
795 expectedFlags);
796 }
797
Svet Ganov5d3bc372020-01-26 23:11:07 -0800798 void consumeMotionPointerDown(int32_t pointerIdx,
799 int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT, int32_t expectedFlags = 0) {
800 int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN
801 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
802 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
803 }
804
805 void consumeMotionPointerUp(int32_t pointerIdx, int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
806 int32_t expectedFlags = 0) {
807 int32_t action = AMOTION_EVENT_ACTION_POINTER_UP
808 | (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
809 consumeEvent(AINPUT_EVENT_TYPE_MOTION, action, expectedDisplayId, expectedFlags);
810 }
811
812 void consumeMotionUp(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
813 int32_t expectedFlags = 0) {
Michael Wright3a240c42019-12-10 20:53:41 +0000814 consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP, expectedDisplayId,
815 expectedFlags);
816 }
817
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100818 void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
819 ASSERT_NE(mInputReceiver, nullptr)
820 << "Cannot consume events from a window with no receiver";
821 mInputReceiver->consumeFocusEvent(hasFocus, inTouchMode);
822 }
823
chaviwd1c23182019-12-20 18:44:56 -0800824 void consumeEvent(int32_t expectedEventType, int32_t expectedAction, int32_t expectedDisplayId,
825 int32_t expectedFlags) {
826 ASSERT_NE(mInputReceiver, nullptr) << "Invalid consume event on window with no receiver";
827 mInputReceiver->consumeEvent(expectedEventType, expectedAction, expectedDisplayId,
828 expectedFlags);
829 }
830
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700831 std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700832 if (mInputReceiver == nullptr) {
833 ADD_FAILURE() << "Invalid receive event on window with no receiver";
834 return std::nullopt;
835 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700836 return mInputReceiver->receiveEvent(outEvent);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700837 }
838
839 void finishEvent(uint32_t sequenceNum) {
840 ASSERT_NE(mInputReceiver, nullptr) << "Invalid receive event on window with no receiver";
841 mInputReceiver->finishEvent(sequenceNum);
842 }
843
chaviwaf87b3e2019-10-01 16:59:28 -0700844 InputEvent* consume() {
845 if (mInputReceiver == nullptr) {
846 return nullptr;
847 }
848 return mInputReceiver->consume();
849 }
850
Arthur Hungb92218b2018-08-14 12:00:21 +0800851 void assertNoEvents() {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -0500852 if (mInputReceiver == nullptr &&
853 mInfo.inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL)) {
854 return; // Can't receive events if the window does not have input channel
855 }
856 ASSERT_NE(nullptr, mInputReceiver)
857 << "Window without InputReceiver must specify feature NO_INPUT_CHANNEL";
chaviwd1c23182019-12-20 18:44:56 -0800858 mInputReceiver->assertNoEvents();
Arthur Hungb92218b2018-08-14 12:00:21 +0800859 }
860
chaviwaf87b3e2019-10-01 16:59:28 -0700861 sp<IBinder> getToken() { return mInfo.token; }
862
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100863 const std::string& getName() { return mName; }
864
chaviwd1c23182019-12-20 18:44:56 -0800865private:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100866 const std::string mName;
chaviwd1c23182019-12-20 18:44:56 -0800867 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700868 static std::atomic<int32_t> sId; // each window gets a unique id, like in surfaceflinger
Arthur Hung2fbf37f2018-09-13 18:16:41 +0800869};
870
Siarhei Vishniakou540dbae2020-05-05 18:17:17 -0700871std::atomic<int32_t> FakeWindowHandle::sId{1};
872
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800873static InputEventInjectionResult injectKey(
874 const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount,
875 int32_t displayId = ADISPLAY_ID_NONE,
876 InputEventInjectionSync syncMode = InputEventInjectionSync::WAIT_FOR_RESULT,
877 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) {
Arthur Hungb92218b2018-08-14 12:00:21 +0800878 KeyEvent event;
879 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
880
881 // Define a valid key down event.
Garfield Tanfbe732e2020-01-24 11:26:14 -0800882 event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700883 INVALID_HMAC, action, /* flags */ 0, AKEYCODE_A, KEY_A, AMETA_NONE,
884 repeatCount, currentTime, currentTime);
Arthur Hungb92218b2018-08-14 12:00:21 +0800885
886 // Inject event until dispatch out.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700887 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, syncMode,
888 injectionTimeout,
889 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
Arthur Hungb92218b2018-08-14 12:00:21 +0800890}
891
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800892static InputEventInjectionResult injectKeyDown(const sp<InputDispatcher>& dispatcher,
893 int32_t displayId = ADISPLAY_ID_NONE) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -0700894 return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId);
895}
896
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -0800897static InputEventInjectionResult injectKeyUp(const sp<InputDispatcher>& dispatcher,
898 int32_t displayId = ADISPLAY_ID_NONE) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700899 return injectKey(dispatcher, AKEY_EVENT_ACTION_UP, /* repeatCount */ 0, displayId);
900}
901
Garfield Tandf26e862020-07-01 20:18:19 -0700902class PointerBuilder {
903public:
904 PointerBuilder(int32_t id, int32_t toolType) {
905 mProperties.clear();
906 mProperties.id = id;
907 mProperties.toolType = toolType;
908 mCoords.clear();
909 }
910
911 PointerBuilder& x(float x) { return axis(AMOTION_EVENT_AXIS_X, x); }
912
913 PointerBuilder& y(float y) { return axis(AMOTION_EVENT_AXIS_Y, y); }
914
915 PointerBuilder& axis(int32_t axis, float value) {
916 mCoords.setAxisValue(axis, value);
917 return *this;
918 }
919
920 PointerProperties buildProperties() const { return mProperties; }
921
922 PointerCoords buildCoords() const { return mCoords; }
923
924private:
925 PointerProperties mProperties;
926 PointerCoords mCoords;
927};
928
929class MotionEventBuilder {
930public:
931 MotionEventBuilder(int32_t action, int32_t source) {
932 mAction = action;
933 mSource = source;
934 mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
935 }
936
937 MotionEventBuilder& eventTime(nsecs_t eventTime) {
938 mEventTime = eventTime;
939 return *this;
940 }
941
942 MotionEventBuilder& displayId(int32_t displayId) {
943 mDisplayId = displayId;
944 return *this;
945 }
946
947 MotionEventBuilder& actionButton(int32_t actionButton) {
948 mActionButton = actionButton;
949 return *this;
950 }
951
952 MotionEventBuilder& buttonState(int32_t actionButton) {
953 mActionButton = actionButton;
954 return *this;
955 }
956
957 MotionEventBuilder& rawXCursorPosition(float rawXCursorPosition) {
958 mRawXCursorPosition = rawXCursorPosition;
959 return *this;
960 }
961
962 MotionEventBuilder& rawYCursorPosition(float rawYCursorPosition) {
963 mRawYCursorPosition = rawYCursorPosition;
964 return *this;
965 }
966
967 MotionEventBuilder& pointer(PointerBuilder pointer) {
968 mPointers.push_back(pointer);
969 return *this;
970 }
971
972 MotionEvent build() {
973 std::vector<PointerProperties> pointerProperties;
974 std::vector<PointerCoords> pointerCoords;
975 for (const PointerBuilder& pointer : mPointers) {
976 pointerProperties.push_back(pointer.buildProperties());
977 pointerCoords.push_back(pointer.buildCoords());
978 }
979
980 // Set mouse cursor position for the most common cases to avoid boilerplate.
981 if (mSource == AINPUT_SOURCE_MOUSE &&
982 !MotionEvent::isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition) &&
983 mPointers.size() == 1) {
984 mRawXCursorPosition = pointerCoords[0].getX();
985 mRawYCursorPosition = pointerCoords[0].getY();
986 }
987
988 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -0700989 ui::Transform identityTransform;
Garfield Tandf26e862020-07-01 20:18:19 -0700990 event.initialize(InputEvent::nextId(), DEVICE_ID, mSource, mDisplayId, INVALID_HMAC,
991 mAction, mActionButton, /* flags */ 0, /* edgeFlags */ 0, AMETA_NONE,
chaviw9eaa22c2020-07-01 16:21:27 -0700992 mButtonState, MotionClassification::NONE, identityTransform,
993 /* xPrecision */ 0, /* yPrecision */ 0, mRawXCursorPosition,
994 mRawYCursorPosition, mEventTime, mEventTime, mPointers.size(),
995 pointerProperties.data(), pointerCoords.data());
Garfield Tandf26e862020-07-01 20:18:19 -0700996
997 return event;
998 }
999
1000private:
1001 int32_t mAction;
1002 int32_t mSource;
1003 nsecs_t mEventTime;
1004 int32_t mDisplayId{ADISPLAY_ID_DEFAULT};
1005 int32_t mActionButton{0};
1006 int32_t mButtonState{0};
1007 float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1008 float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
1009
1010 std::vector<PointerBuilder> mPointers;
1011};
1012
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001013static InputEventInjectionResult injectMotionEvent(
Garfield Tandf26e862020-07-01 20:18:19 -07001014 const sp<InputDispatcher>& dispatcher, const MotionEvent& event,
1015 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001016 InputEventInjectionSync injectionMode = InputEventInjectionSync::WAIT_FOR_RESULT) {
Garfield Tandf26e862020-07-01 20:18:19 -07001017 return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, injectionMode,
1018 injectionTimeout,
1019 POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
1020}
1021
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001022static InputEventInjectionResult injectMotionEvent(
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001023 const sp<InputDispatcher>& dispatcher, int32_t action, int32_t source, int32_t displayId,
1024 const PointF& position,
1025 const PointF& cursorPosition = {AMOTION_EVENT_INVALID_CURSOR_POSITION,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001026 AMOTION_EVENT_INVALID_CURSOR_POSITION},
1027 std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001028 InputEventInjectionSync injectionMode = InputEventInjectionSync::WAIT_FOR_RESULT,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001029 nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC)) {
Garfield Tandf26e862020-07-01 20:18:19 -07001030 MotionEvent event = MotionEventBuilder(action, source)
1031 .displayId(displayId)
1032 .eventTime(eventTime)
1033 .rawXCursorPosition(cursorPosition.x)
1034 .rawYCursorPosition(cursorPosition.y)
1035 .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER)
1036 .x(position.x)
1037 .y(position.y))
1038 .build();
Arthur Hungb92218b2018-08-14 12:00:21 +08001039
1040 // Inject event until dispatch out.
Garfield Tandf26e862020-07-01 20:18:19 -07001041 return injectMotionEvent(dispatcher, event);
Arthur Hungb92218b2018-08-14 12:00:21 +08001042}
1043
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001044static InputEventInjectionResult injectMotionDown(const sp<InputDispatcher>& dispatcher,
1045 int32_t source, int32_t displayId,
1046 const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001047 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, location);
Garfield Tan00f511d2019-06-12 16:55:40 -07001048}
1049
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001050static InputEventInjectionResult injectMotionUp(const sp<InputDispatcher>& dispatcher,
1051 int32_t source, int32_t displayId,
1052 const PointF& location = {100, 200}) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001053 return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, location);
Michael Wright3a240c42019-12-10 20:53:41 +00001054}
1055
Jackal Guof9696682018-10-05 12:23:23 +08001056static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLAY_ID_NONE) {
1057 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1058 // Define a valid key event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001059 NotifyKeyArgs args(/* id */ 0, currentTime, DEVICE_ID, AINPUT_SOURCE_KEYBOARD, displayId,
1060 POLICY_FLAG_PASS_TO_USER, action, /* flags */ 0, AKEYCODE_A, KEY_A,
1061 AMETA_NONE, currentTime);
Jackal Guof9696682018-10-05 12:23:23 +08001062
1063 return args;
1064}
1065
chaviwd1c23182019-12-20 18:44:56 -08001066static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId,
1067 const std::vector<PointF>& points) {
1068 size_t pointerCount = points.size();
chaviwaf87b3e2019-10-01 16:59:28 -07001069 if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_UP) {
1070 EXPECT_EQ(1U, pointerCount) << "Actions DOWN and UP can only contain a single pointer";
1071 }
1072
chaviwd1c23182019-12-20 18:44:56 -08001073 PointerProperties pointerProperties[pointerCount];
1074 PointerCoords pointerCoords[pointerCount];
Jackal Guof9696682018-10-05 12:23:23 +08001075
chaviwd1c23182019-12-20 18:44:56 -08001076 for (size_t i = 0; i < pointerCount; i++) {
1077 pointerProperties[i].clear();
1078 pointerProperties[i].id = i;
1079 pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
Jackal Guof9696682018-10-05 12:23:23 +08001080
chaviwd1c23182019-12-20 18:44:56 -08001081 pointerCoords[i].clear();
1082 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, points[i].x);
1083 pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, points[i].y);
1084 }
Jackal Guof9696682018-10-05 12:23:23 +08001085
1086 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1087 // Define a valid motion event.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001088 NotifyMotionArgs args(/* id */ 0, currentTime, DEVICE_ID, source, displayId,
Garfield Tan00f511d2019-06-12 16:55:40 -07001089 POLICY_FLAG_PASS_TO_USER, action, /* actionButton */ 0, /* flags */ 0,
1090 AMETA_NONE, /* buttonState */ 0, MotionClassification::NONE,
chaviwd1c23182019-12-20 18:44:56 -08001091 AMOTION_EVENT_EDGE_FLAG_NONE, pointerCount, pointerProperties,
1092 pointerCoords, /* xPrecision */ 0, /* yPrecision */ 0,
Garfield Tan00f511d2019-06-12 16:55:40 -07001093 AMOTION_EVENT_INVALID_CURSOR_POSITION,
1094 AMOTION_EVENT_INVALID_CURSOR_POSITION, currentTime, /* videoFrames */ {});
Jackal Guof9696682018-10-05 12:23:23 +08001095
1096 return args;
1097}
1098
chaviwd1c23182019-12-20 18:44:56 -08001099static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source, int32_t displayId) {
1100 return generateMotionArgs(action, source, displayId, {PointF{100, 200}});
1101}
1102
Arthur Hungb92218b2018-08-14 12:00:21 +08001103TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001104 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001105 sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
1106 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001107
Arthur Hung72d8dc32020-03-28 00:48:39 +00001108 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001109 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
1110 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1111 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Arthur Hungb92218b2018-08-14 12:00:21 +08001112
1113 // Window should receive motion event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001114 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001115}
1116
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001117/**
1118 * Calling setInputWindows once with FLAG_NOT_TOUCH_MODAL should not cause any issues.
1119 * To ensure that window receives only events that were directly inside of it, add
1120 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1121 * when finding touched windows.
1122 * This test serves as a sanity check for the next test, where setInputWindows is
1123 * called twice.
1124 */
1125TEST_F(InputDispatcherTest, SetInputWindowOnce_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001126 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001127 sp<FakeWindowHandle> window =
1128 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1129 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001130 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001131
1132 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001133 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001134 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1135 {50, 50}))
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001136 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001137
1138 // Window should receive motion event.
1139 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1140}
1141
1142/**
1143 * Calling setInputWindows twice, with the same info, should not cause any issues.
1144 * To ensure that window receives only events that were directly inside of it, add
1145 * FLAG_NOT_TOUCH_MODAL. This will enforce using the touchableRegion of the input
1146 * when finding touched windows.
1147 */
1148TEST_F(InputDispatcherTest, SetInputWindowTwice_SingleWindowTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001149 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001150 sp<FakeWindowHandle> window =
1151 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1152 window->setFrame(Rect(0, 0, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01001153 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001154
1155 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1156 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001157 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001158 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
1159 {50, 50}))
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001160 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07001161
1162 // Window should receive motion event.
1163 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1164}
1165
Arthur Hungb92218b2018-08-14 12:00:21 +08001166// The foreground window should receive the first touch down event.
1167TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001168 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001169 sp<FakeWindowHandle> windowTop = new FakeWindowHandle(application, mDispatcher, "Top",
1170 ADISPLAY_ID_DEFAULT);
1171 sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
1172 ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001173
Arthur Hung72d8dc32020-03-28 00:48:39 +00001174 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001175 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
1176 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
1177 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Arthur Hungb92218b2018-08-14 12:00:21 +08001178
1179 // Top window should receive the touch down event. Second window should not receive anything.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001180 windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08001181 windowSecond->assertNoEvents();
1182}
1183
Garfield Tandf26e862020-07-01 20:18:19 -07001184TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001185 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001186 sp<FakeWindowHandle> windowLeft =
1187 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1188 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001189 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001190 sp<FakeWindowHandle> windowRight =
1191 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1192 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001193 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001194
1195 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1196
1197 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
1198
1199 // Start cursor position in right window so that we can move the cursor to left window.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001200 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001201 injectMotionEvent(mDispatcher,
1202 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1203 AINPUT_SOURCE_MOUSE)
1204 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1205 .x(900)
1206 .y(400))
1207 .build()));
1208 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1209 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1210 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1211 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1212
1213 // Move cursor into left window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001214 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001215 injectMotionEvent(mDispatcher,
1216 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1217 AINPUT_SOURCE_MOUSE)
1218 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1219 .x(300)
1220 .y(400))
1221 .build()));
1222 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1223 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1224 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1225 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1226 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1227 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1228
1229 // Inject a series of mouse events for a mouse click
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001230 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001231 injectMotionEvent(mDispatcher,
1232 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1233 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1234 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1235 .x(300)
1236 .y(400))
1237 .build()));
1238 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1239
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001240 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001241 injectMotionEvent(mDispatcher,
1242 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1243 AINPUT_SOURCE_MOUSE)
1244 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1245 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1246 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1247 .x(300)
1248 .y(400))
1249 .build()));
1250 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1251 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1252
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001253 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001254 injectMotionEvent(mDispatcher,
1255 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1256 AINPUT_SOURCE_MOUSE)
1257 .buttonState(0)
1258 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1259 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1260 .x(300)
1261 .y(400))
1262 .build()));
1263 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1264 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1265
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001266 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001267 injectMotionEvent(mDispatcher,
1268 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1269 .buttonState(0)
1270 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1271 .x(300)
1272 .y(400))
1273 .build()));
1274 windowLeft->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1275
1276 // Move mouse cursor back to right window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001277 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001278 injectMotionEvent(mDispatcher,
1279 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
1280 AINPUT_SOURCE_MOUSE)
1281 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1282 .x(900)
1283 .y(400))
1284 .build()));
1285 windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1286 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1287 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1288 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1289 windowRight->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
1290 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1291}
1292
1293// This test is different from the test above that HOVER_ENTER and HOVER_EXIT events are injected
1294// directly in this test.
1295TEST_F(InputDispatcherTest, HoverEnterMouseClickAndHoverExit) {
Chris Yea209fde2020-07-22 13:54:51 -07001296 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tandf26e862020-07-01 20:18:19 -07001297 sp<FakeWindowHandle> window =
1298 new FakeWindowHandle(application, mDispatcher, "Window", ADISPLAY_ID_DEFAULT);
1299 window->setFrame(Rect(0, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001300 window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tandf26e862020-07-01 20:18:19 -07001301
1302 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1303
1304 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
1305
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001306 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001307 injectMotionEvent(mDispatcher,
1308 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
1309 AINPUT_SOURCE_MOUSE)
1310 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1311 .x(300)
1312 .y(400))
1313 .build()));
1314 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
1315 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1316
1317 // Inject a series of mouse events for a mouse click
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001318 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001319 injectMotionEvent(mDispatcher,
1320 MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
1321 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1322 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1323 .x(300)
1324 .y(400))
1325 .build()));
1326 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1327
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001328 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001329 injectMotionEvent(mDispatcher,
1330 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
1331 AINPUT_SOURCE_MOUSE)
1332 .buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
1333 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1334 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1335 .x(300)
1336 .y(400))
1337 .build()));
1338 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
1339 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1340
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001341 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001342 injectMotionEvent(mDispatcher,
1343 MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1344 AINPUT_SOURCE_MOUSE)
1345 .buttonState(0)
1346 .actionButton(AMOTION_EVENT_BUTTON_PRIMARY)
1347 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1348 .x(300)
1349 .y(400))
1350 .build()));
1351 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
1352 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1353
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001354 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001355 injectMotionEvent(mDispatcher,
1356 MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
1357 .buttonState(0)
1358 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1359 .x(300)
1360 .y(400))
1361 .build()));
1362 window->consumeMotionUp(ADISPLAY_ID_DEFAULT);
1363
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001364 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tandf26e862020-07-01 20:18:19 -07001365 injectMotionEvent(mDispatcher,
1366 MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
1367 AINPUT_SOURCE_MOUSE)
1368 .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
1369 .x(300)
1370 .y(400))
1371 .build()));
1372 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_EXIT,
1373 ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
1374}
1375
Garfield Tan00f511d2019-06-12 16:55:40 -07001376TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
Chris Yea209fde2020-07-22 13:54:51 -07001377 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Garfield Tan00f511d2019-06-12 16:55:40 -07001378
1379 sp<FakeWindowHandle> windowLeft =
1380 new FakeWindowHandle(application, mDispatcher, "Left", ADISPLAY_ID_DEFAULT);
1381 windowLeft->setFrame(Rect(0, 0, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001382 windowLeft->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001383 sp<FakeWindowHandle> windowRight =
1384 new FakeWindowHandle(application, mDispatcher, "Right", ADISPLAY_ID_DEFAULT);
1385 windowRight->setFrame(Rect(600, 0, 1200, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001386 windowRight->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Garfield Tan00f511d2019-06-12 16:55:40 -07001387
1388 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1389
Arthur Hung72d8dc32020-03-28 00:48:39 +00001390 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
Garfield Tan00f511d2019-06-12 16:55:40 -07001391
1392 // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
1393 // left window. This event should be dispatched to the left window.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001394 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Garfield Tan00f511d2019-06-12 16:55:40 -07001395 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07001396 ADISPLAY_ID_DEFAULT, {610, 400}, {599, 400}));
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08001397 windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Garfield Tan00f511d2019-06-12 16:55:40 -07001398 windowRight->assertNoEvents();
1399}
1400
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001401TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsKeyStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001402 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001403 sp<FakeWindowHandle> window =
1404 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Vishnu Nair47074b82020-08-14 11:54:47 -07001405 window->setFocusable(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001406
Arthur Hung72d8dc32020-03-28 00:48:39 +00001407 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001408 setFocusedWindow(window);
1409
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001410 window->consumeFocusEvent(true);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001411
1412 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1413 mDispatcher->notifyKey(&keyArgs);
1414
1415 // Window should receive key down event.
1416 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1417
1418 // When device reset happens, that key stream should be terminated with FLAG_CANCELED
1419 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001420 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001421 mDispatcher->notifyDeviceReset(&args);
1422 window->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
1423 AKEY_EVENT_FLAG_CANCELED);
1424}
1425
1426TEST_F(InputDispatcherTest, NotifyDeviceReset_CancelsMotionStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001427 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001428 sp<FakeWindowHandle> window =
1429 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1430
Arthur Hung72d8dc32020-03-28 00:48:39 +00001431 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001432
1433 NotifyMotionArgs motionArgs =
1434 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1435 ADISPLAY_ID_DEFAULT);
1436 mDispatcher->notifyMotion(&motionArgs);
1437
1438 // Window should receive motion down event.
1439 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1440
1441 // When device reset happens, that motion stream should be terminated with ACTION_CANCEL
1442 // on the app side.
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001443 NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08001444 mDispatcher->notifyDeviceReset(&args);
1445 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL, ADISPLAY_ID_DEFAULT,
1446 0 /*expectedFlags*/);
1447}
1448
Svet Ganov5d3bc372020-01-26 23:11:07 -08001449TEST_F(InputDispatcherTest, TransferTouchFocus_OnePointer) {
Chris Yea209fde2020-07-22 13:54:51 -07001450 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001451
1452 // Create a couple of windows
1453 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1454 "First Window", ADISPLAY_ID_DEFAULT);
1455 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1456 "Second Window", ADISPLAY_ID_DEFAULT);
1457
1458 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001459 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001460
1461 // Send down to the first window
1462 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1463 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1464 mDispatcher->notifyMotion(&downMotionArgs);
1465 // Only the first window should get the down event
1466 firstWindow->consumeMotionDown();
1467 secondWindow->assertNoEvents();
1468
1469 // Transfer touch focus to the second window
1470 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1471 // The first window gets cancel and the second gets down
1472 firstWindow->consumeMotionCancel();
1473 secondWindow->consumeMotionDown();
1474
1475 // Send up event to the second window
1476 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1477 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1478 mDispatcher->notifyMotion(&upMotionArgs);
1479 // The first window gets no events and the second gets up
1480 firstWindow->assertNoEvents();
1481 secondWindow->consumeMotionUp();
1482}
1483
1484TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointerNoSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001485 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001486
1487 PointF touchPoint = {10, 10};
1488
1489 // Create a couple of windows
1490 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1491 "First Window", ADISPLAY_ID_DEFAULT);
1492 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1493 "Second Window", ADISPLAY_ID_DEFAULT);
1494
1495 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001496 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001497
1498 // Send down to the first window
1499 NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1500 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint});
1501 mDispatcher->notifyMotion(&downMotionArgs);
1502 // Only the first window should get the down event
1503 firstWindow->consumeMotionDown();
1504 secondWindow->assertNoEvents();
1505
1506 // Send pointer down to the first window
1507 NotifyMotionArgs pointerDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1508 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1509 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1510 mDispatcher->notifyMotion(&pointerDownMotionArgs);
1511 // Only the first window should get the pointer down event
1512 firstWindow->consumeMotionPointerDown(1);
1513 secondWindow->assertNoEvents();
1514
1515 // Transfer touch focus to the second window
1516 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1517 // The first window gets cancel and the second gets down and pointer down
1518 firstWindow->consumeMotionCancel();
1519 secondWindow->consumeMotionDown();
1520 secondWindow->consumeMotionPointerDown(1);
1521
1522 // Send pointer up to the second window
1523 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1524 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1525 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {touchPoint, touchPoint});
1526 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1527 // The first window gets nothing and the second gets pointer up
1528 firstWindow->assertNoEvents();
1529 secondWindow->consumeMotionPointerUp(1);
1530
1531 // Send up event to the second window
1532 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1533 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1534 mDispatcher->notifyMotion(&upMotionArgs);
1535 // The first window gets nothing and the second gets up
1536 firstWindow->assertNoEvents();
1537 secondWindow->consumeMotionUp();
1538}
1539
1540TEST_F(InputDispatcherTest, TransferTouchFocus_TwoPointersSplitTouch) {
Chris Yea209fde2020-07-22 13:54:51 -07001541 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Svet Ganov5d3bc372020-01-26 23:11:07 -08001542
1543 // Create a non touch modal window that supports split touch
1544 sp<FakeWindowHandle> firstWindow = new FakeWindowHandle(application, mDispatcher,
1545 "First Window", ADISPLAY_ID_DEFAULT);
1546 firstWindow->setFrame(Rect(0, 0, 600, 400));
Michael Wright44753b12020-07-08 13:48:11 +01001547 firstWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1548 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001549
1550 // Create a non touch modal window that supports split touch
1551 sp<FakeWindowHandle> secondWindow = new FakeWindowHandle(application, mDispatcher,
1552 "Second Window", ADISPLAY_ID_DEFAULT);
1553 secondWindow->setFrame(Rect(0, 400, 600, 800));
Michael Wright44753b12020-07-08 13:48:11 +01001554 secondWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
1555 InputWindowInfo::Flag::SPLIT_TOUCH);
Svet Ganov5d3bc372020-01-26 23:11:07 -08001556
1557 // Add the windows to the dispatcher
Arthur Hung72d8dc32020-03-28 00:48:39 +00001558 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
Svet Ganov5d3bc372020-01-26 23:11:07 -08001559
1560 PointF pointInFirst = {300, 200};
1561 PointF pointInSecond = {300, 600};
1562
1563 // Send down to the first window
1564 NotifyMotionArgs firstDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
1565 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst});
1566 mDispatcher->notifyMotion(&firstDownMotionArgs);
1567 // Only the first window should get the down event
1568 firstWindow->consumeMotionDown();
1569 secondWindow->assertNoEvents();
1570
1571 // Send down to the second window
1572 NotifyMotionArgs secondDownMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_DOWN
1573 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1574 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1575 mDispatcher->notifyMotion(&secondDownMotionArgs);
1576 // The first window gets a move and the second a down
1577 firstWindow->consumeMotionMove();
1578 secondWindow->consumeMotionDown();
1579
1580 // Transfer touch focus to the second window
1581 mDispatcher->transferTouchFocus(firstWindow->getToken(), secondWindow->getToken());
1582 // The first window gets cancel and the new gets pointer down (it already saw down)
1583 firstWindow->consumeMotionCancel();
1584 secondWindow->consumeMotionPointerDown(1);
1585
1586 // Send pointer up to the second window
1587 NotifyMotionArgs pointerUpMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_POINTER_UP
1588 | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
1589 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {pointInFirst, pointInSecond});
1590 mDispatcher->notifyMotion(&pointerUpMotionArgs);
1591 // The first window gets nothing and the second gets pointer up
1592 firstWindow->assertNoEvents();
1593 secondWindow->consumeMotionPointerUp(1);
1594
1595 // Send up event to the second window
1596 NotifyMotionArgs upMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_UP,
1597 AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT);
1598 mDispatcher->notifyMotion(&upMotionArgs);
1599 // The first window gets nothing and the second gets up
1600 firstWindow->assertNoEvents();
1601 secondWindow->consumeMotionUp();
1602}
1603
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001604TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001605 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001606 sp<FakeWindowHandle> window =
1607 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1608
Vishnu Nair47074b82020-08-14 11:54:47 -07001609 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001610 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001611 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001612
1613 window->consumeFocusEvent(true);
1614
1615 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1616 mDispatcher->notifyKey(&keyArgs);
1617
1618 // Window should receive key down event.
1619 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
1620}
1621
1622TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001623 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001624 sp<FakeWindowHandle> window =
1625 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1626
Arthur Hung72d8dc32020-03-28 00:48:39 +00001627 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001628
1629 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1630 mDispatcher->notifyKey(&keyArgs);
1631 mDispatcher->waitForIdle();
1632
1633 window->assertNoEvents();
1634}
1635
1636// If a window is touchable, but does not have focus, it should receive motion events, but not keys
1637TEST_F(InputDispatcherTest, UnfocusedWindow_ReceivesMotionsButNotKeys) {
Chris Yea209fde2020-07-22 13:54:51 -07001638 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001639 sp<FakeWindowHandle> window =
1640 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1641
Arthur Hung72d8dc32020-03-28 00:48:39 +00001642 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001643
1644 // Send key
1645 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
1646 mDispatcher->notifyKey(&keyArgs);
1647 // Send motion
1648 NotifyMotionArgs motionArgs =
1649 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1650 ADISPLAY_ID_DEFAULT);
1651 mDispatcher->notifyMotion(&motionArgs);
1652
1653 // Window should receive only the motion event
1654 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1655 window->assertNoEvents(); // Key event or focus event will not be received
1656}
1657
chaviwd1c23182019-12-20 18:44:56 -08001658class FakeMonitorReceiver {
Michael Wright3a240c42019-12-10 20:53:41 +00001659public:
1660 FakeMonitorReceiver(const sp<InputDispatcher>& dispatcher, const std::string name,
chaviwd1c23182019-12-20 18:44:56 -08001661 int32_t displayId, bool isGestureMonitor = false) {
Garfield Tan15601662020-09-22 15:32:38 -07001662 base::Result<std::unique_ptr<InputChannel>> channel =
1663 dispatcher->createInputMonitor(displayId, isGestureMonitor, name);
1664 mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
Michael Wright3a240c42019-12-10 20:53:41 +00001665 }
1666
chaviwd1c23182019-12-20 18:44:56 -08001667 sp<IBinder> getToken() { return mInputReceiver->getToken(); }
1668
1669 void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1670 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN,
1671 expectedDisplayId, expectedFlags);
1672 }
1673
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001674 std::optional<int32_t> receiveEvent() { return mInputReceiver->receiveEvent(); }
1675
1676 void finishEvent(uint32_t consumeSeq) { return mInputReceiver->finishEvent(consumeSeq); }
1677
chaviwd1c23182019-12-20 18:44:56 -08001678 void consumeMotionDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1679 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN,
1680 expectedDisplayId, expectedFlags);
1681 }
1682
1683 void consumeMotionUp(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
1684 mInputReceiver->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_UP,
1685 expectedDisplayId, expectedFlags);
1686 }
1687
1688 void assertNoEvents() { mInputReceiver->assertNoEvents(); }
1689
1690private:
1691 std::unique_ptr<FakeInputReceiver> mInputReceiver;
Michael Wright3a240c42019-12-10 20:53:41 +00001692};
1693
1694// Tests for gesture monitors
1695TEST_F(InputDispatcherTest, GestureMonitor_ReceivesMotionEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001696 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001697 sp<FakeWindowHandle> window =
1698 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001699 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001700
chaviwd1c23182019-12-20 18:44:56 -08001701 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1702 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001703
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001704 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Michael Wright3a240c42019-12-10 20:53:41 +00001705 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001706 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Michael Wright3a240c42019-12-10 20:53:41 +00001707 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001708 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001709}
1710
1711TEST_F(InputDispatcherTest, GestureMonitor_DoesNotReceiveKeyEvents) {
Chris Yea209fde2020-07-22 13:54:51 -07001712 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001713 sp<FakeWindowHandle> window =
1714 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1715
1716 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001717 window->setFocusable(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001718
Arthur Hung72d8dc32020-03-28 00:48:39 +00001719 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001720 setFocusedWindow(window);
1721
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001722 window->consumeFocusEvent(true);
Michael Wright3a240c42019-12-10 20:53:41 +00001723
chaviwd1c23182019-12-20 18:44:56 -08001724 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1725 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001726
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001727 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
1728 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Michael Wright3a240c42019-12-10 20:53:41 +00001729 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001730 monitor.assertNoEvents();
Michael Wright3a240c42019-12-10 20:53:41 +00001731}
1732
1733TEST_F(InputDispatcherTest, GestureMonitor_CanPilferAfterWindowIsRemovedMidStream) {
Chris Yea209fde2020-07-22 13:54:51 -07001734 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Michael Wright3a240c42019-12-10 20:53:41 +00001735 sp<FakeWindowHandle> window =
1736 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001737 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Michael Wright3a240c42019-12-10 20:53:41 +00001738
chaviwd1c23182019-12-20 18:44:56 -08001739 FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
1740 true /*isGestureMonitor*/);
Michael Wright3a240c42019-12-10 20:53:41 +00001741
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001742 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Michael Wright3a240c42019-12-10 20:53:41 +00001743 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001744 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Michael Wright3a240c42019-12-10 20:53:41 +00001745 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08001746 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001747
1748 window->releaseChannel();
1749
chaviwd1c23182019-12-20 18:44:56 -08001750 mDispatcher->pilferPointers(monitor.getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00001751
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001752 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Michael Wright3a240c42019-12-10 20:53:41 +00001753 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001754 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
chaviwd1c23182019-12-20 18:44:56 -08001755 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
Michael Wright3a240c42019-12-10 20:53:41 +00001756}
1757
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001758TEST_F(InputDispatcherTest, UnresponsiveGestureMonitor_GetsAnr) {
1759 FakeMonitorReceiver monitor =
1760 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
1761 true /*isGestureMonitor*/);
1762
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001763 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001764 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT));
1765 std::optional<uint32_t> consumeSeq = monitor.receiveEvent();
1766 ASSERT_TRUE(consumeSeq);
1767
1768 mFakePolicy->assertNotifyAnrWasCalled(DISPATCHING_TIMEOUT, nullptr, monitor.getToken());
1769 monitor.finishEvent(*consumeSeq);
1770 ASSERT_TRUE(mDispatcher->waitForIdle());
1771}
1772
chaviw81e2bb92019-12-18 15:03:51 -08001773TEST_F(InputDispatcherTest, TestMoveEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001774 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
chaviw81e2bb92019-12-18 15:03:51 -08001775 sp<FakeWindowHandle> window =
1776 new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
1777
Arthur Hung72d8dc32020-03-28 00:48:39 +00001778 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
chaviw81e2bb92019-12-18 15:03:51 -08001779
1780 NotifyMotionArgs motionArgs =
1781 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1782 ADISPLAY_ID_DEFAULT);
1783
1784 mDispatcher->notifyMotion(&motionArgs);
1785 // Window should receive motion down event.
1786 window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
1787
1788 motionArgs.action = AMOTION_EVENT_ACTION_MOVE;
Garfield Tanc51d1ba2020-01-28 13:24:04 -08001789 motionArgs.id += 1;
chaviw81e2bb92019-12-18 15:03:51 -08001790 motionArgs.eventTime = systemTime(SYSTEM_TIME_MONOTONIC);
1791 motionArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
1792 motionArgs.pointerCoords[0].getX() - 10);
1793
1794 mDispatcher->notifyMotion(&motionArgs);
1795 window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_MOVE, ADISPLAY_ID_DEFAULT,
1796 0 /*expectedFlags*/);
1797}
1798
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001799/**
1800 * Dispatcher has touch mode enabled by default. Typically, the policy overrides that value to
1801 * the device default right away. In the test scenario, we check both the default value,
1802 * and the action of enabling / disabling.
1803 */
1804TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) {
Chris Yea209fde2020-07-22 13:54:51 -07001805 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001806 sp<FakeWindowHandle> window =
1807 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1808
1809 // Set focused application.
1810 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001811 window->setFocusable(true);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001812
1813 SCOPED_TRACE("Check default value of touch mode");
Arthur Hung72d8dc32020-03-28 00:48:39 +00001814 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001815 setFocusedWindow(window);
1816
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001817 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1818
1819 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001820 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001821 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001822 window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
1823
1824 SCOPED_TRACE("Disable touch mode");
1825 mDispatcher->setInTouchMode(false);
Vishnu Nair47074b82020-08-14 11:54:47 -07001826 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001827 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001828 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001829 window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
1830
1831 SCOPED_TRACE("Remove the window to trigger focus loss");
Vishnu Nair47074b82020-08-14 11:54:47 -07001832 window->setFocusable(false);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001833 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001834 window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
1835
1836 SCOPED_TRACE("Enable touch mode again");
1837 mDispatcher->setInTouchMode(true);
Vishnu Nair47074b82020-08-14 11:54:47 -07001838 window->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00001839 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001840 setFocusedWindow(window);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001841 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1842
1843 window->assertNoEvents();
1844}
1845
Gang Wange9087892020-01-07 12:17:14 -05001846TEST_F(InputDispatcherTest, VerifyInputEvent_KeyEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001847 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Gang Wange9087892020-01-07 12:17:14 -05001848 sp<FakeWindowHandle> window =
1849 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1850
1851 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07001852 window->setFocusable(true);
Gang Wange9087892020-01-07 12:17:14 -05001853
Arthur Hung72d8dc32020-03-28 00:48:39 +00001854 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Vishnu Nair958da932020-08-21 17:12:37 -07001855 setFocusedWindow(window);
1856
Gang Wange9087892020-01-07 12:17:14 -05001857 window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
1858
1859 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
1860 mDispatcher->notifyKey(&keyArgs);
1861
1862 InputEvent* event = window->consume();
1863 ASSERT_NE(event, nullptr);
1864
1865 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1866 ASSERT_NE(verified, nullptr);
1867 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::KEY);
1868
1869 ASSERT_EQ(keyArgs.eventTime, verified->eventTimeNanos);
1870 ASSERT_EQ(keyArgs.deviceId, verified->deviceId);
1871 ASSERT_EQ(keyArgs.source, verified->source);
1872 ASSERT_EQ(keyArgs.displayId, verified->displayId);
1873
1874 const VerifiedKeyEvent& verifiedKey = static_cast<const VerifiedKeyEvent&>(*verified);
1875
1876 ASSERT_EQ(keyArgs.action, verifiedKey.action);
1877 ASSERT_EQ(keyArgs.downTime, verifiedKey.downTimeNanos);
Gang Wange9087892020-01-07 12:17:14 -05001878 ASSERT_EQ(keyArgs.flags & VERIFIED_KEY_EVENT_FLAGS, verifiedKey.flags);
1879 ASSERT_EQ(keyArgs.keyCode, verifiedKey.keyCode);
1880 ASSERT_EQ(keyArgs.scanCode, verifiedKey.scanCode);
1881 ASSERT_EQ(keyArgs.metaState, verifiedKey.metaState);
1882 ASSERT_EQ(0, verifiedKey.repeatCount);
1883}
1884
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001885TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) {
Chris Yea209fde2020-07-22 13:54:51 -07001886 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001887 sp<FakeWindowHandle> window =
1888 new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
1889
1890 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1891
Arthur Hung72d8dc32020-03-28 00:48:39 +00001892 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
Siarhei Vishniakou47040bf2020-02-28 15:03:13 -08001893
1894 NotifyMotionArgs motionArgs =
1895 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
1896 ADISPLAY_ID_DEFAULT);
1897 mDispatcher->notifyMotion(&motionArgs);
1898
1899 InputEvent* event = window->consume();
1900 ASSERT_NE(event, nullptr);
1901
1902 std::unique_ptr<VerifiedInputEvent> verified = mDispatcher->verifyInputEvent(*event);
1903 ASSERT_NE(verified, nullptr);
1904 ASSERT_EQ(verified->type, VerifiedInputEvent::Type::MOTION);
1905
1906 EXPECT_EQ(motionArgs.eventTime, verified->eventTimeNanos);
1907 EXPECT_EQ(motionArgs.deviceId, verified->deviceId);
1908 EXPECT_EQ(motionArgs.source, verified->source);
1909 EXPECT_EQ(motionArgs.displayId, verified->displayId);
1910
1911 const VerifiedMotionEvent& verifiedMotion = static_cast<const VerifiedMotionEvent&>(*verified);
1912
1913 EXPECT_EQ(motionArgs.pointerCoords[0].getX(), verifiedMotion.rawX);
1914 EXPECT_EQ(motionArgs.pointerCoords[0].getY(), verifiedMotion.rawY);
1915 EXPECT_EQ(motionArgs.action & AMOTION_EVENT_ACTION_MASK, verifiedMotion.actionMasked);
1916 EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos);
1917 EXPECT_EQ(motionArgs.flags & VERIFIED_MOTION_EVENT_FLAGS, verifiedMotion.flags);
1918 EXPECT_EQ(motionArgs.metaState, verifiedMotion.metaState);
1919 EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState);
1920}
1921
chaviw09c8d2d2020-08-24 15:48:26 -07001922/**
1923 * Ensure that separate calls to sign the same data are generating the same key.
1924 * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance
1925 * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky
1926 * tests.
1927 */
1928TEST_F(InputDispatcherTest, GeneratedHmac_IsConsistent) {
1929 KeyEvent event = getTestKeyEvent();
1930 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1931
1932 std::array<uint8_t, 32> hmac1 = mDispatcher->sign(verifiedEvent);
1933 std::array<uint8_t, 32> hmac2 = mDispatcher->sign(verifiedEvent);
1934 ASSERT_EQ(hmac1, hmac2);
1935}
1936
1937/**
1938 * Ensure that changes in VerifiedKeyEvent produce a different hmac.
1939 */
1940TEST_F(InputDispatcherTest, GeneratedHmac_ChangesWhenFieldsChange) {
1941 KeyEvent event = getTestKeyEvent();
1942 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event);
1943 std::array<uint8_t, 32> initialHmac = mDispatcher->sign(verifiedEvent);
1944
1945 verifiedEvent.deviceId += 1;
1946 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1947
1948 verifiedEvent.source += 1;
1949 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1950
1951 verifiedEvent.eventTimeNanos += 1;
1952 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1953
1954 verifiedEvent.displayId += 1;
1955 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1956
1957 verifiedEvent.action += 1;
1958 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1959
1960 verifiedEvent.downTimeNanos += 1;
1961 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1962
1963 verifiedEvent.flags += 1;
1964 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1965
1966 verifiedEvent.keyCode += 1;
1967 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1968
1969 verifiedEvent.scanCode += 1;
1970 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1971
1972 verifiedEvent.metaState += 1;
1973 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1974
1975 verifiedEvent.repeatCount += 1;
1976 ASSERT_NE(initialHmac, mDispatcher->sign(verifiedEvent));
1977}
1978
Vishnu Nair958da932020-08-21 17:12:37 -07001979TEST_F(InputDispatcherTest, SetFocusedWindow) {
1980 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
1981 sp<FakeWindowHandle> windowTop =
1982 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
1983 sp<FakeWindowHandle> windowSecond =
1984 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
1985 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
1986
1987 // Top window is also focusable but is not granted focus.
1988 windowTop->setFocusable(true);
1989 windowSecond->setFocusable(true);
1990 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
1991 setFocusedWindow(windowSecond);
1992
1993 windowSecond->consumeFocusEvent(true);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001994 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
1995 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07001996
1997 // Focused window should receive event.
1998 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
1999 windowTop->assertNoEvents();
2000}
2001
2002TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestInvalidChannel) {
2003 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2004 sp<FakeWindowHandle> window =
2005 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2006 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2007
2008 window->setFocusable(true);
2009 // Release channel for window is no longer valid.
2010 window->releaseChannel();
2011 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2012 setFocusedWindow(window);
2013
2014 // Test inject a key down, should timeout.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002015 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
2016 << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
Vishnu Nair958da932020-08-21 17:12:37 -07002017
2018 // window channel is invalid, so it should not receive any input event.
2019 window->assertNoEvents();
2020}
2021
2022TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestNoFocusableWindow) {
2023 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2024 sp<FakeWindowHandle> window =
2025 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2026 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2027
2028 // Window is not focusable.
2029 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2030 setFocusedWindow(window);
2031
2032 // Test inject a key down, should timeout.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002033 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
2034 << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
Vishnu Nair958da932020-08-21 17:12:37 -07002035
2036 // window is invalid, so it should not receive any input event.
2037 window->assertNoEvents();
2038}
2039
2040TEST_F(InputDispatcherTest, SetFocusedWindow_CheckFocusedToken) {
2041 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2042 sp<FakeWindowHandle> windowTop =
2043 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
2044 sp<FakeWindowHandle> windowSecond =
2045 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2046 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2047
2048 windowTop->setFocusable(true);
2049 windowSecond->setFocusable(true);
2050 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
2051 setFocusedWindow(windowTop);
2052 windowTop->consumeFocusEvent(true);
2053
2054 setFocusedWindow(windowSecond, windowTop);
2055 windowSecond->consumeFocusEvent(true);
2056 windowTop->consumeFocusEvent(false);
2057
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002058 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
2059 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07002060
2061 // Focused window should receive event.
2062 windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
2063}
2064
2065TEST_F(InputDispatcherTest, SetFocusedWindow_DropRequestFocusTokenNotFocused) {
2066 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2067 sp<FakeWindowHandle> windowTop =
2068 new FakeWindowHandle(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT);
2069 sp<FakeWindowHandle> windowSecond =
2070 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2071 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2072
2073 windowTop->setFocusable(true);
2074 windowSecond->setFocusable(true);
2075 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
2076 setFocusedWindow(windowSecond, windowTop);
2077
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002078 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
2079 << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
Vishnu Nair958da932020-08-21 17:12:37 -07002080
2081 // Event should be dropped.
2082 windowTop->assertNoEvents();
2083 windowSecond->assertNoEvents();
2084}
2085
2086TEST_F(InputDispatcherTest, SetFocusedWindow_DeferInvisibleWindow) {
2087 std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
2088 sp<FakeWindowHandle> window =
2089 new FakeWindowHandle(application, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2090 sp<FakeWindowHandle> previousFocusedWindow =
2091 new FakeWindowHandle(application, mDispatcher, "previousFocusedWindow",
2092 ADISPLAY_ID_DEFAULT);
2093 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
2094
2095 window->setFocusable(true);
2096 previousFocusedWindow->setFocusable(true);
2097 window->setVisible(false);
2098 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window, previousFocusedWindow}}});
2099 setFocusedWindow(previousFocusedWindow);
2100 previousFocusedWindow->consumeFocusEvent(true);
2101
2102 // Requesting focus on invisible window takes focus from currently focused window.
2103 setFocusedWindow(window);
2104 previousFocusedWindow->consumeFocusEvent(false);
2105
2106 // Injected key goes to pending queue.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002107 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Vishnu Nair958da932020-08-21 17:12:37 -07002108 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002109 ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE));
Vishnu Nair958da932020-08-21 17:12:37 -07002110
2111 // Window does not get focus event or key down.
2112 window->assertNoEvents();
2113
2114 // Window becomes visible.
2115 window->setVisible(true);
2116 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
2117
2118 // Window receives focus event.
2119 window->consumeFocusEvent(true);
2120 // Focused window receives key down.
2121 window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2122}
2123
Garfield Tan1c7bc862020-01-28 13:24:04 -08002124class InputDispatcherKeyRepeatTest : public InputDispatcherTest {
2125protected:
2126 static constexpr nsecs_t KEY_REPEAT_TIMEOUT = 40 * 1000000; // 40 ms
2127 static constexpr nsecs_t KEY_REPEAT_DELAY = 40 * 1000000; // 40 ms
2128
Chris Yea209fde2020-07-22 13:54:51 -07002129 std::shared_ptr<FakeApplicationHandle> mApp;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002130 sp<FakeWindowHandle> mWindow;
2131
2132 virtual void SetUp() override {
2133 mFakePolicy = new FakeInputDispatcherPolicy();
2134 mFakePolicy->setKeyRepeatConfiguration(KEY_REPEAT_TIMEOUT, KEY_REPEAT_DELAY);
2135 mDispatcher = new InputDispatcher(mFakePolicy);
2136 mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
2137 ASSERT_EQ(OK, mDispatcher->start());
2138
2139 setUpWindow();
2140 }
2141
2142 void setUpWindow() {
Chris Yea209fde2020-07-22 13:54:51 -07002143 mApp = std::make_shared<FakeApplicationHandle>();
Garfield Tan1c7bc862020-01-28 13:24:04 -08002144 mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
2145
Vishnu Nair47074b82020-08-14 11:54:47 -07002146 mWindow->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002147 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002148 setFocusedWindow(mWindow);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002149 mWindow->consumeFocusEvent(true);
2150 }
2151
Chris Ye2ad95392020-09-01 13:44:44 -07002152 void sendAndConsumeKeyDown(int32_t deviceId) {
Garfield Tan1c7bc862020-01-28 13:24:04 -08002153 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
Chris Ye2ad95392020-09-01 13:44:44 -07002154 keyArgs.deviceId = deviceId;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002155 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Otherwise it won't generate repeat event
2156 mDispatcher->notifyKey(&keyArgs);
2157
2158 // Window should receive key down event.
2159 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2160 }
2161
2162 void expectKeyRepeatOnce(int32_t repeatCount) {
2163 SCOPED_TRACE(StringPrintf("Checking event with repeat count %" PRId32, repeatCount));
2164 InputEvent* repeatEvent = mWindow->consume();
2165 ASSERT_NE(nullptr, repeatEvent);
2166
2167 uint32_t eventType = repeatEvent->getType();
2168 ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, eventType);
2169
2170 KeyEvent* repeatKeyEvent = static_cast<KeyEvent*>(repeatEvent);
2171 uint32_t eventAction = repeatKeyEvent->getAction();
2172 EXPECT_EQ(AKEY_EVENT_ACTION_DOWN, eventAction);
2173 EXPECT_EQ(repeatCount, repeatKeyEvent->getRepeatCount());
2174 }
2175
Chris Ye2ad95392020-09-01 13:44:44 -07002176 void sendAndConsumeKeyUp(int32_t deviceId) {
Garfield Tan1c7bc862020-01-28 13:24:04 -08002177 NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
Chris Ye2ad95392020-09-01 13:44:44 -07002178 keyArgs.deviceId = deviceId;
Garfield Tan1c7bc862020-01-28 13:24:04 -08002179 keyArgs.policyFlags |= POLICY_FLAG_TRUSTED; // Unless it won't generate repeat event
2180 mDispatcher->notifyKey(&keyArgs);
2181
2182 // Window should receive key down event.
2183 mWindow->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT,
2184 0 /*expectedFlags*/);
2185 }
2186};
2187
2188TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeat) {
Chris Ye2ad95392020-09-01 13:44:44 -07002189 sendAndConsumeKeyDown(1 /* deviceId */);
2190 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2191 expectKeyRepeatOnce(repeatCount);
2192 }
2193}
2194
2195TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_ReceivesKeyRepeatFromTwoDevices) {
2196 sendAndConsumeKeyDown(1 /* deviceId */);
2197 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2198 expectKeyRepeatOnce(repeatCount);
2199 }
2200 sendAndConsumeKeyDown(2 /* deviceId */);
2201 /* repeatCount will start from 1 for deviceId 2 */
Garfield Tan1c7bc862020-01-28 13:24:04 -08002202 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2203 expectKeyRepeatOnce(repeatCount);
2204 }
2205}
2206
2207TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterUp) {
Chris Ye2ad95392020-09-01 13:44:44 -07002208 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002209 expectKeyRepeatOnce(1 /*repeatCount*/);
Chris Ye2ad95392020-09-01 13:44:44 -07002210 sendAndConsumeKeyUp(1 /* deviceId */);
2211 mWindow->assertNoEvents();
2212}
2213
2214TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_KeyRepeatAfterStaleDeviceKeyUp) {
2215 sendAndConsumeKeyDown(1 /* deviceId */);
2216 expectKeyRepeatOnce(1 /*repeatCount*/);
2217 sendAndConsumeKeyDown(2 /* deviceId */);
2218 expectKeyRepeatOnce(1 /*repeatCount*/);
2219 // Stale key up from device 1.
2220 sendAndConsumeKeyUp(1 /* deviceId */);
2221 // Device 2 is still down, keep repeating
2222 expectKeyRepeatOnce(2 /*repeatCount*/);
2223 expectKeyRepeatOnce(3 /*repeatCount*/);
2224 // Device 2 key up
2225 sendAndConsumeKeyUp(2 /* deviceId */);
2226 mWindow->assertNoEvents();
2227}
2228
2229TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_KeyRepeatStopsAfterRepeatingKeyUp) {
2230 sendAndConsumeKeyDown(1 /* deviceId */);
2231 expectKeyRepeatOnce(1 /*repeatCount*/);
2232 sendAndConsumeKeyDown(2 /* deviceId */);
2233 expectKeyRepeatOnce(1 /*repeatCount*/);
2234 // Device 2 which holds the key repeating goes up, expect the repeating to stop.
2235 sendAndConsumeKeyUp(2 /* deviceId */);
2236 // Device 1 still holds key down, but the repeating was already stopped
Garfield Tan1c7bc862020-01-28 13:24:04 -08002237 mWindow->assertNoEvents();
2238}
2239
2240TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseEventIdFromInputDispatcher) {
Chris Ye2ad95392020-09-01 13:44:44 -07002241 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002242 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2243 InputEvent* repeatEvent = mWindow->consume();
2244 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2245 EXPECT_EQ(IdGenerator::Source::INPUT_DISPATCHER,
2246 IdGenerator::getSource(repeatEvent->getId()));
2247 }
2248}
2249
2250TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseUniqueEventId) {
Chris Ye2ad95392020-09-01 13:44:44 -07002251 sendAndConsumeKeyDown(1 /* deviceId */);
Garfield Tan1c7bc862020-01-28 13:24:04 -08002252
2253 std::unordered_set<int32_t> idSet;
2254 for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
2255 InputEvent* repeatEvent = mWindow->consume();
2256 ASSERT_NE(nullptr, repeatEvent) << "Didn't receive event with repeat count " << repeatCount;
2257 int32_t id = repeatEvent->getId();
2258 EXPECT_EQ(idSet.end(), idSet.find(id));
2259 idSet.insert(id);
2260 }
2261}
2262
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002263/* Test InputDispatcher for MultiDisplay */
2264class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
2265public:
2266 static constexpr int32_t SECOND_DISPLAY_ID = 1;
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002267 virtual void SetUp() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002268 InputDispatcherTest::SetUp();
Arthur Hungb92218b2018-08-14 12:00:21 +08002269
Chris Yea209fde2020-07-22 13:54:51 -07002270 application1 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002271 windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1",
2272 ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002273
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002274 // Set focus window for primary display, but focused display would be second one.
2275 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
Vishnu Nair47074b82020-08-14 11:54:47 -07002276 windowInPrimary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002277 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002278 setFocusedWindow(windowInPrimary);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002279 windowInPrimary->consumeFocusEvent(true);
Arthur Hungb92218b2018-08-14 12:00:21 +08002280
Chris Yea209fde2020-07-22 13:54:51 -07002281 application2 = std::make_shared<FakeApplicationHandle>();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002282 windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2",
2283 SECOND_DISPLAY_ID);
2284 // Set focus to second display window.
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002285 // Set focus display to second one.
2286 mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
2287 // Set focus window for second display.
2288 mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
Vishnu Nair47074b82020-08-14 11:54:47 -07002289 windowInSecondary->setFocusable(true);
Arthur Hung72d8dc32020-03-28 00:48:39 +00002290 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002291 setFocusedWindow(windowInSecondary);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002292 windowInSecondary->consumeFocusEvent(true);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002293 }
2294
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002295 virtual void TearDown() override {
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002296 InputDispatcherTest::TearDown();
2297
Chris Yea209fde2020-07-22 13:54:51 -07002298 application1.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002299 windowInPrimary.clear();
Chris Yea209fde2020-07-22 13:54:51 -07002300 application2.reset();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002301 windowInSecondary.clear();
2302 }
2303
2304protected:
Chris Yea209fde2020-07-22 13:54:51 -07002305 std::shared_ptr<FakeApplicationHandle> application1;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002306 sp<FakeWindowHandle> windowInPrimary;
Chris Yea209fde2020-07-22 13:54:51 -07002307 std::shared_ptr<FakeApplicationHandle> application2;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002308 sp<FakeWindowHandle> windowInSecondary;
2309};
2310
2311TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
2312 // Test touch down on primary display.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002313 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
2314 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
2315 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002316 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hungb92218b2018-08-14 12:00:21 +08002317 windowInSecondary->assertNoEvents();
2318
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002319 // Test touch down on second display.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002320 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
2321 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
2322 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Arthur Hungb92218b2018-08-14 12:00:21 +08002323 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002324 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hungb92218b2018-08-14 12:00:21 +08002325}
2326
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002327TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
Tiger Huang721e26f2018-07-24 22:26:19 +08002328 // Test inject a key down with display id specified.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002329 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2330 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002331 windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Tiger Huang721e26f2018-07-24 22:26:19 +08002332 windowInSecondary->assertNoEvents();
2333
2334 // Test inject a key down without display id specified.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002335 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
2336 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Arthur Hungb92218b2018-08-14 12:00:21 +08002337 windowInPrimary->assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002338 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hungb92218b2018-08-14 12:00:21 +08002339
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002340 // Remove all windows in secondary display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002341 mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
Arthur Hungb92218b2018-08-14 12:00:21 +08002342
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002343 // Old focus should receive a cancel event.
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002344 windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
2345 AKEY_EVENT_FLAG_CANCELED);
Arthur Hungb92218b2018-08-14 12:00:21 +08002346
2347 // Test inject a key down, should timeout because of no target window.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002348 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
2349 << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
Arthur Hungb92218b2018-08-14 12:00:21 +08002350 windowInPrimary->assertNoEvents();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002351 windowInSecondary->consumeFocusEvent(false);
Arthur Hungb92218b2018-08-14 12:00:21 +08002352 windowInSecondary->assertNoEvents();
2353}
2354
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002355// Test per-display input monitors for motion event.
2356TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorMotionEvent_MultiDisplay) {
chaviwd1c23182019-12-20 18:44:56 -08002357 FakeMonitorReceiver monitorInPrimary =
2358 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2359 FakeMonitorReceiver monitorInSecondary =
2360 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002361
2362 // Test touch down on primary display.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002363 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
2364 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
2365 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002366 windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
chaviwd1c23182019-12-20 18:44:56 -08002367 monitorInPrimary.consumeMotionDown(ADISPLAY_ID_DEFAULT);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002368 windowInSecondary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002369 monitorInSecondary.assertNoEvents();
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002370
2371 // Test touch down on second display.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002372 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
2373 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
2374 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002375 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002376 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002377 windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
chaviwd1c23182019-12-20 18:44:56 -08002378 monitorInSecondary.consumeMotionDown(SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002379
2380 // Test inject a non-pointer motion event.
2381 // If specific a display, it will dispatch to the focused window of particular display,
2382 // or it will dispatch to the focused window of focused display.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002383 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
2384 injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
2385 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002386 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002387 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002388 windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002389 monitorInSecondary.consumeMotionDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002390}
2391
2392// Test per-display input monitors for key event.
2393TEST_F(InputDispatcherFocusOnTwoDisplaysTest, MonitorKeyEvent_MultiDisplay) {
2394 //Input monitor per display.
chaviwd1c23182019-12-20 18:44:56 -08002395 FakeMonitorReceiver monitorInPrimary =
2396 FakeMonitorReceiver(mDispatcher, "M_1", ADISPLAY_ID_DEFAULT);
2397 FakeMonitorReceiver monitorInSecondary =
2398 FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002399
2400 // Test inject a key down.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002401 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
2402 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002403 windowInPrimary->assertNoEvents();
chaviwd1c23182019-12-20 18:44:56 -08002404 monitorInPrimary.assertNoEvents();
Siarhei Vishniakouc5ca85c2019-11-15 17:20:00 -08002405 windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
chaviwd1c23182019-12-20 18:44:56 -08002406 monitorInSecondary.consumeKeyDown(ADISPLAY_ID_NONE);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002407}
2408
Vishnu Nair958da932020-08-21 17:12:37 -07002409TEST_F(InputDispatcherFocusOnTwoDisplaysTest, CanFocusWindowOnUnfocusedDisplay) {
2410 sp<FakeWindowHandle> secondWindowInPrimary =
2411 new FakeWindowHandle(application1, mDispatcher, "D_1_W2", ADISPLAY_ID_DEFAULT);
2412 secondWindowInPrimary->setFocusable(true);
2413 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary, secondWindowInPrimary}}});
2414 setFocusedWindow(secondWindowInPrimary);
2415 windowInPrimary->consumeFocusEvent(false);
2416 secondWindowInPrimary->consumeFocusEvent(true);
2417
2418 // Test inject a key down.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002419 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2420 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07002421 windowInPrimary->assertNoEvents();
2422 windowInSecondary->assertNoEvents();
2423 secondWindowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
2424}
2425
Jackal Guof9696682018-10-05 12:23:23 +08002426class InputFilterTest : public InputDispatcherTest {
2427protected:
2428 static constexpr int32_t SECOND_DISPLAY_ID = 1;
2429
2430 void testNotifyMotion(int32_t displayId, bool expectToBeFiltered) {
2431 NotifyMotionArgs motionArgs;
2432
2433 motionArgs = generateMotionArgs(
2434 AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2435 mDispatcher->notifyMotion(&motionArgs);
2436 motionArgs = generateMotionArgs(
2437 AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, displayId);
2438 mDispatcher->notifyMotion(&motionArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002439 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002440 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002441 mFakePolicy->assertFilterInputEventWasCalled(motionArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002442 } else {
2443 mFakePolicy->assertFilterInputEventWasNotCalled();
2444 }
2445 }
2446
2447 void testNotifyKey(bool expectToBeFiltered) {
2448 NotifyKeyArgs keyArgs;
2449
2450 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
2451 mDispatcher->notifyKey(&keyArgs);
2452 keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_UP);
2453 mDispatcher->notifyKey(&keyArgs);
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002454 ASSERT_TRUE(mDispatcher->waitForIdle());
Jackal Guof9696682018-10-05 12:23:23 +08002455
2456 if (expectToBeFiltered) {
Siarhei Vishniakou8935a802019-11-15 16:41:44 -08002457 mFakePolicy->assertFilterInputEventWasCalled(keyArgs);
Jackal Guof9696682018-10-05 12:23:23 +08002458 } else {
2459 mFakePolicy->assertFilterInputEventWasNotCalled();
2460 }
2461 }
2462};
2463
2464// Test InputFilter for MotionEvent
2465TEST_F(InputFilterTest, MotionEvent_InputFilter) {
2466 // Since the InputFilter is disabled by default, check if touch events aren't filtered.
2467 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2468 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2469
2470 // Enable InputFilter
2471 mDispatcher->setInputFilterEnabled(true);
2472 // Test touch on both primary and second display, and check if both events are filtered.
2473 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ true);
2474 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ true);
2475
2476 // Disable InputFilter
2477 mDispatcher->setInputFilterEnabled(false);
2478 // Test touch on both primary and second display, and check if both events aren't filtered.
2479 testNotifyMotion(ADISPLAY_ID_DEFAULT, /*expectToBeFiltered*/ false);
2480 testNotifyMotion(SECOND_DISPLAY_ID, /*expectToBeFiltered*/ false);
2481}
2482
2483// Test InputFilter for KeyEvent
2484TEST_F(InputFilterTest, KeyEvent_InputFilter) {
2485 // Since the InputFilter is disabled by default, check if key event aren't filtered.
2486 testNotifyKey(/*expectToBeFiltered*/ false);
2487
2488 // Enable InputFilter
2489 mDispatcher->setInputFilterEnabled(true);
2490 // Send a key event, and check if it is filtered.
2491 testNotifyKey(/*expectToBeFiltered*/ true);
2492
2493 // Disable InputFilter
2494 mDispatcher->setInputFilterEnabled(false);
2495 // Send a key event, and check if it isn't filtered.
2496 testNotifyKey(/*expectToBeFiltered*/ false);
2497}
2498
chaviwfd6d3512019-03-25 13:23:49 -07002499class InputDispatcherOnPointerDownOutsideFocus : public InputDispatcherTest {
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002500 virtual void SetUp() override {
chaviwfd6d3512019-03-25 13:23:49 -07002501 InputDispatcherTest::SetUp();
2502
Chris Yea209fde2020-07-22 13:54:51 -07002503 std::shared_ptr<FakeApplicationHandle> application =
2504 std::make_shared<FakeApplicationHandle>();
chaviwfd6d3512019-03-25 13:23:49 -07002505 mUnfocusedWindow = new FakeWindowHandle(application, mDispatcher, "Top",
2506 ADISPLAY_ID_DEFAULT);
2507 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
2508 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2509 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002510 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002511
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002512 mFocusedWindow =
2513 new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT);
2514 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01002515 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
chaviwfd6d3512019-03-25 13:23:49 -07002516
2517 // Set focused application.
2518 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
Vishnu Nair47074b82020-08-14 11:54:47 -07002519 mFocusedWindow->setFocusable(true);
chaviwfd6d3512019-03-25 13:23:49 -07002520
2521 // Expect one focus window exist in display.
Arthur Hung72d8dc32020-03-28 00:48:39 +00002522 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002523 setFocusedWindow(mFocusedWindow);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002524 mFocusedWindow->consumeFocusEvent(true);
chaviwfd6d3512019-03-25 13:23:49 -07002525 }
2526
Prabir Pradhan3608aad2019-10-02 17:08:26 -07002527 virtual void TearDown() override {
chaviwfd6d3512019-03-25 13:23:49 -07002528 InputDispatcherTest::TearDown();
2529
2530 mUnfocusedWindow.clear();
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002531 mFocusedWindow.clear();
chaviwfd6d3512019-03-25 13:23:49 -07002532 }
2533
2534protected:
2535 sp<FakeWindowHandle> mUnfocusedWindow;
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002536 sp<FakeWindowHandle> mFocusedWindow;
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002537 static constexpr PointF FOCUSED_WINDOW_TOUCH_POINT = {60, 60};
chaviwfd6d3512019-03-25 13:23:49 -07002538};
2539
2540// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2541// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
2542// the onPointerDownOutsideFocus callback.
2543TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002544 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002545 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2546 {20, 20}))
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002547 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002548 mUnfocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002549
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002550 ASSERT_TRUE(mDispatcher->waitForIdle());
chaviwfd6d3512019-03-25 13:23:49 -07002551 mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
2552}
2553
2554// Have two windows, one with focus. Inject MotionEvent with source TRACKBALL and action
2555// DOWN on the window that doesn't have focus. Ensure no window received the
2556// onPointerDownOutsideFocus callback.
2557TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002558 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002559 injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, {20, 20}))
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002560 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002561 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002562
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002563 ASSERT_TRUE(mDispatcher->waitForIdle());
2564 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002565}
2566
2567// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
2568// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
2569TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002570 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
2571 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002572 mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
chaviwfd6d3512019-03-25 13:23:49 -07002573
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002574 ASSERT_TRUE(mDispatcher->waitForIdle());
2575 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002576}
2577
2578// Have two windows, one with focus. Inject MotionEvent with source TOUCHSCREEN and action
2579// DOWN on the window that already has focus. Ensure no window received the
2580// onPointerDownOutsideFocus callback.
2581TEST_F(InputDispatcherOnPointerDownOutsideFocus,
2582 OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002583 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoub9b15352019-11-26 13:19:26 -08002584 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakoufb9fcda2020-05-04 14:59:19 -07002585 FOCUSED_WINDOW_TOUCH_POINT))
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002586 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakou03aee2a2020-04-13 20:44:54 -07002587 mFocusedWindow->consumeMotionDown();
chaviwfd6d3512019-03-25 13:23:49 -07002588
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08002589 ASSERT_TRUE(mDispatcher->waitForIdle());
2590 mFakePolicy->assertOnPointerDownWasNotCalled();
chaviwfd6d3512019-03-25 13:23:49 -07002591}
2592
chaviwaf87b3e2019-10-01 16:59:28 -07002593// These tests ensures we can send touch events to a single client when there are multiple input
2594// windows that point to the same client token.
2595class InputDispatcherMultiWindowSameTokenTests : public InputDispatcherTest {
2596 virtual void SetUp() override {
2597 InputDispatcherTest::SetUp();
2598
Chris Yea209fde2020-07-22 13:54:51 -07002599 std::shared_ptr<FakeApplicationHandle> application =
2600 std::make_shared<FakeApplicationHandle>();
chaviwaf87b3e2019-10-01 16:59:28 -07002601 mWindow1 = new FakeWindowHandle(application, mDispatcher, "Fake Window 1",
2602 ADISPLAY_ID_DEFAULT);
2603 // Adding FLAG_NOT_TOUCH_MODAL otherwise all taps will go to the top most window.
2604 // 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 +01002605 mWindow1->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2606 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002607 mWindow1->setFrame(Rect(0, 0, 100, 100));
2608
2609 mWindow2 = new FakeWindowHandle(application, mDispatcher, "Fake Window 2",
2610 ADISPLAY_ID_DEFAULT, mWindow1->getToken());
Michael Wright44753b12020-07-08 13:48:11 +01002611 mWindow2->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
2612 InputWindowInfo::Flag::SPLIT_TOUCH);
chaviwaf87b3e2019-10-01 16:59:28 -07002613 mWindow2->setFrame(Rect(100, 100, 200, 200));
2614
Arthur Hung72d8dc32020-03-28 00:48:39 +00002615 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
chaviwaf87b3e2019-10-01 16:59:28 -07002616 }
2617
2618protected:
2619 sp<FakeWindowHandle> mWindow1;
2620 sp<FakeWindowHandle> mWindow2;
2621
2622 // Helper function to convert the point from screen coordinates into the window's space
2623 static PointF getPointInWindow(const InputWindowInfo* windowInfo, const PointF& point) {
chaviw1ff3d1e2020-07-01 15:53:47 -07002624 vec2 vals = windowInfo->transform.transform(point.x, point.y);
2625 return {vals.x, vals.y};
chaviwaf87b3e2019-10-01 16:59:28 -07002626 }
2627
2628 void consumeMotionEvent(const sp<FakeWindowHandle>& window, int32_t expectedAction,
2629 const std::vector<PointF>& points) {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002630 const std::string name = window->getName();
chaviwaf87b3e2019-10-01 16:59:28 -07002631 InputEvent* event = window->consume();
2632
2633 ASSERT_NE(nullptr, event) << name.c_str()
2634 << ": consumer should have returned non-NULL event.";
2635
2636 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
2637 << name.c_str() << "expected " << inputEventTypeToString(AINPUT_EVENT_TYPE_MOTION)
2638 << " event, got " << inputEventTypeToString(event->getType()) << " event";
2639
2640 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
2641 EXPECT_EQ(expectedAction, motionEvent.getAction());
2642
2643 for (size_t i = 0; i < points.size(); i++) {
2644 float expectedX = points[i].x;
2645 float expectedY = points[i].y;
2646
2647 EXPECT_EQ(expectedX, motionEvent.getX(i))
2648 << "expected " << expectedX << " for x[" << i << "] coord of " << name.c_str()
2649 << ", got " << motionEvent.getX(i);
2650 EXPECT_EQ(expectedY, motionEvent.getY(i))
2651 << "expected " << expectedY << " for y[" << i << "] coord of " << name.c_str()
2652 << ", got " << motionEvent.getY(i);
2653 }
2654 }
chaviw9eaa22c2020-07-01 16:21:27 -07002655
2656 void touchAndAssertPositions(int32_t action, std::vector<PointF> touchedPoints,
2657 std::vector<PointF> expectedPoints) {
2658 NotifyMotionArgs motionArgs = generateMotionArgs(action, AINPUT_SOURCE_TOUCHSCREEN,
2659 ADISPLAY_ID_DEFAULT, touchedPoints);
2660 mDispatcher->notifyMotion(&motionArgs);
2661
2662 // Always consume from window1 since it's the window that has the InputReceiver
2663 consumeMotionEvent(mWindow1, action, expectedPoints);
2664 }
chaviwaf87b3e2019-10-01 16:59:28 -07002665};
2666
2667TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchSameScale) {
2668 // Touch Window 1
2669 PointF touchedPoint = {10, 10};
2670 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002671 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002672
2673 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002674 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002675
2676 // Touch Window 2
2677 touchedPoint = {150, 150};
2678 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002679 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002680}
2681
chaviw9eaa22c2020-07-01 16:21:27 -07002682TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchDifferentTransform) {
2683 // Set scale value for window2
chaviwaf87b3e2019-10-01 16:59:28 -07002684 mWindow2->setWindowScale(0.5f, 0.5f);
2685
2686 // Touch Window 1
2687 PointF touchedPoint = {10, 10};
2688 PointF expectedPoint = getPointInWindow(mWindow1->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002689 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002690 // Release touch on Window 1
chaviw9eaa22c2020-07-01 16:21:27 -07002691 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002692
2693 // Touch Window 2
2694 touchedPoint = {150, 150};
2695 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
chaviw9eaa22c2020-07-01 16:21:27 -07002696 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
2697 touchAndAssertPositions(AMOTION_EVENT_ACTION_UP, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002698
chaviw9eaa22c2020-07-01 16:21:27 -07002699 // Update the transform so rotation is set
2700 mWindow2->setWindowTransform(0, -1, 1, 0);
2701 expectedPoint = getPointInWindow(mWindow2->getInfo(), touchedPoint);
2702 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, {touchedPoint}, {expectedPoint});
chaviwaf87b3e2019-10-01 16:59:28 -07002703}
2704
chaviw9eaa22c2020-07-01 16:21:27 -07002705TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002706 mWindow2->setWindowScale(0.5f, 0.5f);
2707
2708 // Touch Window 1
2709 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2710 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002711 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002712
2713 // Touch Window 2
2714 int32_t actionPointerDown =
2715 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002716 touchedPoints.push_back(PointF{150, 150});
2717 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2718 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002719
chaviw9eaa22c2020-07-01 16:21:27 -07002720 // Release Window 2
2721 int32_t actionPointerUp =
2722 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2723 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2724 expectedPoints.pop_back();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002725
chaviw9eaa22c2020-07-01 16:21:27 -07002726 // Update the transform so rotation is set for Window 2
2727 mWindow2->setWindowTransform(0, -1, 1, 0);
2728 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2729 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002730}
2731
chaviw9eaa22c2020-07-01 16:21:27 -07002732TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchMoveDifferentTransform) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002733 mWindow2->setWindowScale(0.5f, 0.5f);
2734
2735 // Touch Window 1
2736 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2737 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002738 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002739
2740 // Touch Window 2
2741 int32_t actionPointerDown =
2742 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002743 touchedPoints.push_back(PointF{150, 150});
2744 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002745
chaviw9eaa22c2020-07-01 16:21:27 -07002746 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002747
2748 // Move both windows
2749 touchedPoints = {{20, 20}, {175, 175}};
2750 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2751 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2752
chaviw9eaa22c2020-07-01 16:21:27 -07002753 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002754
chaviw9eaa22c2020-07-01 16:21:27 -07002755 // Release Window 2
2756 int32_t actionPointerUp =
2757 AMOTION_EVENT_ACTION_POINTER_UP + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
2758 touchAndAssertPositions(actionPointerUp, touchedPoints, expectedPoints);
2759 expectedPoints.pop_back();
2760
2761 // Touch Window 2
2762 mWindow2->setWindowTransform(0, -1, 1, 0);
2763 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
2764 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
2765
2766 // Move both windows
2767 touchedPoints = {{20, 20}, {175, 175}};
2768 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2769 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2770
2771 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002772}
2773
2774TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithScale) {
2775 mWindow1->setWindowScale(0.5f, 0.5f);
2776
2777 // Touch Window 1
2778 std::vector<PointF> touchedPoints = {PointF{10, 10}};
2779 std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
chaviw9eaa22c2020-07-01 16:21:27 -07002780 touchAndAssertPositions(AMOTION_EVENT_ACTION_DOWN, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002781
2782 // Touch Window 2
2783 int32_t actionPointerDown =
2784 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
chaviw9eaa22c2020-07-01 16:21:27 -07002785 touchedPoints.push_back(PointF{150, 150});
2786 expectedPoints.push_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002787
chaviw9eaa22c2020-07-01 16:21:27 -07002788 touchAndAssertPositions(actionPointerDown, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002789
2790 // Move both windows
2791 touchedPoints = {{20, 20}, {175, 175}};
2792 expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
2793 getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
2794
chaviw9eaa22c2020-07-01 16:21:27 -07002795 touchAndAssertPositions(AMOTION_EVENT_ACTION_MOVE, touchedPoints, expectedPoints);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002796}
2797
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002798class InputDispatcherSingleWindowAnr : public InputDispatcherTest {
2799 virtual void SetUp() override {
2800 InputDispatcherTest::SetUp();
2801
Chris Yea209fde2020-07-22 13:54:51 -07002802 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002803 mApplication->setDispatchingTimeout(20ms);
2804 mWindow =
2805 new FakeWindowHandle(mApplication, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
2806 mWindow->setFrame(Rect(0, 0, 30, 30));
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05002807 mWindow->setDispatchingTimeout(30ms);
Vishnu Nair47074b82020-08-14 11:54:47 -07002808 mWindow->setFocusable(true);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002809 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
2810 // window.
Michael Wright44753b12020-07-08 13:48:11 +01002811 mWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002812
2813 // Set focused application.
2814 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
2815
2816 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07002817 setFocusedWindow(mWindow);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002818 mWindow->consumeFocusEvent(true);
2819 }
2820
2821 virtual void TearDown() override {
2822 InputDispatcherTest::TearDown();
2823 mWindow.clear();
2824 }
2825
2826protected:
Chris Yea209fde2020-07-22 13:54:51 -07002827 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002828 sp<FakeWindowHandle> mWindow;
2829 static constexpr PointF WINDOW_LOCATION = {20, 20};
2830
2831 void tapOnWindow() {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002832 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002833 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2834 WINDOW_LOCATION));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002835 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002836 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2837 WINDOW_LOCATION));
2838 }
2839};
2840
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002841// Send a tap and respond, which should not cause an ANR.
2842TEST_F(InputDispatcherSingleWindowAnr, WhenTouchIsConsumed_NoAnr) {
2843 tapOnWindow();
2844 mWindow->consumeMotionDown();
2845 mWindow->consumeMotionUp();
2846 ASSERT_TRUE(mDispatcher->waitForIdle());
2847 mFakePolicy->assertNotifyAnrWasNotCalled();
2848}
2849
2850// Send a regular key and respond, which should not cause an ANR.
2851TEST_F(InputDispatcherSingleWindowAnr, WhenKeyIsConsumed_NoAnr) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002852 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002853 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
2854 ASSERT_TRUE(mDispatcher->waitForIdle());
2855 mFakePolicy->assertNotifyAnrWasNotCalled();
2856}
2857
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05002858TEST_F(InputDispatcherSingleWindowAnr, WhenFocusedApplicationChanges_NoAnr) {
2859 mWindow->setFocusable(false);
2860 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2861 mWindow->consumeFocusEvent(false);
2862
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002863 InputEventInjectionResult result =
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05002864 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002865 InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/);
2866 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result);
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05002867 // Key will not go to window because we have no focused window.
2868 // The 'no focused window' ANR timer should start instead.
2869
2870 // Now, the focused application goes away.
2871 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, nullptr);
2872 // The key should get dropped and there should be no ANR.
2873
2874 ASSERT_TRUE(mDispatcher->waitForIdle());
2875 mFakePolicy->assertNotifyAnrWasNotCalled();
2876}
2877
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002878// Send an event to the app and have the app not respond right away.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002879// When ANR is raised, policy will tell the dispatcher to cancel the events for that window.
2880// So InputDispatcher will enqueue ACTION_CANCEL event as well.
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002881TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002882 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002883 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2884 WINDOW_LOCATION));
2885
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002886 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent(); // ACTION_DOWN
2887 ASSERT_TRUE(sequenceNum);
2888 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2889 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002890
2891 // The remaining lines are not really needed for the test, but kept as a sanity check
2892 mWindow->finishEvent(*sequenceNum);
2893 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
2894 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002895 ASSERT_TRUE(mDispatcher->waitForIdle());
2896}
2897
2898// Send a key to the app and have the app not respond right away.
2899TEST_F(InputDispatcherSingleWindowAnr, OnKeyDown_BasicAnr) {
2900 // Inject a key, and don't respond - expect that ANR is called.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002901 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher));
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002902 std::optional<uint32_t> sequenceNum = mWindow->receiveEvent();
2903 ASSERT_TRUE(sequenceNum);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002904 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002905 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07002906 ASSERT_TRUE(mDispatcher->waitForIdle());
2907}
2908
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002909// We have a focused application, but no focused window
2910TEST_F(InputDispatcherSingleWindowAnr, FocusedApplication_NoFocusedWindow) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002911 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002912 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2913 mWindow->consumeFocusEvent(false);
2914
2915 // taps on the window work as normal
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002916 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002917 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
2918 WINDOW_LOCATION));
2919 ASSERT_NO_FATAL_FAILURE(mWindow->consumeMotionDown());
2920 mDispatcher->waitForIdle();
2921 mFakePolicy->assertNotifyAnrWasNotCalled();
2922
2923 // Once a focused event arrives, we get an ANR for this application
2924 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2925 // injection times out (instead of failing).
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002926 const InputEventInjectionResult result =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002927 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002928 InputEventInjectionSync::WAIT_FOR_RESULT, 10ms);
2929 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002930 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2931 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2932 ASSERT_TRUE(mDispatcher->waitForIdle());
2933}
2934
2935// We have a focused application, but no focused window
2936// If the policy wants to keep waiting on the focused window to be added, make sure
2937// that this timeout extension is honored and ANR is raised again.
2938TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_ExtendsAnr) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002939 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002940 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2941 mWindow->consumeFocusEvent(false);
2942 const std::chrono::duration timeout = 5ms;
2943 mFakePolicy->setAnrTimeout(timeout);
2944
2945 // Once a focused event arrives, we get an ANR for this application
2946 // We specify the injection timeout to be smaller than the application timeout, to ensure that
2947 // injection times out (instead of failing).
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002948 const InputEventInjectionResult result =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002949 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002950 InputEventInjectionSync::WAIT_FOR_RESULT, 10ms);
2951 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002952 const std::chrono::duration appTimeout =
2953 mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2954 mFakePolicy->assertNotifyAnrWasCalled(appTimeout, mApplication, nullptr /*windowToken*/);
2955
2956 // After the extended time has passed, ANR should be raised again
2957 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2958
2959 // If we stop extending the timeout, dispatcher should go to idle.
2960 // Another ANR may be raised during this time
2961 mFakePolicy->setAnrTimeout(0ms);
2962 ASSERT_TRUE(mDispatcher->waitForIdle());
2963}
2964
2965// We have a focused application, but no focused window
2966TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_DropsFocusedEvents) {
Vishnu Nair47074b82020-08-14 11:54:47 -07002967 mWindow->setFocusable(false);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002968 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
2969 mWindow->consumeFocusEvent(false);
2970
2971 // Once a focused event arrives, we get an ANR for this application
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002972 const InputEventInjectionResult result =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002973 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002974 InputEventInjectionSync::WAIT_FOR_RESULT, 10ms);
2975 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002976
2977 const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
2978 mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
2979
2980 // Future focused events get dropped right away
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002981 ASSERT_EQ(InputEventInjectionResult::FAILED, injectKeyDown(mDispatcher));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002982 ASSERT_TRUE(mDispatcher->waitForIdle());
2983 mWindow->assertNoEvents();
2984}
2985
2986/**
2987 * Ensure that the implementation is valid. Since we are using multiset to keep track of the
2988 * ANR timeouts, we are allowing entries with identical timestamps in the same connection.
2989 * If we process 1 of the events, but ANR on the second event with the same timestamp,
2990 * the ANR mechanism should still work.
2991 *
2992 * In this test, we are injecting DOWN and UP events with the same timestamps, and acknowledging the
2993 * DOWN event, while not responding on the second one.
2994 */
2995TEST_F(InputDispatcherSingleWindowAnr, Anr_HandlesEventsWithIdenticalTimestamps) {
2996 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
2997 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
2998 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
2999 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
3000 AMOTION_EVENT_INVALID_CURSOR_POSITION},
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003001 500ms, InputEventInjectionSync::WAIT_FOR_RESULT, currentTime);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003002
3003 // Now send ACTION_UP, with identical timestamp
3004 injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
3005 ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
3006 {AMOTION_EVENT_INVALID_CURSOR_POSITION,
3007 AMOTION_EVENT_INVALID_CURSOR_POSITION},
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003008 500ms, InputEventInjectionSync::WAIT_FOR_RESULT, currentTime);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003009
3010 // We have now sent down and up. Let's consume first event and then ANR on the second.
3011 mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
3012 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3013 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3014}
3015
3016// If an app is not responding to a key event, gesture monitors should continue to receive
3017// new motion events
3018TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnKey) {
3019 FakeMonitorReceiver monitor =
3020 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
3021 true /*isGestureMonitor*/);
3022
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003023 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
3024 injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003025 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003026 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher, ADISPLAY_ID_DEFAULT));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003027
3028 // Stuck on the ACTION_UP
3029 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3030 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
3031
3032 // New tap will go to the gesture monitor, but not to the window
3033 tapOnWindow();
3034 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3035 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3036
3037 mWindow->consumeKeyUp(ADISPLAY_ID_DEFAULT); // still the previous motion
3038 mDispatcher->waitForIdle();
3039 mWindow->assertNoEvents();
3040 monitor.assertNoEvents();
3041}
3042
3043// If an app is not responding to a motion event, gesture monitors should continue to receive
3044// new motion events
3045TEST_F(InputDispatcherSingleWindowAnr, GestureMonitors_ReceiveEventsDuringAppAnrOnMotion) {
3046 FakeMonitorReceiver monitor =
3047 FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
3048 true /*isGestureMonitor*/);
3049
3050 tapOnWindow();
3051 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3052 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3053
3054 mWindow->consumeMotionDown();
3055 // Stuck on the ACTION_UP
3056 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3057 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr, mWindow->getToken());
3058
3059 // New tap will go to the gesture monitor, but not to the window
3060 tapOnWindow();
3061 monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
3062 monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
3063
3064 mWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT); // still the previous motion
3065 mDispatcher->waitForIdle();
3066 mWindow->assertNoEvents();
3067 monitor.assertNoEvents();
3068}
3069
3070// If a window is unresponsive, then you get anr. if the window later catches up and starts to
3071// process events, you don't get an anr. When the window later becomes unresponsive again, you
3072// get an ANR again.
3073// 1. tap -> block on ACTION_UP -> receive ANR
3074// 2. consume all pending events (= queue becomes healthy again)
3075// 3. tap again -> block on ACTION_UP again -> receive ANR second time
3076TEST_F(InputDispatcherSingleWindowAnr, SameWindow_CanReceiveAnrTwice) {
3077 tapOnWindow();
3078
3079 mWindow->consumeMotionDown();
3080 // Block on ACTION_UP
3081 const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3082 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3083 mWindow->consumeMotionUp(); // Now the connection should be healthy again
3084 mDispatcher->waitForIdle();
3085 mWindow->assertNoEvents();
3086
3087 tapOnWindow();
3088 mWindow->consumeMotionDown();
3089 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3090 mWindow->consumeMotionUp();
3091
3092 mDispatcher->waitForIdle();
3093 mWindow->assertNoEvents();
3094}
3095
3096// If the policy tells us to raise ANR again after some time, ensure that the timeout extension
3097// is honored
3098TEST_F(InputDispatcherSingleWindowAnr, Policy_CanExtendTimeout) {
3099 const std::chrono::duration timeout = 5ms;
3100 mFakePolicy->setAnrTimeout(timeout);
3101
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003102 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003103 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3104 WINDOW_LOCATION));
3105
3106 const std::chrono::duration windowTimeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3107 mFakePolicy->assertNotifyAnrWasCalled(windowTimeout, nullptr /*application*/,
3108 mWindow->getToken());
3109
3110 // Since the policy wanted to extend ANR, make sure it is called again after the extension
3111 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/, mWindow->getToken());
3112 mFakePolicy->setAnrTimeout(0ms);
3113 std::this_thread::sleep_for(windowTimeout);
3114 // We are not checking if ANR has been called, because it may have been called again by the
3115 // time we set the timeout to 0
3116
3117 // When the policy finally says stop, we should get ACTION_CANCEL
3118 mWindow->consumeMotionDown();
3119 mWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_CANCEL,
3120 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3121 mWindow->assertNoEvents();
3122}
3123
3124/**
3125 * If a window is processing a motion event, and then a key event comes in, the key event should
3126 * not to to the focused window until the motion is processed.
3127 *
3128 * Warning!!!
3129 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
3130 * and the injection timeout that we specify when injecting the key.
3131 * We must have the injection timeout (10ms) be smaller than
3132 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
3133 *
3134 * If that value changes, this test should also change.
3135 */
3136TEST_F(InputDispatcherSingleWindowAnr, Key_StaysPendingWhileMotionIsProcessed) {
3137 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
3138 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
3139
3140 tapOnWindow();
3141 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
3142 ASSERT_TRUE(downSequenceNum);
3143 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
3144 ASSERT_TRUE(upSequenceNum);
3145 // Don't finish the events yet, and send a key
3146 // Injection will "succeed" because we will eventually give up and send the key to the focused
3147 // window even if motions are still being processed. But because the injection timeout is short,
3148 // we will receive INJECTION_TIMED_OUT as the result.
3149
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003150 InputEventInjectionResult result =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003151 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003152 InputEventInjectionSync::WAIT_FOR_RESULT, 10ms);
3153 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003154 // Key will not be sent to the window, yet, because the window is still processing events
3155 // and the key remains pending, waiting for the touch events to be processed
3156 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
3157 ASSERT_FALSE(keySequenceNum);
3158
3159 std::this_thread::sleep_for(500ms);
3160 // if we wait long enough though, dispatcher will give up, and still send the key
3161 // to the focused window, even though we have not yet finished the motion event
3162 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3163 mWindow->finishEvent(*downSequenceNum);
3164 mWindow->finishEvent(*upSequenceNum);
3165}
3166
3167/**
3168 * If a window is processing a motion event, and then a key event comes in, the key event should
3169 * not go to the focused window until the motion is processed.
3170 * If then a new motion comes in, then the pending key event should be going to the currently
3171 * focused window right away.
3172 */
3173TEST_F(InputDispatcherSingleWindowAnr,
3174 PendingKey_IsDroppedWhileMotionIsProcessedAndNewTouchComesIn) {
3175 mWindow->setDispatchingTimeout(2s); // Set a long ANR timeout to prevent it from triggering
3176 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
3177
3178 tapOnWindow();
3179 std::optional<uint32_t> downSequenceNum = mWindow->receiveEvent();
3180 ASSERT_TRUE(downSequenceNum);
3181 std::optional<uint32_t> upSequenceNum = mWindow->receiveEvent();
3182 ASSERT_TRUE(upSequenceNum);
3183 // Don't finish the events yet, and send a key
3184 // Injection is async, so it will succeed
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003185 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003186 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003187 ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003188 // At this point, key is still pending, and should not be sent to the application yet.
3189 std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
3190 ASSERT_FALSE(keySequenceNum);
3191
3192 // Now tap down again. It should cause the pending key to go to the focused window right away.
3193 tapOnWindow();
3194 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT); // it doesn't matter that we haven't ack'd
3195 // the other events yet. We can finish events in any order.
3196 mWindow->finishEvent(*downSequenceNum); // first tap's ACTION_DOWN
3197 mWindow->finishEvent(*upSequenceNum); // first tap's ACTION_UP
3198 mWindow->consumeMotionDown();
3199 mWindow->consumeMotionUp();
3200 mWindow->assertNoEvents();
3201}
3202
3203class InputDispatcherMultiWindowAnr : public InputDispatcherTest {
3204 virtual void SetUp() override {
3205 InputDispatcherTest::SetUp();
3206
Chris Yea209fde2020-07-22 13:54:51 -07003207 mApplication = std::make_shared<FakeApplicationHandle>();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003208 mApplication->setDispatchingTimeout(10ms);
3209 mUnfocusedWindow =
3210 new FakeWindowHandle(mApplication, mDispatcher, "Unfocused", ADISPLAY_ID_DEFAULT);
3211 mUnfocusedWindow->setFrame(Rect(0, 0, 30, 30));
3212 // Adding FLAG_NOT_TOUCH_MODAL to ensure taps outside this window are not sent to this
3213 // window.
3214 // Adding FLAG_WATCH_OUTSIDE_TOUCH to receive ACTION_OUTSIDE when another window is tapped
Michael Wright44753b12020-07-08 13:48:11 +01003215 mUnfocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3216 InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH |
3217 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003218
3219 mFocusedWindow =
3220 new FakeWindowHandle(mApplication, mDispatcher, "Focused", ADISPLAY_ID_DEFAULT);
Siarhei Vishniakoua7d36fd2020-06-30 19:32:39 -05003221 mFocusedWindow->setDispatchingTimeout(30ms);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003222 mFocusedWindow->setFrame(Rect(50, 50, 100, 100));
Michael Wright44753b12020-07-08 13:48:11 +01003223 mFocusedWindow->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL |
3224 InputWindowInfo::Flag::SPLIT_TOUCH);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003225
3226 // Set focused application.
3227 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApplication);
Vishnu Nair47074b82020-08-14 11:54:47 -07003228 mFocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003229
3230 // Expect one focus window exist in display.
3231 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07003232 setFocusedWindow(mFocusedWindow);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003233 mFocusedWindow->consumeFocusEvent(true);
3234 }
3235
3236 virtual void TearDown() override {
3237 InputDispatcherTest::TearDown();
3238
3239 mUnfocusedWindow.clear();
3240 mFocusedWindow.clear();
3241 }
3242
3243protected:
Chris Yea209fde2020-07-22 13:54:51 -07003244 std::shared_ptr<FakeApplicationHandle> mApplication;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003245 sp<FakeWindowHandle> mUnfocusedWindow;
3246 sp<FakeWindowHandle> mFocusedWindow;
3247 static constexpr PointF UNFOCUSED_WINDOW_LOCATION = {20, 20};
3248 static constexpr PointF FOCUSED_WINDOW_LOCATION = {75, 75};
3249 static constexpr PointF LOCATION_OUTSIDE_ALL_WINDOWS = {40, 40};
3250
3251 void tapOnFocusedWindow() { tap(FOCUSED_WINDOW_LOCATION); }
3252
3253 void tapOnUnfocusedWindow() { tap(UNFOCUSED_WINDOW_LOCATION); }
3254
3255private:
3256 void tap(const PointF& location) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003257 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003258 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3259 location));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003260 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003261 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3262 location));
3263 }
3264};
3265
3266// If we have 2 windows that are both unresponsive, the one with the shortest timeout
3267// should be ANR'd first.
3268TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsive) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003269 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003270 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3271 FOCUSED_WINDOW_LOCATION))
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003272 << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003273 mFocusedWindow->consumeMotionDown();
3274 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3275 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3276 // We consumed all events, so no ANR
3277 ASSERT_TRUE(mDispatcher->waitForIdle());
3278 mFakePolicy->assertNotifyAnrWasNotCalled();
3279
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003280 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003281 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3282 FOCUSED_WINDOW_LOCATION));
3283 std::optional<uint32_t> unfocusedSequenceNum = mUnfocusedWindow->receiveEvent();
3284 ASSERT_TRUE(unfocusedSequenceNum);
3285 std::optional<uint32_t> focusedSequenceNum = mFocusedWindow->receiveEvent();
3286 ASSERT_TRUE(focusedSequenceNum);
3287
3288 const std::chrono::duration timeout =
3289 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3290 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3291 mFocusedWindow->getToken());
3292
3293 mFocusedWindow->finishEvent(*focusedSequenceNum);
3294 mUnfocusedWindow->finishEvent(*unfocusedSequenceNum);
3295 ASSERT_TRUE(mDispatcher->waitForIdle());
3296}
3297
3298// If we have 2 windows with identical timeouts that are both unresponsive,
3299// it doesn't matter which order they should have ANR.
3300// But we should receive ANR for both.
3301TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsiveWithSameTimeout) {
3302 // Set the timeout for unfocused window to match the focused window
3303 mUnfocusedWindow->setDispatchingTimeout(10ms);
3304 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3305
3306 tapOnFocusedWindow();
3307 // we should have ACTION_DOWN/ACTION_UP on focused window and ACTION_OUTSIDE on unfocused window
Chris Yea209fde2020-07-22 13:54:51 -07003308 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData1 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003309 mFakePolicy->getNotifyAnrData(10ms);
Chris Yea209fde2020-07-22 13:54:51 -07003310 std::pair<std::shared_ptr<InputApplicationHandle>, sp<IBinder>> anrData2 =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003311 mFakePolicy->getNotifyAnrData(0ms);
3312
3313 // We don't know which window will ANR first. But both of them should happen eventually.
3314 ASSERT_TRUE(mFocusedWindow->getToken() == anrData1.second ||
3315 mFocusedWindow->getToken() == anrData2.second);
3316 ASSERT_TRUE(mUnfocusedWindow->getToken() == anrData1.second ||
3317 mUnfocusedWindow->getToken() == anrData2.second);
3318
3319 ASSERT_TRUE(mDispatcher->waitForIdle());
3320 mFakePolicy->assertNotifyAnrWasNotCalled();
3321}
3322
3323// If a window is already not responding, the second tap on the same window should be ignored.
3324// We should also log an error to account for the dropped event (not tested here).
3325// At the same time, FLAG_WATCH_OUTSIDE_TOUCH targets should not receive any events.
3326TEST_F(InputDispatcherMultiWindowAnr, DuringAnr_SecondTapIsIgnored) {
3327 tapOnFocusedWindow();
3328 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3329 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3330 // Receive the events, but don't respond
3331 std::optional<uint32_t> downEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_DOWN
3332 ASSERT_TRUE(downEventSequenceNum);
3333 std::optional<uint32_t> upEventSequenceNum = mFocusedWindow->receiveEvent(); // ACTION_UP
3334 ASSERT_TRUE(upEventSequenceNum);
3335 const std::chrono::duration timeout =
3336 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3337 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3338 mFocusedWindow->getToken());
3339
3340 // Tap once again
3341 // We cannot use "tapOnFocusedWindow" because it asserts the injection result to be success
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003342 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003343 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3344 FOCUSED_WINDOW_LOCATION));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003345 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003346 injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3347 FOCUSED_WINDOW_LOCATION));
3348 // Unfocused window does not receive ACTION_OUTSIDE because the tapped window is not a
3349 // valid touch target
3350 mUnfocusedWindow->assertNoEvents();
3351
3352 // Consume the first tap
3353 mFocusedWindow->finishEvent(*downEventSequenceNum);
3354 mFocusedWindow->finishEvent(*upEventSequenceNum);
3355 ASSERT_TRUE(mDispatcher->waitForIdle());
3356 // The second tap did not go to the focused window
3357 mFocusedWindow->assertNoEvents();
3358 // should not have another ANR after the window just became healthy again
3359 mFakePolicy->assertNotifyAnrWasNotCalled();
3360}
3361
3362// If you tap outside of all windows, there will not be ANR
3363TEST_F(InputDispatcherMultiWindowAnr, TapOutsideAllWindows_DoesNotAnr) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003364 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003365 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3366 LOCATION_OUTSIDE_ALL_WINDOWS));
3367 ASSERT_TRUE(mDispatcher->waitForIdle());
3368 mFakePolicy->assertNotifyAnrWasNotCalled();
3369}
3370
3371// Since the focused window is paused, tapping on it should not produce any events
3372TEST_F(InputDispatcherMultiWindowAnr, Window_CanBePaused) {
3373 mFocusedWindow->setPaused(true);
3374 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
3375
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003376 ASSERT_EQ(InputEventInjectionResult::FAILED,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003377 injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3378 FOCUSED_WINDOW_LOCATION));
3379
3380 std::this_thread::sleep_for(mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT));
3381 ASSERT_TRUE(mDispatcher->waitForIdle());
3382 // Should not ANR because the window is paused, and touches shouldn't go to it
3383 mFakePolicy->assertNotifyAnrWasNotCalled();
3384
3385 mFocusedWindow->assertNoEvents();
3386 mUnfocusedWindow->assertNoEvents();
3387}
3388
3389/**
3390 * If a window is processing a motion event, and then a key event comes in, the key event should
3391 * not to to the focused window until the motion is processed.
3392 * If a different window becomes focused at this time, the key should go to that window instead.
3393 *
3394 * Warning!!!
3395 * This test depends on the value of android::inputdispatcher::KEY_WAITING_FOR_MOTION_TIMEOUT
3396 * and the injection timeout that we specify when injecting the key.
3397 * We must have the injection timeout (10ms) be smaller than
3398 * KEY_WAITING_FOR_MOTION_TIMEOUT (currently 500ms).
3399 *
3400 * If that value changes, this test should also change.
3401 */
3402TEST_F(InputDispatcherMultiWindowAnr, PendingKey_GoesToNewlyFocusedWindow) {
3403 // Set a long ANR timeout to prevent it from triggering
3404 mFocusedWindow->setDispatchingTimeout(2s);
3405 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3406
3407 tapOnUnfocusedWindow();
3408 std::optional<uint32_t> downSequenceNum = mUnfocusedWindow->receiveEvent();
3409 ASSERT_TRUE(downSequenceNum);
3410 std::optional<uint32_t> upSequenceNum = mUnfocusedWindow->receiveEvent();
3411 ASSERT_TRUE(upSequenceNum);
3412 // Don't finish the events yet, and send a key
3413 // Injection will succeed because we will eventually give up and send the key to the focused
3414 // window even if motions are still being processed.
3415
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003416 InputEventInjectionResult result =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003417 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003418 InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/);
3419 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003420 // Key will not be sent to the window, yet, because the window is still processing events
3421 // and the key remains pending, waiting for the touch events to be processed
3422 std::optional<uint32_t> keySequenceNum = mFocusedWindow->receiveEvent();
3423 ASSERT_FALSE(keySequenceNum);
3424
3425 // Switch the focus to the "unfocused" window that we tapped. Expect the key to go there
Vishnu Nair47074b82020-08-14 11:54:47 -07003426 mFocusedWindow->setFocusable(false);
3427 mUnfocusedWindow->setFocusable(true);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003428 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
Vishnu Nair958da932020-08-21 17:12:37 -07003429 setFocusedWindow(mUnfocusedWindow);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003430
3431 // Focus events should precede the key events
3432 mUnfocusedWindow->consumeFocusEvent(true);
3433 mFocusedWindow->consumeFocusEvent(false);
3434
3435 // Finish the tap events, which should unblock dispatcher
3436 mUnfocusedWindow->finishEvent(*downSequenceNum);
3437 mUnfocusedWindow->finishEvent(*upSequenceNum);
3438
3439 // Now that all queues are cleared and no backlog in the connections, the key event
3440 // can finally go to the newly focused "mUnfocusedWindow".
3441 mUnfocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3442 mFocusedWindow->assertNoEvents();
3443 mUnfocusedWindow->assertNoEvents();
3444}
3445
3446// When the touch stream is split across 2 windows, and one of them does not respond,
3447// then ANR should be raised and the touch should be canceled for the unresponsive window.
3448// The other window should not be affected by that.
3449TEST_F(InputDispatcherMultiWindowAnr, SplitTouch_SingleWindowAnr) {
3450 // Touch Window 1
3451 NotifyMotionArgs motionArgs =
3452 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3453 ADISPLAY_ID_DEFAULT, {FOCUSED_WINDOW_LOCATION});
3454 mDispatcher->notifyMotion(&motionArgs);
3455 mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
3456 ADISPLAY_ID_DEFAULT, 0 /*flags*/);
3457
3458 // Touch Window 2
3459 int32_t actionPointerDown =
3460 AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
3461
3462 motionArgs =
3463 generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
3464 {FOCUSED_WINDOW_LOCATION, UNFOCUSED_WINDOW_LOCATION});
3465 mDispatcher->notifyMotion(&motionArgs);
3466
3467 const std::chrono::duration timeout =
3468 mFocusedWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
3469 mFakePolicy->assertNotifyAnrWasCalled(timeout, nullptr /*application*/,
3470 mFocusedWindow->getToken());
3471
3472 mUnfocusedWindow->consumeMotionDown();
3473 mFocusedWindow->consumeMotionDown();
3474 // Focused window may or may not receive ACTION_MOVE
3475 // But it should definitely receive ACTION_CANCEL due to the ANR
3476 InputEvent* event;
3477 std::optional<int32_t> moveOrCancelSequenceNum = mFocusedWindow->receiveEvent(&event);
3478 ASSERT_TRUE(moveOrCancelSequenceNum);
3479 mFocusedWindow->finishEvent(*moveOrCancelSequenceNum);
3480 ASSERT_NE(nullptr, event);
3481 ASSERT_EQ(event->getType(), AINPUT_EVENT_TYPE_MOTION);
3482 MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
3483 if (motionEvent.getAction() == AMOTION_EVENT_ACTION_MOVE) {
3484 mFocusedWindow->consumeMotionCancel();
3485 } else {
3486 ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionEvent.getAction());
3487 }
3488
3489 ASSERT_TRUE(mDispatcher->waitForIdle());
3490 mUnfocusedWindow->assertNoEvents();
3491 mFocusedWindow->assertNoEvents();
3492}
3493
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05003494/**
3495 * If we have no focused window, and a key comes in, we start the ANR timer.
3496 * The focused application should add a focused window before the timer runs out to prevent ANR.
3497 *
3498 * If the user touches another application during this time, the key should be dropped.
3499 * Next, if a new focused window comes in, without toggling the focused application,
3500 * then no ANR should occur.
3501 *
3502 * Normally, we would expect the new focused window to be accompanied by 'setFocusedApplication',
3503 * but in some cases the policy may not update the focused application.
3504 */
3505TEST_F(InputDispatcherMultiWindowAnr, FocusedWindowWithoutSetFocusedApplication_NoAnr) {
3506 std::shared_ptr<FakeApplicationHandle> focusedApplication =
3507 std::make_shared<FakeApplicationHandle>();
3508 focusedApplication->setDispatchingTimeout(60ms);
3509 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, focusedApplication);
3510 // The application that owns 'mFocusedWindow' and 'mUnfocusedWindow' is not focused.
3511 mFocusedWindow->setFocusable(false);
3512
3513 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3514 mFocusedWindow->consumeFocusEvent(false);
3515
3516 // Send a key. The ANR timer should start because there is no focused window.
3517 // 'focusedApplication' will get blamed if this timer completes.
3518 // Key will not be sent anywhere because we have no focused window. It will remain pending.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003519 InputEventInjectionResult result =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05003520 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003521 InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/);
3522 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result);
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05003523
3524 // Wait until dispatcher starts the "no focused window" timer. If we don't wait here,
3525 // then the injected touches won't cause the focused event to get dropped.
3526 // The dispatcher only checks for whether the queue should be pruned upon queueing.
3527 // If we inject the touch right away and the ANR timer hasn't started, the touch event would
3528 // simply be added to the queue without 'shouldPruneInboundQueueLocked' returning 'true'.
3529 // For this test, it means that the key would get delivered to the window once it becomes
3530 // focused.
3531 std::this_thread::sleep_for(10ms);
3532
3533 // Touch unfocused window. This should force the pending key to get dropped.
3534 NotifyMotionArgs motionArgs =
3535 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3536 ADISPLAY_ID_DEFAULT, {UNFOCUSED_WINDOW_LOCATION});
3537 mDispatcher->notifyMotion(&motionArgs);
3538
3539 // We do not consume the motion right away, because that would require dispatcher to first
3540 // process (== drop) the key event, and by that time, ANR will be raised.
3541 // Set the focused window first.
3542 mFocusedWindow->setFocusable(true);
3543 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mFocusedWindow, mUnfocusedWindow}}});
3544 setFocusedWindow(mFocusedWindow);
3545 mFocusedWindow->consumeFocusEvent(true);
3546 // We do not call "setFocusedApplication" here, even though the newly focused window belongs
3547 // to another application. This could be a bug / behaviour in the policy.
3548
3549 mUnfocusedWindow->consumeMotionDown();
3550
3551 ASSERT_TRUE(mDispatcher->waitForIdle());
3552 // Should not ANR because we actually have a focused window. It was just added too slowly.
3553 ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertNotifyAnrWasNotCalled());
3554}
3555
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05003556// These tests ensure we cannot send touch events to a window that's positioned behind a window
3557// that has feature NO_INPUT_CHANNEL.
3558// Layout:
3559// Top (closest to user)
3560// mNoInputWindow (above all windows)
3561// mBottomWindow
3562// Bottom (furthest from user)
3563class InputDispatcherMultiWindowOcclusionTests : public InputDispatcherTest {
3564 virtual void SetUp() override {
3565 InputDispatcherTest::SetUp();
3566
3567 mApplication = std::make_shared<FakeApplicationHandle>();
3568 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3569 "Window without input channel", ADISPLAY_ID_DEFAULT,
3570 std::make_optional<sp<IBinder>>(nullptr) /*token*/);
3571
3572 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3573 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3574 // It's perfectly valid for this window to not have an associated input channel
3575
3576 mBottomWindow = new FakeWindowHandle(mApplication, mDispatcher, "Bottom window",
3577 ADISPLAY_ID_DEFAULT);
3578 mBottomWindow->setFrame(Rect(0, 0, 100, 100));
3579
3580 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3581 }
3582
3583protected:
3584 std::shared_ptr<FakeApplicationHandle> mApplication;
3585 sp<FakeWindowHandle> mNoInputWindow;
3586 sp<FakeWindowHandle> mBottomWindow;
3587};
3588
3589TEST_F(InputDispatcherMultiWindowOcclusionTests, NoInputChannelFeature_DropsTouches) {
3590 PointF touchedPoint = {10, 10};
3591
3592 NotifyMotionArgs motionArgs =
3593 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3594 ADISPLAY_ID_DEFAULT, {touchedPoint});
3595 mDispatcher->notifyMotion(&motionArgs);
3596
3597 mNoInputWindow->assertNoEvents();
3598 // Even though the window 'mNoInputWindow' positioned above 'mBottomWindow' does not have
3599 // an input channel, it is not marked as FLAG_NOT_TOUCHABLE,
3600 // and therefore should prevent mBottomWindow from receiving touches
3601 mBottomWindow->assertNoEvents();
3602}
3603
3604/**
3605 * If a window has feature NO_INPUT_CHANNEL, and somehow (by mistake) still has an input channel,
3606 * ensure that this window does not receive any touches, and blocks touches to windows underneath.
3607 */
3608TEST_F(InputDispatcherMultiWindowOcclusionTests,
3609 NoInputChannelFeature_DropsTouchesWithValidChannel) {
3610 mNoInputWindow = new FakeWindowHandle(mApplication, mDispatcher,
3611 "Window with input channel and NO_INPUT_CHANNEL",
3612 ADISPLAY_ID_DEFAULT);
3613
3614 mNoInputWindow->setInputFeatures(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
3615 mNoInputWindow->setFrame(Rect(0, 0, 100, 100));
3616 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mNoInputWindow, mBottomWindow}}});
3617
3618 PointF touchedPoint = {10, 10};
3619
3620 NotifyMotionArgs motionArgs =
3621 generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
3622 ADISPLAY_ID_DEFAULT, {touchedPoint});
3623 mDispatcher->notifyMotion(&motionArgs);
3624
3625 mNoInputWindow->assertNoEvents();
3626 mBottomWindow->assertNoEvents();
3627}
3628
Vishnu Nair958da932020-08-21 17:12:37 -07003629class InputDispatcherMirrorWindowFocusTests : public InputDispatcherTest {
3630protected:
3631 std::shared_ptr<FakeApplicationHandle> mApp;
3632 sp<FakeWindowHandle> mWindow;
3633 sp<FakeWindowHandle> mMirror;
3634
3635 virtual void SetUp() override {
3636 InputDispatcherTest::SetUp();
3637 mApp = std::make_shared<FakeApplicationHandle>();
3638 mWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT);
3639 mMirror = new FakeWindowHandle(mApp, mDispatcher, "TestWindowMirror", ADISPLAY_ID_DEFAULT,
3640 mWindow->getToken());
3641 mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp);
3642 mWindow->setFocusable(true);
3643 mMirror->setFocusable(true);
3644 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3645 }
3646};
3647
3648TEST_F(InputDispatcherMirrorWindowFocusTests, CanGetFocus) {
3649 // Request focus on a mirrored window
3650 setFocusedWindow(mMirror);
3651
3652 // window gets focused
3653 mWindow->consumeFocusEvent(true);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003654 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
3655 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003656 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
3657}
3658
3659// A focused & mirrored window remains focused only if the window and its mirror are both
3660// focusable.
3661TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAllWindowsFocusable) {
3662 setFocusedWindow(mMirror);
3663
3664 // window gets focused
3665 mWindow->consumeFocusEvent(true);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003666 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
3667 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003668 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003669 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
3670 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003671 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3672
3673 mMirror->setFocusable(false);
3674 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3675
3676 // window loses focus since one of the windows associated with the token in not focusable
3677 mWindow->consumeFocusEvent(false);
3678
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003679 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
3680 << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
Vishnu Nair958da932020-08-21 17:12:37 -07003681 mWindow->assertNoEvents();
3682}
3683
3684// A focused & mirrored window remains focused until the window and its mirror both become
3685// invisible.
3686TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedIfAnyWindowVisible) {
3687 setFocusedWindow(mMirror);
3688
3689 // window gets focused
3690 mWindow->consumeFocusEvent(true);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003691 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
3692 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003693 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003694 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
3695 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003696 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3697
3698 mMirror->setVisible(false);
3699 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3700
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003701 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
3702 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003703 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003704 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
3705 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003706 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3707
3708 mWindow->setVisible(false);
3709 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3710
3711 // window loses focus only after all windows associated with the token become invisible.
3712 mWindow->consumeFocusEvent(false);
3713
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003714 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
3715 << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
Vishnu Nair958da932020-08-21 17:12:37 -07003716 mWindow->assertNoEvents();
3717}
3718
3719// A focused & mirrored window remains focused until both windows are removed.
3720TEST_F(InputDispatcherMirrorWindowFocusTests, FocusedWhileWindowsAlive) {
3721 setFocusedWindow(mMirror);
3722
3723 // window gets focused
3724 mWindow->consumeFocusEvent(true);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003725 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
3726 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003727 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003728 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
3729 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003730 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3731
3732 // single window is removed but the window token remains focused
3733 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mMirror}}});
3734
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003735 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
3736 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003737 mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003738 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
3739 << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
Vishnu Nair958da932020-08-21 17:12:37 -07003740 mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
3741
3742 // Both windows are removed
3743 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {}}});
3744 mWindow->consumeFocusEvent(false);
3745
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003746 ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
3747 << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
Vishnu Nair958da932020-08-21 17:12:37 -07003748 mWindow->assertNoEvents();
3749}
3750
3751// Focus request can be pending until one window becomes visible.
3752TEST_F(InputDispatcherMirrorWindowFocusTests, DeferFocusWhenInvisible) {
3753 // Request focus on an invisible mirror.
3754 mWindow->setVisible(false);
3755 mMirror->setVisible(false);
3756 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3757 setFocusedWindow(mMirror);
3758
3759 // Injected key goes to pending queue.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003760 ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
Vishnu Nair958da932020-08-21 17:12:37 -07003761 injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003762 ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE));
Vishnu Nair958da932020-08-21 17:12:37 -07003763
3764 mMirror->setVisible(true);
3765 mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
3766
3767 // window gets focused
3768 mWindow->consumeFocusEvent(true);
3769 // window gets the pending key event
3770 mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
3771}
Garfield Tane84e6f92019-08-29 17:28:41 -07003772} // namespace android::inputdispatcher