Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6695f3e0 authored by Cosmin Băieș's avatar Cosmin Băieș Committed by Android (Google) Code Review
Browse files

Merge "Remove testing variant of setImeLayeringTarget" into main

parents 2e9dcd82 31e2e5a6
Loading
Loading
Loading
Loading
+8 −12
Original line number Diff line number Diff line
@@ -675,10 +675,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    private InsetsControlTarget mImeControlTarget;

    /**
     * The last {@link #mImeInputTarget} processed from {@link #setImeLayeringTargetInner}. This
     * enables updating the {@link #mImeControlTarget} when the {@link #mImeLayeringTarget} remains
     * the same, and only the {@link #mImeInputTarget} changes. For example, this can happen when
     * the IME is moving to a SurfaceControlViewHost backed EmbeddedWindow.
     * The last {@link #mImeInputTarget} processed from {@link #setImeLayeringTarget}. This enables
     * updating the {@link #mImeControlTarget} when the {@link #mImeLayeringTarget} remains the
     * same, and only the {@link #mImeInputTarget} changes. For example, this can happen when the
     * IME is moving to a SurfaceControlViewHost backed EmbeddedWindow.
     */
    @Nullable
    private InputTarget mLastImeInputTarget;
@@ -4165,7 +4165,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }

        if (update) {
            setImeLayeringTargetInner(target);
            setImeLayeringTarget(target);
        }

        return target;
@@ -4306,11 +4306,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }
    }

    @VisibleForTesting
    void setImeLayeringTarget(@Nullable WindowState target) {
        mImeLayeringTarget = target;
    }

    /**
     * Sets the IME layering target, and updates the IME control target. Also updates the IME parent
     * if necessary.
@@ -4318,7 +4313,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     * @param target the window to place the IME on top of. If {@code null}, the IME will be placed
     *               on top of its parent's surface.
     */
    private void setImeLayeringTargetInner(@Nullable WindowState target) {
    @VisibleForTesting
    void setImeLayeringTarget(@Nullable WindowState target) {
        // This function is also responsible for updating the IME control target and so in the case
        // where the IME layering target does not change but the IME input target does (for example,
        // IME moving to a SurfaceControlViewHost) we have to continue executing this function,
@@ -4342,7 +4338,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            }
        }

        ProtoLog.i(WM_DEBUG_IME, "setImeLayeringTargetInner %s", target);
        ProtoLog.i(WM_DEBUG_IME, "setImeLayeringTarget %s", target);
        boolean forceUpdateImeParent = target != mImeLayeringTarget;
        mImeLayeringTarget = target;

+28 −24
Original line number Diff line number Diff line
@@ -644,8 +644,8 @@ public class DisplayContentTests extends WindowTestsBase {
        final DisplayContent dc = mDisplayContent;
        final WindowState ws = newWindowBuilder("app window", TYPE_APPLICATION).setDisplay(
                dc).build();
        dc.setImeLayeringTarget(ws);
        dc.setImeInputTarget(ws);
        dc.setImeLayeringTarget(ws);

        // Adjust bounds so that matchesRootDisplayAreaBounds() returns false.
        final Rect bounds = new Rect(dc.getBounds());
@@ -1230,8 +1230,9 @@ public class DisplayContentTests extends WindowTestsBase {
    @Test
    public void testComputeImeParent_app() {
        final DisplayContent dc = createNewDisplay();
        dc.setImeLayeringTarget(newWindowBuilder("app", TYPE_BASE_APPLICATION).build());
        dc.setImeInputTarget(dc.getImeLayeringTarget());
        final var appWin = newWindowBuilder("appWin", TYPE_BASE_APPLICATION).setDisplay(dc).build();
        dc.setImeInputTarget(appWin);
        dc.setImeLayeringTarget(appWin);
        assertEquals(dc.getImeLayeringTarget().mActivityRecord.getSurfaceControl(),
                dc.computeImeParent().getSurfaceControl());
    }
@@ -1239,9 +1240,10 @@ public class DisplayContentTests extends WindowTestsBase {
    @Test
    public void testComputeImeParent_app_notFullscreen() {
        final DisplayContent dc = createNewDisplay();
        dc.setImeLayeringTarget(newWindowBuilder("app", TYPE_STATUS_BAR).build());
        dc.getImeLayeringTarget().setWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
        dc.setImeInputTarget(dc.getImeLayeringTarget());
        final var appWin = newWindowBuilder("appWin", TYPE_STATUS_BAR).setDisplay(dc)
                .setWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW).build();
        dc.setImeInputTarget(appWin);
        dc.setImeLayeringTarget(appWin);
        assertEquals(dc.getImeContainer().getParentSurfaceControl(),
                dc.computeImeParent().getSurfaceControl());
    }
@@ -1260,8 +1262,9 @@ public class DisplayContentTests extends WindowTestsBase {
    @Test
    public void testComputeImeParent_noApp() {
        final DisplayContent dc = createNewDisplay();
        dc.setImeLayeringTarget(newWindowBuilder("statusBar", TYPE_STATUS_BAR).build());
        dc.setImeInputTarget(dc.getImeLayeringTarget());
        final var statusBar = newWindowBuilder("statusBar", TYPE_STATUS_BAR).setDisplay(dc).build();
        dc.setImeInputTarget(statusBar);
        dc.setImeLayeringTarget(statusBar);
        assertEquals(dc.getImeContainer().getParentSurfaceControl(),
                dc.computeImeParent().getSurfaceControl());
    }
@@ -1272,8 +1275,8 @@ public class DisplayContentTests extends WindowTestsBase {
        WindowState app1 = newWindowBuilder("app1", TYPE_BASE_APPLICATION).build();
        WindowState app2 = newWindowBuilder("app2", TYPE_BASE_APPLICATION).build();
        doReturn(true).when(mDisplayContent).shouldImeAttachedToApp();
        mDisplayContent.setImeLayeringTarget(app1);
        mDisplayContent.setImeInputTarget(app1);
        mDisplayContent.setImeLayeringTarget(app1);
        assertEquals(app1.mActivityRecord.getSurfaceControl(),
                mDisplayContent.computeImeParent().getSurfaceControl());
        mDisplayContent.setImeLayeringTarget(app2);
@@ -1289,8 +1292,8 @@ public class DisplayContentTests extends WindowTestsBase {
        overlay.setBounds(100, 100, 200, 200);
        overlay.mAttrs.flags = FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM;
        WindowState app = newWindowBuilder("app", TYPE_BASE_APPLICATION).build();
        mDisplayContent.setImeLayeringTarget(overlay);
        mDisplayContent.setImeInputTarget(app);
        mDisplayContent.setImeLayeringTarget(overlay);
        assertFalse(mDisplayContent.shouldImeAttachedToApp());
        assertEquals(mDisplayContent.getImeContainer().getParentSurfaceControl(),
                mDisplayContent.computeImeParent().getSurfaceControl());
@@ -1302,9 +1305,9 @@ public class DisplayContentTests extends WindowTestsBase {
        WindowState app1 = newWindowBuilder("app1", TYPE_BASE_APPLICATION).build();
        WindowState app2 = newWindowBuilder("app2", TYPE_BASE_APPLICATION).build();

        dc.setImeLayeringTarget(app1);
        dc.setImeInputTarget(app2);
        dc.setRemoteInsetsController(createDisplayWindowInsetsController());
        dc.setImeInputTarget(app2);
        dc.setImeLayeringTarget(app1);
        dc.getImeLayeringTarget().setWindowingMode(
                WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
        dc.getImeInputTarget().getWindowState().setWindowingMode(
@@ -1357,11 +1360,11 @@ public class DisplayContentTests extends WindowTestsBase {
    @Test
    public void testComputeImeControlTarget_splitscreen() {
        final DisplayContent dc = createNewDisplay();
        dc.setImeInputTarget(newWindowBuilder("app", TYPE_BASE_APPLICATION).build());
        dc.getImeInputTarget().getWindowState().setWindowingMode(
                WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
        dc.setImeLayeringTarget(dc.getImeInputTarget().getWindowState());
        dc.setRemoteInsetsController(createDisplayWindowInsetsController());
        final var appWin = newWindowBuilder("appWin", TYPE_BASE_APPLICATION).setDisplay(dc)
                .setWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW).build();
        dc.setImeInputTarget(appWin);
        dc.setImeLayeringTarget(appWin);
        assertNotEquals(dc.getImeInputTarget().getWindowState(), dc.computeImeControlTarget());
    }

@@ -1384,9 +1387,9 @@ public class DisplayContentTests extends WindowTestsBase {
    public void testComputeImeControlTarget_notMatchParentBounds() {
        spyOn(mAppWindow.mActivityRecord);
        doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds();
        mDisplayContent.setImeInputTarget(mAppWindow);
        mDisplayContent.setImeLayeringTarget(mDisplayContent.getImeInputTarget().getWindowState());
        mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController());
        mDisplayContent.setImeInputTarget(mAppWindow);
        mDisplayContent.setImeLayeringTarget(mAppWindow);
        assertEquals(mAppWindow, mDisplayContent.computeImeControlTarget());
    }

@@ -1400,9 +1403,9 @@ public class DisplayContentTests extends WindowTestsBase {
        spyOn(mAppWindow.mActivityRecord);
        doReturn(imeTargetBounds).when(mAppWindow).getBounds();
        doReturn(true).when(mAppWindow.mActivityRecord).matchParentBounds();
        mDisplayContent.setImeInputTarget(mAppWindow);
        mDisplayContent.setImeLayeringTarget(mDisplayContent.getImeInputTarget().getWindowState());
        mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController());
        mDisplayContent.setImeInputTarget(mAppWindow);
        mDisplayContent.setImeLayeringTarget(mAppWindow);
        final DisplayArea.Tokens imeContainer = mDisplayContent.getImeContainer();
        spyOn(imeContainer);
        doReturn(imeContainerBounds).when(imeContainer).getBounds();
@@ -2244,6 +2247,7 @@ public class DisplayContentTests extends WindowTestsBase {
        spyOn(child1);
        doReturn(false).when(mDisplayContent).shouldImeAttachedToApp();
        mDisplayContent.setImeLayeringTarget(child1);
        verify(child1).needsRelativeLayeringToIme();

        spyOn(nextImeTargetApp);
        spyOn(mAppWindow);
@@ -2255,7 +2259,8 @@ public class DisplayContentTests extends WindowTestsBase {

        verify(mDisplayContent).computeImeLayeringTarget(true /* update */);
        assertNull(mDisplayContent.getImeInputTarget());
        verify(child1, never()).needsRelativeLayeringToIme();
        // Still only one call, earlier when child1 was set as IME layering target.
        verify(child1).needsRelativeLayeringToIme();
    }

    @SetupWindows(addWindows = W_INPUT_METHOD)
@@ -2321,9 +2326,8 @@ public class DisplayContentTests extends WindowTestsBase {
        final WindowState win = newWindowBuilder("win", TYPE_BASE_APPLICATION).setWindowToken(
                activity).build();

        mDisplayContent.setImeLayeringTarget(win);
        mDisplayContent.setImeInputTarget(win);
        spyOn(mDisplayContent);
        mDisplayContent.setImeLayeringTarget(win);
        spyOn(mDisplayContent.mInputMethodWindow);
        doReturn(true).when(mDisplayContent.mInputMethodWindow).isVisible();
        mDisplayContent.getInsetsStateController().getImeSourceProvider().setImeShowing(true);
@@ -2349,8 +2353,8 @@ public class DisplayContentTests extends WindowTestsBase {
                activity).build();
        makeWindowVisible(mDisplayContent.mInputMethodWindow);

        mDisplayContent.setImeLayeringTarget(win);
        mDisplayContent.setImeInputTarget(win);
        mDisplayContent.setImeLayeringTarget(win);
        mDisplayContent.getInsetsStateController().getImeSourceProvider().setImeShowing(true);
        mDisplayContent.showImeScreenshot();
        assertNotNull(mDisplayContent.mImeScreenshot);
+3 −3
Original line number Diff line number Diff line
@@ -787,9 +787,9 @@ public class SizeCompatTests extends WindowTestsBase {
        assertFitted();

        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
        mActivity.mDisplayContent.setImeLayeringTarget(addWindowToActivity(mActivity));
        mActivity.mDisplayContent.setImeInputTarget(
                mActivity.mDisplayContent.getImeLayeringTarget());
        final var appWindow = addWindowToActivity(mActivity);
        mActivity.mDisplayContent.setImeInputTarget(appWindow);
        mActivity.mDisplayContent.setImeLayeringTarget(appWindow);
        // Because the aspect ratio of display doesn't exceed the max aspect ratio of activity.
        // The activity should still fill its parent container and IME can attach to the activity.
        assertTrue(mActivity.matchParentBounds());
+1 −1
Original line number Diff line number Diff line
@@ -66,8 +66,8 @@ public class WindowContainerTraversalTests extends WindowTestsBase {
    @SetupWindows(addWindows = { W_ACTIVITY, W_INPUT_METHOD })
    @Test
    public void testTraverseImeRegardlessOfImeTarget() {
        mDisplayContent.setImeLayeringTarget(mAppWindow);
        mDisplayContent.setImeInputTarget(mAppWindow);
        mDisplayContent.setImeLayeringTarget(mAppWindow);
        mAppWindow.mHasSurface = false;
        mAppWindow.mActivityRecord.setVisibleRequested(false);
        mAppWindow.mActivityRecord.setVisible(false);
+70 −65
Original line number Diff line number Diff line
@@ -113,7 +113,6 @@ import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowRelayoutResult;
import android.view.inputmethod.ImeTracker;
import android.window.ClientWindowFrames;
import android.window.ITaskFragmentOrganizer;
import android.window.TaskFragmentOrganizer;
@@ -1329,80 +1328,86 @@ public class WindowStateTests extends WindowTestsBase {
        assertTrue(mAppWindow.getInsetsState().isSourceOrDefaultVisible(navId, navigationBars()));
    }

    @SetupWindows(addWindows = { W_INPUT_METHOD })
    @Test
    public void testAdjustImeInsetsVisibilityWhenSwitchingApps() {
        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
        final WindowState app2 = newWindowBuilder("app2", TYPE_APPLICATION).build();
        final WindowState imeWindow = newWindowBuilder("imeWindow", TYPE_APPLICATION).build();
        spyOn(imeWindow);
        doReturn(true).when(imeWindow).isVisible();
        mDisplayContent.mInputMethodWindow = imeWindow;
        final var appWin1 = newWindowBuilder("appWin1", TYPE_APPLICATION).build();
        final var appWin2 = newWindowBuilder("appWin2", TYPE_APPLICATION).build();
        makeWindowVisibleAndDrawn(mImeWindow);

        final InsetsStateController controller = mDisplayContent.getInsetsStateController();
        controller.getImeSourceProvider().setWindowContainer(imeWindow, null, null);

        // Simulate app requests IME with updating all windows Insets State when IME is above app.
        mDisplayContent.setImeLayeringTarget(app);
        mDisplayContent.setImeInputTarget(app);
        app.setRequestedVisibleTypes(ime(), ime());
        assertTrue(mDisplayContent.shouldImeAttachedToApp());
        controller.getImeSourceProvider().scheduleShowImePostLayout(app, ImeTracker.Token.empty());
        controller.getImeSourceProvider().getSource().setVisible(true);
        controller.updateAboveInsetsState(false);

        // Expect all app windows behind IME can receive IME insets visible.
        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertTrue(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));

        // Simulate app plays closing transition to app2.
        app.mActivityRecord.commitVisibility(false, false);
        mDisplayContent.computeImeLayeringTarget(true /* update */);
        assertTrue(app.mActivityRecord.mLastImeShown);

        // Verify the IME insets is visible on app, but not for app2 during app task switching.
        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertFalse(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        controller.getImeSourceProvider().setWindowContainer(mImeWindow, null, null);

        // Simulate appWin2 requests IME.
        appWin2.setRequestedVisibleTypes(ime(), ime());
        mDisplayContent.setImeInputTarget(appWin2);
        mDisplayContent.setImeLayeringTarget(appWin2);
        assertEquals("appWin2 is the IME control target",
                appWin2, mDisplayContent.getImeControlTarget());
        controller.getImeSourceProvider().onPostLayout();

        // Expect all windows behind IME can receive IME insets visible.
        assertTrue("appWin1 has IME insets visible",
                appWin1.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertTrue("appWin2 has IME insets visible",
                appWin2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));

        // Simulate appWin2 plays closing transition to appWin1.
        appWin2.mActivityRecord.commitVisibility(false /* visible */, false /* performLayout */);
        assertNull("appWin1 does not have frozen insets", appWin1.getFrozenInsetsState());
        assertNotNull("appWin2 has frozen insets", appWin2.getFrozenInsetsState());
        mDisplayContent.setImeInputTarget(appWin1);
        mDisplayContent.setImeLayeringTarget(appWin1);
        assertEquals("appWin1 is the IME control target",
                appWin1, mDisplayContent.getImeControlTarget());

        assertFalse("appWin1 does not have IME insets visible",
                appWin1.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertTrue("appWin2 still has IME insets visible, as they were frozen",
                appWin2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
    }

    @SetupWindows(addWindows = { W_INPUT_METHOD })
    @Test
    public void testAdjustImeInsetsVisibilityWhenSwitchingApps_toAppInMultiWindowMode() {
        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
        final WindowState app2 = newWindowBuilder("app2", TYPE_APPLICATION).setWindowingMode(
                WINDOWING_MODE_MULTI_WINDOW).setActivityType(ACTIVITY_TYPE_STANDARD).setDisplay(
                mDisplayContent).build();
        final WindowState imeWindow = newWindowBuilder("imeWindow", TYPE_APPLICATION).build();
        spyOn(imeWindow);
        doReturn(true).when(imeWindow).isVisible();
        mDisplayContent.mInputMethodWindow = imeWindow;
        final var appWin1 = newWindowBuilder("appWin1", TYPE_APPLICATION)
                .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW).build();
        final var appWin2 = newWindowBuilder("appWin2", TYPE_APPLICATION).build();
        makeWindowVisibleAndDrawn(mImeWindow);
        mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController());

        final InsetsStateController controller = mDisplayContent.getInsetsStateController();
        controller.getImeSourceProvider().setWindowContainer(imeWindow, null, null);

        // Simulate app2 in multi-window mode is going to background to switch to the fullscreen
        // app which requests IME with updating all windows Insets State when IME is above app.
        app2.mActivityRecord.setVisibleRequested(false);
        mDisplayContent.setImeLayeringTarget(app);
        mDisplayContent.setImeInputTarget(app);
        app.setRequestedVisibleTypes(ime(), ime());
        assertTrue(mDisplayContent.shouldImeAttachedToApp());
        controller.getImeSourceProvider().scheduleShowImePostLayout(app, ImeTracker.Token.empty());
        controller.getImeSourceProvider().getSource().setVisible(true);
        controller.updateAboveInsetsState(false);

        // Expect app windows behind IME can receive IME insets visible,
        // but not for app2 in background.
        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertFalse(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));

        // Simulate app plays closing transition to app2.
        // And app2 is now IME layering target but not yet to be the IME input target.
        mDisplayContent.setImeLayeringTarget(app2);
        app.mActivityRecord.commitVisibility(false, false);
        assertTrue(app.mActivityRecord.mLastImeShown);

        // Verify the IME insets is still visible on app, but not for app2 during task switching.
        assertTrue(app.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertFalse(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        controller.getImeSourceProvider().setWindowContainer(mImeWindow, null, null);

        // Simulate appWin1 in multi-window mode is going to background to switch to the
        // fullscreen appWin2 which requests IME.
        appWin1.mActivityRecord.commitVisibility(false /* visible */, false /* performLayout */);
        assertNotNull("appWin1 has frozen insets", appWin1.getFrozenInsetsState());
        assertNull("appWin2 does not have frozen insets", appWin2.getFrozenInsetsState());
        appWin2.setRequestedVisibleTypes(ime(), ime());
        mDisplayContent.setImeInputTarget(appWin2);
        mDisplayContent.setImeLayeringTarget(appWin2);
        controller.getImeSourceProvider().onPostLayout();

        assertFalse("appWin1 does not have IME insets visible, as it is in background",
                appWin1.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertTrue("appWin2 has IME insets visible",
                appWin2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));

        // Simulate appWin2 plays closing transition to appWin1.
        appWin2.mActivityRecord.commitVisibility(false /* visible */, false /* performLayout */);
        appWin1.mActivityRecord.commitVisibility(true /* visible */, false /* performLayout */);
        assertNull("appWin1 does not have frozen insets", appWin1.getFrozenInsetsState());
        assertNotNull("appWin2 has frozen insets", appWin2.getFrozenInsetsState());
        mDisplayContent.setImeInputTarget(appWin1);
        mDisplayContent.setImeLayeringTarget(appWin1);
        assertEquals("RemoteInsetsControlTarget is the IME control target",
                mDisplayContent.mRemoteInsetsControlTarget, mDisplayContent.getImeControlTarget());

        assertFalse("appWin1 does not have IME insets visible",
                appWin1.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertTrue("appWin2 still has IME insets visible, as they were frozen",
                appWin2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
    }

    @SetupWindows(addWindows = W_ACTIVITY)
Loading