Loading services/core/java/com/android/server/wm/AppWindowToken.java +39 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,11 @@ class AppWindowToken extends WindowToken { // case do not clear allDrawn until the animation completes. boolean deferClearAllDrawn; // These are to track the app's real drawing status if there were no saved surfaces. boolean allDrawnExcludingSaved; int numInterestingWindowsExcludingSaved; int numDrawnWindowsExclusingSaved; // Is this window's surface needed? This is almost like hidden, except // it will sometimes be true a little earlier: when the token has // been shown, but is still waiting for its app transition to execute Loading Loading @@ -411,6 +416,39 @@ class AppWindowToken extends WindowToken { } } /** * Whether the app has some window that is invisible in layout, but * animating with saved surface. */ boolean isAnimatingInvisibleWithSavedSurface() { for (int i = allAppWindows.size() - 1; i >= 0; i--) { final WindowState w = allAppWindows.get(i); if (w.isAnimatingInvisibleWithSavedSurface()) { return true; } } return false; } /** * Hide all window surfaces that's still invisible in layout but animating * with a saved surface, and mark them destroying. */ void stopUsingSavedSurfaceLocked() { for (int i = allAppWindows.size() - 1; i >= 0; i--) { final WindowState w = allAppWindows.get(i); if (w.isAnimatingInvisibleWithSavedSurface()) { if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG, "stopUsingSavedSurfaceLocked: " + w); w.clearAnimatingWithSavedSurface(); w.mDestroying = true; w.mWinAnimator.hide("stopUsingSavedSurfaceLocked"); w.mWinAnimator.mWallpaperControllerLocked.hideWallpapers(w); } } destroySurfaces(); } void restoreSavedSurfaces() { if (!canRestoreSurfaces()) { clearVisibleBeforeClientHidden(); Loading Loading @@ -456,6 +494,7 @@ class AppWindowToken extends WindowToken { void clearAllDrawn() { allDrawn = false; deferClearAllDrawn = false; allDrawnExcludingSaved = false; } @Override Loading services/core/java/com/android/server/wm/WindowAnimator.java +1 −0 Original line number Diff line number Diff line Loading @@ -788,6 +788,7 @@ public class WindowAnimator { removeReplacedWindowsLocked(); } mService.stopUsingSavedSurfaceLocked(); mService.destroyPreservedSurfaceLocked(); mService.mWindowPlacerLocked.destroyPendingSurfaces(); Loading services/core/java/com/android/server/wm/WindowManagerService.java +33 −0 Original line number Diff line number Diff line Loading @@ -414,6 +414,13 @@ public class WindowManagerService extends IWindowManager.Stub */ final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<>(); /** * List of window tokens that have finished drawing their own windows and * no longer need to show any saved surfaces. Windows that's still showing * saved surfaces will be cleaned up after next animation pass. */ final ArrayList<AppWindowToken> mFinishedEarlyAnim = new ArrayList<>(); /** * List of app window tokens that are waiting for replacing windows. If the * replacement doesn't come in time the stale windows needs to be disposed of. Loading Loading @@ -2330,6 +2337,23 @@ public class WindowManagerService extends IWindowManager.Stub Binder.restoreCallingIdentity(origId); return; } if (win.isAnimatingWithSavedSurface() && !appToken.allDrawnExcludingSaved) { // We started enter animation early with a saved surface, now the app asks to remove // this window. If we remove it now and the app is not yet drawn, we'll show a // flicker. Delay the removal now until it's really drawn. if (DEBUG_ADD_REMOVE) { Slog.d(TAG_WM, "removeWindowLocked: delay removal of " + win + " due to early animation"); } // Do not set mAnimatingExit to true here, it will cause the surface to be hidden // immediately after the enter animation is done. If the app is not yet drawn then // it will show up as a flicker. win.mRemoveOnExit = true; win.mWindowRemovalAllowed = true; Binder.restoreCallingIdentity(origId); return; } // If we are not currently running the exit animation, we need to see about starting one wasVisible = win.isWinVisibleLw(); Loading Loading @@ -8560,6 +8584,15 @@ public class WindowManagerService extends IWindowManager.Stub } mDestroyPreservedSurface.clear(); } void stopUsingSavedSurfaceLocked() { for (int i = mFinishedEarlyAnim.size() - 1; i >= 0 ; i--) { final AppWindowToken wtoken = mFinishedEarlyAnim.get(i); wtoken.stopUsingSavedSurfaceLocked(); } mFinishedEarlyAnim.clear(); } // ------------------------------------------------------------- // IWindowManager API // ------------------------------------------------------------- Loading services/core/java/com/android/server/wm/WindowState.java +35 −1 Original line number Diff line number Diff line Loading @@ -437,7 +437,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { // used to start an entering animation earlier. private boolean mSurfaceSaved = false; // Whether we're performing an entering animation with a saved surface. // Whether we're performing an entering animation with a saved surface. This flag is // true during the time we're showing a window with a previously saved surface. It's // cleared when surface is destroyed, saved, or re-drawn by the app. private boolean mAnimatingWithSavedSurface; // Whether the window was visible when we set the app to invisible last time. WM uses Loading Loading @@ -1255,6 +1257,32 @@ final class WindowState implements WindowManagerPolicy.WindowState { return !mAttachedHidden || mWinAnimator.mAnimation != null; } /** * Whether this window's drawn state might affect the drawn states of the app token. * * @param visibleOnly Whether we should consider only the windows that's currently * visible in layout. If true, windows that has not relayout to VISIBLE * would always return false. * * @return true if the window should be considered while evaluating allDrawn flags. */ boolean mightAffectAllDrawn(boolean visibleOnly) { final boolean isViewVisible = (mViewVisibility == View.VISIBLE) && (mAppToken == null || !mAppToken.clientHidden); return (isOnScreenIgnoringKeyguard() && (!visibleOnly || isViewVisible) || mWinAnimator.mAttrType == TYPE_BASE_APPLICATION) && !mAnimatingExit && !mDestroying; } /** * Whether this window is "interesting" when evaluating allDrawn. If it's interesting, * it must be drawn before allDrawn can become true. */ boolean isInteresting() { return mAppToken != null && !mAppDied && (!mAppToken.mAppAnimator.freezingScreen || !mAppFreezing); } /** * Like isOnScreen(), but we don't return true if the window is part * of a transition that has not yet been started. Loading Loading @@ -1960,6 +1988,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mAnimatingWithSavedSurface; } boolean isAnimatingInvisibleWithSavedSurface() { return mAnimatingWithSavedSurface && (mViewVisibility != View.VISIBLE || mWindowRemovalAllowed); } public void setVisibleBeforeClientHidden() { mWasVisibleBeforeClientHidden |= (mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface); Loading Loading @@ -2042,6 +2075,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { if (mWinAnimator.mSurfaceController != null) { mWinAnimator.mSurfaceController.disconnectInTransaction(); } mAnimatingWithSavedSurface = false; } else { mWinAnimator.destroySurfaceLocked(); } Loading services/core/java/com/android/server/wm/WindowSurfacePlacer.java +41 −6 Original line number Diff line number Diff line Loading @@ -792,15 +792,16 @@ class WindowSurfacePlacer { + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn + " freezingScreen=" + atoken.mAppAnimator.freezingScreen); } if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) { if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved || atoken.mAppAnimator.freezingScreen)) { if (atoken.lastTransactionSequence != mService.mTransactionSequence) { atoken.lastTransactionSequence = mService.mTransactionSequence; atoken.numInterestingWindows = atoken.numDrawnWindows = 0; atoken.numInterestingWindowsExcludingSaved = 0; atoken.numDrawnWindowsExclusingSaved = 0; atoken.startingDisplayed = false; } if ((w.isOnScreenIgnoringKeyguard() || winAnimator.mAttrType == TYPE_BASE_APPLICATION) && !w.mAnimatingExit && !w.mDestroying) { if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) { if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() Loading @@ -816,13 +817,14 @@ class WindowSurfacePlacer { } } if (w != atoken.startingWindow) { if (!w.mAppDied && (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing)) { if (w.isInteresting()) { atoken.numInterestingWindows++; if (w.isDrawnLw()) { atoken.numDrawnWindows++; if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: " + atoken + " w=" + w + " numInteresting=" + atoken.numInterestingWindows + " freezingScreen=" + atoken.mAppAnimator.freezingScreen + " mAppFreezing=" + w.mAppFreezing); Loading @@ -834,6 +836,23 @@ class WindowSurfacePlacer { atoken.startingDisplayed = true; } } if (!atoken.allDrawnExcludingSaved && w.mightAffectAllDrawn(true /* visibleOnly */)) { if (w != atoken.startingWindow && w.isInteresting()) { atoken.numInterestingWindowsExcludingSaved++; if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) { atoken.numDrawnWindowsExclusingSaved++; if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken + " w=" + w + " numInteresting=" + atoken.numInterestingWindowsExcludingSaved + " freezingScreen=" + atoken.mAppAnimator.freezingScreen + " mAppFreezing=" + w.mAppFreezing); updateAllDrawn = true; } } } } if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus Loading Loading @@ -1539,6 +1558,22 @@ class WindowSurfacePlacer { wtoken.token).sendToTarget(); } } if (!wtoken.allDrawnExcludingSaved) { int numInteresting = wtoken.numInterestingWindowsExcludingSaved; if (numInteresting > 0 && wtoken.numDrawnWindowsExclusingSaved >= numInteresting) { if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawnExcludingSaved: " + wtoken + " interesting=" + numInteresting + " drawn=" + wtoken.numDrawnWindowsExclusingSaved); wtoken.allDrawnExcludingSaved = true; displayContent.layoutNeeded = true; if (wtoken.isAnimatingInvisibleWithSavedSurface() && !mService.mFinishedEarlyAnim.contains(wtoken)) { mService.mFinishedEarlyAnim.add(wtoken); } } } } } } Loading Loading
services/core/java/com/android/server/wm/AppWindowToken.java +39 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,11 @@ class AppWindowToken extends WindowToken { // case do not clear allDrawn until the animation completes. boolean deferClearAllDrawn; // These are to track the app's real drawing status if there were no saved surfaces. boolean allDrawnExcludingSaved; int numInterestingWindowsExcludingSaved; int numDrawnWindowsExclusingSaved; // Is this window's surface needed? This is almost like hidden, except // it will sometimes be true a little earlier: when the token has // been shown, but is still waiting for its app transition to execute Loading Loading @@ -411,6 +416,39 @@ class AppWindowToken extends WindowToken { } } /** * Whether the app has some window that is invisible in layout, but * animating with saved surface. */ boolean isAnimatingInvisibleWithSavedSurface() { for (int i = allAppWindows.size() - 1; i >= 0; i--) { final WindowState w = allAppWindows.get(i); if (w.isAnimatingInvisibleWithSavedSurface()) { return true; } } return false; } /** * Hide all window surfaces that's still invisible in layout but animating * with a saved surface, and mark them destroying. */ void stopUsingSavedSurfaceLocked() { for (int i = allAppWindows.size() - 1; i >= 0; i--) { final WindowState w = allAppWindows.get(i); if (w.isAnimatingInvisibleWithSavedSurface()) { if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG, "stopUsingSavedSurfaceLocked: " + w); w.clearAnimatingWithSavedSurface(); w.mDestroying = true; w.mWinAnimator.hide("stopUsingSavedSurfaceLocked"); w.mWinAnimator.mWallpaperControllerLocked.hideWallpapers(w); } } destroySurfaces(); } void restoreSavedSurfaces() { if (!canRestoreSurfaces()) { clearVisibleBeforeClientHidden(); Loading Loading @@ -456,6 +494,7 @@ class AppWindowToken extends WindowToken { void clearAllDrawn() { allDrawn = false; deferClearAllDrawn = false; allDrawnExcludingSaved = false; } @Override Loading
services/core/java/com/android/server/wm/WindowAnimator.java +1 −0 Original line number Diff line number Diff line Loading @@ -788,6 +788,7 @@ public class WindowAnimator { removeReplacedWindowsLocked(); } mService.stopUsingSavedSurfaceLocked(); mService.destroyPreservedSurfaceLocked(); mService.mWindowPlacerLocked.destroyPendingSurfaces(); Loading
services/core/java/com/android/server/wm/WindowManagerService.java +33 −0 Original line number Diff line number Diff line Loading @@ -414,6 +414,13 @@ public class WindowManagerService extends IWindowManager.Stub */ final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<>(); /** * List of window tokens that have finished drawing their own windows and * no longer need to show any saved surfaces. Windows that's still showing * saved surfaces will be cleaned up after next animation pass. */ final ArrayList<AppWindowToken> mFinishedEarlyAnim = new ArrayList<>(); /** * List of app window tokens that are waiting for replacing windows. If the * replacement doesn't come in time the stale windows needs to be disposed of. Loading Loading @@ -2330,6 +2337,23 @@ public class WindowManagerService extends IWindowManager.Stub Binder.restoreCallingIdentity(origId); return; } if (win.isAnimatingWithSavedSurface() && !appToken.allDrawnExcludingSaved) { // We started enter animation early with a saved surface, now the app asks to remove // this window. If we remove it now and the app is not yet drawn, we'll show a // flicker. Delay the removal now until it's really drawn. if (DEBUG_ADD_REMOVE) { Slog.d(TAG_WM, "removeWindowLocked: delay removal of " + win + " due to early animation"); } // Do not set mAnimatingExit to true here, it will cause the surface to be hidden // immediately after the enter animation is done. If the app is not yet drawn then // it will show up as a flicker. win.mRemoveOnExit = true; win.mWindowRemovalAllowed = true; Binder.restoreCallingIdentity(origId); return; } // If we are not currently running the exit animation, we need to see about starting one wasVisible = win.isWinVisibleLw(); Loading Loading @@ -8560,6 +8584,15 @@ public class WindowManagerService extends IWindowManager.Stub } mDestroyPreservedSurface.clear(); } void stopUsingSavedSurfaceLocked() { for (int i = mFinishedEarlyAnim.size() - 1; i >= 0 ; i--) { final AppWindowToken wtoken = mFinishedEarlyAnim.get(i); wtoken.stopUsingSavedSurfaceLocked(); } mFinishedEarlyAnim.clear(); } // ------------------------------------------------------------- // IWindowManager API // ------------------------------------------------------------- Loading
services/core/java/com/android/server/wm/WindowState.java +35 −1 Original line number Diff line number Diff line Loading @@ -437,7 +437,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { // used to start an entering animation earlier. private boolean mSurfaceSaved = false; // Whether we're performing an entering animation with a saved surface. // Whether we're performing an entering animation with a saved surface. This flag is // true during the time we're showing a window with a previously saved surface. It's // cleared when surface is destroyed, saved, or re-drawn by the app. private boolean mAnimatingWithSavedSurface; // Whether the window was visible when we set the app to invisible last time. WM uses Loading Loading @@ -1255,6 +1257,32 @@ final class WindowState implements WindowManagerPolicy.WindowState { return !mAttachedHidden || mWinAnimator.mAnimation != null; } /** * Whether this window's drawn state might affect the drawn states of the app token. * * @param visibleOnly Whether we should consider only the windows that's currently * visible in layout. If true, windows that has not relayout to VISIBLE * would always return false. * * @return true if the window should be considered while evaluating allDrawn flags. */ boolean mightAffectAllDrawn(boolean visibleOnly) { final boolean isViewVisible = (mViewVisibility == View.VISIBLE) && (mAppToken == null || !mAppToken.clientHidden); return (isOnScreenIgnoringKeyguard() && (!visibleOnly || isViewVisible) || mWinAnimator.mAttrType == TYPE_BASE_APPLICATION) && !mAnimatingExit && !mDestroying; } /** * Whether this window is "interesting" when evaluating allDrawn. If it's interesting, * it must be drawn before allDrawn can become true. */ boolean isInteresting() { return mAppToken != null && !mAppDied && (!mAppToken.mAppAnimator.freezingScreen || !mAppFreezing); } /** * Like isOnScreen(), but we don't return true if the window is part * of a transition that has not yet been started. Loading Loading @@ -1960,6 +1988,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mAnimatingWithSavedSurface; } boolean isAnimatingInvisibleWithSavedSurface() { return mAnimatingWithSavedSurface && (mViewVisibility != View.VISIBLE || mWindowRemovalAllowed); } public void setVisibleBeforeClientHidden() { mWasVisibleBeforeClientHidden |= (mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface); Loading Loading @@ -2042,6 +2075,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { if (mWinAnimator.mSurfaceController != null) { mWinAnimator.mSurfaceController.disconnectInTransaction(); } mAnimatingWithSavedSurface = false; } else { mWinAnimator.destroySurfaceLocked(); } Loading
services/core/java/com/android/server/wm/WindowSurfacePlacer.java +41 −6 Original line number Diff line number Diff line Loading @@ -792,15 +792,16 @@ class WindowSurfacePlacer { + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn + " freezingScreen=" + atoken.mAppAnimator.freezingScreen); } if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) { if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved || atoken.mAppAnimator.freezingScreen)) { if (atoken.lastTransactionSequence != mService.mTransactionSequence) { atoken.lastTransactionSequence = mService.mTransactionSequence; atoken.numInterestingWindows = atoken.numDrawnWindows = 0; atoken.numInterestingWindowsExcludingSaved = 0; atoken.numDrawnWindowsExclusingSaved = 0; atoken.startingDisplayed = false; } if ((w.isOnScreenIgnoringKeyguard() || winAnimator.mAttrType == TYPE_BASE_APPLICATION) && !w.mAnimatingExit && !w.mDestroying) { if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) { if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() Loading @@ -816,13 +817,14 @@ class WindowSurfacePlacer { } } if (w != atoken.startingWindow) { if (!w.mAppDied && (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing)) { if (w.isInteresting()) { atoken.numInterestingWindows++; if (w.isDrawnLw()) { atoken.numDrawnWindows++; if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: " + atoken + " w=" + w + " numInteresting=" + atoken.numInterestingWindows + " freezingScreen=" + atoken.mAppAnimator.freezingScreen + " mAppFreezing=" + w.mAppFreezing); Loading @@ -834,6 +836,23 @@ class WindowSurfacePlacer { atoken.startingDisplayed = true; } } if (!atoken.allDrawnExcludingSaved && w.mightAffectAllDrawn(true /* visibleOnly */)) { if (w != atoken.startingWindow && w.isInteresting()) { atoken.numInterestingWindowsExcludingSaved++; if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) { atoken.numDrawnWindowsExclusingSaved++; if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken + " w=" + w + " numInteresting=" + atoken.numInterestingWindowsExcludingSaved + " freezingScreen=" + atoken.mAppAnimator.freezingScreen + " mAppFreezing=" + w.mAppFreezing); updateAllDrawn = true; } } } } if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus Loading Loading @@ -1539,6 +1558,22 @@ class WindowSurfacePlacer { wtoken.token).sendToTarget(); } } if (!wtoken.allDrawnExcludingSaved) { int numInteresting = wtoken.numInterestingWindowsExcludingSaved; if (numInteresting > 0 && wtoken.numDrawnWindowsExclusingSaved >= numInteresting) { if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawnExcludingSaved: " + wtoken + " interesting=" + numInteresting + " drawn=" + wtoken.numDrawnWindowsExclusingSaved); wtoken.allDrawnExcludingSaved = true; displayContent.layoutNeeded = true; if (wtoken.isAnimatingInvisibleWithSavedSurface() && !mService.mFinishedEarlyAnim.contains(wtoken)) { mService.mFinishedEarlyAnim.add(wtoken); } } } } } } Loading