Merge "Fixes for broken saved surface"

This commit is contained in:
Chong Zhang
2016-01-21 21:48:55 +00:00
committed by Android (Google) Code Review
6 changed files with 73 additions and 50 deletions

View File

@@ -302,6 +302,13 @@ class AppWindowToken extends WindowToken {
}
}
void markSurfacesExiting() {
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
WindowState win = allAppWindows.get(i);
win.mExiting = true;
}
}
/**
* Checks whether we should save surfaces for this app.
*
@@ -329,15 +336,14 @@ class AppWindowToken extends WindowToken {
if (!hasSavedSurface()) {
return;
}
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
"Restoring saved surfaces: " + this + ", allDrawn=" + allDrawn);
mAnimatingWithSavedSurface = true;
for (int i = windows.size() - 1; i >= 0; i--) {
WindowState ws = windows.get(i);
ws.restoreSavedSurface();
}
// Mark the app allDrawn since it must be allDrawn at the time
// it was first saved.
allDrawn = true;
}
void destroySavedSurfaces() {

View File

@@ -281,8 +281,7 @@ public class WindowAnimator {
final int flags = win.mAttrs.flags;
boolean canBeForceHidden = mPolicy.canBeForceHidden(win, win.mAttrs);
boolean shouldBeForceHidden = shouldForceHide(win);
if (winAnimator.mSurfaceController != null
&& winAnimator.mSurfaceController.hasSurface()) {
if (winAnimator.hasSurface()) {
final boolean wasAnimating = winAnimator.mWasAnimating;
final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
winAnimator.mWasAnimating = nowAnimating;

View File

@@ -2679,20 +2679,11 @@ public class WindowManagerService extends IWindowManager.Stub
} else {
winAnimator.mEnterAnimationPending = false;
winAnimator.mEnteringAnimation = false;
if (winAnimator.mSurfaceController != null &&
winAnimator.mSurfaceController.hasSurface()) {
if (winAnimator.hasSurface() && !win.mExiting) {
if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win
+ ": mExiting=" + win.mExiting);
// If we are using a saved surface to do enter animation, just let the
// animation run and don't destroy the surface. This could happen when
// the app sets visibility to invisible for the first time after resume,
// or when the user exits immediately after a resume. In both cases, we
// don't want to destroy the saved surface.
// If we are not currently running the exit animation, we
// need to see about starting one.
final boolean notExitingOrAnimating =
!win.mExiting && !win.isAnimatingWithSavedSurface();
result |= notExitingOrAnimating ? RELAYOUT_RES_SURFACE_CHANGED : 0;
// We don't want to animate visibility of windows which are pending
// replacement. In the case of activity relaunch child windows
// could request visibility changes as they are detached from the main
@@ -2700,11 +2691,11 @@ public class WindowManagerService extends IWindowManager.Stub
// these visibility changes though, we would cause a visual glitch
// hiding the window before it's replacement was available.
// So we just do nothing on our side.
if (notExitingOrAnimating && win.mWillReplaceWindow == false) {
focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay,
focusMayChange);
if (!win.mWillReplaceWindow) {
focusMayChange = tryStartExitingAnimation(
win, winAnimator, isDefaultDisplay, focusMayChange);
}
result |= RELAYOUT_RES_SURFACE_CHANGED;
}
outSurface.release();
@@ -2787,7 +2778,7 @@ public class WindowManagerService extends IWindowManager.Stub
return result;
}
private boolean tryStartingAnimation(WindowState win, WindowStateAnimator winAnimator,
private boolean tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator,
boolean isDefaultDisplay, boolean focusMayChange) {
// Try starting an animation; if there isn't one, we
// can destroy the surface right away.
@@ -4240,6 +4231,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
} else {
wtoken.markSurfacesExiting();
mClosingApps.add(wtoken);
wtoken.mEnteringAnimation = false;
}
@@ -10278,10 +10270,6 @@ public class WindowManagerService extends IWindowManager.Stub
return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);
}
void scheduleSurfaceDestroy(WindowState win) {
mDestroySurface.add(win);
}
@Override
public void registerDockedStackListener(IDockedStackListener listener) {
if (!checkCallingPermission(android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS,

View File

@@ -1768,45 +1768,69 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return mAppToken != null && mAppToken.mAnimatingWithSavedSurface;
}
// Returns true if the surface is saved.
boolean destroyOrSaveSurface() {
Task task = getTask();
private boolean shouldSaveSurface() {
if (ActivityManager.isLowRamDeviceStatic()) {
// Don't save surfaces on Svelte devices.
mSurfaceSaved = false;
} else if (task == null || task.inHomeStack()
|| task.getTopVisibleAppToken() != mAppToken) {
return false;
}
if (isChildWindow()) {
return false;
}
Task task = getTask();
if (task == null || task.inHomeStack()) {
// Don't save surfaces for home stack apps. These usually resume and draw
// first frame very fast. Saving surfaces are mostly a waste of memory.
// Don't save if the window is not the topmost window.
mSurfaceSaved = false;
} else if (isChildWindow()) {
mSurfaceSaved = false;
} else {
mSurfaceSaved = mAppToken.shouldSaveSurface();
return false;
}
if (mSurfaceSaved == false) {
final AppWindowToken taskTop = task.getTopVisibleAppToken();
if (taskTop != null && taskTop != mAppToken) {
// Don't save if the window is not the topmost window.
return false;
}
return mAppToken.shouldSaveSurface();
}
void destroyOrSaveSurface() {
mSurfaceSaved = shouldSaveSurface();
if (mSurfaceSaved) {
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Slog.v(TAG, "Saving surface: " + this);
}
mWinAnimator.hide("saved surface");
mWinAnimator.mDrawState = WindowStateAnimator.NO_SURFACE;
setHasSurface(false);
} else {
mWinAnimator.destroySurfaceLocked();
}
return mSurfaceSaved;
}
public void destroySavedSurface() {
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "Destroying saved surface: " + this);
if (mSurfaceSaved) {
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Slog.v(TAG, "Destroying saved surface: " + this);
}
mWinAnimator.destroySurfaceLocked();
}
}
public void restoreSavedSurface() {
mSurfaceSaved = false;
setHasSurface(true);
mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Slog.v(TAG, "Restoring saved surface: " + this);
}
}
public boolean hasSavedSurface() {
return mSurfaceSaved;
}
public void restoreSavedSurface() {
mSurfaceSaved = false;
mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
}
@Override
public boolean isDefaultDisplay() {
final DisplayContent displayContent = getDisplayContent();

View File

@@ -468,7 +468,7 @@ class WindowStateAnimator {
if (WindowManagerService.localLOGV) Slog.v(
TAG, "Exit animation finished in " + this
+ ": remove=" + mWin.mRemoveOnExit);
if (mSurfaceController != null && mSurfaceController.hasSurface()) {
if (hasSurface()) {
mService.mDestroySurface.add(mWin);
mWin.mDestroying = true;
hide("finishExit");
@@ -734,6 +734,11 @@ class WindowStateAnimator {
mTmpSize.bottom += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);
}
boolean hasSurface() {
return !mWin.mSurfaceSaved
&& mSurfaceController != null && mSurfaceController.hasSurface();
}
void destroySurfaceLocked() {
final AppWindowToken wtoken = mWin.mAppToken;
if (wtoken != null) {
@@ -1229,7 +1234,7 @@ class WindowStateAnimator {
void prepareSurfaceLocked(final boolean recoveringMemory) {
final WindowState w = mWin;
if (mSurfaceController == null || !mSurfaceController.hasSurface()) {
if (!hasSurface()) {
if (w.mOrientationChanging) {
if (DEBUG_ORIENTATION) {
Slog.v(TAG, "Orientation change skips hidden " + w);
@@ -1311,7 +1316,7 @@ class WindowStateAnimator {
w.mOrientationChanging = false;
}
}
if (mSurfaceController != null && mSurfaceController.hasSurface()) {
if (hasSurface()) {
w.mToken.hasVisible = true;
}
} else {

View File

@@ -1161,6 +1161,9 @@ class WindowSurfacePlacer {
appAnimator.animation = null;
}
wtoken.inPendingTransaction = false;
wtoken.restoreSavedSurfaces();
if (!mService.setTokenVisibilityLocked(
wtoken, animLp, true, transit, false, voiceInteraction)){
// This token isn't going to be animating. Add it to the list of tokens to
@@ -1217,8 +1220,6 @@ class WindowSurfacePlacer {
if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
}
wtoken.restoreSavedSurfaces();
}
return topOpeningApp;
}