Merge "Fixes for restoring more than one child surfaces" into nyc-dev

This commit is contained in:
Chong Zhang
2016-05-10 21:30:39 +00:00
committed by Android (Google) Code Review
5 changed files with 107 additions and 47 deletions

View File

@@ -185,8 +185,7 @@ public class AppWindowAnimator {
clearThumbnail(); clearThumbnail();
setNullAnimation(); setNullAnimation();
if (mAppToken.deferClearAllDrawn) { if (mAppToken.deferClearAllDrawn) {
mAppToken.allDrawn = false; mAppToken.clearAllDrawn();
mAppToken.deferClearAllDrawn = false;
} }
mStackClip = STACK_CLIP_BEFORE_ANIM; mStackClip = STACK_CLIP_BEFORE_ANIM;
} }

View File

@@ -27,6 +27,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEME
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.WINDOW_REPLACEMENT_TIMEOUT_DURATION; import static com.android.server.wm.WindowManagerService.WINDOW_REPLACEMENT_TIMEOUT_DURATION;
import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
import com.android.server.input.InputApplicationHandle; import com.android.server.input.InputApplicationHandle;
import com.android.server.wm.WindowManagerService.H; import com.android.server.wm.WindowManagerService.H;
@@ -65,10 +66,6 @@ class AppWindowToken extends WindowToken {
final boolean voiceInteraction; final boolean voiceInteraction;
// Whether we're performing an entering animation with a saved surface.
boolean mAnimatingWithSavedSurface;
Task mTask; Task mTask;
boolean appFullscreen; boolean appFullscreen;
int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -160,6 +157,13 @@ class AppWindowToken extends WindowToken {
} }
} }
void setVisibleBeforeClientHidden() {
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
final WindowState w = allAppWindows.get(i);
w.setVisibleBeforeClientHidden();
}
}
void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) { void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
firstWindowDrawn = true; firstWindowDrawn = true;
@@ -295,7 +299,7 @@ class AppWindowToken extends WindowToken {
// If we're animating with a saved surface, we're already visible. // If we're animating with a saved surface, we're already visible.
// Return true so that the alpha doesn't get cleared. // Return true so that the alpha doesn't get cleared.
if (!win.mAppFreezing if (!win.mAppFreezing
&& (win.mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface && (win.mViewVisibility == View.VISIBLE || win.isAnimatingWithSavedSurface()
|| (win.mWinAnimator.isAnimationSet() || (win.mWinAnimator.isAnimationSet()
&& !service.mAppTransition.isTransitionSet())) && !service.mAppTransition.isTransitionSet()))
&& !win.mDestroying && !win.mDestroying
@@ -347,7 +351,6 @@ class AppWindowToken extends WindowToken {
win.destroyOrSaveSurface(); win.destroyOrSaveSurface();
if (win.mRemoveOnExit) { if (win.mRemoveOnExit) {
win.mAnimatingExit = false;
service.removeWindowInnerLocked(win); service.removeWindowInnerLocked(win);
} }
final DisplayContent displayContent = win.getDisplayContent(); final DisplayContent displayContent = win.getDisplayContent();
@@ -391,43 +394,56 @@ class AppWindowToken extends WindowToken {
return allDrawn; return allDrawn;
} }
boolean hasSavedSurface() { boolean canRestoreSurfaces() {
for (int i = allAppWindows.size() -1; i >= 0; i--) { for (int i = allAppWindows.size() -1; i >= 0; i--) {
final WindowState ws = allAppWindows.get(i); final WindowState w = allAppWindows.get(i);
if (ws.hasSavedSurface()) { if (w.canRestoreSurface()) {
return true; return true;
} }
} }
return false; return false;
} }
void clearVisibleBeforeClientHidden() {
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
final WindowState w = allAppWindows.get(i);
w.clearVisibleBeforeClientHidden();
}
}
void restoreSavedSurfaces() { void restoreSavedSurfaces() {
if (!hasSavedSurface()) { if (!canRestoreSurfaces()) {
clearVisibleBeforeClientHidden();
return; return;
} }
mAnimatingWithSavedSurface = true;
// Check if we have enough drawn windows to mark allDrawn= true. // Check if we have enough drawn windows to mark allDrawn= true.
int numInteresting = 0; int numInteresting = 0;
int numDrawn = 0; int numDrawn = 0;
for (int i = allAppWindows.size() - 1; i >= 0; i--) { for (int i = allAppWindows.size() - 1; i >= 0; i--) {
WindowState w = allAppWindows.get(i); WindowState w = allAppWindows.get(i);
if (w != startingWindow && !w.mAppDied && w.wasVisibleBeforeClientHidden()
&& (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
numInteresting++;
if (w.hasSavedSurface()) { if (w.hasSavedSurface()) {
w.restoreSavedSurface(); w.restoreSavedSurface();
} }
if (w != startingWindow && !w.mAppDied
&& (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
numInteresting++;
if (w.isDrawnLw()) { if (w.isDrawnLw()) {
numDrawn++; numDrawn++;
} }
} }
} }
allDrawn |= (numInteresting > 0) && (numInteresting == numDrawn); if (!allDrawn) {
allDrawn = (numInteresting > 0) && (numInteresting == numDrawn);
if (allDrawn) {
service.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
}
}
clearVisibleBeforeClientHidden();
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG, if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG,
"restoreSavedSurfaces: " + appWindowToken + " allDrawn=" + allDrawn); "restoreSavedSurfaces: " + appWindowToken + " allDrawn=" + allDrawn
+ " numInteresting=" + numInteresting + " numDrawn=" + numDrawn);
} }
void destroySavedSurfaces() { void destroySavedSurfaces() {
@@ -435,7 +451,11 @@ class AppWindowToken extends WindowToken {
WindowState win = allAppWindows.get(i); WindowState win = allAppWindows.get(i);
win.destroySavedSurface(); win.destroySavedSurface();
} }
mAnimatingWithSavedSurface = false; }
void clearAllDrawn() {
allDrawn = false;
deferClearAllDrawn = false;
} }
@Override @Override

View File

@@ -2170,7 +2170,7 @@ public class WindowManagerService extends IWindowManager.Stub
* Returns true if we're done setting up any transitions. * Returns true if we're done setting up any transitions.
*/ */
private boolean prepareWindowReplacementTransition(AppWindowToken atoken) { private boolean prepareWindowReplacementTransition(AppWindowToken atoken) {
atoken.allDrawn = false; atoken.clearAllDrawn();
WindowState replacedWindow = null; WindowState replacedWindow = null;
for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; i--) { for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; i--) {
WindowState candidate = atoken.windows.get(i); WindowState candidate = atoken.windows.get(i);
@@ -2316,7 +2316,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is " if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is "
+ "added"); + "added");
// TODO: We are overloading mAnimatingExit flag to prevent the window state from // TODO: We are overloading mAnimatingExit flag to prevent the window state from
// been removed. We probably need another falg to indicate that window removal // been removed. We probably need another flag to indicate that window removal
// should be deffered vs. overloading the flag that says we are playing an exit // should be deffered vs. overloading the flag that says we are playing an exit
// animation. // animation.
win.mAnimatingExit = true; win.mAnimatingExit = true;
@@ -2464,7 +2464,7 @@ public class WindowManagerService extends IWindowManager.Stub
mTokenMap.remove(token.token); mTokenMap.remove(token.token);
} else if (atoken != null) { } else if (atoken != null) {
atoken.firstWindowDrawn = false; atoken.firstWindowDrawn = false;
atoken.allDrawn = false; atoken.clearAllDrawn();
} }
} }
@@ -4423,6 +4423,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Now that the app is going invisible, we can remove it. It will be restarted // Now that the app is going invisible, we can remove it. It will be restarted
// if made visible again. // if made visible again.
wtoken.removeAllDeadWindows(); wtoken.removeAllDeadWindows();
wtoken.setVisibleBeforeClientHidden();
} else if (visible) { } else if (visible) {
if (!mAppTransition.isTransitionSet() && mAppTransition.isReady()) { if (!mAppTransition.isTransitionSet() && mAppTransition.isReady()) {
// Add the app mOpeningApps if transition is unset but ready. This means // Add the app mOpeningApps if transition is unset but ready. This means
@@ -4434,8 +4435,7 @@ public class WindowManagerService extends IWindowManager.Stub
// If the token is currently hidden (should be the common case), or has been // If the token is currently hidden (should be the common case), or has been
// stopped, then we need to set up to wait for its windows to be ready. // stopped, then we need to set up to wait for its windows to be ready.
if (wtoken.hidden || wtoken.mAppStopped) { if (wtoken.hidden || wtoken.mAppStopped) {
wtoken.allDrawn = false; wtoken.clearAllDrawn();
wtoken.deferClearAllDrawn = false;
// If the app was already visible, don't reset the waitingToShow state. // If the app was already visible, don't reset the waitingToShow state.
if (wtoken.hidden) { if (wtoken.hidden) {
@@ -9234,8 +9234,7 @@ public class WindowManagerService extends IWindowManager.Stub
} }
winAnimator.mDrawState = DRAW_PENDING; winAnimator.mDrawState = DRAW_PENDING;
if (w.mAppToken != null) { if (w.mAppToken != null) {
w.mAppToken.allDrawn = false; w.mAppToken.clearAllDrawn();
w.mAppToken.deferClearAllDrawn = false;
} }
} }
if (!mResizingWindows.contains(w)) { if (!mResizingWindows.contains(w)) {
@@ -9392,7 +9391,7 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): " Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
+ ws + " surface=" + wsa.mSurfaceController + ws + " surface=" + wsa.mSurfaceController
+ " token=" + ws.mAppToken + " token=" + ws.mAppToken
+ " saved=" + ws.mAppToken.hasSavedSurface()); + " saved=" + ws.hasSavedSurface());
if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false); if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
wsa.destroySurface(); wsa.destroySurface();
leakedSurface = true; leakedSurface = true;

View File

@@ -435,7 +435,15 @@ final class WindowState implements WindowManagerPolicy.WindowState {
// Whether the window has a saved surface from last pause, which can be // Whether the window has a saved surface from last pause, which can be
// used to start an entering animation earlier. // used to start an entering animation earlier.
public boolean mSurfaceSaved = false; private boolean mSurfaceSaved = false;
// Whether we're performing an entering animation with a saved surface.
private boolean mAnimatingWithSavedSurface;
// Whether the window was visible when we set the app to invisible last time. WM uses
// this as a hint to restore the surface (if available) for early animation next time
// the app is brought visible.
boolean mWasVisibleBeforeClientHidden;
// This window will be replaced due to relaunch. This allows window manager // This window will be replaced due to relaunch. This allows window manager
// to differentiate between simple removal of a window and replacement. In the latter case it // to differentiate between simple removal of a window and replacement. In the latter case it
@@ -1949,7 +1957,20 @@ final class WindowState implements WindowManagerPolicy.WindowState {
} }
boolean isAnimatingWithSavedSurface() { boolean isAnimatingWithSavedSurface() {
return mAppToken != null && mAppToken.mAnimatingWithSavedSurface; return mAnimatingWithSavedSurface;
}
public void setVisibleBeforeClientHidden() {
mWasVisibleBeforeClientHidden |=
(mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface);
}
public void clearVisibleBeforeClientHidden() {
mWasVisibleBeforeClientHidden = false;
}
public boolean wasVisibleBeforeClientHidden() {
return mWasVisibleBeforeClientHidden;
} }
private boolean shouldSaveSurface() { private boolean shouldSaveSurface() {
@@ -1958,6 +1979,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return false; return false;
} }
if (!mWasVisibleBeforeClientHidden) {
return false;
}
if ((mAttrs.flags & FLAG_SECURE) != 0) { if ((mAttrs.flags & FLAG_SECURE) != 0) {
// We don't save secure surfaces since their content shouldn't be shown while the app // We don't save secure surfaces since their content shouldn't be shown while the app
// isn't on screen and content might leak through during the transition animation with // isn't on screen and content might leak through during the transition animation with
@@ -2020,18 +2045,22 @@ final class WindowState implements WindowManagerPolicy.WindowState {
} else { } else {
mWinAnimator.destroySurfaceLocked(); mWinAnimator.destroySurfaceLocked();
} }
// Clear animating flags now, since the surface is now gone. (Note this is true even
// if the surface is saved, to outside world the surface is still NO_SURFACE.)
mAnimatingExit = false;
} }
public void destroySavedSurface() { void destroySavedSurface() {
if (mSurfaceSaved) { if (mSurfaceSaved) {
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Slog.v(TAG, "Destroying saved surface: " + this); Slog.v(TAG, "Destroying saved surface: " + this);
} }
mWinAnimator.destroySurfaceLocked(); mWinAnimator.destroySurfaceLocked();
} }
mWasVisibleBeforeClientHidden = false;
} }
public void restoreSavedSurface() { void restoreSavedSurface() {
if (!mSurfaceSaved) { if (!mSurfaceSaved) {
return; return;
} }
@@ -2039,6 +2068,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (mWinAnimator.mSurfaceController != null) { if (mWinAnimator.mSurfaceController != null) {
setHasSurface(true); setHasSurface(true);
mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW; mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
mAnimatingWithSavedSurface = true;
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Slog.v(TAG, "Restoring saved surface: " + this); Slog.v(TAG, "Restoring saved surface: " + this);
@@ -2051,10 +2081,30 @@ final class WindowState implements WindowManagerPolicy.WindowState {
} }
} }
public boolean hasSavedSurface() { boolean canRestoreSurface() {
return mWasVisibleBeforeClientHidden && mSurfaceSaved;
}
boolean hasSavedSurface() {
return mSurfaceSaved; return mSurfaceSaved;
} }
void clearHasSavedSurface() {
mSurfaceSaved = false;
mAnimatingWithSavedSurface = false;
mWasVisibleBeforeClientHidden = false;
}
void clearAnimatingWithSavedSurface() {
if (mAnimatingWithSavedSurface) {
// App has drawn something to its windows, we're no longer animating with
// the saved surfaces.
if (DEBUG_ANIM) Slog.d(TAG,
"clearAnimatingWithSavedSurface(): win=" + this);
mAnimatingWithSavedSurface = false;
}
}
@Override @Override
public boolean isDefaultDisplay() { public boolean isDefaultDisplay() {
final DisplayContent displayContent = getDisplayContent(); final DisplayContent displayContent = getDisplayContent();

View File

@@ -584,14 +584,8 @@ class WindowStateAnimator {
+ drawStateToString()); + drawStateToString());
} }
if (mWin.mAppToken != null && mWin.mAppToken.mAnimatingWithSavedSurface) { mWin.clearAnimatingWithSavedSurface();
// App has drawn something to its windows, we're no longer animating with
// the saved surfaces. If the user exits now, we only want to save again
// if allDrawn is true.
if (DEBUG_ANIM) Slog.d(TAG,
"finishDrawingLocked: mAnimatingWithSavedSurface=false " + mWin);
mWin.mAppToken.mAnimatingWithSavedSurface = false;
}
if (mDrawState == DRAW_PENDING) { if (mDrawState == DRAW_PENDING) {
if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION) if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in " Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
@@ -687,8 +681,7 @@ class WindowStateAnimator {
mDrawState = DRAW_PENDING; mDrawState = DRAW_PENDING;
if (w.mAppToken != null) { if (w.mAppToken != null) {
if (w.mAppToken.mAppAnimator.animation == null) { if (w.mAppToken.mAppAnimator.animation == null) {
w.mAppToken.allDrawn = false; w.mAppToken.clearAllDrawn();
w.mAppToken.deferClearAllDrawn = false;
} else { } else {
// Currently animating, persist current state of allDrawn until animation // Currently animating, persist current state of allDrawn until animation
// is complete. // is complete.
@@ -840,20 +833,19 @@ class WindowStateAnimator {
} }
boolean hasSurface() { boolean hasSurface() {
return !mWin.mSurfaceSaved return !mWin.hasSavedSurface()
&& mSurfaceController != null && mSurfaceController.hasSurface(); && mSurfaceController != null && mSurfaceController.hasSurface();
} }
void destroySurfaceLocked() { void destroySurfaceLocked() {
final AppWindowToken wtoken = mWin.mAppToken; final AppWindowToken wtoken = mWin.mAppToken;
if (wtoken != null) { if (wtoken != null) {
wtoken.mAnimatingWithSavedSurface = false;
if (mWin == wtoken.startingWindow) { if (mWin == wtoken.startingWindow) {
wtoken.startingDisplayed = false; wtoken.startingDisplayed = false;
} }
} }
mWin.mSurfaceSaved = false; mWin.clearHasSavedSurface();
if (mSurfaceController == null) { if (mSurfaceController == null) {
return; return;