am 5284dd8d: am 91283969: Merge "Fixing crash in recents window transition. (Bug 18246975, 18159006)" into lmp-mr1-dev
* commit '5284dd8d6933156ee785d3270754cc6671252625':
Fixing crash in recents window transition. (Bug 18246975, 18159006)
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index bfc7659..eeb007c 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -691,8 +691,10 @@
throw new RuntimeException("Invalid thumbnail transition state");
}
- return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight,
- THUMBNAIL_APP_TRANSITION_DURATION, mThumbnailFastOutSlowInInterpolator);
+ int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
+ THUMBNAIL_APP_TRANSITION_DURATION);
+ return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
+ mThumbnailFastOutSlowInInterpolator);
}
/**
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 69c9144..bf96ea5 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -58,7 +58,9 @@
// the state changes.
boolean allDrawn;
- // Special surface for thumbnail animation.
+ // Special surface for thumbnail animation. If deferThumbnailDestruction is enabled, then we
+ // will make sure that the thumbnail is destroyed after the other surface is completed. This
+ // requires that the duration of the two animations are the same.
SurfaceControl thumbnail;
int thumbnailTransactionSeq;
int thumbnailX;
@@ -68,13 +70,12 @@
Animation thumbnailAnimation;
final Transformation thumbnailTransformation = new Transformation();
// This flag indicates that the destruction of the thumbnail surface is synchronized with
- // another animation, so do not pre-emptively destroy the thumbnail surface when the animation
- // completes
+ // another animation, so defer the destruction of this thumbnail surface for a single frame
+ // after the secondary animation completes.
boolean deferThumbnailDestruction;
- // This is the thumbnail surface that has been bestowed upon this animator, and when the
- // surface for this animator's animation is complete, we will destroy the thumbnail surface
- // as well. Do not animate or do anything with this surface.
- SurfaceControl deferredThumbnail;
+ // This flag is set if the animator has deferThumbnailDestruction set and has reached the final
+ // frame of animation. It will extend the animation by one frame and then clean up afterwards.
+ boolean deferFinalFrameCleanup;
/** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<WindowStateAnimator>();
@@ -134,9 +135,7 @@
animation = null;
animating = true;
}
- if (!deferThumbnailDestruction) {
- clearThumbnail();
- }
+ clearThumbnail();
if (mAppToken.deferClearAllDrawn) {
mAppToken.allDrawn = false;
mAppToken.deferClearAllDrawn = false;
@@ -148,13 +147,7 @@
thumbnail.destroy();
thumbnail = null;
}
- }
-
- public void clearDeferredThumbnail() {
- if (deferredThumbnail != null) {
- deferredThumbnail.destroy();
- deferredThumbnail = null;
- }
+ deferThumbnailDestruction = false;
}
void updateLayers() {
@@ -223,19 +216,26 @@
return false;
}
transformation.clear();
- final boolean more = animation.getTransformation(currentTime, transformation);
- if (false && WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Stepped animation in " + mAppToken + ": more=" + more + ", xform=" + transformation);
- if (!more) {
- animation = null;
- if (!deferThumbnailDestruction) {
+ boolean hasMoreFrames = animation.getTransformation(currentTime, transformation);
+ if (!hasMoreFrames) {
+ if (deferThumbnailDestruction && !deferFinalFrameCleanup) {
+ // We are deferring the thumbnail destruction, so extend the animation for one more
+ // (dummy) frame before we clean up
+ deferFinalFrameCleanup = true;
+ hasMoreFrames = true;
+ } else {
+ if (false && WindowManagerService.DEBUG_ANIM) Slog.v(
+ TAG, "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
+ ", xform=" + transformation);
+ deferFinalFrameCleanup = false;
+ animation = null;
clearThumbnail();
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ TAG, "Finished animation in " + mAppToken + " @ " + currentTime);
}
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Finished animation in " + mAppToken + " @ " + currentTime);
}
- hasTransformation = more;
- return more;
+ hasTransformation = hasMoreFrames;
+ return hasMoreFrames;
}
// This must be called while inside a transaction.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ccb5bfc..968b35c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -9244,12 +9244,6 @@
topClosingLayer);
openingAppAnimator.deferThumbnailDestruction =
!mAppTransition.isNextThumbnailTransitionScaleUp();
- if (openingAppAnimator.deferThumbnailDestruction) {
- if (closingAppAnimator != null &&
- closingAppAnimator.animation != null) {
- closingAppAnimator.deferredThumbnail = surfaceControl;
- }
- }
} else {
anim = mAppTransition.createThumbnailScaleAnimationLocked(
displayInfo.appWidth, displayInfo.appHeight, transit);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index e7c235f..1dadb17 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -975,11 +975,6 @@
mWin.mHasSurface = false;
mDrawState = NO_SURFACE;
}
-
- // Destroy any deferred thumbnail surfaces
- if (mAppAnimator != null) {
- mAppAnimator.clearDeferredThumbnail();
- }
}
void destroyDeferredSurfaceLocked() {