Merge "Fix IME flickering when playing Keyguard launching remote animation" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
9ad299f24d
@@ -4140,6 +4140,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
target.mActivityRecord.mImeInsetsFrozenUntilStartInput = false;
|
target.mActivityRecord.mImeInsetsFrozenUntilStartInput = false;
|
||||||
}
|
}
|
||||||
setImeInputTarget(target);
|
setImeInputTarget(target);
|
||||||
|
mInsetsStateController.updateAboveInsetsState(mInputMethodWindow, mInsetsStateController
|
||||||
|
.getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME));
|
||||||
updateImeControlTarget();
|
updateImeControlTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4967,20 +4967,27 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
|||||||
|
|
||||||
private boolean applyImeWindowsIfNeeded(ToBooleanFunction<WindowState> callback,
|
private boolean applyImeWindowsIfNeeded(ToBooleanFunction<WindowState> callback,
|
||||||
boolean traverseTopToBottom) {
|
boolean traverseTopToBottom) {
|
||||||
// If this window is the current IME target, so we need to process the IME windows
|
// No need to apply to IME window if the window is not the current IME layering target.
|
||||||
// directly above it. The exception is if we are in split screen
|
if (!isImeLayeringTarget()) {
|
||||||
// in which case we process the IME at the DisplayContent level to
|
return false;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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,
|
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_APP_TRANSITION;
|
||||||
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;
|
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 junit.framework.Assert.fail;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyFloat;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
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) {
|
private AnimationAdapter setupForNonAppTargetNavBar(int transit, boolean shouldAttachNavBar) {
|
||||||
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
|
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
|
||||||
mDisplayContent.mOpeningApps.add(win.mActivityRecord);
|
mDisplayContent.mOpeningApps.add(win.mActivityRecord);
|
||||||
|
|||||||
Reference in New Issue
Block a user