1 /*
2 * Copyright 2024 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
17 #include "FakeInputDispatcherPolicy.h"
18
19 #include <gtest/gtest.h>
20
21 namespace android {
22
23 // --- FakeInputDispatcherPolicy ---
24
assertFilterInputEventWasCalled(const NotifyKeyArgs & args)25 void FakeInputDispatcherPolicy::assertFilterInputEventWasCalled(const NotifyKeyArgs& args) {
26 assertFilterInputEventWasCalledInternal([&args](const InputEvent& event) {
27 ASSERT_EQ(event.getType(), InputEventType::KEY);
28 EXPECT_EQ(event.getDisplayId(), args.displayId);
29
30 const auto& keyEvent = static_cast<const KeyEvent&>(event);
31 EXPECT_EQ(keyEvent.getEventTime(), args.eventTime);
32 EXPECT_EQ(keyEvent.getAction(), args.action);
33 });
34 }
35
assertFilterInputEventWasCalled(const NotifyMotionArgs & args,vec2 point)36 void FakeInputDispatcherPolicy::assertFilterInputEventWasCalled(const NotifyMotionArgs& args,
37 vec2 point) {
38 assertFilterInputEventWasCalledInternal([&](const InputEvent& event) {
39 ASSERT_EQ(event.getType(), InputEventType::MOTION);
40 EXPECT_EQ(event.getDisplayId(), args.displayId);
41
42 const auto& motionEvent = static_cast<const MotionEvent&>(event);
43 EXPECT_EQ(motionEvent.getEventTime(), args.eventTime);
44 EXPECT_EQ(motionEvent.getAction(), args.action);
45 EXPECT_NEAR(motionEvent.getX(0), point.x, MotionEvent::ROUNDING_PRECISION);
46 EXPECT_NEAR(motionEvent.getY(0), point.y, MotionEvent::ROUNDING_PRECISION);
47 EXPECT_NEAR(motionEvent.getRawX(0), point.x, MotionEvent::ROUNDING_PRECISION);
48 EXPECT_NEAR(motionEvent.getRawY(0), point.y, MotionEvent::ROUNDING_PRECISION);
49 });
50 }
51
assertFilterInputEventWasNotCalled()52 void FakeInputDispatcherPolicy::assertFilterInputEventWasNotCalled() {
53 std::scoped_lock lock(mLock);
54 ASSERT_EQ(nullptr, mFilteredEvent);
55 }
56
assertNotifyConfigurationChangedWasCalled(nsecs_t when)57 void FakeInputDispatcherPolicy::assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
58 std::scoped_lock lock(mLock);
59 ASSERT_TRUE(mConfigurationChangedTime) << "Timed out waiting for configuration changed call";
60 ASSERT_EQ(*mConfigurationChangedTime, when);
61 mConfigurationChangedTime = std::nullopt;
62 }
63
assertNotifySwitchWasCalled(const NotifySwitchArgs & args)64 void FakeInputDispatcherPolicy::assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
65 std::scoped_lock lock(mLock);
66 ASSERT_TRUE(mLastNotifySwitch);
67 // We do not check id because it is not exposed to the policy
68 EXPECT_EQ(args.eventTime, mLastNotifySwitch->eventTime);
69 EXPECT_EQ(args.policyFlags, mLastNotifySwitch->policyFlags);
70 EXPECT_EQ(args.switchValues, mLastNotifySwitch->switchValues);
71 EXPECT_EQ(args.switchMask, mLastNotifySwitch->switchMask);
72 mLastNotifySwitch = std::nullopt;
73 }
74
assertOnPointerDownEquals(const sp<IBinder> & touchedToken)75 void FakeInputDispatcherPolicy::assertOnPointerDownEquals(const sp<IBinder>& touchedToken) {
76 std::scoped_lock lock(mLock);
77 ASSERT_EQ(touchedToken, mOnPointerDownToken);
78 mOnPointerDownToken.clear();
79 }
80
assertOnPointerDownWasNotCalled()81 void FakeInputDispatcherPolicy::assertOnPointerDownWasNotCalled() {
82 std::scoped_lock lock(mLock);
83 ASSERT_TRUE(mOnPointerDownToken == nullptr)
84 << "Expected onPointerDownOutsideFocus to not have been called";
85 }
86
assertNotifyNoFocusedWindowAnrWasCalled(std::chrono::nanoseconds timeout,const std::shared_ptr<InputApplicationHandle> & expectedApplication)87 void FakeInputDispatcherPolicy::assertNotifyNoFocusedWindowAnrWasCalled(
88 std::chrono::nanoseconds timeout,
89 const std::shared_ptr<InputApplicationHandle>& expectedApplication) {
90 std::unique_lock lock(mLock);
91 android::base::ScopedLockAssertion assumeLocked(mLock);
92 std::shared_ptr<InputApplicationHandle> application;
93 ASSERT_NO_FATAL_FAILURE(
94 application = getAnrTokenLockedInterruptible(timeout, mAnrApplications, lock));
95 ASSERT_EQ(expectedApplication, application);
96 }
97
assertNotifyWindowUnresponsiveWasCalled(std::chrono::nanoseconds timeout,const sp<gui::WindowInfoHandle> & window)98 void FakeInputDispatcherPolicy::assertNotifyWindowUnresponsiveWasCalled(
99 std::chrono::nanoseconds timeout, const sp<gui::WindowInfoHandle>& window) {
100 LOG_ALWAYS_FATAL_IF(window == nullptr, "window should not be null");
101 assertNotifyWindowUnresponsiveWasCalled(timeout, window->getToken(),
102 window->getInfo()->ownerPid);
103 }
104
assertNotifyWindowUnresponsiveWasCalled(std::chrono::nanoseconds timeout,const sp<IBinder> & expectedToken,std::optional<gui::Pid> expectedPid)105 void FakeInputDispatcherPolicy::assertNotifyWindowUnresponsiveWasCalled(
106 std::chrono::nanoseconds timeout, const sp<IBinder>& expectedToken,
107 std::optional<gui::Pid> expectedPid) {
108 std::unique_lock lock(mLock);
109 android::base::ScopedLockAssertion assumeLocked(mLock);
110 AnrResult result;
111 ASSERT_NO_FATAL_FAILURE(result = getAnrTokenLockedInterruptible(timeout, mAnrWindows, lock));
112 ASSERT_EQ(expectedToken, result.token);
113 ASSERT_EQ(expectedPid, result.pid);
114 }
115
getUnresponsiveWindowToken(std::chrono::nanoseconds timeout)116 sp<IBinder> FakeInputDispatcherPolicy::getUnresponsiveWindowToken(
117 std::chrono::nanoseconds timeout) {
118 std::unique_lock lock(mLock);
119 android::base::ScopedLockAssertion assumeLocked(mLock);
120 AnrResult result = getAnrTokenLockedInterruptible(timeout, mAnrWindows, lock);
121 const auto& [token, _] = result;
122 return token;
123 }
124
assertNotifyWindowResponsiveWasCalled(const sp<IBinder> & expectedToken,std::optional<gui::Pid> expectedPid)125 void FakeInputDispatcherPolicy::assertNotifyWindowResponsiveWasCalled(
126 const sp<IBinder>& expectedToken, std::optional<gui::Pid> expectedPid) {
127 std::unique_lock lock(mLock);
128 android::base::ScopedLockAssertion assumeLocked(mLock);
129 AnrResult result;
130 ASSERT_NO_FATAL_FAILURE(result = getAnrTokenLockedInterruptible(0s, mResponsiveWindows, lock));
131 ASSERT_EQ(expectedToken, result.token);
132 ASSERT_EQ(expectedPid, result.pid);
133 }
134
getResponsiveWindowToken()135 sp<IBinder> FakeInputDispatcherPolicy::getResponsiveWindowToken() {
136 std::unique_lock lock(mLock);
137 android::base::ScopedLockAssertion assumeLocked(mLock);
138 AnrResult result = getAnrTokenLockedInterruptible(0s, mResponsiveWindows, lock);
139 const auto& [token, _] = result;
140 return token;
141 }
142
assertNotifyAnrWasNotCalled()143 void FakeInputDispatcherPolicy::assertNotifyAnrWasNotCalled() {
144 std::scoped_lock lock(mLock);
145 ASSERT_TRUE(mAnrApplications.empty());
146 ASSERT_TRUE(mAnrWindows.empty());
147 ASSERT_TRUE(mResponsiveWindows.empty())
148 << "ANR was not called, but please also consume the 'connection is responsive' "
149 "signal";
150 }
151
assertSetPointerCaptureCalled(const sp<gui::WindowInfoHandle> & window,bool enabled)152 PointerCaptureRequest FakeInputDispatcherPolicy::assertSetPointerCaptureCalled(
153 const sp<gui::WindowInfoHandle>& window, bool enabled) {
154 std::unique_lock lock(mLock);
155 base::ScopedLockAssertion assumeLocked(mLock);
156
157 if (!mPointerCaptureChangedCondition
158 .wait_for(lock, 100ms, [this, enabled, window]() REQUIRES(mLock) {
159 if (enabled) {
160 return mPointerCaptureRequest->isEnable() &&
161 mPointerCaptureRequest->window == window->getToken();
162 } else {
163 return !mPointerCaptureRequest->isEnable();
164 }
165 })) {
166 ADD_FAILURE() << "Timed out waiting for setPointerCapture(" << window->getName() << ", "
167 << enabled << ") to be called.";
168 return {};
169 }
170 auto request = *mPointerCaptureRequest;
171 mPointerCaptureRequest.reset();
172 return request;
173 }
174
assertSetPointerCaptureNotCalled()175 void FakeInputDispatcherPolicy::assertSetPointerCaptureNotCalled() {
176 std::unique_lock lock(mLock);
177 base::ScopedLockAssertion assumeLocked(mLock);
178
179 if (mPointerCaptureChangedCondition.wait_for(lock, 100ms) != std::cv_status::timeout) {
180 FAIL() << "Expected setPointerCapture(request) to not be called, but was called. "
181 "enabled = "
182 << std::to_string(mPointerCaptureRequest->isEnable());
183 }
184 mPointerCaptureRequest.reset();
185 }
186
assertDropTargetEquals(const InputDispatcherInterface & dispatcher,const sp<IBinder> & targetToken)187 void FakeInputDispatcherPolicy::assertDropTargetEquals(const InputDispatcherInterface& dispatcher,
188 const sp<IBinder>& targetToken) {
189 dispatcher.waitForIdle();
190 std::scoped_lock lock(mLock);
191 ASSERT_TRUE(mNotifyDropWindowWasCalled);
192 ASSERT_EQ(targetToken, mDropTargetWindowToken);
193 mNotifyDropWindowWasCalled = false;
194 }
195
assertNotifyInputChannelBrokenWasCalled(const sp<IBinder> & token)196 void FakeInputDispatcherPolicy::assertNotifyInputChannelBrokenWasCalled(const sp<IBinder>& token) {
197 std::unique_lock lock(mLock);
198 base::ScopedLockAssertion assumeLocked(mLock);
199 std::optional<sp<IBinder>> receivedToken =
200 getItemFromStorageLockedInterruptible(100ms, mBrokenInputChannels, lock,
201 mNotifyInputChannelBroken);
202 ASSERT_TRUE(receivedToken.has_value()) << "Did not receive the broken channel token";
203 ASSERT_EQ(token, *receivedToken);
204 }
205
setInterceptKeyTimeout(std::chrono::milliseconds timeout)206 void FakeInputDispatcherPolicy::setInterceptKeyTimeout(std::chrono::milliseconds timeout) {
207 mInterceptKeyTimeout = timeout;
208 }
209
getKeyWaitingForEventsTimeout()210 std::chrono::nanoseconds FakeInputDispatcherPolicy::getKeyWaitingForEventsTimeout() {
211 return 500ms;
212 }
213
setStaleEventTimeout(std::chrono::nanoseconds timeout)214 void FakeInputDispatcherPolicy::setStaleEventTimeout(std::chrono::nanoseconds timeout) {
215 mStaleEventTimeout = timeout;
216 }
217
setConsumeKeyBeforeDispatching(bool consumeKeyBeforeDispatching)218 void FakeInputDispatcherPolicy::setConsumeKeyBeforeDispatching(bool consumeKeyBeforeDispatching) {
219 mConsumeKeyBeforeDispatching = consumeKeyBeforeDispatching;
220 }
221
assertFocusedDisplayNotified(ui::LogicalDisplayId expectedDisplay)222 void FakeInputDispatcherPolicy::assertFocusedDisplayNotified(ui::LogicalDisplayId expectedDisplay) {
223 std::unique_lock lock(mLock);
224 base::ScopedLockAssertion assumeLocked(mLock);
225
226 if (!mFocusedDisplayNotifiedCondition.wait_for(lock, 100ms,
227 [this, expectedDisplay]() REQUIRES(mLock) {
228 if (!mNotifiedFocusedDisplay.has_value() ||
229 mNotifiedFocusedDisplay.value() !=
230 expectedDisplay) {
231 return false;
232 }
233 return true;
234 })) {
235 ADD_FAILURE() << "Timed out waiting for notifyFocusedDisplayChanged(" << expectedDisplay
236 << ") to be called.";
237 }
238 }
239
assertUserActivityNotPoked()240 void FakeInputDispatcherPolicy::assertUserActivityNotPoked() {
241 std::unique_lock lock(mLock);
242 base::ScopedLockAssertion assumeLocked(mLock);
243
244 std::optional<UserActivityPokeEvent> pokeEvent =
245 getItemFromStorageLockedInterruptible(500ms, mUserActivityPokeEvents, lock,
246 mNotifyUserActivity);
247
248 ASSERT_FALSE(pokeEvent) << "Expected user activity not to have been poked";
249 }
250
assertUserActivityPoked(std::optional<UserActivityPokeEvent> expectedPokeEvent)251 void FakeInputDispatcherPolicy::assertUserActivityPoked(
252 std::optional<UserActivityPokeEvent> expectedPokeEvent) {
253 std::unique_lock lock(mLock);
254 base::ScopedLockAssertion assumeLocked(mLock);
255
256 std::optional<UserActivityPokeEvent> pokeEvent =
257 getItemFromStorageLockedInterruptible(500ms, mUserActivityPokeEvents, lock,
258 mNotifyUserActivity);
259 ASSERT_TRUE(pokeEvent) << "Expected a user poke event";
260
261 if (expectedPokeEvent) {
262 ASSERT_EQ(expectedPokeEvent, *pokeEvent);
263 }
264 }
265
assertNotifyDeviceInteractionWasCalled(int32_t deviceId,std::set<gui::Uid> uids)266 void FakeInputDispatcherPolicy::assertNotifyDeviceInteractionWasCalled(int32_t deviceId,
267 std::set<gui::Uid> uids) {
268 ASSERT_EQ(std::make_pair(deviceId, uids), mNotifiedInteractions.popWithTimeout(100ms));
269 }
270
assertNotifyDeviceInteractionWasNotCalled()271 void FakeInputDispatcherPolicy::assertNotifyDeviceInteractionWasNotCalled() {
272 ASSERT_FALSE(mNotifiedInteractions.popWithTimeout(10ms));
273 }
274
setUnhandledKeyHandler(std::function<std::optional<KeyEvent> (const KeyEvent &)> handler)275 void FakeInputDispatcherPolicy::setUnhandledKeyHandler(
276 std::function<std::optional<KeyEvent>(const KeyEvent&)> handler) {
277 std::scoped_lock lock(mLock);
278 mUnhandledKeyHandler = handler;
279 }
280
assertUnhandledKeyReported(int32_t keycode)281 void FakeInputDispatcherPolicy::assertUnhandledKeyReported(int32_t keycode) {
282 std::unique_lock lock(mLock);
283 base::ScopedLockAssertion assumeLocked(mLock);
284 std::optional<int32_t> unhandledKeycode =
285 getItemFromStorageLockedInterruptible(100ms, mReportedUnhandledKeycodes, lock,
286 mNotifyUnhandledKey);
287 ASSERT_TRUE(unhandledKeycode) << "Expected unhandled key to be reported";
288 ASSERT_EQ(unhandledKeycode, keycode);
289 }
290
assertUnhandledKeyNotReported()291 void FakeInputDispatcherPolicy::assertUnhandledKeyNotReported() {
292 std::unique_lock lock(mLock);
293 base::ScopedLockAssertion assumeLocked(mLock);
294 std::optional<int32_t> unhandledKeycode =
295 getItemFromStorageLockedInterruptible(10ms, mReportedUnhandledKeycodes, lock,
296 mNotifyUnhandledKey);
297 ASSERT_FALSE(unhandledKeycode) << "Expected unhandled key NOT to be reported";
298 }
299
300 template <class T>
getAnrTokenLockedInterruptible(std::chrono::nanoseconds timeout,std::queue<T> & storage,std::unique_lock<std::mutex> & lock)301 T FakeInputDispatcherPolicy::getAnrTokenLockedInterruptible(std::chrono::nanoseconds timeout,
302 std::queue<T>& storage,
303 std::unique_lock<std::mutex>& lock)
304 REQUIRES(mLock) {
305 // If there is an ANR, Dispatcher won't be idle because there are still events
306 // in the waitQueue that we need to check on. So we can't wait for dispatcher to be idle
307 // before checking if ANR was called.
308 // Since dispatcher is not guaranteed to call notifyNoFocusedWindowAnr right away, we need
309 // to provide it some time to act. 100ms seems reasonable.
310 std::chrono::duration timeToWait = timeout + 100ms; // provide some slack
311 const std::chrono::time_point start = std::chrono::steady_clock::now();
312 std::optional<T> token =
313 getItemFromStorageLockedInterruptible(timeToWait, storage, lock, mNotifyAnr);
314 if (!token.has_value()) {
315 ADD_FAILURE() << "Did not receive the ANR callback";
316 return {};
317 }
318
319 const std::chrono::duration waited = std::chrono::steady_clock::now() - start;
320 // Ensure that the ANR didn't get raised too early. We can't be too strict here because
321 // the dispatcher started counting before this function was called
322 if (std::chrono::abs(timeout - waited) > 100ms) {
323 ADD_FAILURE() << "ANR was raised too early or too late. Expected "
324 << std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count()
325 << "ms, but waited "
326 << std::chrono::duration_cast<std::chrono::milliseconds>(waited).count()
327 << "ms instead";
328 }
329 return *token;
330 }
331
332 template <class T>
getItemFromStorageLockedInterruptible(std::chrono::nanoseconds timeout,std::queue<T> & storage,std::unique_lock<std::mutex> & lock,std::condition_variable & condition)333 std::optional<T> FakeInputDispatcherPolicy::getItemFromStorageLockedInterruptible(
334 std::chrono::nanoseconds timeout, std::queue<T>& storage,
335 std::unique_lock<std::mutex>& lock, std::condition_variable& condition) REQUIRES(mLock) {
336 condition.wait_for(lock, timeout, [&storage]() REQUIRES(mLock) { return !storage.empty(); });
337 if (storage.empty()) {
338 return std::nullopt;
339 }
340 T item = storage.front();
341 storage.pop();
342 return std::make_optional(item);
343 }
344
notifyConfigurationChanged(nsecs_t when)345 void FakeInputDispatcherPolicy::notifyConfigurationChanged(nsecs_t when) {
346 std::scoped_lock lock(mLock);
347 mConfigurationChangedTime = when;
348 }
349
notifyWindowUnresponsive(const sp<IBinder> & connectionToken,std::optional<gui::Pid> pid,const std::string &)350 void FakeInputDispatcherPolicy::notifyWindowUnresponsive(const sp<IBinder>& connectionToken,
351 std::optional<gui::Pid> pid,
352 const std::string&) {
353 std::scoped_lock lock(mLock);
354 mAnrWindows.push({connectionToken, pid});
355 mNotifyAnr.notify_all();
356 }
357
notifyWindowResponsive(const sp<IBinder> & connectionToken,std::optional<gui::Pid> pid)358 void FakeInputDispatcherPolicy::notifyWindowResponsive(const sp<IBinder>& connectionToken,
359 std::optional<gui::Pid> pid) {
360 std::scoped_lock lock(mLock);
361 mResponsiveWindows.push({connectionToken, pid});
362 mNotifyAnr.notify_all();
363 }
364
notifyNoFocusedWindowAnr(const std::shared_ptr<InputApplicationHandle> & applicationHandle)365 void FakeInputDispatcherPolicy::notifyNoFocusedWindowAnr(
366 const std::shared_ptr<InputApplicationHandle>& applicationHandle) {
367 std::scoped_lock lock(mLock);
368 mAnrApplications.push(applicationHandle);
369 mNotifyAnr.notify_all();
370 }
371
notifyInputChannelBroken(const sp<IBinder> & connectionToken)372 void FakeInputDispatcherPolicy::notifyInputChannelBroken(const sp<IBinder>& connectionToken) {
373 std::scoped_lock lock(mLock);
374 mBrokenInputChannels.push(connectionToken);
375 mNotifyInputChannelBroken.notify_all();
376 }
377
notifyFocusChanged(const sp<IBinder> &,const sp<IBinder> &)378 void FakeInputDispatcherPolicy::notifyFocusChanged(const sp<IBinder>&, const sp<IBinder>&) {}
379
notifySensorEvent(int32_t deviceId,InputDeviceSensorType sensorType,InputDeviceSensorAccuracy accuracy,nsecs_t timestamp,const std::vector<float> & values)380 void FakeInputDispatcherPolicy::notifySensorEvent(int32_t deviceId,
381 InputDeviceSensorType sensorType,
382 InputDeviceSensorAccuracy accuracy,
383 nsecs_t timestamp,
384 const std::vector<float>& values) {}
385
notifySensorAccuracy(int deviceId,InputDeviceSensorType sensorType,InputDeviceSensorAccuracy accuracy)386 void FakeInputDispatcherPolicy::notifySensorAccuracy(int deviceId, InputDeviceSensorType sensorType,
387 InputDeviceSensorAccuracy accuracy) {}
388
notifyVibratorState(int32_t deviceId,bool isOn)389 void FakeInputDispatcherPolicy::notifyVibratorState(int32_t deviceId, bool isOn) {}
390
filterInputEvent(const InputEvent & inputEvent,uint32_t policyFlags)391 bool FakeInputDispatcherPolicy::filterInputEvent(const InputEvent& inputEvent,
392 uint32_t policyFlags) {
393 std::scoped_lock lock(mLock);
394 switch (inputEvent.getType()) {
395 case InputEventType::KEY: {
396 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(inputEvent);
397 mFilteredEvent = std::make_unique<KeyEvent>(keyEvent);
398 break;
399 }
400
401 case InputEventType::MOTION: {
402 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(inputEvent);
403 mFilteredEvent = std::make_unique<MotionEvent>(motionEvent);
404 break;
405 }
406 default: {
407 ADD_FAILURE() << "Should only filter keys or motions";
408 break;
409 }
410 }
411 return true;
412 }
413
interceptKeyBeforeQueueing(const KeyEvent & inputEvent,uint32_t &)414 void FakeInputDispatcherPolicy::interceptKeyBeforeQueueing(const KeyEvent& inputEvent, uint32_t&) {
415 if (inputEvent.getAction() == AKEY_EVENT_ACTION_UP) {
416 // Clear intercept state when we handled the event.
417 mInterceptKeyTimeout = 0ms;
418 }
419 }
420
interceptMotionBeforeQueueing(ui::LogicalDisplayId,uint32_t,int32_t,nsecs_t,uint32_t &)421 void FakeInputDispatcherPolicy::interceptMotionBeforeQueueing(ui::LogicalDisplayId, uint32_t,
422 int32_t, nsecs_t, uint32_t&) {}
423
interceptKeyBeforeDispatching(const sp<IBinder> &,const KeyEvent &,uint32_t)424 nsecs_t FakeInputDispatcherPolicy::interceptKeyBeforeDispatching(const sp<IBinder>&,
425 const KeyEvent&, uint32_t) {
426 if (mConsumeKeyBeforeDispatching) {
427 return -1;
428 }
429 nsecs_t delay = std::chrono::nanoseconds(mInterceptKeyTimeout).count();
430 // Clear intercept state so we could dispatch the event in next wake.
431 mInterceptKeyTimeout = 0ms;
432 return delay;
433 }
434
dispatchUnhandledKey(const sp<IBinder> &,const KeyEvent & event,uint32_t)435 std::optional<KeyEvent> FakeInputDispatcherPolicy::dispatchUnhandledKey(const sp<IBinder>&,
436 const KeyEvent& event,
437 uint32_t) {
438 std::scoped_lock lock(mLock);
439 mReportedUnhandledKeycodes.emplace(event.getKeyCode());
440 mNotifyUnhandledKey.notify_all();
441 return mUnhandledKeyHandler != nullptr ? mUnhandledKeyHandler(event) : std::nullopt;
442 }
443
notifySwitch(nsecs_t when,uint32_t switchValues,uint32_t switchMask,uint32_t policyFlags)444 void FakeInputDispatcherPolicy::notifySwitch(nsecs_t when, uint32_t switchValues,
445 uint32_t switchMask, uint32_t policyFlags) {
446 std::scoped_lock lock(mLock);
447 // We simply reconstruct NotifySwitchArgs in policy because InputDispatcher is
448 // essentially a passthrough for notifySwitch.
449 mLastNotifySwitch =
450 NotifySwitchArgs(InputEvent::nextId(), when, policyFlags, switchValues, switchMask);
451 }
452
pokeUserActivity(nsecs_t eventTime,int32_t eventType,ui::LogicalDisplayId displayId)453 void FakeInputDispatcherPolicy::pokeUserActivity(nsecs_t eventTime, int32_t eventType,
454 ui::LogicalDisplayId displayId) {
455 std::scoped_lock lock(mLock);
456 mNotifyUserActivity.notify_all();
457 mUserActivityPokeEvents.push({eventTime, eventType, displayId});
458 }
459
isStaleEvent(nsecs_t currentTime,nsecs_t eventTime)460 bool FakeInputDispatcherPolicy::isStaleEvent(nsecs_t currentTime, nsecs_t eventTime) {
461 return std::chrono::nanoseconds(currentTime - eventTime) >= mStaleEventTimeout;
462 }
463
onPointerDownOutsideFocus(const sp<IBinder> & newToken)464 void FakeInputDispatcherPolicy::onPointerDownOutsideFocus(const sp<IBinder>& newToken) {
465 std::scoped_lock lock(mLock);
466 mOnPointerDownToken = newToken;
467 }
468
setPointerCapture(const PointerCaptureRequest & request)469 void FakeInputDispatcherPolicy::setPointerCapture(const PointerCaptureRequest& request) {
470 std::scoped_lock lock(mLock);
471 mPointerCaptureRequest = {request};
472 mPointerCaptureChangedCondition.notify_all();
473 }
474
notifyDropWindow(const sp<IBinder> & token,float x,float y)475 void FakeInputDispatcherPolicy::notifyDropWindow(const sp<IBinder>& token, float x, float y) {
476 std::scoped_lock lock(mLock);
477 mNotifyDropWindowWasCalled = true;
478 mDropTargetWindowToken = token;
479 }
480
notifyDeviceInteraction(int32_t deviceId,nsecs_t timestamp,const std::set<gui::Uid> & uids)481 void FakeInputDispatcherPolicy::notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp,
482 const std::set<gui::Uid>& uids) {
483 ASSERT_TRUE(mNotifiedInteractions.emplace(deviceId, uids));
484 }
485
assertFilterInputEventWasCalledInternal(const std::function<void (const InputEvent &)> & verify)486 void FakeInputDispatcherPolicy::assertFilterInputEventWasCalledInternal(
487 const std::function<void(const InputEvent&)>& verify) {
488 std::scoped_lock lock(mLock);
489 ASSERT_NE(nullptr, mFilteredEvent) << "Expected filterInputEvent() to have been called.";
490 verify(*mFilteredEvent);
491 mFilteredEvent = nullptr;
492 }
493
notifyFocusedDisplayChanged(ui::LogicalDisplayId displayId)494 void FakeInputDispatcherPolicy::notifyFocusedDisplayChanged(ui::LogicalDisplayId displayId) {
495 std::scoped_lock lock(mLock);
496 mNotifiedFocusedDisplay = displayId;
497 mFocusedDisplayNotifiedCondition.notify_all();
498 }
499
500 } // namespace android
501