am 91283969: Merge "Fixing crash in recents window transition. (Bug 18246975, 18159006)" into lmp-mr1-dev

* commit '9128396982233d6af49613231100f1bc4b6c477b':
  Fixing crash in recents window transition.  (Bug 18246975, 18159006)
This commit is contained in:
Winson Chung
2014-11-05 21:42:38 +00:00
committed by Android Git Automerger
4 changed files with 31 additions and 40 deletions

View File

@@ -691,8 +691,10 @@ public class AppTransition implements Dump {
throw new RuntimeException("Invalid thumbnail transition state"); throw new RuntimeException("Invalid thumbnail transition state");
} }
return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
THUMBNAIL_APP_TRANSITION_DURATION, mThumbnailFastOutSlowInInterpolator); THUMBNAIL_APP_TRANSITION_DURATION);
return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
mThumbnailFastOutSlowInInterpolator);
} }
/** /**

View File

@@ -58,7 +58,9 @@ public class AppWindowAnimator {
// the state changes. // the state changes.
boolean allDrawn; 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; SurfaceControl thumbnail;
int thumbnailTransactionSeq; int thumbnailTransactionSeq;
int thumbnailX; int thumbnailX;
@@ -68,13 +70,12 @@ public class AppWindowAnimator {
Animation thumbnailAnimation; Animation thumbnailAnimation;
final Transformation thumbnailTransformation = new Transformation(); final Transformation thumbnailTransformation = new Transformation();
// This flag indicates that the destruction of the thumbnail surface is synchronized with // 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 // another animation, so defer the destruction of this thumbnail surface for a single frame
// completes // after the secondary animation completes.
boolean deferThumbnailDestruction; boolean deferThumbnailDestruction;
// This is the thumbnail surface that has been bestowed upon this animator, and when the // This flag is set if the animator has deferThumbnailDestruction set and has reached the final
// surface for this animator's animation is complete, we will destroy the thumbnail surface // frame of animation. It will extend the animation by one frame and then clean up afterwards.
// as well. Do not animate or do anything with this surface. boolean deferFinalFrameCleanup;
SurfaceControl deferredThumbnail;
/** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */ /** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<WindowStateAnimator>(); ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<WindowStateAnimator>();
@@ -134,9 +135,7 @@ public class AppWindowAnimator {
animation = null; animation = null;
animating = true; animating = true;
} }
if (!deferThumbnailDestruction) {
clearThumbnail(); clearThumbnail();
}
if (mAppToken.deferClearAllDrawn) { if (mAppToken.deferClearAllDrawn) {
mAppToken.allDrawn = false; mAppToken.allDrawn = false;
mAppToken.deferClearAllDrawn = false; mAppToken.deferClearAllDrawn = false;
@@ -148,13 +147,7 @@ public class AppWindowAnimator {
thumbnail.destroy(); thumbnail.destroy();
thumbnail = null; thumbnail = null;
} }
} deferThumbnailDestruction = false;
public void clearDeferredThumbnail() {
if (deferredThumbnail != null) {
deferredThumbnail.destroy();
deferredThumbnail = null;
}
} }
void updateLayers() { void updateLayers() {
@@ -223,19 +216,26 @@ public class AppWindowAnimator {
return false; return false;
} }
transformation.clear(); transformation.clear();
final boolean more = animation.getTransformation(currentTime, transformation); 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( if (false && WindowManagerService.DEBUG_ANIM) Slog.v(
TAG, "Stepped animation in " + mAppToken + ": more=" + more + ", xform=" + transformation); TAG, "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
if (!more) { ", xform=" + transformation);
deferFinalFrameCleanup = false;
animation = null; animation = null;
if (!deferThumbnailDestruction) {
clearThumbnail(); clearThumbnail();
}
if (WindowManagerService.DEBUG_ANIM) Slog.v( if (WindowManagerService.DEBUG_ANIM) Slog.v(
TAG, "Finished animation in " + mAppToken + " @ " + currentTime); TAG, "Finished animation in " + mAppToken + " @ " + currentTime);
} }
hasTransformation = more; }
return more; hasTransformation = hasMoreFrames;
return hasMoreFrames;
} }
// This must be called while inside a transaction. // This must be called while inside a transaction.

View File

@@ -9244,12 +9244,6 @@ public class WindowManagerService extends IWindowManager.Stub
topClosingLayer); topClosingLayer);
openingAppAnimator.deferThumbnailDestruction = openingAppAnimator.deferThumbnailDestruction =
!mAppTransition.isNextThumbnailTransitionScaleUp(); !mAppTransition.isNextThumbnailTransitionScaleUp();
if (openingAppAnimator.deferThumbnailDestruction) {
if (closingAppAnimator != null &&
closingAppAnimator.animation != null) {
closingAppAnimator.deferredThumbnail = surfaceControl;
}
}
} else { } else {
anim = mAppTransition.createThumbnailScaleAnimationLocked( anim = mAppTransition.createThumbnailScaleAnimationLocked(
displayInfo.appWidth, displayInfo.appHeight, transit); displayInfo.appWidth, displayInfo.appHeight, transit);

View File

@@ -975,11 +975,6 @@ class WindowStateAnimator {
mWin.mHasSurface = false; mWin.mHasSurface = false;
mDrawState = NO_SURFACE; mDrawState = NO_SURFACE;
} }
// Destroy any deferred thumbnail surfaces
if (mAppAnimator != null) {
mAppAnimator.clearDeferredThumbnail();
}
} }
void destroyDeferredSurfaceLocked() { void destroyDeferredSurfaceLocked() {