Propagate displayId in ImeTargetChangeListener

This is a follow up CL to our previous CLs [1][2], which added

  ImeTargetChangeListener.

To support concurrent multi-user multi-display scenarios, we need to
distinguish whose IMEs these callbacks are talking about. To do so,
with this CL the relevant display ID also starts being propagated into
ImeVisibilityStateComputer.

These display IDs are not yet used thus there must be no observable
behavior change in this CL.

 [1]: I90c59c298e2e4568e308fb2c0dc4ca309d5546a3
      f8c633712b095736a07f6e9192b0e85da53fba99
 [2]: I3a950423f73f0a97432589d0a90ac8fd1c84f05e
      8fb9afd6559357f6583f19b04422312749ca910e

Fix: 356177006
Test: presubmit
Test: atest WmTests:WindowStateTests
Test: atest FrameworksInputMethodSystemServerTests
Flag: EXEMPT refactor
Change-Id: Ib50f7fdfb455b6d09707f680e71ad3dd7b0a18f2
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
index 42a99de..b67dd0f 100644
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
@@ -220,7 +220,7 @@
             @Override
             public void onImeTargetOverlayVisibilityChanged(@NonNull IBinder overlayWindowToken,
                     @WindowManager.LayoutParams.WindowType int windowType, boolean visible,
-                    boolean removed) {
+                    boolean removed, int displayId) {
                 // Ignoring the starting window since it's ok to cover the IME target
                 // window in temporary without affecting the IME visibility.
                 final boolean hasOverlay = visible && !removed
@@ -232,7 +232,7 @@
 
             @Override
             public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget,
-                    boolean visibleRequested, boolean removed) {
+                    boolean visibleRequested, boolean removed, int displayId) {
                 final boolean visibleAndNotRemoved = visibleRequested && !removed;
                 synchronized (ImfLock.class) {
                     if (visibleAndNotRemoved) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3a0de85..9c8c759 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -4415,13 +4415,14 @@
                                 mWmService.dispatchImeInputTargetVisibilityChanged(
                                         targetWin.mClient.asBinder(), isVisibleRequested,
                                         targetWin.mActivityRecord != null
-                                                && targetWin.mActivityRecord.finishing);
+                                                && targetWin.mActivityRecord.finishing,
+                                        mDisplayId);
                             }
                         });
                 targetWin.mToken.registerWindowContainerListener(
                         mImeTargetTokenListenerPair.second);
                 mWmService.dispatchImeInputTargetVisibilityChanged(targetWin.mClient.asBinder(),
-                        targetWin.isVisible() /* visible */, false /* removed */);
+                        targetWin.isVisible() /* visible */, false /* removed */, mDisplayId);
             }
         }
         if (refreshImeSecureFlag(getPendingTransaction())) {
diff --git a/services/core/java/com/android/server/wm/ImeTargetChangeListener.java b/services/core/java/com/android/server/wm/ImeTargetChangeListener.java
index 88b76aa..e94f17c 100644
--- a/services/core/java/com/android/server/wm/ImeTargetChangeListener.java
+++ b/services/core/java/com/android/server/wm/ImeTargetChangeListener.java
@@ -37,25 +37,27 @@
      * @param visible            the visibility of the overlay window, {@code true} means visible
      *                           and {@code false} otherwise.
      * @param removed            Whether the IME target overlay window has being removed.
+     * @param displayId          display ID where the overlay window exists.
      */
     default void onImeTargetOverlayVisibilityChanged(@NonNull IBinder overlayWindowToken,
             @WindowManager.LayoutParams.WindowType int windowType,
-            boolean visible, boolean removed) {
+            boolean visible, boolean removed, int displayId) {
     }
 
     /**
      * Called when the visibility of IME input target window has changed.
      *
      * @param imeInputTarget   the window token of the IME input target window.
-     * @param visible          the new window visibility made by {@param imeInputTarget}. visible is
+     * @param visible          the new window visibility made by {@code imeInputTarget}. visible is
      *                         {@code true} when switching to the new visible IME input target
      *                         window and started input, or the same input target relayout to
      *                         visible from invisible. In contrast, visible is {@code false} when
      *                         closing the input target, or the same input target relayout to
      *                         invisible from visible.
      * @param removed          Whether the IME input target window has being removed.
+     * @param displayId        display ID where the overlay window exists.
      */
     default void onImeInputTargetVisibilityChanged(@NonNull IBinder imeInputTarget, boolean visible,
-            boolean removed) {
+            boolean removed, int displayId) {
     }
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d73d509..cf92f1b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1897,7 +1897,8 @@
                 displayContent.computeImeTarget(true /* updateImeTarget */);
                 if (win.isImeOverlayLayeringTarget()) {
                     dispatchImeTargetOverlayVisibilityChanged(client.asBinder(), win.mAttrs.type,
-                            win.isVisibleRequestedOrAdding(), false /* removed */);
+                            win.isVisibleRequestedOrAdding(), false /* removed */,
+                            displayContent.getDisplayId());
                 }
             }
 
@@ -2661,13 +2662,13 @@
             final boolean winVisibleChanged = win.isVisible() != wasVisible;
             if (win.isImeOverlayLayeringTarget() && winVisibleChanged) {
                 dispatchImeTargetOverlayVisibilityChanged(client.asBinder(), win.mAttrs.type,
-                        win.isVisible(), false /* removed */);
+                        win.isVisible(), false /* removed */, win.getDisplayId());
             }
             // Notify listeners about IME input target window visibility change.
             final boolean isImeInputTarget = win.getDisplayContent().getImeInputTarget() == win;
             if (isImeInputTarget && winVisibleChanged) {
                 dispatchImeInputTargetVisibilityChanged(win.mClient.asBinder(),
-                        win.isVisible() /* visible */, false /* removed */);
+                        win.isVisible() /* visible */, false /* removed */, win.getDisplayId());
             }
 
             if (outRelayoutResult != null) {
@@ -3515,27 +3516,29 @@
 
     void dispatchImeTargetOverlayVisibilityChanged(@NonNull IBinder token,
             @WindowManager.LayoutParams.WindowType int windowType, boolean visible,
-            boolean removed) {
+            boolean removed, int displayId) {
         if (mImeTargetChangeListener != null) {
             if (DEBUG_INPUT_METHOD) {
                 Slog.d(TAG, "onImeTargetOverlayVisibilityChanged, win=" + mWindowMap.get(token)
                         + ", type=" + ViewDebug.intToString(WindowManager.LayoutParams.class,
-                        "type", windowType) + "visible=" + visible + ", removed=" + removed);
+                        "type", windowType) + "visible=" + visible + ", removed=" + removed
+                        + ", displayId=" + displayId);
             }
             mH.post(() -> mImeTargetChangeListener.onImeTargetOverlayVisibilityChanged(token,
-                    windowType, visible, removed));
+                    windowType, visible, removed, displayId));
         }
     }
 
     void dispatchImeInputTargetVisibilityChanged(@NonNull IBinder token, boolean visible,
-            boolean removed) {
+            boolean removed, int displayId) {
         if (mImeTargetChangeListener != null) {
             if (DEBUG_INPUT_METHOD) {
                 Slog.d(TAG, "onImeInputTargetVisibilityChanged, win=" + mWindowMap.get(token)
-                        + "visible=" + visible + ", removed=" + removed);
+                        + "visible=" + visible + ", removed=" + removed
+                        + ", displayId" + displayId);
             }
             mH.post(() -> mImeTargetChangeListener.onImeInputTargetVisibilityChanged(token,
-                    visible, removed));
+                    visible, removed, displayId));
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 153d41b..a61925f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2359,11 +2359,11 @@
         }
         super.removeImmediately();
 
+        final DisplayContent dc = getDisplayContent();
         if (isImeOverlayLayeringTarget()) {
             mWmService.dispatchImeTargetOverlayVisibilityChanged(mClient.asBinder(), mAttrs.type,
-                    false /* visible */, true /* removed */);
+                    false /* visible */, true /* removed */, dc.getDisplayId());
         }
-        final DisplayContent dc = getDisplayContent();
         if (isImeLayeringTarget()) {
             // Remove the attached IME screenshot surface.
             dc.removeImeSurfaceByTarget(this);
@@ -2374,7 +2374,7 @@
         }
         if (dc.getImeInputTarget() == this && !inRelaunchingActivity()) {
             mWmService.dispatchImeInputTargetVisibilityChanged(mClient.asBinder(),
-                    false /* visible */, true /* removed */);
+                    false /* visible */, true /* removed */, dc.getDisplayId());
             dc.updateImeInputAndControlTarget(null);
         }
 
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
index dd3b33e..4cd3157 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
@@ -302,12 +302,14 @@
             final IBinder testImeInputTarget = new Binder();
 
             // Simulate a test IME input target was visible.
-            mListener.onImeInputTargetVisibilityChanged(testImeInputTarget, true, false);
+            mListener.onImeInputTargetVisibilityChanged(testImeInputTarget, true, false,
+                    DEFAULT_DISPLAY);
 
             // Simulate a test IME layering target overlay fully occluded the IME input target.
             mListener.onImeTargetOverlayVisibilityChanged(testImeTargetOverlay,
-                    TYPE_APPLICATION_OVERLAY, true, false);
-            mListener.onImeInputTargetVisibilityChanged(testImeInputTarget, false, false);
+                    TYPE_APPLICATION_OVERLAY, true, false, DEFAULT_DISPLAY);
+            mListener.onImeInputTargetVisibilityChanged(testImeInputTarget, false, false,
+                    DEFAULT_DISPLAY);
             final ArgumentCaptor<IBinder> targetCaptor = ArgumentCaptor.forClass(IBinder.class);
             final ArgumentCaptor<ImeVisibilityResult> resultCaptor = ArgumentCaptor.forClass(
                     ImeVisibilityResult.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index b46189c..11df331 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -1351,6 +1351,7 @@
         assertThat(listener.mImeTargetToken).isEqualTo(imeTarget.mClient.asBinder());
         assertThat(listener.mIsRemoved).isFalse();
         assertThat(listener.mIsVisibleForImeInputTarget).isTrue();
+        assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
 
         imeTarget.mActivityRecord.setVisibleRequested(false);
         waitHandlerIdle(mWm.mH);
@@ -1358,11 +1359,13 @@
         assertThat(listener.mImeTargetToken).isEqualTo(imeTarget.mClient.asBinder());
         assertThat(listener.mIsRemoved).isFalse();
         assertThat(listener.mIsVisibleForImeInputTarget).isFalse();
+        assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
 
         imeTarget.removeImmediately();
         assertThat(listener.mImeTargetToken).isEqualTo(imeTarget.mClient.asBinder());
         assertThat(listener.mIsRemoved).isTrue();
         assertThat(listener.mIsVisibleForImeInputTarget).isFalse();
+        assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
     }
 
     @SetupWindows(addWindows = {W_INPUT_METHOD})
@@ -1402,6 +1405,7 @@
         assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
         assertThat(listener.mIsRemoved).isFalse();
         assertThat(listener.mIsVisibleForImeTargetOverlay).isTrue();
+        assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
 
         // Scenario 2: test relayoutWindow to let the Ime layering target overlay window invisible.
         mWm.relayoutWindow(session, client, params, 100, 200, View.GONE, 0, 0, 0,
@@ -1412,6 +1416,7 @@
         assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
         assertThat(listener.mIsRemoved).isFalse();
         assertThat(listener.mIsVisibleForImeTargetOverlay).isFalse();
+        assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
 
         // Scenario 3: test removeWindow to remove the Ime layering target overlay window.
         mWm.removeClientToken(session, client.asBinder());
@@ -1420,6 +1425,7 @@
         assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
         assertThat(listener.mIsRemoved).isTrue();
         assertThat(listener.mIsVisibleForImeTargetOverlay).isFalse();
+        assertThat(listener.mDisplayId).isEqualTo(mDisplayContent.getDisplayId());
     }
 
     @Test
@@ -1468,22 +1474,25 @@
         private boolean mIsRemoved;
         private boolean mIsVisibleForImeTargetOverlay;
         private boolean mIsVisibleForImeInputTarget;
+        private int mDisplayId;
 
         @Override
         public void onImeTargetOverlayVisibilityChanged(IBinder overlayWindowToken,
                 @WindowManager.LayoutParams.WindowType int windowType, boolean visible,
-                boolean removed) {
+                boolean removed, int displayId) {
             mImeTargetToken = overlayWindowToken;
             mIsVisibleForImeTargetOverlay = visible;
             mIsRemoved = removed;
+            mDisplayId = displayId;
         }
 
         @Override
         public void onImeInputTargetVisibilityChanged(IBinder imeInputTarget,
-                boolean visibleRequested, boolean removed) {
+                boolean visibleRequested, boolean removed, int displayId) {
             mImeTargetToken = imeInputTarget;
             mIsVisibleForImeInputTarget = visibleRequested;
             mIsRemoved = removed;
+            mDisplayId = displayId;
         }
     }
 }