Reparent IME window and handle non-fullscreen windows correctly
IME window is attached to the IME target if possible. This ensures
a smooth enter/exit animation when the activity is coming in/going
away.
Furthermore, if the controlling window doesn't span the entire
display, we can't offer controlling it in a frame-by-frame
manner, and we need to do the inset calculations relative to the
display frame.
Test:
adb shell setprop persist.wm.new_insets 1
adb shell setprop persist.pre_render_ime_views 0
Test: Open IME, go home, reopen app
Test: Show dialog with EditText
Bug: 111084606
Change-Id: Id40470f6f8284b48acfa4719049afd14fde332d6
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 3826fac..a62bc71 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -51,17 +51,22 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
import android.annotation.SuppressLint;
+import android.app.WindowConfiguration;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
import android.view.DisplayCutout;
+import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
+import android.view.ViewRootImpl;
+import android.view.test.InsetsModeSession;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
@@ -628,6 +633,39 @@
eq(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
}
+ @Test
+ public void testComputeImeParent_app() throws Exception {
+ try (final InsetsModeSession session =
+ new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
+ final DisplayContent dc = createNewDisplay();
+ dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
+ assertEquals(dc.mInputMethodTarget.mAppToken.getSurfaceControl(),
+ dc.computeImeParent());
+ }
+ }
+
+ @Test
+ public void testComputeImeParent_app_notFullscreen() throws Exception {
+ try (final InsetsModeSession session =
+ new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
+ final DisplayContent dc = createNewDisplay();
+ dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app");
+ dc.mInputMethodTarget.setWindowingMode(
+ WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ assertEquals(dc.getWindowingLayer(), dc.computeImeParent());
+ }
+ }
+
+ @Test
+ public void testComputeImeParent_noApp() throws Exception {
+ try (final InsetsModeSession session =
+ new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) {
+ final DisplayContent dc = createNewDisplay();
+ dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar");
+ assertEquals(dc.getWindowingLayer(), dc.computeImeParent());
+ }
+ }
+
private boolean isOptionsPanelAtRight(int displayId) {
return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
}