Wait until dispatcher is idle

Add a mechanism for waiting until the dispatcher is idle. This will
allow tests to not have to wait until a specific timeout is reached when
asserting that a callback did not happen.

For example, the current test approach is like this: 1) do something 2)
monitor policy for a certain amount of time 3) check that the thing you
are interested in did not happen.

With this approach, we will modify this behaviour to be as follows: 1)
do something 2) wait until dispatcher is idle 3) check that the thing
didn't happen.

In this case, the dispatcher is idle condition will happen sooner than
the timeout in the original approach. This will help keep the tests
fast.

Bug: 70668286
Test: atest inputflinger_tests
Change-Id: I2ac5e38ccbc388fe6d94832405b68ef9e52d25f4
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 9c0e08e..b9bec44 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -298,6 +298,12 @@
         if (runCommandsLockedInterruptible()) {
             nextWakeupTime = LONG_LONG_MIN;
         }
+
+        // We are about to enter an infinitely long sleep, because we have no commands or
+        // pending or queued events
+        if (nextWakeupTime == LONG_LONG_MAX) {
+            mDispatcherEnteredIdle.notify_all();
+        }
     } // release lock
 
     // Wait for callback or timeout or wake.  (make sure we round up, not down)
@@ -4582,4 +4588,22 @@
     mDispatcherIsAlive.wait(_l);
 }
 
+/**
+ * Wake up the dispatcher and wait until it processes all events and commands.
+ * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
+ * this method can be safely called from any thread, as long as you've ensured that
+ * the work you are interested in completing has already been queued.
+ */
+bool InputDispatcher::waitForIdle() {
+    /**
+     * Timeout should represent the longest possible time that a device might spend processing
+     * events and commands.
+     */
+    constexpr std::chrono::duration TIMEOUT = 100ms;
+    std::unique_lock lock(mLock);
+    mLooper->wake();
+    std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
+    return result == std::cv_status::no_timeout;
+}
+
 } // namespace android::inputdispatcher