Check for focused window before raising 'no focused window' ANR

Previously, we were relying on the dispatcher trying to send a focused
event prior to raising ANR due to no focused window.

So, the previous expected behavior was:
1. A key comes in, and there is no focused window
2. ANR timer starts
3. Focused window appears
4. We try to dispatch the key again, and realize there's a focused
window
5. We stop the ANR timer

However, there are cases when the pending key event gets dropped. For
example, this could happen if the user touches another application. That
would lead to the following sequence of events:
1. A key comes in, and there is no focused window
2. ANR timer starts
3. User touches another application, and the pending key gets dropped
4. Focused window appears
5. We don't try to dispatch the pending key anymore (since nothing is
pending)
6. We raise the "no focused window" ANR, even though we have a focused
window (and don't even have a focused event to dispatch anymore).

Solution: always check for focused window presence before raising the
"no focused window" ANR. This way, we will no longer rely on other events
happening for this ANR to be functioning correctly.

Bug: 164754075
Test: atest inputflinger_tests
Change-Id: I70162d507fa7d65132c83fcba96ad9931e373647
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index efe2bb1..0f06ddf 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -481,6 +481,33 @@
 }
 
 /**
+ * Raise ANR if there is no focused window.
+ * Before the ANR is raised, do a final state check:
+ * 1. The currently focused application must be the same one we are waiting for.
+ * 2. Ensure we still don't have a focused window.
+ */
+void InputDispatcher::processNoFocusedWindowAnrLocked() {
+    // Check if the application that we are waiting for is still focused.
+    std::shared_ptr<InputApplicationHandle> focusedApplication =
+            getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
+    if (focusedApplication == nullptr ||
+        focusedApplication->getApplicationToken() !=
+                mAwaitedFocusedApplication->getApplicationToken()) {
+        // Unexpected because we should have reset the ANR timer when focused application changed
+        ALOGE("Waited for a focused window, but focused application has already changed to %s",
+              focusedApplication->getName().c_str());
+        return; // The focused application has changed.
+    }
+
+    const sp<InputWindowHandle>& focusedWindowHandle =
+            getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
+    if (focusedWindowHandle != nullptr) {
+        return; // We now have a focused window. No need for ANR.
+    }
+    onAnrLocked(mAwaitedFocusedApplication);
+}
+
+/**
  * Check if any of the connections' wait queues have events that are too old.
  * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
  * Return the time at which we should wake up next.
@@ -491,8 +518,9 @@
     // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
     if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
         if (currentTime >= *mNoFocusedWindowTimeoutTime) {
-            onAnrLocked(mAwaitedFocusedApplication);
+            processNoFocusedWindowAnrLocked();
             mAwaitedFocusedApplication.reset();
+            mNoFocusedWindowTimeoutTime = std::nullopt;
             return LONG_LONG_MIN;
         } else {
             // Keep waiting
@@ -1494,6 +1522,7 @@
                     DEFAULT_INPUT_DISPATCHING_TIMEOUT);
             mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
             mAwaitedFocusedApplication = focusedApplicationHandle;
+            mAwaitedApplicationDisplayId = displayId;
             ALOGW("Waiting because no window has focus but %s may eventually add a "
                   "window when it finishes starting up. Will wait for %" PRId64 "ms",
                   mAwaitedFocusedApplication->getName().c_str(), millis(timeout));