Loading services/core/java/com/android/server/wm/DisplayContent.java +13 −6 Original line number Diff line number Diff line Loading @@ -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(); } } Loading Loading @@ -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; } } Loading Loading @@ -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 Loading @@ -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); } /** Loading @@ -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); } Loading services/core/java/com/android/server/wm/WindowContainer.java +7 −2 Original line number Diff line number Diff line Loading @@ -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 Loading services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +19 −0 Original line number Diff line number Diff line Loading @@ -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. Loading services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +25 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +13 −6 Original line number Diff line number Diff line Loading @@ -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(); } } Loading Loading @@ -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; } } Loading Loading @@ -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 Loading @@ -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); } /** Loading @@ -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); } Loading
services/core/java/com/android/server/wm/WindowContainer.java +7 −2 Original line number Diff line number Diff line Loading @@ -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 Loading
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +19 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +25 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading