diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/DisplayContent.java | 57 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java | 89 |
2 files changed, 92 insertions, 54 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 2a676e1de5af..f2d1a411c2c1 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -26,6 +26,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; @@ -141,6 +142,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; +import android.app.WindowConfiguration; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.ScreenOrientation; @@ -3370,34 +3372,18 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } + private boolean isImeControlledByApp() { + return mInputMethodTarget != null && !WindowConfiguration.isSplitScreenWindowingMode( + mInputMethodTarget.getWindowingMode()); + } + boolean isImeAttachedToApp() { - return (mInputMethodTarget != null && mInputMethodTarget.mActivityRecord != null + return isImeControlledByApp() + && mInputMethodTarget.mActivityRecord != null && mInputMethodTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN // An activity with override bounds should be letterboxed inside its parent bounds, // so it doesn't fill the screen. - && mInputMethodTarget.mActivityRecord.matchParentBounds()); - } - - /** - * Get IME target that should host IME when this display that is reparented to another - * WindowState. - * IME is never displayed in a child display. - * Use {@link WindowState#getImeControlTarget()} when IME target window - * which originally called - * {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} is known. - * - * @return {@link WindowState} of host that controls IME. - * {@code null} when {@param dc} is not a virtual display. - * @see DisplayContent#reparent - */ - @Nullable - WindowState getImeControlTarget() { - WindowState imeTarget = mInputMethodTarget; - if (imeTarget != null) { - return imeTarget.getImeControlTarget(); - } - - return getInsetsStateController().getImeSourceProvider().getControlTarget().getWindow(); + && mInputMethodTarget.mActivityRecord.matchParentBounds(); } /** @@ -3407,7 +3393,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * * @param target current IME target. * @return {@link WindowState} that can host IME. - * @see DisplayContent#getImeControlTarget() */ WindowState getImeHostOrFallback(WindowState target) { if (target != null && target.getDisplayContent().canShowIme()) { @@ -3448,8 +3433,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo /** * The IME input target is the window which receives input from IME. It is also a candidate * which controls the visibility and animation of the input method window. - * - * @param target the window that receives input from IME. */ void setInputMethodInputTarget(WindowState target) { if (mInputMethodInputTarget != target) { @@ -3459,12 +3442,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } private void updateImeControlTarget() { - if (!isImeAttachedToApp() && mRemoteInsetsControlTarget != null) { - mInputMethodControlTarget = mRemoteInsetsControlTarget; - } else { - // Otherwise, we just use the ime input target - mInputMethodControlTarget = mInputMethodInputTarget; - } + mInputMethodControlTarget = computeImeControlTarget(); mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget); } @@ -3477,6 +3455,19 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } /** + * Computes the window where we hand IME control to. + */ + @VisibleForTesting + InsetsControlTarget computeImeControlTarget() { + if (!isImeControlledByApp() && mRemoteInsetsControlTarget != null) { + return mRemoteInsetsControlTarget; + } else { + // Otherwise, we just use the ime target as received from IME. + return mInputMethodInputTarget; + } + } + + /** * Computes the window the IME should be attached to. */ @VisibleForTesting 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 3fd81b47c546..daff14992e94 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -65,6 +65,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; @@ -84,10 +85,13 @@ import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; import android.view.DisplayCutout; import android.view.Gravity; +import android.view.IDisplayWindowInsetsController; import android.view.IDisplayWindowRotationCallback; import android.view.IDisplayWindowRotationController; import android.view.ISystemGestureExclusionListener; import android.view.IWindowManager; +import android.view.InsetsSourceControl; +import android.view.InsetsState; import android.view.MotionEvent; import android.view.Surface; import android.view.SurfaceControl.Transaction; @@ -810,25 +814,19 @@ public class DisplayContentTests extends WindowTestsBase { @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.mActivityRecord.getSurfaceControl(), - dc.computeImeParent()); - } + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app"); + assertEquals(dc.mInputMethodTarget.mActivityRecord.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.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); - } + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app"); + dc.mInputMethodTarget.setWindowingMode( + WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); } @Test @@ -843,12 +841,61 @@ public class DisplayContentTests extends WindowTestsBase { @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.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); - } + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar"); + assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); + } + + @Test + public void testComputeImeControlTarget() throws Exception { + final DisplayContent dc = createNewDisplay(); + dc.setRemoteInsetsController(createDisplayWindowInsetsController()); + dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app"); + dc.mInputMethodTarget = dc.mInputMethodInputTarget; + assertEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget()); + } + + @Test + public void testComputeImeControlTarget_splitscreen() throws Exception { + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app"); + dc.mInputMethodInputTarget.setWindowingMode( + WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + dc.mInputMethodTarget = dc.mInputMethodInputTarget; + dc.setRemoteInsetsController(createDisplayWindowInsetsController()); + assertNotEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget()); + } + + @Test + public void testComputeImeControlTarget_notMatchParentBounds() throws Exception { + spyOn(mAppWindow.mActivityRecord); + doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds(); + mDisplayContent.mInputMethodInputTarget = mAppWindow; + mDisplayContent.mInputMethodTarget = mDisplayContent.mInputMethodInputTarget; + mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController()); + assertEquals(mAppWindow, mDisplayContent.computeImeControlTarget()); + } + + private IDisplayWindowInsetsController createDisplayWindowInsetsController() { + return new IDisplayWindowInsetsController.Stub() { + + @Override + public void insetsChanged(InsetsState insetsState) throws RemoteException { + } + + @Override + public void insetsControlChanged(InsetsState insetsState, + InsetsSourceControl[] insetsSourceControls) throws RemoteException { + } + + @Override + public void showInsets(int i, boolean b) throws RemoteException { + } + + @Override + public void hideInsets(int i, boolean b) throws RemoteException { + } + }; } @Test |