Merge "Don't call property getters during initialization." into udc-dev

This commit is contained in:
Treehugger Robot
2023-06-02 01:23:20 +00:00
committed by Android (Google) Code Review
4 changed files with 84 additions and 77 deletions

View File

@@ -568,13 +568,13 @@ public abstract class Animator implements Cloneable {
* repetition. lastPlayTime is similar and is used to calculate how many repeats have been
* done between the two times.
*/
void animateValuesInRange(long currentPlayTime, long lastPlayTime, boolean notify) {}
void animateValuesInRange(long currentPlayTime, long lastPlayTime) {}
/**
* Internal use only. This animates any animation that has ended since lastPlayTime.
* If an animation hasn't been finished, no change will be made.
*/
void animateSkipToEnds(long currentPlayTime, long lastPlayTime, boolean notify) {}
void animateSkipToEnds(long currentPlayTime, long lastPlayTime) {}
/**
* Internal use only. Adds all start times (after delay) to and end times to times.

View File

@@ -825,8 +825,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
private void animateBasedOnPlayTime(
long currentPlayTime,
long lastPlayTime,
boolean inReverse,
boolean notify
boolean inReverse
) {
if (currentPlayTime < 0 || lastPlayTime < -1) {
throw new UnsupportedOperationException("Error: Play time should never be negative.");
@@ -857,8 +856,8 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
while (index < endIndex) {
long playTime = startEndTimes[index];
if (lastPlayTime != playTime) {
animateSkipToEnds(playTime, lastPlayTime, notify);
animateValuesInRange(playTime, lastPlayTime, notify);
animateSkipToEnds(playTime, lastPlayTime);
animateValuesInRange(playTime, lastPlayTime);
lastPlayTime = playTime;
}
index++;
@@ -868,15 +867,15 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
index--;
long playTime = startEndTimes[index];
if (lastPlayTime != playTime) {
animateSkipToEnds(playTime, lastPlayTime, notify);
animateValuesInRange(playTime, lastPlayTime, notify);
animateSkipToEnds(playTime, lastPlayTime);
animateValuesInRange(playTime, lastPlayTime);
lastPlayTime = playTime;
}
}
}
if (currentPlayTime != lastPlayTime) {
animateSkipToEnds(currentPlayTime, lastPlayTime, notify);
animateValuesInRange(currentPlayTime, lastPlayTime, notify);
animateSkipToEnds(currentPlayTime, lastPlayTime);
animateValuesInRange(currentPlayTime, lastPlayTime);
}
}
@@ -896,13 +895,11 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
}
@Override
void animateSkipToEnds(long currentPlayTime, long lastPlayTime, boolean notify) {
void animateSkipToEnds(long currentPlayTime, long lastPlayTime) {
initAnimation();
if (lastPlayTime > currentPlayTime) {
if (notify) {
notifyStartListeners(true);
}
notifyStartListeners(true);
for (int i = mEvents.size() - 1; i >= 0; i--) {
AnimationEvent event = mEvents.get(i);
Node node = event.mNode;
@@ -916,31 +913,25 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
if (currentPlayTime <= start && start < lastPlayTime) {
animator.animateSkipToEnds(
0,
lastPlayTime - node.mStartTime,
notify
lastPlayTime - node.mStartTime
);
if (notify) {
mPlayingSet.remove(node);
}
mPlayingSet.remove(node);
} else if (start <= currentPlayTime && currentPlayTime <= end) {
animator.animateSkipToEnds(
currentPlayTime - node.mStartTime,
lastPlayTime - node.mStartTime,
notify
lastPlayTime - node.mStartTime
);
if (notify && !mPlayingSet.contains(node)) {
if (!mPlayingSet.contains(node)) {
mPlayingSet.add(node);
}
}
}
}
if (currentPlayTime <= 0 && notify) {
if (currentPlayTime <= 0) {
notifyEndListeners(true);
}
} else {
if (notify) {
notifyStartListeners(false);
}
notifyStartListeners(false);
int eventsSize = mEvents.size();
for (int i = 0; i < eventsSize; i++) {
AnimationEvent event = mEvents.get(i);
@@ -955,45 +946,39 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
if (lastPlayTime < end && end <= currentPlayTime) {
animator.animateSkipToEnds(
end - node.mStartTime,
lastPlayTime - node.mStartTime,
notify
lastPlayTime - node.mStartTime
);
if (notify) {
mPlayingSet.remove(node);
}
mPlayingSet.remove(node);
} else if (start <= currentPlayTime && currentPlayTime <= end) {
animator.animateSkipToEnds(
currentPlayTime - node.mStartTime,
lastPlayTime - node.mStartTime,
notify
lastPlayTime - node.mStartTime
);
if (notify && !mPlayingSet.contains(node)) {
if (!mPlayingSet.contains(node)) {
mPlayingSet.add(node);
}
}
}
}
if (currentPlayTime >= getTotalDuration() && notify) {
if (currentPlayTime >= getTotalDuration()) {
notifyEndListeners(false);
}
}
}
@Override
void animateValuesInRange(long currentPlayTime, long lastPlayTime, boolean notify) {
void animateValuesInRange(long currentPlayTime, long lastPlayTime) {
initAnimation();
if (notify) {
if (lastPlayTime < 0 || (lastPlayTime == 0 && currentPlayTime > 0)) {
notifyStartListeners(false);
} else {
long duration = getTotalDuration();
if (duration >= 0
&& (lastPlayTime > duration || (lastPlayTime == duration
&& currentPlayTime < duration))
) {
notifyStartListeners(true);
}
if (lastPlayTime < 0 || (lastPlayTime == 0 && currentPlayTime > 0)) {
notifyStartListeners(false);
} else {
long duration = getTotalDuration();
if (duration >= 0
&& (lastPlayTime > duration || (lastPlayTime == duration
&& currentPlayTime < duration))
) {
notifyStartListeners(true);
}
}
@@ -1014,8 +999,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
) {
animator.animateValuesInRange(
currentPlayTime - node.mStartTime,
Math.max(-1, lastPlayTime - node.mStartTime),
notify
Math.max(-1, lastPlayTime - node.mStartTime)
);
}
}
@@ -1111,7 +1095,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
}
}
mSeekState.setPlayTime(playTime, mReversing);
animateBasedOnPlayTime(playTime, lastPlayTime, mReversing, true);
animateBasedOnPlayTime(playTime, lastPlayTime, mReversing);
}
/**
@@ -1144,16 +1128,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
private void initChildren() {
if (!isInitialized()) {
mChildrenInitialized = true;
// We have to initialize all the start values so that they are based on the previous
// values.
long[] times = ensureChildStartAndEndTimes();
long previousTime = -1;
for (long time : times) {
animateBasedOnPlayTime(time, previousTime, false, false);
previousTime = time;
}
skipToEndValue(false);
}
}
@@ -1489,6 +1464,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
anim.mPauseTime = -1;
anim.mSeekState = new SeekState();
anim.mSelfPulse = true;
anim.mStartListenersCalled = false;
anim.mPlayingSet = new ArrayList<Node>();
anim.mNodeMap = new ArrayMap<Animator, Node>();
anim.mNodes = new ArrayList<Node>(nodeCount);

View File

@@ -1417,21 +1417,19 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
* will be called.
*/
@Override
void animateValuesInRange(long currentPlayTime, long lastPlayTime, boolean notify) {
void animateValuesInRange(long currentPlayTime, long lastPlayTime) {
if (currentPlayTime < 0 || lastPlayTime < -1) {
throw new UnsupportedOperationException("Error: Play time should never be negative.");
}
initAnimation();
long duration = getTotalDuration();
if (notify) {
if (lastPlayTime < 0 || (lastPlayTime == 0 && currentPlayTime > 0)) {
notifyStartListeners(false);
} else if (lastPlayTime > duration
|| (lastPlayTime == duration && currentPlayTime < duration)
) {
notifyStartListeners(true);
}
if (lastPlayTime < 0 || (lastPlayTime == 0 && currentPlayTime > 0)) {
notifyStartListeners(false);
} else if (lastPlayTime > duration
|| (lastPlayTime == duration && currentPlayTime < duration)
) {
notifyStartListeners(true);
}
if (duration >= 0) {
lastPlayTime = Math.min(duration, lastPlayTime);
@@ -1448,7 +1446,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
iteration = Math.min(iteration, mRepeatCount);
lastIteration = Math.min(lastIteration, mRepeatCount);
if (notify && iteration != lastIteration) {
if (iteration != lastIteration) {
notifyListeners(AnimatorCaller.ON_REPEAT, false);
}
}
@@ -1464,7 +1462,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
}
@Override
void animateSkipToEnds(long currentPlayTime, long lastPlayTime, boolean notify) {
void animateSkipToEnds(long currentPlayTime, long lastPlayTime) {
boolean inReverse = currentPlayTime < lastPlayTime;
boolean doSkip;
if (currentPlayTime <= 0 && lastPlayTime > 0) {
@@ -1474,13 +1472,9 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
doSkip = duration >= 0 && currentPlayTime >= duration && lastPlayTime < duration;
}
if (doSkip) {
if (notify) {
notifyStartListeners(inReverse);
}
notifyStartListeners(inReverse);
skipToEndValue(inReverse);
if (notify) {
notifyEndListeners(inReverse);
}
notifyEndListeners(inReverse);
}
}

View File

@@ -21,6 +21,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.util.Property;
import android.view.View;
import androidx.test.annotation.UiThreadTest;
@@ -576,6 +577,42 @@ public class AnimatorSetActivityTest {
});
}
@Test
public void testInitializeWithoutReadingValues() throws Throwable {
// Some consumers crash while reading values before the animator starts
Property<int[], Integer> property = new Property<>(Integer.class, "firstValue") {
@Override
public Integer get(int[] target) {
throw new IllegalStateException("Shouldn't be called");
}
@Override
public void set(int[] target, Integer value) {
target[0] = value;
}
};
int[] target1 = new int[1];
int[] target2 = new int[1];
int[] target3 = new int[1];
ObjectAnimator animator1 = ObjectAnimator.ofInt(target1, property, 0, 100);
ObjectAnimator animator2 = ObjectAnimator.ofInt(target2, property, 0, 100);
ObjectAnimator animator3 = ObjectAnimator.ofInt(target3, property, 0, 100);
AnimatorSet set = new AnimatorSet();
set.playSequentially(animator1, animator2, animator3);
mActivityRule.runOnUiThread(() -> {
set.setCurrentPlayTime(900);
assertEquals(100, target1[0]);
assertEquals(100, target2[0]);
assertEquals(100, target3[0]);
set.setCurrentPlayTime(0);
assertEquals(0, target1[0]);
assertEquals(0, target2[0]);
assertEquals(0, target3[0]);
});
}
/**
* Check that the animator list contains exactly the given animators and nothing else.
*/