InputDispatcher: Blame the window from the focus request for ANR

If there are no focusable windows, then try to blame the window that
was requested to become focused. This will avoid blaming the wrong
process when WM requests focus on a window that is placed on top
of the focused app and the window fails to become focusable.

Test: atest inputflinger_tests
Fixes: b/239907039

Change-Id: Ie2bc3dc66516b51784159a875c7cf865b4cb5b35
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index ff63967..b52e312 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -659,6 +659,13 @@
     if (focusedWindowHandle != nullptr) {
         return; // We now have a focused window. No need for ANR.
     }
+    std::optional<FocusRequest> pendingRequest =
+            mFocusResolver.getFocusRequest(mAwaitedApplicationDisplayId);
+    if (pendingRequest.has_value() && onAnrLocked(*pendingRequest)) {
+        // We don't have a focusable window but we know which window should have
+        // been focused. Blame that process in case it doesn't belong to the focused app.
+        return;
+    }
     onAnrLocked(mAwaitedFocusedApplication);
 }
 
@@ -5848,6 +5855,25 @@
     postCommandLocked(std::move(command));
 }
 
+bool InputDispatcher::onAnrLocked(const android::gui::FocusRequest& pendingFocusRequest) {
+    if (pendingFocusRequest.token == nullptr) {
+        return false;
+    }
+
+    const std::string reason = android::base::StringPrintf("%s is not focusable.",
+                                                           pendingFocusRequest.windowName.c_str());
+    updateLastAnrStateLocked(pendingFocusRequest.windowName, reason);
+    sp<Connection> connection = getConnectionLocked(pendingFocusRequest.token);
+    if (connection != nullptr) {
+        processConnectionUnresponsiveLocked(*connection, std::move(reason));
+        // Stop waking up for events on this connection, it is already unresponsive
+        cancelEventsForAnrLocked(connection);
+    } else {
+        sendWindowUnresponsiveCommandLocked(pendingFocusRequest.token, std::nullopt, reason);
+    }
+    return true;
+}
+
 void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
     if (connection == nullptr) {
         LOG_ALWAYS_FATAL("Caller must check for nullness");