Get animation update timing for AVD

The goal for this change is to get the timing for animation update. Since
AnimatorSet does not support update listeners, we have to go with the a different
approach, which sets up a value animator that runs between the start and end of
the AnimatorSet. We can then get the animation update timing from the ValueAnimator.

Bug: 26329675
Change-Id: Ibe7fce81eb6da5e05c87a732c1d3bc904b4e5e6f
(cherry picked from commit I378a0964da8f7090f65f6b56275a302e30668835)
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 1857345..e786971 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -19,6 +19,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.Animator.AnimatorListener;
+import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.res.ColorStateList;
@@ -140,6 +141,16 @@
     /** Local, mutable animator set. */
     private final AnimatorSet mAnimatorSet = new AnimatorSet();
 
+    // Setup a value animator to get animation update callbacks.
+    private final ValueAnimator mUpdateAnim = ValueAnimator.ofFloat(0f, 1f);
+    private final ValueAnimator.AnimatorUpdateListener mUpdateListener =
+            new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    invalidateSelf();
+                }
+            };
+
     /**
      * The resources against which this drawable was created. Used to attempt
      * to inflate animators if applyTheme() doesn't get called.
@@ -605,6 +616,32 @@
         if (!mHasAnimatorSet) {
             mAnimatedVectorState.prepareLocalAnimators(mAnimatorSet, mRes);
             mHasAnimatorSet = true;
+            // Setup an infinitely running ValueAnimator, start it when AnimatorSet starts and
+            // end it when AnimatorSet ends, so we get the animation update timing for
+            // invalidating the drawable. Ideally, we would set an update listener on AnimatorSet,
+            // but since AnimatorSet doesn't support that yet, this is the alternative to achieve
+            // the same goal.
+            mUpdateAnim.setRepeatCount(ValueAnimator.INFINITE);
+            mUpdateAnim.addUpdateListener(mUpdateListener);
+            mAnimatorSet.addListener(new AnimatorListener() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    mUpdateAnim.start();
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mUpdateAnim.end();
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                }
+
+                @Override
+                public void onAnimationRepeat(Animator animation) {
+                }
+            });
             mRes = null;
         }
     }
@@ -730,4 +767,4 @@
         mAnimationCallbacks.clear();
     }
 
-}
\ No newline at end of file
+}