From c5eb816f92e81e617cb03d4cdb3805ee084662bd Mon Sep 17 00:00:00 2001 From: chaviw Date: Fri, 25 May 2018 16:18:42 -0700 Subject: [PATCH] Add animation to running animation list before starting. The animation needs to be added to the animation list before starting to ensure it's in the list before onAnimationEnd is called. Specifically, this can happen if the duration is 0 since the animation will complete very quickly. If that occurs, the animation will be added to the list after it's been "removed" which means there will continue to be a reference to that animation even after it's completed. Also fix a few other issues: 1. Don't create a dim layer if stopDim is called. This causes excess layers to be created, just so they can be destroyed. 2. Add try/catch to dim layer create so the system doesn't crash if the layer fails to create. Test: Enter split screen and move divider so dim layers are show and hidden. There are no longer excess dim layers being created and leashes are being properly dereferenced. Fixes: 80206408 Change-Id: I7198bd5e972fce32633869697a4d26f51e675d48 --- .../java/com/android/server/wm/Dimmer.java | 36 ++++++++++++------- .../server/wm/SurfaceAnimationRunner.java | 5 +-- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index b8431b1d8ad8a..65c8e96a07742 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -22,7 +22,9 @@ import static com.android.server.wm.AlphaAnimationSpecProto.TO; import static com.android.server.wm.AnimationSpecProto.ALPHA; import android.graphics.Rect; +import android.util.Log; import android.util.proto.ProtoOutputStream; +import android.view.Surface; import android.view.SurfaceControl; import com.android.internal.annotations.VisibleForTesting; @@ -171,14 +173,18 @@ class Dimmer { */ private DimState getDimState(WindowContainer container) { if (mDimState == null) { - final SurfaceControl ctl = makeDimLayer(); - mDimState = new DimState(ctl); - /** - * See documentation on {@link #dimAbove} to understand lifecycle management of Dim's - * via state resetting for Dim's with containers. - */ - if (container == null) { - mDimState.mDontReset = true; + try { + final SurfaceControl ctl = makeDimLayer(); + mDimState = new DimState(ctl); + /** + * See documentation on {@link #dimAbove} to understand lifecycle management of + * Dim's via state resetting for Dim's with containers. + */ + if (container == null) { + mDimState.mDontReset = true; + } + } catch (Surface.OutOfResourcesException e) { + Log.w(TAG, "OutOfResourcesException creating dim surface"); } } @@ -189,6 +195,11 @@ class Dimmer { private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer, float alpha) { final DimState d = getDimState(container); + + if (d == null) { + return; + } + if (container != null) { // The dim method is called from WindowState.prepareSurfaces(), which is always called // in the correct Z from lowest Z to highest. This ensures that the dim layer is always @@ -208,10 +219,11 @@ class Dimmer { * @param t A Transaction in which to finish the dim. */ void stopDim(SurfaceControl.Transaction t) { - DimState d = getDimState(null); - t.hide(d.mDimLayer); - d.isVisible = false; - d.mDontReset = false; + if (mDimState != null) { + t.hide(mDimState.mDimLayer); + mDimState.isVisible = false; + mDimState.mDontReset = false; + } } /** diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index 7211533c1b446..2bfff269e4576 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -206,6 +206,9 @@ class SurfaceAnimationRunner { } } }); + a.mAnim = anim; + mRunningAnimations.put(a.mLeash, a); + anim.start(); if (a.mAnimSpec.canSkipFirstFrame()) { // If we can skip the first frame, we start one frame later. @@ -215,8 +218,6 @@ class SurfaceAnimationRunner { // Immediately start the animation by manually applying an animation frame. Otherwise, the // start time would only be set in the next frame, leading to a delay. anim.doAnimationFrame(mChoreographer.getFrameTime()); - a.mAnim = anim; - mRunningAnimations.put(a.mLeash, a); } private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) {