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:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user