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