Behavior compat for child being manipulated outside Animatorset

When a child animator is being manipulated outside of the AnimatorSet,
such as when the child animator is running before the AnimatorSet gets
started, we need to make sure we maintain the behavoir on N:
The child animator will be re-started at its scheduled start time in
the AnimatorSet.

BUG: 37507882
Test: Repro steps in comment #1 & ag/2144081/
Change-Id: Ib97e85706f01d18a2e72fb4d1d678e22cf959894
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index fe496e3..cdeca13 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -1092,6 +1092,14 @@
                 AnimationEvent event = mEvents.get(i);
                 Node node = event.mNode;
                 if (event.mEvent == AnimationEvent.ANIMATION_END) {
+                    if (node.mAnimation.isStarted()) {
+                        // If the animation has already been started before its due time (i.e.
+                        // the child animator is being manipulated outside of the AnimatorSet), we
+                        // need to cancel the animation to reset the internal state (e.g. frame
+                        // time tracking) and remove the self pulsing callbacks
+                        node.mAnimation.cancel();
+                    }
+                    node.mEnded = false;
                     mPlayingSet.add(event.mNode);
                     node.mAnimation.startWithoutPulsing(true);
                     pulseFrame(node, 0);
@@ -1106,6 +1114,14 @@
                 Node node = event.mNode;
                 if (event.mEvent == AnimationEvent.ANIMATION_START) {
                     mPlayingSet.add(event.mNode);
+                    if (node.mAnimation.isStarted()) {
+                        // If the animation has already been started before its due time (i.e.
+                        // the child animator is being manipulated outside of the AnimatorSet), we
+                        // need to cancel the animation to reset the internal state (e.g. frame
+                        // time tracking) and remove the self pulsing callbacks
+                        node.mAnimation.cancel();
+                    }
+                    node.mEnded = false;
                     node.mAnimation.startWithoutPulsing(false);
                     pulseFrame(node, 0);
                 } else if (event.mEvent == AnimationEvent.ANIMATION_END && !node.mEnded) {