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

Commit 0d1c27a7 authored by Chet Haase's avatar Chet Haase
Browse files

Fix seeking and scaled duration behavior

The animation scaled was not being factored in early enough in the
activity lifecycle. Also, setCurrentPlaytTime() was not accounting for
the scaled duration correctly. Finally, added setCurrentFraction() as
a more general-purpose seeking facility.

Issue #18222006 Animator duration scale ignored in some situations
Issue #17951668 add ability to seek fraction, not just time

Change-Id: Idad401f5ff5026d7046c36eee09d78a4793215dc
parent 5aadd5b6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3111,6 +3111,7 @@ package android.animation {
    method public void removeAllUpdateListeners();
    method public void removeUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
    method public void reverse();
    method public void setCurrentFraction(float);
    method public void setCurrentPlayTime(long);
    method public android.animation.ValueAnimator setDuration(long);
    method public void setEvaluator(android.animation.TypeEvaluator);
+25 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.animation;

import android.view.animation.AnimationUtils;

/**
 * This class provides a simple callback mechanism to listeners that is synchronized with all
 * other animators in the system. There is no duration, interpolation, or object value-setting
@@ -29,6 +47,13 @@ public class TimeAnimator extends ValueAnimator {
        return false;
    }

    @Override
    public void setCurrentPlayTime(long playTime) {
        long currentTime = AnimationUtils.currentAnimationTimeMillis();
        mStartTime = Math.max(mStartTime, currentTime - playTime);
        animationFrame(currentTime);
    }

    /**
     * Sets a listener that is sent update events throughout the life of
     * an animation.
+31 −11
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ public class ValueAnimator extends Animator {
     * Set when setCurrentPlayTime() is called. If negative, animation is not currently seeked
     * to a value.
     */
    long mSeekTime = -1;
    float mSeekFraction = -1;

    /**
     * Set on the next frame after pause() is called, used to calculate a new startTime
@@ -537,14 +537,31 @@ public class ValueAnimator extends Animator {
     * @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
     */
    public void setCurrentPlayTime(long playTime) {
        float fraction = mUnscaledDuration > 0 ? (float) playTime / mUnscaledDuration :
                playTime == 0 ? 0 : 1;
        setCurrentFraction(fraction);
    }

    /**
     * Sets the position of the animation to the specified fraction. This fraction should
     * be between 0 and the total fraction of the animation, including any repetition. That is,
     * a fraction of 0 will position the animation at the beginning, a value of 1 at the end,
     * and a value of 2 at the beginning of a reversing animator that repeats once. If
     * the animation has not yet been started, then it will not advance forward after it is
     * set to this fraction; it will simply set the fraction to this value and perform any
     * appropriate actions based on that fraction. If the animation is already running, then
     * setCurrentFraction() will set the current fraction to this value and continue
     * playing from that point.
     *
     * @param fraction The fraction to which the animation is advanced or rewound.
     */
    public void setCurrentFraction(float fraction) {
        initAnimation();
        long currentTime = AnimationUtils.currentAnimationTimeMillis();
        if (mPlayingState != RUNNING) {
            mSeekTime = playTime;
            mSeekFraction = fraction;
            mPlayingState = SEEKED;
        }
        mStartTime = currentTime - playTime;
        doAnimationFrame(currentTime);
        animateValue(fraction);
    }

    /**
@@ -948,6 +965,7 @@ public class ValueAnimator extends Animator {
        }
        mPlayingBackwards = playBackwards;
        mCurrentIteration = 0;
        int prevPlayingState = mPlayingState;
        mPlayingState = STOPPED;
        mStarted = true;
        mStartedDelay = false;
@@ -957,7 +975,9 @@ public class ValueAnimator extends Animator {
        animationHandler.mPendingAnimations.add(this);
        if (mStartDelay == 0) {
            // This sets the initial value of the animation, prior to actually starting it running
            if (prevPlayingState != SEEKED) {
                setCurrentPlayTime(0);
            }
            mPlayingState = STOPPED;
            mRunning = true;
            notifyStartListeners();
@@ -1221,12 +1241,12 @@ public class ValueAnimator extends Animator {
    final boolean doAnimationFrame(long frameTime) {
        if (mPlayingState == STOPPED) {
            mPlayingState = RUNNING;
            if (mSeekTime < 0) {
            if (mSeekFraction < 0) {
                mStartTime = frameTime;
            } else {
                mStartTime = frameTime - mSeekTime;
                // Now that we're playing, reset the seek time
                mSeekTime = -1;
                long seekTime = (long) (mDuration * mSeekFraction);
                mStartTime = frameTime - seekTime;
                mSeekFraction = -1;
            }
        }
        if (mPaused) {
@@ -1292,7 +1312,7 @@ public class ValueAnimator extends Animator {
        if (mUpdateListeners != null) {
            anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>(mUpdateListeners);
        }
        anim.mSeekTime = -1;
        anim.mSeekFraction = -1;
        anim.mPlayingBackwards = false;
        anim.mCurrentIteration = 0;
        anim.mInitialized = false;
+5 −0
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@ import android.util.Slog;
import android.util.SuperNotCalledException;
import android.view.Display;
import android.view.HardwareRenderer;
import android.view.IWindowManager;
import android.view.IWindowSessionCallback;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewManager;
@@ -2366,6 +2368,9 @@ public final class ActivityThread {
        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);

        // Initialize before creating the activity
        WindowManagerGlobal.initialize();

        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
+1 −1
Original line number Diff line number Diff line
@@ -3763,7 +3763,7 @@ public class Intent implements Parcelable, Cloneable {
     * This flag is used to open a document into a new task rooted at the activity launched
     * by this Intent. Through the use of this flag, or its equivalent attribute,
     * {@link android.R.attr#documentLaunchMode} multiple instances of the same activity
     * containing different douments will appear in the recent tasks list.
     * containing different documents will appear in the recent tasks list.
     *
     * <p>The use of the activity attribute form of this,
     * {@link android.R.attr#documentLaunchMode}, is
Loading