Only restore saved surfaces in the last visible rotation.
Sometimes we see a sequence like this when transitioning between apps causes rotation changes. 1. New app becomes visible, causing the orientation to change 2. Old app gets marked as invisible, at this point its window are still visible from client, so surface is marked as eligible to be saved. 3. Old app calls relayout to invisible, we save surface. Now if we restore the Surface it will be in the wrong orientation. It never had a visible layout in the new one, it was just covered up by the screenshot. To address this we track the rotation a window was last visibily laid out in. If it doesn't match our current rotation we can't use the saved surface. Bug: 30171992 Change-Id: If814131810b6d01c5112afd145072a13a30b0401
This commit is contained in:
@@ -3081,6 +3081,9 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
if (oldVisibility == View.GONE) {
|
||||
winAnimator.mEnterAnimationPending = true;
|
||||
}
|
||||
|
||||
win.mLastVisibleLayoutRotation = mRotation;
|
||||
|
||||
winAnimator.mEnteringAnimation = true;
|
||||
if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
|
||||
win.prepareWindowToDisplayDuringRelayout(outConfig);
|
||||
|
||||
@@ -394,6 +394,13 @@ final class WindowState implements WindowManagerPolicy.WindowState {
|
||||
*/
|
||||
boolean mOrientationChanging;
|
||||
|
||||
/**
|
||||
* The orientation during the last visible call to relayout. If our
|
||||
* current orientation is different, the window can't be ready
|
||||
* to be shown.
|
||||
*/
|
||||
int mLastVisibleLayoutRotation = -1;
|
||||
|
||||
/**
|
||||
* How long we last kept the screen frozen.
|
||||
*/
|
||||
@@ -2095,6 +2102,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
|
||||
Slog.v(TAG, "Destroying saved surface: " + this);
|
||||
}
|
||||
mWinAnimator.destroySurfaceLocked();
|
||||
mSurfaceSaved = false;
|
||||
}
|
||||
mWasVisibleBeforeClientHidden = false;
|
||||
}
|
||||
@@ -2103,7 +2111,18 @@ final class WindowState implements WindowManagerPolicy.WindowState {
|
||||
if (!mSurfaceSaved) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sometimes we save surfaces due to layout invisible
|
||||
// directly after rotation occurs. However this means
|
||||
// the surface was never laid out in the new orientation.
|
||||
// We can only restore to the last rotation we were
|
||||
// laid out as visible in.
|
||||
if (mLastVisibleLayoutRotation != mService.mRotation) {
|
||||
destroySavedSurface();
|
||||
return;
|
||||
}
|
||||
mSurfaceSaved = false;
|
||||
|
||||
if (mWinAnimator.mSurfaceController != null) {
|
||||
setHasSurface(true);
|
||||
mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
|
||||
|
||||
Reference in New Issue
Block a user