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

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

Merge "Fix disappearing ripple background, treat active ripple separately" into lmp-dev

parents af0fe973 fdbb98e5
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -105,6 +105,9 @@ class Ripple {
    /** Whether we have an explicit maximum radius. */
    private boolean mHasMaxRadius;

    /** Whether we were canceled externally and should avoid self-removal. */
    private boolean mCanceled;

    /**
     * Creates a new ripple.
     */
@@ -295,6 +298,8 @@ class Ripple {
     * Starts the enter animation.
     */
    public void enter() {
        cancel();

        final int radiusDuration = (int)
                (1000 * Math.sqrt(mOuterRadius / WAVE_TOUCH_DOWN_ACCELERATION * mDensity) + 0.5);

@@ -332,7 +337,8 @@ class Ripple {
     * Starts the exit animation.
     */
    public void exit() {
        cancelSoftwareAnimations();
        cancel();

        final float radius = MathUtils.lerp(0, mOuterRadius, mTweenRadius);
        final float remaining;
        if (mAnimRadius != null && mAnimRadius.isRunning()) {
@@ -399,9 +405,15 @@ class Ripple {
        invalidateSelf();
    }

    /**
     * Jump all animations to their end state. The caller is responsible for
     * removing the ripple from the list of animating ripples.
     */
    public void jump() {
        mCanceled = true;
        endSoftwareAnimations();
        endHardwareAnimations();
        mCanceled = false;
    }

    private void endSoftwareAnimations() {
@@ -436,6 +448,8 @@ class Ripple {
            mPendingAnimations.clear();
            removeSelf();
        }

        mHardwareAnimating = false;
    }

    private Paint getTempPaint() {
@@ -479,11 +493,14 @@ class Ripple {
    }

    /**
     * Cancel all animations.
     * Cancels all animations. The caller is responsible for removing
     * the ripple from the list of animating ripples.
     */
    public void cancel() {
        mCanceled = true;
        cancelSoftwareAnimations();
        cancelHardwareAnimations(true);
        mCanceled = false;
    }

    private void cancelSoftwareAnimations() {
@@ -517,14 +534,17 @@ class Ripple {

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

        mHardwareAnimating = false;
    }

    private void removeSelf() {
        // The owner will invalidate itself.
        if (!mCanceled) {
            mOwner.removeRipple(this);
        }
    }

    private void invalidateSelf() {
        mOwner.invalidateSelf();
+23 −4
Original line number Diff line number Diff line
@@ -107,6 +107,9 @@ class RippleBackground {
    /** Whether we have an explicit maximum radius. */
    private boolean mHasMaxRadius;

    /** Whether we were canceled externally and should avoid self-removal. */
    private boolean mCanceled;

    /**
     * Creates a new ripple.
     */
@@ -284,6 +287,8 @@ class RippleBackground {
     * Starts the enter animation.
     */
    public void enter() {
        cancel();

        final int radiusDuration = (int)
                (1000 * Math.sqrt(mOuterRadius / WAVE_TOUCH_DOWN_ACCELERATION * mDensity) + 0.5);
        final int outerDuration = (int) (1000 * 1.0f / WAVE_OUTER_OPACITY_ENTER_VELOCITY);
@@ -321,7 +326,7 @@ class RippleBackground {
     * Starts the exit animation.
     */
    public void exit() {
        cancelSoftwareAnimations();
        cancel();

        // Scale the outer max opacity and opacity velocity based
        // on the size of the outer radius.
@@ -404,9 +409,15 @@ class RippleBackground {
        invalidateSelf();
    }

    /**
     * Jump all animations to their end state. The caller is responsible for
     * removing the ripple from the list of animating ripples.
     */
    public void jump() {
        mCanceled = true;
        endSoftwareAnimations();
        endHardwareAnimations();
        mCanceled = false;
    }

    private void endSoftwareAnimations() {
@@ -437,6 +448,8 @@ class RippleBackground {
            mPendingAnimations.clear();
            removeSelf();
        }

        mHardwareAnimating = false;
    }

    private Paint getTempPaint() {
@@ -509,11 +522,14 @@ class RippleBackground {
    }

    /**
     * Cancel all animations.
     * Cancel all animations. The caller is responsible for removing
     * the ripple from the list of animating ripples.
     */
    public void cancel() {
        mCanceled = true;
        cancelSoftwareAnimations();
        cancelHardwareAnimations(true);
        mCanceled = false;
    }

    private void cancelSoftwareAnimations() {
@@ -544,14 +560,17 @@ class RippleBackground {

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

        mHardwareAnimating = false;
    }

    private void removeSelf() {
        // The owner will invalidate itself.
        if (!mCanceled) {
            mOwner.removeBackground(this);
        }
    }

    private void invalidateSelf() {
        mOwner.invalidateSelf();
+68 −77
Original line number Diff line number Diff line
@@ -140,8 +140,8 @@ public class RippleDrawable extends LayerDrawable {
     * Lazily-created array of actively animating ripples. Inactive ripples are
     * pruned during draw(). The locations of these will not change.
     */
    private Ripple[] mAnimatingRipples;
    private int mAnimatingRipplesCount = 0;
    private Ripple[] mExitingRipples;
    private int mExitingRipplesCount = 0;

    /** Paint used to control appearance of ripples. */
    private Paint mRipplePaint;
@@ -155,12 +155,6 @@ public class RippleDrawable extends LayerDrawable {
    /** Whether bounds are being overridden. */
    private boolean mOverrideBounds;

    /**
     * Whether hotspots are being cleared. Used to prevent re-entry by
     * animation finish listeners.
     */
    private boolean mClearingHotspots;

    /**
     * Constructor used for drawable inflation.
     */
@@ -209,19 +203,21 @@ public class RippleDrawable extends LayerDrawable {
            mBackground.jump();
        }

        mClearingHotspots = true;
        final int count = mAnimatingRipplesCount;
        final Ripple[] ripples = mAnimatingRipples;
        cancelExitingRipples();
        invalidateSelf();
    }

    private void cancelExitingRipples() {
        final int count = mExitingRipplesCount;
        final Ripple[] ripples = mExitingRipples;
        for (int i = 0; i < count; i++) {
            ripples[i].jump();
            ripples[i].cancel();
        }

        if (ripples != null) {
            Arrays.fill(ripples, 0, count, null);
        }
        mAnimatingRipplesCount = 0;
        mClearingHotspots = false;

        invalidateSelf();
        mExitingRipplesCount = 0;
    }

    @Override
@@ -287,9 +283,9 @@ public class RippleDrawable extends LayerDrawable {
        if (mRippleActive != active) {
            mRippleActive = active;
            if (active) {
                activateRipple();
                tryRippleEnter();
            } else {
                removeRipple();
                tryRippleExit();
            }
        }
    }
@@ -298,9 +294,9 @@ public class RippleDrawable extends LayerDrawable {
        if (mBackgroundActive != active) {
            mBackgroundActive = active;
            if (active) {
                activateBackground();
                tryBackgroundEnter();
            } else {
                removeBackground();
                tryBackgroundExit();
            }
        }
    }
@@ -327,11 +323,11 @@ public class RippleDrawable extends LayerDrawable {
            // If we just became visible, ensure the background and ripple
            // visibilities are consistent with their internal states.
            if (mRippleActive) {
                activateRipple();
                tryRippleEnter();
            }

            if (mBackgroundActive) {
                activateBackground();
                tryBackgroundEnter();
            }
        }

@@ -491,7 +487,7 @@ public class RippleDrawable extends LayerDrawable {
    /**
     * Creates an active hotspot at the specified location.
     */
    private void activateBackground() {
    private void tryBackgroundEnter() {
        if (mBackground == null) {
            final float x;
            final float y;
@@ -511,7 +507,7 @@ public class RippleDrawable extends LayerDrawable {
        mBackground.enter();
    }

    private void removeBackground() {
    private void tryBackgroundExit() {
        if (mBackground != null) {
            // Don't null out the background, we need it to draw!
            mBackground.exit();
@@ -519,10 +515,11 @@ public class RippleDrawable extends LayerDrawable {
    }

    /**
     * Creates an active hotspot at the specified location.
     * Attempts to start an enter animation for the active hotspot. Fails if
     * there are too many animating ripples.
     */
    private void activateRipple() {
        if (mAnimatingRipplesCount >= MAX_RIPPLES) {
    private void tryRippleEnter() {
        if (mExitingRipplesCount >= MAX_RIPPLES) {
            // This should never happen unless the user is tapping like a maniac
            // or there is a bug that's preventing ripples from being removed.
            return;
@@ -545,29 +542,27 @@ public class RippleDrawable extends LayerDrawable {
        final int color = mState.mColor.getColorForState(getState(), Color.TRANSPARENT);
        mRipple.setup(mState.mMaxRadius, color, mDensity);
        mRipple.enter();

        if (mAnimatingRipples == null) {
            mAnimatingRipples = new Ripple[MAX_RIPPLES];
        }
        mAnimatingRipples[mAnimatingRipplesCount++] = mRipple;
    }

    @Override
    public void invalidateSelf() {
        // Don't invalidate when we're clearing hotspots. We'll handle that
        // manually when we're done.
        if (!mClearingHotspots) {
            super.invalidateSelf();
        }
    }

    private void removeRipple() {
    /**
     * Attempts to start an exit animation for the active hotspot. Fails if
     * there is no active hotspot.
     */
    private void tryRippleExit() {
        if (mRipple != null) {
            if (mExitingRipples == null) {
                mExitingRipples = new Ripple[MAX_RIPPLES];
            }
            mExitingRipples[mExitingRipplesCount++] = mRipple;
            mRipple.exit();
            mRipple = null;
        }
    }

    /**
     * Cancels and removes the active ripple, all exiting ripples, and the
     * background. Nothing will be drawn after this method is called.
     */
    private void clearHotspots() {
        if (mRipple != null) {
            mRipple.cancel();
@@ -579,18 +574,7 @@ public class RippleDrawable extends LayerDrawable {
            mBackground = null;
        }

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

        cancelExitingRipples();
        invalidateSelf();
    }

@@ -612,8 +596,8 @@ public class RippleDrawable extends LayerDrawable {
     * Notifies all the animating ripples that the hotspot bounds have changed.
     */
    private void onHotspotBoundsChanged() {
        final int count = mAnimatingRipplesCount;
        final Ripple[] ripples = mAnimatingRipples;
        final int count = mExitingRipplesCount;
        final Ripple[] ripples = mExitingRipples;
        for (int i = 0; i < count; i++) {
            ripples[i].onHotspotBoundsChanged();
        }
@@ -683,24 +667,23 @@ public class RippleDrawable extends LayerDrawable {
    }

    /**
     * Removes a ripple from the animating ripple list.
     * Removes a ripple from the exiting ripple list.
     *
     * @param ripple the ripple to remove
     */
    void removeRipple(Ripple ripple) {
        if (!mClearingHotspots) {
        // Ripple ripple ripple ripple. Ripple ripple.
            final Ripple[] ripples = mAnimatingRipples;
            final int count = mAnimatingRipplesCount;
        final Ripple[] ripples = mExitingRipples;
        final int count = mExitingRipplesCount;
        final int index = getRippleIndex(ripple);
        if (index >= 0) {
            System.arraycopy(ripples, index + 1, ripples, index, count - (index + 1));
            ripples[count - 1] = null;
                mAnimatingRipplesCount--;
            mExitingRipplesCount--;

            invalidateSelf();
        }
    }
    }

    void removeBackground(RippleBackground background) {
        if (mBackground == background) {
@@ -710,8 +693,8 @@ public class RippleDrawable extends LayerDrawable {
    }

    private int getRippleIndex(Ripple ripple) {
        final Ripple[] ripples = mAnimatingRipples;
        final int count = mAnimatingRipplesCount;
        final Ripple[] ripples = mExitingRipples;
        final int count = mExitingRipplesCount;
        for (int i = 0; i < count; i++) {
            if (ripples[i] == ripple) {
                return i;
@@ -727,7 +710,7 @@ public class RippleDrawable extends LayerDrawable {
        // We don't need a layer if we don't expect to draw any ripples, we have
        // an explicit mask, or if the non-mask content is all opaque.
        boolean needsLayer = false;
        if ((mAnimatingRipplesCount > 0 || mBackground != null) && mMask == null) {
        if ((mExitingRipplesCount > 0 || mBackground != null) && mMask == null) {
            for (int i = 0; i < count; i++) {
                if (array[i].mId != R.id.mask
                        && array[i].mDrawable.getOpacity() != PixelFormat.OPAQUE) {
@@ -831,10 +814,17 @@ public class RippleDrawable extends LayerDrawable {
        int restoreTranslate = -1;

        // Draw ripples and update the animating ripples array.
        final int count = mAnimatingRipplesCount;
        final Ripple[] ripples = mAnimatingRipples;
        for (int i = 0; i < count; i++) {
            final Ripple ripple = ripples[i];
        final int count = mExitingRipplesCount;
        final Ripple[] ripples = mExitingRipples;
        for (int i = 0; i <= count; i++) {
            final Ripple ripple;
            if (i < count) {
                ripple = ripples[i];
            } else if (mRipple != null) {
                ripple = mRipple;
            } else {
                continue;
            }

            // If we're masking the ripple layer, make sure we have a layer
            // first. This will merge SRC_OVER (directly) onto the canvas.
@@ -898,8 +888,9 @@ public class RippleDrawable extends LayerDrawable {
            final int cX = (int) mHotspotBounds.exactCenterX();
            final int cY = (int) mHotspotBounds.exactCenterY();
            final Rect rippleBounds = mTempRect;
            final Ripple[] activeRipples = mAnimatingRipples;
            final int N = mAnimatingRipplesCount;

            final Ripple[] activeRipples = mExitingRipples;
            final int N = mExitingRipplesCount;
            for (int i = 0; i < N; i++) {
                activeRipples[i].getBounds(rippleBounds);
                rippleBounds.offset(cX, cY);