Add tests for animator cloning and inflater
Bug: 17456416
Change-Id: I03b97df20d5920fff7305c5778f6633752449197
diff --git a/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java b/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
index 35a0b4c..3ececed 100644
--- a/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
+++ b/tests/tests/animation/src/android/animation/cts/AnimatorSetTest.java
@@ -16,8 +16,11 @@
package android.animation.cts;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
@@ -25,6 +28,7 @@
import android.test.ActivityInstrumentationTestCase2;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
+import android.view.animation.LinearInterpolator;
public class AnimatorSetTest extends
ActivityInstrumentationTestCase2<AnimationActivity> {
@@ -34,6 +38,7 @@
private Object object;
private ObjectAnimator yAnimator;
private ObjectAnimator xAnimator;
+ Set<Integer> identityHashes = new HashSet<Integer>();
public AnimatorSetTest() {
super(AnimationActivity.class);
@@ -158,4 +163,81 @@
}
});
}
+
+ private void assertUnique(Object object) {
+ assertUnique(object, "");
+ }
+
+ private void assertUnique(Object object, String msg) {
+ final int code = System.identityHashCode(object);
+ assertTrue("object should be unique " + msg + ", obj:" + object, identityHashes.add(code));
+
+ }
+
+ public void testClone() {
+ AnimatorSet set1 = new AnimatorSet();
+ final AnimatorListenerAdapter setListener = new AnimatorListenerAdapter() {};
+ set1.addListener(setListener);
+ ObjectAnimator animator1 = new ObjectAnimator();
+ animator1.setDuration(100);
+ animator1.setPropertyName("x");
+ animator1.setIntValues(5);
+ animator1.setInterpolator(new LinearInterpolator());
+ AnimatorListenerAdapter listener1 = new AnimatorListenerAdapter(){};
+ AnimatorListenerAdapter listener2 = new AnimatorListenerAdapter(){};
+ animator1.addListener(listener1);
+
+ ObjectAnimator animator2 = new ObjectAnimator();
+ animator2.setDuration(100);
+ animator2.setInterpolator(new LinearInterpolator());
+ animator2.addListener(listener2);
+ animator2.setPropertyName("y");
+ animator2.setIntValues(10);
+
+ set1.playTogether(animator1, animator2);
+
+ AnimateObject target = new AnimateObject();
+ set1.setTarget(target);
+ set1.start();
+ assertTrue(set1.isStarted());
+
+ animator1.getListeners();
+ AnimatorSet set2 = set1.clone();
+ assertFalse(set2.isStarted());
+
+ assertUnique(set1);
+ assertUnique(animator1);
+ assertUnique(animator2);
+
+ assertUnique(set2);
+ assertEquals(2, set2.getChildAnimations().size());
+
+ Animator clone1 = set2.getChildAnimations().get(0);
+ Animator clone2 = set2.getChildAnimations().get(1);
+
+ for (Animator animator : set2.getChildAnimations()) {
+ assertUnique(animator);
+ }
+
+ assertTrue(clone1.getListeners().contains(listener1));
+ assertTrue(clone2.getListeners().contains(listener2));
+
+ assertTrue(set2.getListeners().contains(setListener));
+ assertEquals(set1.getChangingConfigurations(), set2.getChangingConfigurations());
+
+
+ for (Animator.AnimatorListener listener : set1.getListeners()) {
+ assertTrue(set2.getListeners().contains(listener));
+ }
+
+ assertEquals(animator1.getDuration(), clone1.getDuration());
+ assertEquals(animator2.getDuration(), clone2.getDuration());
+ assertSame(animator1.getInterpolator(), clone1.getInterpolator());
+ assertSame(animator2.getInterpolator(), clone2.getInterpolator());
+ }
+
+ class AnimateObject {
+ int x = 1;
+ int y = 2;
+ }
}
diff --git a/tests/tests/view/res/anim-land/changing_reset_state_anim.xml b/tests/tests/view/res/anim-land/changing_reset_state_anim.xml
new file mode 100644
index 0000000..0b3279a
--- /dev/null
+++ b/tests/tests/view/res/anim-land/changing_reset_state_anim.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="100dp" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="100dp" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="100dp" android:valueType="floatType"/>
+</set>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim-land/changing_state_list_animator.xml b/tests/tests/view/res/anim-land/changing_state_list_animator.xml
new file mode 100644
index 0000000..4c1c41e
--- /dev/null
+++ b/tests/tests/view/res/anim-land/changing_state_list_animator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="10" android:valueType="floatType"/>
+ </item>
+ <!-- base state-->
+ <item>
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="200dp" android:valueType="floatType"/>
+ </item>
+</selector>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim-land/changing_test_animator.xml b/tests/tests/view/res/anim-land/changing_test_animator.xml
new file mode 100644
index 0000000..d5c83cd
--- /dev/null
+++ b/tests/tests/view/res/anim-land/changing_test_animator.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<!-- if you change this, you should also change AnimatorInflaterTest#testLoadAnimator-->
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="x" android:duration="100"
+ android:interpolator="@android:anim/bounce_interpolator"
+ android:valueTo="1" android:valueType="floatType"/>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/changing_reset_state_anim.xml b/tests/tests/view/res/anim/changing_reset_state_anim.xml
new file mode 100644
index 0000000..dd2b233
--- /dev/null
+++ b/tests/tests/view/res/anim/changing_reset_state_anim.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="50dp" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="50dp" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="50dp" android:valueType="floatType"/>
+</set>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/changing_state_list_animator.xml b/tests/tests/view/res/anim/changing_state_list_animator.xml
new file mode 100644
index 0000000..6bcc0d9
--- /dev/null
+++ b/tests/tests/view/res/anim/changing_state_list_animator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="10" android:valueType="floatType"/>
+ </item>
+ <!-- base state-->
+ <item>
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="100dp" android:valueType="floatType"/>
+ </item>
+</selector>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/changing_test_animator.xml b/tests/tests/view/res/anim/changing_test_animator.xml
new file mode 100644
index 0000000..739a71b
--- /dev/null
+++ b/tests/tests/view/res/anim/changing_test_animator.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<!-- if you change this, you should also change AnimatorInflaterTest#testLoadAnimator-->
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:propertyName="x" android:duration="100"
+ android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+ android:valueTo="1" android:valueType="floatType"/>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/reset_state_anim.xml b/tests/tests/view/res/anim/reset_state_anim.xml
new file mode 100644
index 0000000..4bbbe62
--- /dev/null
+++ b/tests/tests/view/res/anim/reset_state_anim.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+</set>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/test_animator.xml b/tests/tests/view/res/anim/test_animator.xml
new file mode 100644
index 0000000..94e9ec8
--- /dev/null
+++ b/tests/tests/view/res/anim/test_animator.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- if you change this, you should also change AnimatorInflaterTest#testLoadAnimator-->
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="@dimen/test_animator_target_x" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="@dimen/test_animator_target_y" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="left" android:duration="100" android:valueTo="2" android:valueType="intType"/>
+</set>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/test_state_list_animator.xml b/tests/tests/view/res/anim/test_state_list_animator.xml
new file mode 100644
index 0000000..b6a4822
--- /dev/null
+++ b/tests/tests/view/res/anim/test_state_list_animator.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <set>
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="10" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="20" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="20" android:valueType="floatType"/>
+ </set>
+ </item>
+ <item android:state_enabled="true" android:state_pressed="false">
+ <set>
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ <objectAnimator android:propertyName="z" android:duration="100" android:valueTo="0" android:valueType="floatType"/>
+ </set>
+ </item>
+ <!-- base state-->
+ <item android:animation="@anim/reset_state_anim"/>
+</selector>
\ No newline at end of file
diff --git a/tests/tests/view/res/anim/test_state_list_animator_2.xml b/tests/tests/view/res/anim/test_state_list_animator_2.xml
new file mode 100644
index 0000000..6aeb41f
--- /dev/null
+++ b/tests/tests/view/res/anim/test_state_list_animator_2.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true">
+ <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="10" android:valueType="floatType"/>
+ </item>
+ <!-- base state-->
+ <item android:animation="@anim/changing_reset_state_anim"/>
+</selector>
\ No newline at end of file
diff --git a/tests/tests/view/res/values-land/dimens.xml b/tests/tests/view/res/values-land/dimens.xml
new file mode 100644
index 0000000..17b5395
--- /dev/null
+++ b/tests/tests/view/res/values-land/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+ <dimen name="test_animator_target_y">30dp</dimen>
+ <!-- this value is equal to the value in changing_reset_state_anim. It is NOT referenced
+ in the XML on purpose-->
+ <dimen name="reset_state_value">100dp</dimen>
+ <!-- this value is equal to the value in changing_state_list_animator. It is NOT referenced in the XML on purpose-->
+ <dimen name="changing_state_list_anim_target_x_value">200dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/view/res/values/dimens.xml b/tests/tests/view/res/values/dimens.xml
new file mode 100644
index 0000000..16e5084
--- /dev/null
+++ b/tests/tests/view/res/values/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+ <dimen name="test_animator_target_x">10dp</dimen>
+ <dimen name="test_animator_target_y">20dp</dimen>
+ <!-- this value is equal to the value in changing_reset_state_anim. It is NOT referenced in the XML on purpose-->
+ <dimen name="reset_state_value">50dp</dimen>
+ <!-- this value is equal to the value in changing_state_list_animator. It is NOT referenced in the XML on purpose-->
+ <dimen name="changing_state_list_anim_target_x_value">100dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java b/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
new file mode 100644
index 0000000..eeda5a3
--- /dev/null
+++ b/tests/tests/view/src/android/view/animation/cts/AnimatorInflaterTest.java
@@ -0,0 +1,271 @@
+/*
+* Copyright (C) 2014 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.view.animation.cts;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.StateListAnimator;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.os.Debug;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.View;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import com.android.cts.view.R;
+
+public class AnimatorInflaterTest
+ extends ActivityInstrumentationTestCase2<AnimationTestCtsActivity> {
+
+ Set<Integer> identityHashes = new HashSet<Integer>();
+
+ public AnimatorInflaterTest() {
+ super("com.android.cts.view", AnimationTestCtsActivity.class);
+ }
+
+ private void assertUnique(Object object) {
+ assertUnique(object, "");
+ }
+
+ private void assertUnique(Object object, String msg) {
+ final int code = System.identityHashCode(object);
+ assertTrue("object should be unique " + msg + ", obj:" + object, identityHashes.add(code));
+
+ }
+
+ public void testLoadAnimatorWithDifferentInterpolators() throws Throwable {
+ Animator anim1 = AnimatorInflater
+ .loadAnimator(getActivity(), R.anim.changing_test_animator);
+ rotate();
+ Animator anim2 = AnimatorInflater
+ .loadAnimator(getActivity(), R.anim.changing_test_animator);
+ assertNotSame(anim1, anim2);
+ assertNotSame("interpolater is orientation dependent, should change",
+ anim1.getInterpolator(), anim2.getInterpolator());
+ }
+
+ /**
+ * Tests animators with dimension references.
+ */
+ public void testLoadAnimator() throws Throwable {
+ // to identify objects
+ Animator anim1 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ Animator anim2 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ assertNotSame("a different animation should be returned", anim1, anim2);
+ assertSame("interpolator should be shallow cloned", anim1.getInterpolator(),
+ anim2.getInterpolator());
+ for (int i = 0; i < 2; i++) {
+ float targetX = getActivity().getResources()
+ .getDimension(R.dimen.test_animator_target_x);
+ // y value changes in landscape orientation
+ float targetY = getActivity().getResources()
+ .getDimension(R.dimen.test_animator_target_y);
+ for (Animator anim : new Animator[]{anim1, anim2}) {
+ assertTrue(anim instanceof AnimatorSet);
+ assertUnique(anim);
+ AnimatorSet set = (AnimatorSet) anim;
+ assertEquals("should have 3 sub animations", 3, set.getChildAnimations().size());
+ for (Animator subAnim : set.getChildAnimations()) {
+ assertUnique(subAnim);
+ assertTrue(subAnim instanceof ObjectAnimator);
+ }
+ final ObjectAnimator child1 = (ObjectAnimator) set.getChildAnimations().get(0);
+ final ObjectAnimator child2 = (ObjectAnimator) set.getChildAnimations().get(1);
+ final DummyObject dummyObject = new DummyObject();
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ for (ObjectAnimator animator : new ObjectAnimator[]{child1, child2}) {
+ animator.setTarget(dummyObject);
+ animator.setupStartValues();
+ animator.start();
+ animator.end();
+ }
+ }
+ });
+ assertEquals(targetX, dummyObject.x);
+ assertEquals(targetY, dummyObject.y);
+ }
+ if (i == 0) {
+ rotate();
+ }
+ anim1 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ anim2 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+
+ }
+ }
+
+ private void rotate() throws Throwable {
+ final Activity activity = getActivity();
+ int orientation = activity.getResources().getConfiguration().orientation;
+ final int nextOrientation = orientation == Configuration.ORIENTATION_LANDSCAPE
+ ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+ : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+ Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(
+ activity.getClass().getName(), null, false);
+ getInstrumentation().addMonitor(monitor);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ activity.setRequestedOrientation(nextOrientation);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ Activity newAct = getInstrumentation()
+ .waitForMonitorWithTimeout(monitor, TimeUnit.SECONDS.toMillis(2));
+ if (newAct != null) {
+ setActivity(newAct);
+ }
+ }
+
+ /**
+ * Simple state list animator test that checks for cloning
+ */
+ public void testLoadStateListAnimator() {
+ StateListAnimator sla1 = AnimatorInflater.loadStateListAnimator(getActivity(),
+ R.anim.test_state_list_animator);
+ StateListAnimator sla2 = AnimatorInflater.loadStateListAnimator(getActivity(),
+ R.anim.test_state_list_animator);
+ assertUnique(sla1);
+ assertUnique(sla2);
+ }
+
+ /**
+ * Tests a state list animator which has an @anim reference that has different xmls per
+ * orientation
+ */
+ public void testLoadStateListAnimatorWithChangingResetState() throws Throwable {
+ loadStateListAnimatorWithChangingResetStateTest();
+ rotate();
+ loadStateListAnimatorWithChangingResetStateTest();
+ }
+
+ private void loadStateListAnimatorWithChangingResetStateTest() throws Throwable {
+ final StateListAnimator sla = AnimatorInflater.loadStateListAnimator(getActivity(),
+ R.anim.test_state_list_animator_2);
+ final View testView = getTestView();
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ testView.setStateListAnimator(sla);
+ testView.jumpDrawablesToCurrentState();
+ }
+ });
+ float resetValue = getActivity().getResources().getDimension(R.dimen.reset_state_value);
+ getInstrumentation().waitForIdleSync();
+ assertEquals(resetValue, testView.getX());
+ assertEquals(resetValue, testView.getY());
+ assertEquals(resetValue, testView.getZ());
+ }
+
+ /**
+ * Tests a state list animator which has different xml descriptions per orientation.
+ */
+ public void testLoadChangingStateListAnimator() throws Throwable {
+ loadChangingStateListAnimatorTest();
+ rotate();
+ loadChangingStateListAnimatorTest();
+ }
+
+ private void loadChangingStateListAnimatorTest() throws Throwable {
+ final StateListAnimator sla = AnimatorInflater.loadStateListAnimator(getActivity(),
+ R.anim.changing_state_list_animator);
+ final View testView = getTestView();
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ testView.setStateListAnimator(sla);
+ testView.jumpDrawablesToCurrentState();
+ }
+ });
+ float targetValue = getActivity().getResources()
+ .getDimension(R.dimen.changing_state_list_anim_target_x_value);
+ getInstrumentation().waitForIdleSync();
+ assertEquals(targetValue, testView.getX());
+ }
+
+ /**
+ * Tests that makes sure that reloaded animator is not affected by previous changes
+ */
+ public void testReloadedAnimatorIsNotModified() throws Throwable {
+ final Animator anim1 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ final CountDownLatch mStarted = new CountDownLatch(1);
+ final AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ mStarted.countDown();
+ }
+ };
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ anim1.setTarget(getTestView());
+ anim1.addListener(listener);
+ anim1.start();
+ }
+ });
+ Animator anim2 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
+ assertTrue(anim1.isStarted());
+ assertFalse(anim2.isStarted());
+ assertFalse("anim2 should not include the listener",
+ anim2.getListeners() != null && anim2.getListeners().contains(listener));
+ assertTrue("animator should start", mStarted.await(10, TimeUnit.SECONDS));
+ assertFalse(anim2.isRunning());
+
+ }
+
+ public View getTestView() {
+ return getActivity().findViewById(R.id.anim_window);
+ }
+
+ class DummyObject {
+
+ float x;
+ float y;
+
+ public float getX() {
+ return x;
+ }
+
+ public void setX(float x) {
+ this.x = x;
+ }
+
+ public float getY() {
+ return y;
+ }
+
+ public void setY(float y) {
+ this.y = y;
+ }
+ }
+}
+