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
This commit is contained in:
chaviw
2018-05-25 16:18:42 -07:00
parent ccf93b2792
commit c5eb816f92
2 changed files with 27 additions and 14 deletions

View File

@@ -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;
}
}
/**

View File

@@ -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) {