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

Commit fb4ae8b4 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Force update IME container relative layer when IME parent is changed" into sc-dev

parents 0079fcad 4515b220
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -3856,6 +3856,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        if (newParent != null && newParent != mInputMethodSurfaceParent) {
            mInputMethodSurfaceParent = newParent;
            getPendingTransaction().reparent(mImeWindowsContainer.mSurfaceControl, newParent);
            // When surface parent is removed, the relative layer will also be removed. We need to
            // do a force update to make sure there is a layer set for the new parent.
            assignRelativeLayerForIme(getPendingTransaction(), true /* forceUpdate */);
            scheduleAnimation();
        }
    }
@@ -4537,11 +4540,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }

        @Override
        void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
        void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer,
                boolean forceUpdate) {
            if (!mNeedsLayer) {
                return;
            }
            super.assignRelativeLayer(t, relativeTo, layer);
            super.assignRelativeLayer(t, relativeTo, layer, forceUpdate);
            mNeedsLayer = false;
        }
    }
@@ -4631,6 +4635,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    @Override
    void assignChildLayers(SurfaceControl.Transaction t) {
        assignRelativeLayerForIme(t, false /* forceUpdate */);
        super.assignChildLayers(t);
    }

    private void assignRelativeLayerForIme(SurfaceControl.Transaction t, boolean forceUpdate) {
        mImeWindowsContainer.setNeedsLayer();
        final WindowState imeTarget = mImeLayeringTarget;
        // In the case where we have an IME target that is not in split-screen mode IME
@@ -4657,14 +4666,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            mImeWindowsContainer.assignRelativeLayer(t, imeTarget.getSurfaceControl(),
                    // TODO: We need to use an extra level on the app surface to ensure
                    // this is always above SurfaceView but always below attached window.
                    1);
                    1, forceUpdate);
        } else if (mInputMethodSurfaceParent != null) {
            // The IME surface parent may not be its window parent's surface
            // (@see #computeImeParent), so set relative layer here instead of letting the window
            // parent to assign layer.
            mImeWindowsContainer.assignRelativeLayer(t, mInputMethodSurfaceParent, 1);
            mImeWindowsContainer.assignRelativeLayer(t, mInputMethodSurfaceParent, 1, forceUpdate);
        }
        super.assignChildLayers(t);
    }

    /**
@@ -4677,7 +4685,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     * with {@link WindowState#assignLayer}
     */
    void assignRelativeLayerForImeTargetChild(SurfaceControl.Transaction t, WindowContainer child) {
        mImeWindowsContainer.setNeedsLayer();
        child.assignRelativeLayer(t, mImeWindowsContainer.getSurfaceControl(), 1);
    }

+7 −2
Original line number Diff line number Diff line
@@ -2241,15 +2241,20 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
        }
    }

    void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
    void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer,
            boolean forceUpdate) {
        final boolean changed = layer != mLastLayer || mLastRelativeToLayer != relativeTo;
        if (mSurfaceControl != null && changed) {
        if (mSurfaceControl != null && (changed || forceUpdate)) {
            setRelativeLayer(t, relativeTo, layer);
            mLastLayer = layer;
            mLastRelativeToLayer = relativeTo;
        }
    }

    void assignRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
        assignRelativeLayer(t, relativeTo, layer, false /* forceUpdate */);
    }

    protected void setLayer(Transaction t, int layer) {

        // Route through surface animator to accommodate that our surface control might be
+19 −0
Original line number Diff line number Diff line
@@ -342,6 +342,25 @@ public class DisplayContentTests extends WindowTestsBase {
        verify(imeTarget.getRootDisplayArea()).placeImeContainer(imeContainer);
    }

    @Test
    public void testUpdateImeParent_forceUpdateRelativeLayer() {
        final DisplayArea.Tokens imeContainer = mDisplayContent.getImeContainer();
        final ActivityRecord activity = createActivityRecord(mDisplayContent);

        final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, activity,
                "startingWin");
        startingWin.setHasSurface(true);
        assertTrue(startingWin.canBeImeTarget());
        final SurfaceControl imeSurfaceParent = mock(SurfaceControl.class);
        doReturn(imeSurfaceParent).when(mDisplayContent).computeImeParent();
        spyOn(imeContainer);

        mDisplayContent.updateImeParent();

        // Force reassign the relative layer when the IME surface parent is changed.
        verify(imeContainer).assignRelativeLayer(any(), eq(imeSurfaceParent), anyInt(), eq(true));
    }

    /**
     * This tests stack movement between displays and proper stack's, task's and app token's display
     * container references updates.
+25 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.clearInvocations;

import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
@@ -1029,6 +1030,30 @@ public class WindowContainerTests extends WindowTestsBase {
        verify(win).clearFrozenInsetsState();
    }

    @Test
    public void testAssignRelativeLayer() {
        final WindowContainer container = new WindowContainer(mWm);
        container.mSurfaceControl = mock(SurfaceControl.class);
        final SurfaceAnimator surfaceAnimator = container.mSurfaceAnimator;
        final SurfaceControl relativeParent = mock(SurfaceControl.class);
        final SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
        spyOn(container);
        spyOn(surfaceAnimator);

        // Trigger for first relative layer call.
        container.assignRelativeLayer(t, relativeParent, 1 /* layer */);
        verify(surfaceAnimator).setRelativeLayer(t, relativeParent, 1 /* layer */);

        // Not trigger for the same relative layer call.
        clearInvocations(surfaceAnimator);
        container.assignRelativeLayer(t, relativeParent, 1 /* layer */);
        verify(surfaceAnimator, never()).setRelativeLayer(t, relativeParent, 1 /* layer */);

        // Trigger for the same relative layer call if forceUpdate=true
        container.assignRelativeLayer(t, relativeParent, 1 /* layer */, true /* forceUpdate */);
        verify(surfaceAnimator).setRelativeLayer(t, relativeParent, 1 /* layer */);
    }

    /* Used so we can gain access to some protected members of the {@link WindowContainer} class */
    private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
        private final int mLayer;