Fix the starting window could not be removed.
When trying to remove the starting window from an activity and
there is another new transition applied, the starting window
could not be removed because
1. ActivityRecord#startingDisplayed were set to false.
2. Cannot apply TRANSIT_PREV_DONE animation in removeIfPossible
because firstWindowDrawn and startingDisplayed are both false.
3. Because the task is animating, so it thought the animation is
applied and we should wait for #onAnimationFinished.
There are two things to do for fix this issue
1. Only set startingDisplayed to false when the starting window
must not exist.
2. Check the animation is applied for the starting window instead
check isAnimating for whole task.
Fixes: 154189349
Test: atest AppWindowTokenTests
Change-Id: I9bda35c792aaa4d0865b370faca09f1a90035c29
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 131e449..3920c9d 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1929,7 +1929,6 @@
mStartingData = null;
startingSurface = null;
startingWindow = null;
- startingDisplayed = false;
if (surface == null) {
ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
"startingWindow was set but startingSurface==null, couldn't "
@@ -5453,7 +5452,6 @@
if (mLastTransactionSequence != mWmService.mTransactionSequence) {
mLastTransactionSequence = mWmService.mTransactionSequence;
mNumDrawnWindows = 0;
- startingDisplayed = false;
// There is the main base application window, even if it is exiting, wait for it
mNumInterestingWindows = findMainWindow(false /* includeStartingApp */) != null ? 1 : 0;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e925ce5..a948ece 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2191,9 +2191,9 @@
if (wasVisible) {
final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE;
-
+ final int flags = startingWindow ? 0 /* self */ : PARENTS;
// Try starting an animation.
- if (mWinAnimator.applyAnimationLocked(transit, false)) {
+ if (mWinAnimator.applyAnimationLocked(transit, false, flags)) {
mAnimatingExit = true;
// mAnimatingExit affects canAffectSystemUiFlags(). Run layout such that
@@ -2205,7 +2205,9 @@
mWmService.mAccessibilityController.onWindowTransitionLocked(this, transit);
}
}
- final boolean isAnimating = isAnimating(TRANSITION | PARENTS)
+ final boolean isAnimating = startingWindow
+ ? isAnimating(0)
+ : isAnimating(TRANSITION | PARENTS)
&& (mActivityRecord == null || !mActivityRecord.isWaitingForTransitionStart());
final boolean lastWindowIsStartingWindow = startingWindow && mActivityRecord != null
&& mActivityRecord.isLastWindow(this);
@@ -2227,6 +2229,9 @@
}
}
+ if (startingWindow && mActivityRecord != null) {
+ mActivityRecord.startingDisplayed = false;
+ }
removeImmediately();
// Removing a visible window will effect the computed orientation
// So just update orientation if needed.
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c570cf1..e70f3e4 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1400,9 +1400,25 @@
* the switch statement below.
* @param isEntrance The animation type the last time this was called. Used to keep from
* loading the same animation twice.
- * @return true if an animation has been loaded.
+ * @return {@code true} if an animation has been loaded, includes the parents.
+ *
*/
boolean applyAnimationLocked(int transit, boolean isEntrance) {
+ return applyAnimationLocked(transit, isEntrance, PARENTS);
+ }
+
+ /**
+ * Choose the correct animation and set it to the passed WindowState.
+ * @param transit If AppTransition.TRANSIT_PREVIEW_DONE and the app window has been drawn
+ * then the animation will be app_starting_exit. Any other value loads the animation from
+ * the switch statement below.
+ * @param isEntrance The animation type the last time this was called. Used to keep from
+ * loading the same animation twice.
+ * @param flags The combination of bitmask flags to specify targets and condition for
+ * checking animating status. See {@link WindowContainer.AnimationFlags}.
+ * @return {@code true} if an animation has been loaded.
+ */
+ boolean applyAnimationLocked(int transit, boolean isEntrance, int flags) {
if (mWin.isAnimating() && mAnimationIsEntrance == isEntrance) {
// If we are trying to apply an animation, but already running
// an animation of the same type, then just leave that one alone.
@@ -1472,7 +1488,7 @@
mWin.getDisplayContent().adjustForImeIfNeeded();
}
- return mWin.isAnimating(PARENTS);
+ return mWin.isAnimating(flags);
}
void dumpDebug(ProtoOutputStream proto, long fieldId) {