Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d78a4457 authored by Alan Viverette's avatar Alan Viverette
Browse files

Jump drawable state (including ripples) on view detach

BUG: 15350931
Change-Id: I09928f59fb7b9f6d87b1f5219353a41ae6b5681d
parent 38dd601d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -13090,6 +13090,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        removeSendViewScrolledAccessibilityEventCallback();
        stopNestedScroll();
        // Anything that started animating right before detach should already
        // be in its final state when re-attached.
        jumpDrawablesToCurrentState();
        destroyDrawingCache();
        cleanupDraw();
+48 −5
Original line number Diff line number Diff line
@@ -211,7 +211,7 @@ class Ripple {
        final boolean canUseHardware = c.isHardwareAccelerated();
        if (mCanUseHardware != canUseHardware && mCanUseHardware) {
            // We've switched from hardware to non-hardware mode. Panic.
            cancelHardwareAnimations();
            cancelHardwareAnimations(true);
        }
        mCanUseHardware = canUseHardware;

@@ -231,7 +231,7 @@ class Ripple {
        final ArrayList<RenderNodeAnimator> pendingAnimations = mPendingAnimations;
        final int N = pendingAnimations.size();
        if (N > 0) {
            cancelHardwareAnimations();
            cancelHardwareAnimations(false);

            for (int i = 0; i < N; i++) {
                pendingAnimations.get(i).setTarget(c);
@@ -399,6 +399,45 @@ class Ripple {
        invalidateSelf();
    }

    public void jump() {
        endSoftwareAnimations();
        endHardwareAnimations();
    }

    private void endSoftwareAnimations() {
        if (mAnimRadius != null) {
            mAnimRadius.end();
        }

        if (mAnimOpacity != null) {
            mAnimOpacity.end();
        }

        if (mAnimX != null) {
            mAnimX.end();
        }

        if (mAnimY != null) {
            mAnimY.end();
        }
    }

    private void endHardwareAnimations() {
        final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations;
        final int N = runningAnimations.size();
        for (int i = 0; i < N; i++) {
            runningAnimations.get(i).end();
        }
        runningAnimations.clear();

        // Abort any pending animations. Since we always have a completion
        // listener on a pending animation, we also need to remove ourselves.
        if (!mPendingAnimations.isEmpty()) {
            mPendingAnimations.clear();
            removeSelf();
        }
    }

    private Paint getTempPaint() {
        if (mTempPaint == null) {
            mTempPaint = new Paint();
@@ -444,7 +483,7 @@ class Ripple {
     */
    public void cancel() {
        cancelSoftwareAnimations();
        cancelHardwareAnimations();
        cancelHardwareAnimations(true);
    }

    private void cancelSoftwareAnimations() {
@@ -468,14 +507,18 @@ class Ripple {
    /**
     * Cancels any running hardware animations.
     */
    private void cancelHardwareAnimations() {
    private void cancelHardwareAnimations(boolean cancelPending) {
        final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations;
        final int N = runningAnimations.size();
        for (int i = 0; i < N; i++) {
            runningAnimations.get(i).cancel();
        }

        runningAnimations.clear();

        if (cancelPending && !mPendingAnimations.isEmpty()) {
            mPendingAnimations.clear();
            removeSelf();
        }
    }

    private void removeSelf() {
+44 −4
Original line number Diff line number Diff line
@@ -203,7 +203,7 @@ class RippleBackground {
        final boolean canUseHardware = c.isHardwareAccelerated();
        if (mCanUseHardware != canUseHardware && mCanUseHardware) {
            // We've switched from hardware to non-hardware mode. Panic.
            cancelHardwareAnimations();
            cancelHardwareAnimations(true);
        }
        mCanUseHardware = canUseHardware;

@@ -223,7 +223,7 @@ class RippleBackground {
        final ArrayList<RenderNodeAnimator> pendingAnimations = mPendingAnimations;
        final int N = pendingAnimations.size();
        if (N > 0) {
            cancelHardwareAnimations();
            cancelHardwareAnimations(false);

            for (int i = 0; i < N; i++) {
                pendingAnimations.get(i).setTarget(c);
@@ -403,6 +403,41 @@ class RippleBackground {
        invalidateSelf();
    }

    public void jump() {
        endSoftwareAnimations();
        endHardwareAnimations();
    }

    private void endSoftwareAnimations() {
        if (mAnimOuterOpacity != null) {
            mAnimOuterOpacity.end();
        }

        if (mAnimX != null) {
            mAnimX.end();
        }

        if (mAnimY != null) {
            mAnimY.end();
        }
    }

    private void endHardwareAnimations() {
        final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations;
        final int N = runningAnimations.size();
        for (int i = 0; i < N; i++) {
            runningAnimations.get(i).end();
        }
        runningAnimations.clear();

        // Abort any pending animations. Since we always have a completion
        // listener on a pending animation, we also need to remove ourselves.
        if (!mPendingAnimations.isEmpty()) {
            mPendingAnimations.clear();
            removeSelf();
        }
    }

    private Paint getTempPaint() {
        if (mTempPaint == null) {
            mTempPaint = new Paint();
@@ -477,7 +512,7 @@ class RippleBackground {
     */
    public void cancel() {
        cancelSoftwareAnimations();
        cancelHardwareAnimations();
        cancelHardwareAnimations(true);
    }

    private void cancelSoftwareAnimations() {
@@ -497,7 +532,7 @@ class RippleBackground {
    /**
     * Cancels any running hardware animations.
     */
    private void cancelHardwareAnimations() {
    private void cancelHardwareAnimations(boolean cancelPending) {
        final ArrayList<RenderNodeAnimator> runningAnimations = mRunningAnimations;
        final int N = runningAnimations.size();
        for (int i = 0; i < N; i++) {
@@ -505,6 +540,11 @@ class RippleBackground {
        }

        runningAnimations.clear();

        if (cancelPending && !mPendingAnimations.isEmpty()) {
            mPendingAnimations.clear();
            removeSelf();
        }
    }

    private void removeSelf() {
+32 −13
Original line number Diff line number Diff line
@@ -198,6 +198,29 @@ public class RippleDrawable extends LayerDrawable {
        initializeFromState();
    }

    @Override
    public void jumpToCurrentState() {
        super.jumpToCurrentState();

        if (mRipple != null) {
            mRipple.jump();
        }

        if (mBackground != null) {
            mBackground.jump();
        }

        mClearingHotspots = true;
        final int count = mAnimatingRipplesCount;
        final Ripple[] ripples = mAnimatingRipples;
        for (int i = 0; i < count; i++) {
            ripples[i].jump();
            ripples[i] = null;
        }
        mAnimatingRipplesCount = 0;
        mClearingHotspots = false;
    }

    @Override
    public void setAlpha(int alpha) {
        super.setAlpha(alpha);
@@ -534,18 +557,6 @@ public class RippleDrawable extends LayerDrawable {
    }

    private void clearHotspots() {
        mClearingHotspots = true;

        final int count = mAnimatingRipplesCount;
        final Ripple[] ripples = mAnimatingRipples;
        for (int i = 0; i < count; i++) {
            // Calling cancel may remove the ripple from the animating ripple
            // array, so cache the reference before nulling it out.
            final Ripple ripple = ripples[i];
            ripples[i] = null;
            ripple.cancel();
        }

        if (mRipple != null) {
            mRipple.cancel();
            mRipple = null;
@@ -556,8 +567,16 @@ public class RippleDrawable extends LayerDrawable {
            mBackground = null;
        }

        mClearingHotspots = false;
        mClearingHotspots = true;
        final int count = mAnimatingRipplesCount;
        final Ripple[] ripples = mAnimatingRipples;
        for (int i = 0; i < count; i++) {
            ripples[i].cancel();
            ripples[i] = null;
        }
        mAnimatingRipplesCount = 0;
        mClearingHotspots = false;

        invalidateSelf();
    }