From 9017ec0b150ee19ca1041b61c2560dff759686d7 Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Thu, 25 Feb 2016 08:55:25 -0800 Subject: [PATCH] Remove starting window whenever the acitvity is stopped The main app window will never finish drawing at this point so there is nothing to trigger the removal of the starting window. Also, set ActivityRecord.mStartingWindowShown to true for some cases where we were telling WM to show starting window but not setting the flag that would later be used for clean-up. Bug: 26659857 Change-Id: I7a8582521853f1f95b77d8b08f4dd0cf778f8cbf --- .../com/android/server/am/ActivityRecord.java | 1 + .../com/android/server/am/ActivityStack.java | 2 ++ .../com/android/server/wm/AppWindowToken.java | 28 ++++++++++++++++++- .../com/android/server/wm/WindowState.java | 3 +- .../server/wm/WindowStateAnimator.java | 18 +----------- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 90a7da9773555..32ca5bfa3049d 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -321,6 +321,7 @@ final class ActivityRecord { pw.print(" visible="); pw.print(visible); pw.print(" sleeping="); pw.print(sleeping); pw.print(" idle="); pw.println(idle); + pw.print(" mStartingWindowShown="); pw.println(mStartingWindowShown); pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen); pw.print(" noDisplay="); pw.print(noDisplay); pw.print(" immersive="); pw.print(immersive); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index acde10fa29e28..ec37667a37c2d 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -2263,6 +2263,7 @@ final class ActivityStack { mService.compatibilityInfoForPackageLocked(next.info.applicationInfo), next.nonLocalizedLabel, next.labelRes, next.icon, next.logo, next.windowFlags, null, true); + next.mStartingWindowShown = true; } mStackSupervisor.startSpecificActivityLocked(next, true, false); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); @@ -2295,6 +2296,7 @@ final class ActivityStack { next.nonLocalizedLabel, next.labelRes, next.icon, next.logo, next.windowFlags, null, true); + next.mStartingWindowShown = true; } if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next); } diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 12c62bdc93bf5..f9e258d35d8e7 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -159,6 +160,25 @@ class AppWindowToken extends WindowToken { } } + void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) { + firstWindowDrawn = true; + + // We now have a good window to show, remove dead placeholders + removeAllDeadWindows(); + + if (startingData != null) { + if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting " + + win.mToken + ": first real window is shown, no animation"); + // If this initial window is animating, stop it -- we will do an animation to reveal + // it from behind the starting window, so there is no need for it to also be doing its + // own stuff. + winAnimator.clearAnimation(); + winAnimator.mService.mFinishedStarting.add(this); + winAnimator.mService.mH.sendEmptyMessage(H.FINISHED_STARTING); + } + updateReportedVisibilityLocked(); + } + void updateReportedVisibilityLocked() { if (appToken == null) { return; @@ -357,6 +377,9 @@ class AppWindowToken extends WindowToken { void notifyAppStopped() { mAppStopped = true; destroySurfaces(); + + // Remove any starting window that was added for this app if they are still around. + mTask.mService.scheduleRemoveStartingWindowLocked(this); } /** @@ -594,6 +617,9 @@ class AppWindowToken extends WindowToken { if (paused) { pw.print(prefix); pw.print("paused="); pw.println(paused); } + if (mAppStopped) { + pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped); + } if (numInterestingWindows != 0 || numDrawnWindows != 0 || allDrawn || mAppAnimator.allDrawn) { pw.print(prefix); pw.print("numInterestingWindows="); @@ -619,7 +645,7 @@ class AppWindowToken extends WindowToken { pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow); pw.print(" startingView="); pw.print(startingView); pw.print(" startingDisplayed="); pw.print(startingDisplayed); - pw.print(" startingMoved"); pw.println(startingMoved); + pw.print(" startingMoved="); pw.println(startingMoved); } if (!mFrozenBounds.isEmpty()) { pw.print(prefix); pw.print("mFrozenBounds="); pw.print(mFrozenBounds); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 44ed7e2314b5f..40b6b50da6dd9 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2347,7 +2347,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface); pw.print(" mShownPosition="); mShownPosition.printShortString(pw); pw.print(" isReadyForDisplay()="); pw.print(isReadyForDisplay()); - pw.print(" hasSavedSurface()="); pw.println(hasSavedSurface()); + pw.print(" hasSavedSurface()="); pw.print(hasSavedSurface()); + pw.print(" mWindowRemovalAllowed="); pw.println(mWindowRemovalAllowed); if (dumpAll) { pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw); pw.print(" last="); mLastFrame.printShortString(pw); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 2d8a4c9aedf5e..c623047a7db67 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1522,23 +1522,7 @@ class WindowStateAnimator { } if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING && mWin.mAppToken != null) { - mWin.mAppToken.firstWindowDrawn = true; - - // We now have a good window to show, remove dead placeholders - mWin.mAppToken.removeAllDeadWindows(); - - if (mWin.mAppToken.startingData != null) { - if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting " - + mWin.mToken + ": first real window is shown, no animation"); - // If this initial window is animating, stop it -- we - // will do an animation to reveal it from behind the - // starting window, so there is no need for it to also - // be doing its own stuff. - clearAnimation(); - mService.mFinishedStarting.add(mWin.mAppToken); - mService.mH.sendEmptyMessage(H.FINISHED_STARTING); - } - mWin.mAppToken.updateReportedVisibilityLocked(); + mWin.mAppToken.onFirstWindowDrawn(mWin, this); } return true;