Merge "Fix IME flickering when playing Keyguard launching remote animation" into sc-v2-dev am: 9ad299f24d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16038030

Change-Id: Iff7cdd9923329ac4599f3f711833a11238f50934
This commit is contained in:
TreeHugger Robot
2021-10-26 02:00:18 +00:00
committed by Automerger Merge Worker
3 changed files with 69 additions and 13 deletions

View File

@@ -4140,6 +4140,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
target.mActivityRecord.mImeInsetsFrozenUntilStartInput = false;
}
setImeInputTarget(target);
mInsetsStateController.updateAboveInsetsState(mInputMethodWindow, mInsetsStateController
.getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME));
updateImeControlTarget();
}
}

View File

@@ -4967,20 +4967,27 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
private boolean applyImeWindowsIfNeeded(ToBooleanFunction<WindowState> callback,
boolean traverseTopToBottom) {
// If this window is the current IME target, so we need to process the IME windows
// directly above it. The exception is if we are in split screen
// in which case we process the IME at the DisplayContent level to
// ensure it is above the docked divider.
// (i.e. Like {@link DisplayContent.ImeContainer#skipImeWindowsDuringTraversal}, the IME
// window will be ignored to traverse when the IME target is still in split-screen mode).
if (isImeLayeringTarget()
&& (!mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()
|| getTask() == null)) {
if (mDisplayContent.forAllImeWindows(callback, traverseTopToBottom)) {
return true;
}
// No need to apply to IME window if the window is not the current IME layering target.
if (!isImeLayeringTarget()) {
return false;
}
return false;
// If we are in split screen which case we process the IME at the DisplayContent level to
// ensure it is above the docked divider.
// i.e. Like {@link DisplayContent.ImeContainer#skipImeWindowsDuringTraversal}, the IME
// window will be ignored to traverse when the IME target is still in split-screen mode.
if (mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()
&& getTask() != null) {
return false;
}
// Note that we don't process IME window if the IME input target is not on the screen.
// In case some unexpected IME visibility cases happen like starting the remote
// animation on the keyguard but seeing the IME window that originally on the app
// which behinds the keyguard.
final WindowState imeInputTarget = getImeInputTarget();
if (imeInputTarget != null && !(imeInputTarget.isDrawn() || imeInputTarget.isVisible())) {
return false;
}
return mDisplayContent.forAllImeWindows(callback, traverseTopToBottom);
}
private boolean applyInOrderWithImeWindows(ToBooleanFunction<WindowState> callback,

View File

@@ -36,12 +36,14 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.fail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -699,6 +701,51 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
}
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@Test
public void testLaunchRemoteAnimationWithoutImeBehind() {
final WindowState win1 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin1");
final WindowState win2 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin2");
// Simulating win1 has shown IME and being IME layering/input target
mDisplayContent.setImeLayeringTarget(win1);
mDisplayContent.setImeInputTarget(win1);
mImeWindow.mWinAnimator.mSurfaceController = mock(WindowSurfaceController.class);
mImeWindow.mWinAnimator.hide(mDisplayContent.getPendingTransaction(), "test");
spyOn(mDisplayContent);
doReturn(true).when(mImeWindow.mWinAnimator.mSurfaceController).hasSurface();
doReturn(true).when(mImeWindow.mWinAnimator.mSurfaceController)
.prepareToShowInTransaction(any(), anyFloat());
makeWindowVisibleAndDrawn(mImeWindow);
assertTrue(mImeWindow.isOnScreen());
assertFalse(mImeWindow.isParentWindowHidden());
try {
// Simulating now win1 is being covered by the lockscreen which has no surface,
// and then launching an activity win2 with the remote animation
win1.mHasSurface = false;
mDisplayContent.mOpeningApps.add(win2.mActivityRecord);
final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
win2.mActivityRecord, new Point(50, 100), null,
new Rect(50, 100, 150, 150), null).mAdapter;
adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
mFinishedCallback);
mDisplayContent.applySurfaceChangesTransaction();
mController.goodToGo(TRANSIT_OLD_TASK_OPEN);
mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN),
any(), any(), any(), any());
// Verify the IME window won't apply surface change transaction with forAllImeWindows
verify(mDisplayContent, never()).forAllImeWindows(any(), eq(true));
} catch (Exception e) {
// no-op
} finally {
mDisplayContent.mOpeningApps.clear();
}
}
private AnimationAdapter setupForNonAppTargetNavBar(int transit, boolean shouldAttachNavBar) {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
mDisplayContent.mOpeningApps.add(win.mActivityRecord);