1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view.animation.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertTrue; 23 24 import android.app.Activity; 25 import android.app.Instrumentation; 26 import android.content.res.XmlResourceParser; 27 import android.graphics.Matrix; 28 import android.util.AttributeSet; 29 import android.util.Xml; 30 import android.view.View; 31 import android.view.animation.Animation; 32 import android.view.animation.LinearInterpolator; 33 import android.view.animation.RotateAnimation; 34 import android.view.animation.Transformation; 35 import android.view.cts.R; 36 37 import androidx.test.InstrumentationRegistry; 38 import androidx.test.filters.MediumTest; 39 import androidx.test.rule.ActivityTestRule; 40 import androidx.test.runner.AndroidJUnit4; 41 42 import org.junit.Before; 43 import org.junit.Rule; 44 import org.junit.Test; 45 import org.junit.runner.RunWith; 46 47 @MediumTest 48 @RunWith(AndroidJUnit4.class) 49 public class RotateAnimationTest { 50 private static final long DURATION = 1000; 51 private static final float ROTATE_DELTA = 0.001f; 52 private static final float FROM_DEGREE = 0.0f; 53 private static final float TO_DEGREE = 90.0f; 54 55 private Instrumentation mInstrumentation; 56 private Activity mActivity; 57 58 @Rule 59 public ActivityTestRule<AnimationTestCtsActivity> mActivityRule = 60 new ActivityTestRule<>(AnimationTestCtsActivity.class); 61 62 @Before 63 public void setup() { 64 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 65 mActivity = mActivityRule.getActivity(); 66 } 67 68 @Test 69 public void testConstructors() { 70 // Test with null AttributeSet 71 new RotateAnimation(mActivity, null); 72 73 final XmlResourceParser parser = mActivity.getResources().getAnimation( 74 R.anim.anim_rotate); 75 final AttributeSet attr = Xml.asAttributeSet(parser); 76 assertNotNull(attr); 77 // Test with real AttributeSet 78 new RotateAnimation(mActivity, attr); 79 80 // Test {@link RotateAnimation#RotateAnimation(float, float)} 81 new RotateAnimation(0.6f, 0.6f); 82 // Test negative input values 83 new RotateAnimation(-0.6f, -0.6f); 84 85 // Test {@link RotateAnimation#RotateAnimation(float, float, float, float)} 86 new RotateAnimation(0.6f, 0.6f, 0.6f, 0.6f); 87 // Test negative input values 88 new RotateAnimation(-0.6f, -0.6f, -0.6f, -0.6f); 89 90 // Test {@link RotateAnimation#RotateAnimation(float, float, int, float, int, float)} 91 new RotateAnimation(0.6f, 0.6f, Animation.ABSOLUTE, 0.6f, Animation.ABSOLUTE, 0.6f); 92 // Test negative input values 93 new RotateAnimation(-0.6f, -0.6f, Animation.ABSOLUTE, -0.6f, Animation.ABSOLUTE, -0.6f); 94 } 95 96 @Test 97 public void testRotateAgainstOrigin() throws Throwable { 98 final View animWindowParent = mActivity.findViewById(R.id.anim_window_parent); 99 final View animWindow = mActivity.findViewById(R.id.anim_window); 100 Transformation transformation = new Transformation(); 101 // Test when mPivot x and y equal to 0. 102 MyRotateAnimation rotateAnimation = new MyRotateAnimation(FROM_DEGREE, TO_DEGREE); 103 rotateAnimation.setDuration(DURATION); 104 rotateAnimation.setInterpolator(new LinearInterpolator()); 105 106 assertFalse(rotateAnimation.isInitialized()); 107 rotateAnimation.initialize(animWindow.getWidth(), animWindow.getHeight(), 108 animWindowParent.getWidth(), animWindowParent.getHeight()); 109 assertTrue(rotateAnimation.isInitialized()); 110 111 AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, 112 rotateAnimation); 113 final long startTime = rotateAnimation.getStartTime(); 114 115 Matrix expectedMatrix = new Matrix(); 116 expectedMatrix.setRotate(FROM_DEGREE); 117 rotateAnimation.getTransformation(startTime, transformation); 118 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 119 transformation.clear(); 120 rotateAnimation.applyTransformation(0.0f, transformation); 121 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 122 123 expectedMatrix.reset(); 124 expectedMatrix.setRotate((FROM_DEGREE + TO_DEGREE) / 2); 125 rotateAnimation.getTransformation(startTime + DURATION / 2, transformation); 126 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 127 transformation.clear(); 128 rotateAnimation.applyTransformation(0.5f, transformation); 129 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 130 131 expectedMatrix.reset(); 132 expectedMatrix.setRotate(TO_DEGREE); 133 rotateAnimation.getTransformation(startTime + DURATION, transformation); 134 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 135 rotateAnimation.applyTransformation(1.0f, transformation); 136 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 137 } 138 139 private void assertMatrixEquals(Matrix expectedMatrix, Matrix actualMatrix) { 140 final float[] expectedMatrixValues = new float[9]; 141 final float[] actualMatrixValues = new float[9]; 142 expectedMatrix.getValues(expectedMatrixValues); 143 actualMatrix.getValues(actualMatrixValues); 144 for (int i = 0; i < 9; i++) { 145 assertEquals(expectedMatrixValues[i], actualMatrixValues[i], ROTATE_DELTA); 146 } 147 } 148 149 @Test 150 public void testRotateAgainstPoint() throws Throwable { 151 final View animWindowParent = mActivity.findViewById(R.id.anim_window_parent); 152 final View animWindow = mActivity.findViewById(R.id.anim_window); 153 Transformation transformation = new Transformation(); 154 final float pivotX = 0.2f; 155 final float pivotY = 0.2f; 156 final float actualPivotX = pivotX * animWindowParent.getWidth(); 157 final float actualPivotY = pivotY * animWindow.getHeight(); 158 // Test when mPivot x and y are not origin 159 MyRotateAnimation rotateAnimation = new MyRotateAnimation(FROM_DEGREE, TO_DEGREE, 160 Animation.RELATIVE_TO_PARENT, pivotX, Animation.RELATIVE_TO_SELF, pivotY); 161 rotateAnimation.setDuration(DURATION); 162 rotateAnimation.setInterpolator(new LinearInterpolator()); 163 164 assertFalse(rotateAnimation.isInitialized()); 165 rotateAnimation.initialize(animWindow.getWidth(), animWindow.getHeight(), 166 animWindowParent.getWidth(), animWindowParent.getHeight()); 167 assertTrue(rotateAnimation.isInitialized()); 168 169 AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow, 170 rotateAnimation); 171 final long startTime = rotateAnimation.getStartTime(); 172 173 Matrix expectedMatrix = new Matrix(); 174 expectedMatrix.setRotate(FROM_DEGREE, actualPivotX, actualPivotY); 175 rotateAnimation.getTransformation(startTime, transformation); 176 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 177 transformation.clear(); 178 rotateAnimation.applyTransformation(0.0f, transformation); 179 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 180 181 expectedMatrix.reset(); 182 expectedMatrix.setRotate((FROM_DEGREE + TO_DEGREE) / 2, actualPivotX, actualPivotY); 183 rotateAnimation.getTransformation(startTime + DURATION / 2, transformation); 184 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 185 transformation.clear(); 186 rotateAnimation.applyTransformation(0.5f, transformation); 187 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 188 189 expectedMatrix.reset(); 190 expectedMatrix.setRotate(TO_DEGREE, actualPivotX, actualPivotY); 191 rotateAnimation.getTransformation(startTime + DURATION, transformation); 192 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 193 transformation.clear(); 194 rotateAnimation.applyTransformation(1.0f, transformation); 195 assertMatrixEquals(expectedMatrix, transformation.getMatrix()); 196 } 197 198 private static class MyRotateAnimation extends RotateAnimation { 199 200 public MyRotateAnimation(float fromDegrees, float toDegrees) { 201 super(fromDegrees, toDegrees); 202 } 203 204 public MyRotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) { 205 super(fromDegrees, toDegrees, pivotX, pivotY); 206 } 207 208 public MyRotateAnimation(float fromDegrees, float toDegrees, int pivotXType, 209 float pivotX, int pivotYType, float pivotY) { 210 super(fromDegrees, toDegrees, pivotXType, pivotX, pivotYType, pivotY); 211 } 212 213 @Override 214 protected void applyTransformation(float interpolatedTime, Transformation t) { 215 super.applyTransformation(interpolatedTime, t); 216 } 217 } 218 } 219