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

Commit 65e4e7d7 authored by Pablo Gamito's avatar Pablo Gamito Committed by Automerger Merge Worker
Browse files

Merge "Update status bar transition start time" into sc-qpr1-dev am: 5784ba0c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15879493

Change-Id: I9d65f117c5b7b022e367d42f0be64b4d4ef2b419
parents 307c5490 5784ba0c
Loading
Loading
Loading
Loading
+58 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ public class TranslateAnimation extends Animation {
    /** @hide */
    protected float mToYDelta;

    private int mWidth;
    private int mParentWidth;

    /**
     * Constructor used when a TranslateAnimation is loaded from a resource.
     *
@@ -179,5 +182,60 @@ public class TranslateAnimation extends Animation {
        mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth);
        mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight);
        mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight);

        mWidth = width;
        mParentWidth = parentWidth;
    }

    /**
     * Checks whether or not the translation is exclusively an x axis translation.
     *
     * @hide
     */
    public boolean isXAxisTransition() {
        return mFromXDelta - mToXDelta != 0 && mFromYDelta - mToYDelta == 0;
    }

    /**
     * Checks whether or not the translation is a full width x axis slide in or out translation.
     *
     * @hide
     */
    public boolean isFullWidthTranslate() {
        boolean isXAxisSlideTransition =
                isSlideInLeft() || isSlideOutRight() || isSlideInRight() || isSlideOutLeft();
        return mWidth == mParentWidth && isXAxisSlideTransition;
    }

    private boolean isSlideInLeft() {
        boolean startsOutOfParentOnLeft = mFromXDelta <= -mWidth;
        return startsOutOfParentOnLeft && endsXEnclosedWithinParent();
    }

    private boolean isSlideOutRight() {
        boolean endOutOfParentOnRight = mToXDelta >= mParentWidth;
        return startsXEnclosedWithinParent() && endOutOfParentOnRight;
    }

    private boolean isSlideInRight() {
        boolean startsOutOfParentOnRight = mFromXDelta >= mParentWidth;
        return startsOutOfParentOnRight && endsXEnclosedWithinParent();
    }

    private boolean isSlideOutLeft() {
        boolean endOutOfParentOnLeft = mToXDelta <= -mWidth;
        return startsXEnclosedWithinParent() && endOutOfParentOnLeft;
    }

    private boolean endsXEnclosedWithinParent() {
        return mWidth <= mParentWidth
                && mToXDelta + mWidth <= mParentWidth
                && mToXDelta >= 0;
    }

    private boolean startsXEnclosedWithinParent() {
        return mWidth <= mParentWidth
                && mFromXDelta + mWidth <= mParentWidth
                && mFromXDelta >= 0;
    }
}
+46 −13
Original line number Diff line number Diff line
@@ -125,16 +125,30 @@ public class WindowAnimationSpec implements AnimationSpec {
    @Override
    public long calculateStatusBarTransitionStartTime() {
        TranslateAnimation openTranslateAnimation = findTranslateAnimation(mAnimation);

        if (openTranslateAnimation != null) {
            if (openTranslateAnimation.isXAxisTransition()
                    && openTranslateAnimation.isFullWidthTranslate()) {
                // On X axis transitions that are fullscreen (heuristic for task like transitions)
                // we want the status bar to animate right in the middle of the translation when
                // the windows/tasks have each moved half way across.
                float t = findMiddleOfTranslationFraction(openTranslateAnimation.getInterpolator());

                return SystemClock.uptimeMillis()
                        + openTranslateAnimation.getStartOffset()
                        + (long) (openTranslateAnimation.getDuration() * t)
                        - (long) (STATUS_BAR_TRANSITION_DURATION * 0.5);
            } else {
                // Some interpolators are extremely quickly mostly finished, but not completely. For
            // our purposes, we need to find the fraction for which ther interpolator is mostly
                // our purposes, we need to find the fraction for which their interpolator is mostly
                // there, and use that value for the calculation.
                float t = findAlmostThereFraction(openTranslateAnimation.getInterpolator());

                return SystemClock.uptimeMillis()
                        + openTranslateAnimation.getStartOffset()
                        + (long) (openTranslateAnimation.getDuration() * t)
                        - STATUS_BAR_TRANSITION_DURATION;
            }
        } else {
            return SystemClock.uptimeMillis();
        }
@@ -183,20 +197,39 @@ public class WindowAnimationSpec implements AnimationSpec {
    }

    /**
     * Binary searches for a {@code t} such that there exists a {@code -0.01 < eps < 0.01} for which
     * {@code interpolator(t + eps) > 0.99}.
     * Finds the fraction of the animation's duration at which the transition is almost done with a
     * maximal error of 0.01 when it is animated with {@code interpolator}.
     */
    private static float findAlmostThereFraction(Interpolator interpolator) {
        return findInterpolationAdjustedTargetFraction(interpolator, 0.99f, 0.01f);
    }

    /**
     * Finds the fraction of the animation's duration at which the transition is spacially half way
     * done with a maximal error of 0.01 when it is animated with {@code interpolator}.
     */
    private float findMiddleOfTranslationFraction(Interpolator interpolator) {
        return findInterpolationAdjustedTargetFraction(interpolator, 0.5f, 0.01f);
    }

    /**
     * Binary searches for a {@code val} such that there exists an {@code -0.01 < epsilon < 0.01}
     * for which {@code interpolator(val + epsilon) > target}.
     */
    private static float findInterpolationAdjustedTargetFraction(
            Interpolator interpolator, float target, float epsilon) {
        float val = 0.5f;
        float adj = 0.25f;
        while (adj >= 0.01f) {
            if (interpolator.getInterpolation(val) < 0.99f) {

        while (adj >= epsilon) {
            if (interpolator.getInterpolation(val) < target) {
                val += adj;
            } else {
                val -= adj;
            }
            adj /= 2;
        }

        return val;
    }