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

This commit is contained in:
Chris Li
2021-03-08 18:30:15 +00:00
committed by Android (Google) Code Review
4 changed files with 64 additions and 8 deletions

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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;