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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user