FocusRequest token can be nullable

When a freeform app is focused but its window is not ready, the input
focus on the window of the previously focused app should be removed.
To do so, a FocusRequest needs to be send to the InputFlinger, and there
will be no token because the new window is not ready. Change token to be
nullable, so InputRequest can be pass to FocusResolver.

Bug: 216852742
Test: atest AnrTests#slowOnCreateWithKeyEventTriggersAnr
Change-Id: If2ed666a17576557a602a8e46494d8c66d8ce89f
diff --git a/libs/gui/android/gui/FocusRequest.aidl b/libs/gui/android/gui/FocusRequest.aidl
index 9018635..b13c600 100644
--- a/libs/gui/android/gui/FocusRequest.aidl
+++ b/libs/gui/android/gui/FocusRequest.aidl
@@ -21,7 +21,7 @@
     /**
      * Input channel token used to identify the window that should gain focus.
      */
-    IBinder token;
+    @nullable IBinder token;
     @utf8InCpp String windowName;
     /**
      * The token that the caller expects currently to be focused. If the
diff --git a/services/inputflinger/tests/FocusResolver_test.cpp b/services/inputflinger/tests/FocusResolver_test.cpp
index ffce9f6..91be4a3 100644
--- a/services/inputflinger/tests/FocusResolver_test.cpp
+++ b/services/inputflinger/tests/FocusResolver_test.cpp
@@ -84,6 +84,30 @@
     ASSERT_FALSE(changes);
 }
 
+TEST(FocusResolverTest, RemoveFocusFromFocusedWindow) {
+    sp<IBinder> focusableWindowToken = new BBinder();
+    std::vector<sp<WindowInfoHandle>> windows;
+    windows.push_back(new FakeWindowHandle("Focusable", focusableWindowToken, true /* focusable */,
+                                           true /* visible */));
+
+    FocusRequest request;
+    request.displayId = 42;
+    request.token = focusableWindowToken;
+    FocusResolver focusResolver;
+    // Focusable window gets focus.
+    request.token = focusableWindowToken;
+    std::optional<FocusResolver::FocusChanges> changes =
+            focusResolver.setFocusedWindow(request, windows);
+    ASSERT_FOCUS_CHANGE(changes, nullptr, focusableWindowToken);
+
+    // Window token of a request is null, focus should be revoked.
+    request.token = NULL;
+    changes = focusResolver.setFocusedWindow(request, windows);
+    ASSERT_EQ(focusableWindowToken, changes->oldFocus);
+    ASSERT_EQ(nullptr, changes->newFocus);
+    ASSERT_FOCUS_CHANGE(changes, focusableWindowToken, nullptr);
+}
+
 TEST(FocusResolverTest, SetFocusedMirroredWindow) {
     sp<IBinder> focusableWindowToken = new BBinder();
     sp<IBinder> invisibleWindowToken = new BBinder();