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

Commit 04e723c1 authored by Alan Viverette's avatar Alan Viverette Committed by Android (Google) Code Review
Browse files

Merge "Jump drawable state (including ripples) on view detach" into lmp-dev

parents edf82bd2 d78a4457
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();
    }