Merge "Update IME layer when non-app window requests visible IME" into udc-dev am: 74ebaefe2f am: 894d901641

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23406958

Change-Id: If1f1cfb41ff0698628142eae6ec8be6986e67ec8
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index ff2985c..e8a4c1c 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -91,6 +91,21 @@
     }
 
     @Override
+    void setClientVisible(boolean clientVisible) {
+        final boolean wasClientVisible = isClientVisible();
+        super.setClientVisible(clientVisible);
+        // The layer of ImePlaceholder needs to be updated on a higher z-order for
+        // non-activity window (For activity window, IME is already on top of it).
+        if (!wasClientVisible && isClientVisible()) {
+            final InsetsControlTarget imeControlTarget = getControlTarget();
+            if (imeControlTarget != null && imeControlTarget.getWindow() != null
+                    && imeControlTarget.getWindow().mActivityRecord == null) {
+                mDisplayContent.assignWindowLayers(false /* setLayoutNeeded */);
+            }
+        }
+    }
+
+    @Override
     void setServerVisible(boolean serverVisible) {
         mServerVisible = serverVisible;
         if (!mFrozen) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 8662607..114796d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -25,6 +25,7 @@
 import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
@@ -38,6 +39,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.spy;
@@ -419,10 +421,10 @@
 
     @Test
     public void testUpdateAboveInsetsState_zOrderChanged() {
-        final WindowState ime = createTestWindow("ime");
-        final WindowState app = createTestWindow("app");
-        final WindowState statusBar = createTestWindow("statusBar");
-        final WindowState navBar = createTestWindow("navBar");
+        final WindowState ime = createNonAppWindow("ime");
+        final WindowState app = createNonAppWindow("app");
+        final WindowState statusBar = createNonAppWindow("statusBar");
+        final WindowState navBar = createNonAppWindow("navBar");
 
         final InsetsSourceProvider imeSourceProvider =
                 getController().getOrCreateSourceProvider(ID_IME, ime());
@@ -430,7 +432,9 @@
 
         waitUntilHandlersIdle();
         clearInvocations(mDisplayContent);
+        imeSourceProvider.updateControlForTarget(app, false /* force */);
         imeSourceProvider.setClientVisible(true);
+        verify(mDisplayContent).assignWindowLayers(anyBoolean());
         waitUntilHandlersIdle();
         // The visibility change should trigger a traversal to notify the change.
         verify(mDisplayContent).notifyInsetsChanged(any());
@@ -546,6 +550,7 @@
                 control2.getInsetsHint().bottom);
     }
 
+    /** Creates a window which is associated with ActivityRecord. */
     private WindowState createTestWindow(String name) {
         final WindowState win = createWindow(null, TYPE_APPLICATION, name);
         win.setHasSurface(true);
@@ -553,6 +558,14 @@
         return win;
     }
 
+    /** Creates a non-activity window. */
+    private WindowState createNonAppWindow(String name) {
+        final WindowState win = createWindow(null, LAST_APPLICATION_WINDOW + 1, name);
+        win.setHasSurface(true);
+        spyOn(win);
+        return win;
+    }
+
     private InsetsStateController getController() {
         return mDisplayContent.getInsetsStateController();
     }