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

am: 7e7449f18a

* commit '7e7449f18af5485fd49d9401fb887435224ebde2':
  Fixes for restoring more than one child surfaces

Change-Id: I28a7688752c8e90887002d0be0c7bed0523ce433
This commit is contained in:
Chong Zhang
2016-05-10 21:36:51 +00:00
committed by android-build-merger
5 changed files with 107 additions and 47 deletions

View File

@@ -185,8 +185,7 @@ public class AppWindowAnimator {
clearThumbnail();
setNullAnimation();
if (mAppToken.deferClearAllDrawn) {
mAppToken.allDrawn = false;
mAppToken.deferClearAllDrawn = false;
mAppToken.clearAllDrawn();
}
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_WM;
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.wm.WindowManagerService.H;
@@ -65,10 +66,6 @@ class AppWindowToken extends WindowToken {
final boolean voiceInteraction;
// Whether we're performing an entering animation with a saved surface.
boolean mAnimatingWithSavedSurface;
Task mTask;
boolean appFullscreen;
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) {
firstWindowDrawn = true;
@@ -295,7 +299,7 @@ class AppWindowToken extends WindowToken {
// If we're animating with a saved surface, we're already visible.
// Return true so that the alpha doesn't get cleared.
if (!win.mAppFreezing
&& (win.mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface
&& (win.mViewVisibility == View.VISIBLE || win.isAnimatingWithSavedSurface()
|| (win.mWinAnimator.isAnimationSet()
&& !service.mAppTransition.isTransitionSet()))
&& !win.mDestroying
@@ -347,7 +351,6 @@ class AppWindowToken extends WindowToken {
win.destroyOrSaveSurface();
if (win.mRemoveOnExit) {
win.mAnimatingExit = false;
service.removeWindowInnerLocked(win);
}
final DisplayContent displayContent = win.getDisplayContent();
@@ -391,43 +394,56 @@ class AppWindowToken extends WindowToken {
return allDrawn;
}
boolean hasSavedSurface() {
boolean canRestoreSurfaces() {
for (int i = allAppWindows.size() -1; i >= 0; i--) {
final WindowState ws = allAppWindows.get(i);
if (ws.hasSavedSurface()) {
final WindowState w = allAppWindows.get(i);
if (w.canRestoreSurface()) {
return true;
}
}
return false;
}
void clearVisibleBeforeClientHidden() {
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
final WindowState w = allAppWindows.get(i);
w.clearVisibleBeforeClientHidden();
}
}
void restoreSavedSurfaces() {
if (!hasSavedSurface()) {
if (!canRestoreSurfaces()) {
clearVisibleBeforeClientHidden();
return;
}
mAnimatingWithSavedSurface = true;
// Check if we have enough drawn windows to mark allDrawn= true.
int numInteresting = 0;
int numDrawn = 0;
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
WindowState w = allAppWindows.get(i);
if (w.hasSavedSurface()) {
w.restoreSavedSurface();
}
if (w != startingWindow && !w.mAppDied
if (w != startingWindow && !w.mAppDied && w.wasVisibleBeforeClientHidden()
&& (!mAppAnimator.freezingScreen || !w.mAppFreezing)) {
numInteresting++;
if (w.hasSavedSurface()) {
w.restoreSavedSurface();
}
if (w.isDrawnLw()) {
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,
"restoreSavedSurfaces: " + appWindowToken + " allDrawn=" + allDrawn);
"restoreSavedSurfaces: " + appWindowToken + " allDrawn=" + allDrawn
+ " numInteresting=" + numInteresting + " numDrawn=" + numDrawn);
}
void destroySavedSurfaces() {
@@ -435,7 +451,11 @@ class AppWindowToken extends WindowToken {
WindowState win = allAppWindows.get(i);
win.destroySavedSurface();
}
mAnimatingWithSavedSurface = false;
}
void clearAllDrawn() {
allDrawn = false;
deferClearAllDrawn = false;
}
@Override

View File

@@ -2170,7 +2170,7 @@ public class WindowManagerService extends IWindowManager.Stub
* Returns true if we're done setting up any transitions.
*/
private boolean prepareWindowReplacementTransition(AppWindowToken atoken) {
atoken.allDrawn = false;
atoken.clearAllDrawn();
WindowState replacedWindow = null;
for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; 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 "
+ "added");
// 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
// animation.
win.mAnimatingExit = true;
@@ -2464,7 +2464,7 @@ public class WindowManagerService extends IWindowManager.Stub
mTokenMap.remove(token.token);
} else if (atoken != null) {
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
// if made visible again.
wtoken.removeAllDeadWindows();
wtoken.setVisibleBeforeClientHidden();
} else if (visible) {
if (!mAppTransition.isTransitionSet() && mAppTransition.isReady()) {
// 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
// stopped, then we need to set up to wait for its windows to be ready.
if (wtoken.hidden || wtoken.mAppStopped) {
wtoken.allDrawn = false;
wtoken.deferClearAllDrawn = false;
wtoken.clearAllDrawn();
// If the app was already visible, don't reset the waitingToShow state.
if (wtoken.hidden) {
@@ -9234,8 +9234,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
winAnimator.mDrawState = DRAW_PENDING;
if (w.mAppToken != null) {
w.mAppToken.allDrawn = false;
w.mAppToken.deferClearAllDrawn = false;
w.mAppToken.clearAllDrawn();
}
}
if (!mResizingWindows.contains(w)) {
@@ -9392,7 +9391,7 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
+ ws + " surface=" + wsa.mSurfaceController
+ " token=" + ws.mAppToken
+ " saved=" + ws.mAppToken.hasSavedSurface());
+ " saved=" + ws.hasSavedSurface());
if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
wsa.destroySurface();
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
// 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
// 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() {
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() {
@@ -1958,6 +1979,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return false;
}
if (!mWasVisibleBeforeClientHidden) {
return false;
}
if ((mAttrs.flags & FLAG_SECURE) != 0) {
// 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
@@ -2020,18 +2045,22 @@ final class WindowState implements WindowManagerPolicy.WindowState {
} else {
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 (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
Slog.v(TAG, "Destroying saved surface: " + this);
}
mWinAnimator.destroySurfaceLocked();
}
mWasVisibleBeforeClientHidden = false;
}
public void restoreSavedSurface() {
void restoreSavedSurface() {
if (!mSurfaceSaved) {
return;
}
@@ -2039,6 +2068,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (mWinAnimator.mSurfaceController != null) {
setHasSurface(true);
mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
mAnimatingWithSavedSurface = true;
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
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;
}
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
public boolean isDefaultDisplay() {
final DisplayContent displayContent = getDisplayContent();

View File

@@ -584,14 +584,8 @@ class WindowStateAnimator {
+ drawStateToString());
}
if (mWin.mAppToken != null && mWin.mAppToken.mAnimatingWithSavedSurface) {
// 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;
}
mWin.clearAnimatingWithSavedSurface();
if (mDrawState == DRAW_PENDING) {
if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
@@ -687,8 +681,7 @@ class WindowStateAnimator {
mDrawState = DRAW_PENDING;
if (w.mAppToken != null) {
if (w.mAppToken.mAppAnimator.animation == null) {
w.mAppToken.allDrawn = false;
w.mAppToken.deferClearAllDrawn = false;
w.mAppToken.clearAllDrawn();
} else {
// Currently animating, persist current state of allDrawn until animation
// is complete.
@@ -840,20 +833,19 @@ class WindowStateAnimator {
}
boolean hasSurface() {
return !mWin.mSurfaceSaved
return !mWin.hasSavedSurface()
&& mSurfaceController != null && mSurfaceController.hasSurface();
}
void destroySurfaceLocked() {
final AppWindowToken wtoken = mWin.mAppToken;
if (wtoken != null) {
wtoken.mAnimatingWithSavedSurface = false;
if (mWin == wtoken.startingWindow) {
wtoken.startingDisplayed = false;
}
}
mWin.mSurfaceSaved = false;
mWin.clearHasSavedSurface();
if (mSurfaceController == null) {
return;