Request focus using setFocusedWindow

Switch from using setInputWindow to setFocusedWindow to set the focused
window for a display. setInputWindows will still handle window state
changes such as visibility and focusability which can take focus away
from the currently focused window.

This change explicitly defines how mirrored window or windows sharing a
window token handles focus. For a window to be focusable, all the
windows sharing its window token must be focusable and at least one of
the window must be visible. This different from the previous behaviour
where z-order and the state of a single window determined focus via
setInputWindows.

In addition, if focus is requested on an invisible window, the request
is queued up until the window becomes focus or a new request is made.
Any key events are queued and delivered to the new window as it becomes
focused. This allows the system to deliver any key events to the new
window between the time that the system wants to show a new window and
the window is ready to receive input.

Test: atest inputflinger_tests
Test: atest CtsWindowManagerDeviceTestCases
Test: atest FlickerTests

Change-Id: Id09cce42f55fb7d36a3eb0aa9d28f6a44bd1cf07
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 93d3fde..8f3d5dc 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -136,6 +136,14 @@
         STALE,
     };
 
+    enum class FocusResult {
+        OK,
+        NO_WINDOW,
+        NOT_FOCUSABLE,
+        NOT_VISIBLE,
+    };
+    static const char* typeToString(FocusResult result);
+
     std::unique_ptr<InputThread> mThread;
 
     sp<InputDispatcherPolicyInterface> mPolicy;
@@ -308,6 +316,9 @@
     sp<InputWindowHandle> getFocusedWindowHandleLocked(int displayId) const REQUIRES(mLock);
     bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const REQUIRES(mLock);
     bool hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const REQUIRES(mLock);
+    FocusResult handleFocusRequestLocked(const FocusRequest&) REQUIRES(mLock);
+    FocusResult checkTokenFocusableLocked(const sp<IBinder>& token, int32_t displayId) const
+            REQUIRES(mLock);
 
     /*
      * Validate and update InputWindowHandles for a given display.
@@ -380,6 +391,14 @@
      */
     std::shared_ptr<InputApplicationHandle> mAwaitedFocusedApplication GUARDED_BY(mLock);
 
+    /**
+     * This map will store the pending focus requests that cannot be currently processed. This can
+     * happen if the window requested to be focused is not currently visible. Such a window might
+     * become visible later, and these requests would be processed at that time.
+     */
+    std::unordered_map<int32_t /* displayId */, FocusRequest> mPendingFocusRequests
+            GUARDED_BY(mLock);
+
     // Optimization: AnrTracker is used to quickly find which connection is due for a timeout next.
     // AnrTracker must be kept in-sync with all responsive connection.waitQueues.
     // If a connection is not responsive, then the entries should not be added to the AnrTracker.