Home | History | Annotate | Download | only in cts
      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.assertSame;
     23 import static org.junit.Assert.assertTrue;
     24 
     25 import android.app.Activity;
     26 import android.app.Instrumentation;
     27 import android.content.res.XmlResourceParser;
     28 import android.util.AttributeSet;
     29 import android.util.Xml;
     30 import android.view.View;
     31 import android.view.animation.AccelerateInterpolator;
     32 import android.view.animation.AlphaAnimation;
     33 import android.view.animation.Animation;
     34 import android.view.animation.AnimationSet;
     35 import android.view.animation.ScaleAnimation;
     36 import android.view.animation.Transformation;
     37 import android.view.animation.TranslateAnimation;
     38 import android.view.cts.R;
     39 
     40 import androidx.test.InstrumentationRegistry;
     41 import androidx.test.filters.MediumTest;
     42 import androidx.test.rule.ActivityTestRule;
     43 import androidx.test.runner.AndroidJUnit4;
     44 
     45 import org.junit.Before;
     46 import org.junit.Rule;
     47 import org.junit.Test;
     48 import org.junit.runner.RunWith;
     49 
     50 import java.util.List;
     51 
     52 @MediumTest
     53 @RunWith(AndroidJUnit4.class)
     54 public class AnimationSetTest {
     55     private static final float DELTA = 0.001f;
     56     private static final long SHORT_CHILD_DURATION = 400;
     57     private static final long MEDIUM_CHILD_DURATION = 800;
     58     private static final long LONG_CHILD_DURATION = 1200;
     59     /**
     60      * initial size for initialize(int width, int height, int parentWidth, int parentHeight)
     61      */
     62     private static final int INITIAL_SIZE = 100;
     63     private static final long ANIMATIONSET_DURATION = 1000;
     64 
     65     private Instrumentation mInstrumentation;
     66     private Activity mActivity;
     67 
     68     @Rule
     69     public ActivityTestRule<AnimationTestCtsActivity> mActivityRule =
     70             new ActivityTestRule<>(AnimationTestCtsActivity.class);
     71 
     72     @Before
     73     public void setup() {
     74         mInstrumentation = InstrumentationRegistry.getInstrumentation();
     75         mActivity = mActivityRule.getActivity();
     76     }
     77 
     78     @Test
     79     public void testConstructor() {
     80         new AnimationSet(true);
     81 
     82         final XmlResourceParser parser = mActivity.getResources().getAnimation(
     83                 R.anim.anim_set);
     84         final AttributeSet attr = Xml.asAttributeSet(parser);
     85         assertNotNull(attr);
     86         // Test with real AttributeSet
     87         new AnimationSet(mActivity, attr);
     88     }
     89 
     90     @Test
     91     public void testInitialize() {
     92         final AnimationSet animationSet = createAnimationSet();
     93         animationSet.setDuration(ANIMATIONSET_DURATION);
     94         // Before initialize, the durations are original.
     95         List<Animation> children = animationSet.getAnimations();
     96         assertEquals(SHORT_CHILD_DURATION, children.get(0).getDuration());
     97         assertEquals(MEDIUM_CHILD_DURATION, children.get(1).getDuration());
     98         assertEquals(LONG_CHILD_DURATION, children.get(2).getDuration());
     99 
    100         // After initialize, AnimationSet override the child values.
    101         assertFalse(animationSet.isInitialized());
    102         animationSet.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    103         assertTrue(animationSet.isInitialized());
    104         children = animationSet.getAnimations();
    105         assertEquals(ANIMATIONSET_DURATION, children.get(0).getDuration());
    106         assertEquals(ANIMATIONSET_DURATION, children.get(1).getDuration());
    107         assertEquals(ANIMATIONSET_DURATION, children.get(2).getDuration());
    108     }
    109 
    110     private AnimationSet createAnimationSet() {
    111         AnimationSet animationSet = new AnimationSet(true);
    112 
    113         Animation animation1 = new AlphaAnimation(0.0f, 1.0f);
    114         animation1.setDuration(SHORT_CHILD_DURATION);
    115         animationSet.addAnimation(animation1);
    116 
    117         Animation animation2 = new ScaleAnimation(1.0f, 2.0f, 1.0f, 3.0f);
    118         animation2.setDuration(MEDIUM_CHILD_DURATION);
    119         animationSet.addAnimation(animation2);
    120 
    121         Animation animation3 = new TranslateAnimation(0.0f, 50.0f, 0.0f, 5.0f);
    122         animation3.setDuration(LONG_CHILD_DURATION);
    123         animationSet.addAnimation(animation3);
    124 
    125         return animationSet;
    126     }
    127 
    128     @Test
    129     public void testSetFillAfter() {
    130         final AnimationSet animationSet = createAnimationSet();
    131         assertFalse(animationSet.getFillAfter());
    132 
    133         List<Animation> children = animationSet.getAnimations();
    134         children.get(0).setFillAfter(true);
    135         children.get(1).setFillAfter(false);
    136 
    137         animationSet.setFillAfter(true);
    138         animationSet.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    139         assertTrue(animationSet.getFillAfter());
    140         children = animationSet.getAnimations();
    141         for (int i = 0; i < children.size(); i++) {
    142             assertTrue(children.get(i).getFillAfter());
    143         }
    144     }
    145 
    146     @Test
    147     public void testSetFillBefore() {
    148         final AnimationSet animationSet = createAnimationSet();
    149         assertTrue(animationSet.getFillBefore());
    150 
    151         List<Animation> children = animationSet.getAnimations();
    152         children.get(0).setFillBefore(true);
    153         children.get(1).setFillBefore(false);
    154 
    155         animationSet.setFillBefore(false);
    156         animationSet.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    157         assertFalse(animationSet.getFillBefore());
    158         children = animationSet.getAnimations();
    159         for (int i = 0; i < children.size(); i++) {
    160             assertFalse(children.get(i).getFillBefore());
    161         }
    162     }
    163 
    164     @Test
    165     public void testAccessDuration() {
    166         final AnimationSet animationSet = createAnimationSet();
    167         assertEquals(LONG_CHILD_DURATION, animationSet.getDuration());
    168 
    169         assertTrue(animationSet.getDuration() > ANIMATIONSET_DURATION);
    170         animationSet.setDuration(ANIMATIONSET_DURATION);
    171         animationSet.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    172         assertEquals(ANIMATIONSET_DURATION, animationSet.getDuration());
    173         final List<Animation> children = animationSet.getAnimations();
    174         for (int i = 0; i < children.size(); i++) {
    175             assertEquals(ANIMATIONSET_DURATION, children.get(i).getDuration());
    176         }
    177     }
    178 
    179     @Test
    180     public void testRestrictDuration() {
    181         final AnimationSet animationSet = new AnimationSet(false);
    182         Animation child = null;
    183         final long[] originChildDuration = { 1000, 1000, 500 };
    184         final long[] originChildStartOffset = { 2000, 1000, 0 };
    185         final int[] originChildRepeatCount = { 0, 0, 4 };
    186         final long[] originChildDurationHint = new long[3];
    187         for (int i = 0; i < 3; i++) {
    188             child = new AlphaAnimation(0.0f, 1.0f);
    189             child.setDuration(originChildDuration[i]);
    190             child.setStartOffset(originChildStartOffset[i]);
    191             child.setRepeatCount(originChildRepeatCount[i]);
    192             originChildDurationHint[i] = child.computeDurationHint();
    193             animationSet.addAnimation(child);
    194         }
    195         final long restrictDuration = 1500;
    196         animationSet.restrictDuration(restrictDuration);
    197         final List<Animation> children = animationSet.getAnimations();
    198 
    199         assertTrue(originChildStartOffset[0] > restrictDuration);
    200         assertEquals(0, children.get(0).getDuration());
    201         assertEquals(restrictDuration, children.get(0).getStartOffset());
    202 
    203         assertTrue(originChildStartOffset[1] < restrictDuration);
    204         assertTrue(originChildDurationHint[1] > restrictDuration);
    205         assertTrue(children.get(1).computeDurationHint() <= restrictDuration);
    206 
    207         assertTrue(originChildDurationHint[2] > restrictDuration);
    208         assertTrue(children.get(2).computeDurationHint() <= restrictDuration);
    209         assertTrue(originChildRepeatCount[2] > children.get(2).getRepeatCount());
    210     }
    211 
    212     @Test
    213     public void testComputeDurationHint() {
    214         final AnimationSet animationSet = createAnimationSet();
    215         final List<Animation> children = animationSet.getAnimations();
    216         long expectedDuration = 0;
    217         for (int i = 0; i < children.size(); i++) {
    218             expectedDuration = Math.max(expectedDuration, children.get(i).computeDurationHint());
    219         }
    220         assertEquals(expectedDuration, animationSet.computeDurationHint());
    221     }
    222 
    223     @Test
    224     public void testScaleCurrentDuration() {
    225         final AnimationSet animationSet = createAnimationSet();
    226         List<Animation> children = animationSet.getAnimations();
    227         final long[] originDurations = new long[children.size()];
    228         for (int i = 0; i < children.size(); i++) {
    229             originDurations[i] = children.get(i).getDuration();
    230         }
    231 
    232         final float scaleFactor = 2.0f;
    233         animationSet.scaleCurrentDuration(scaleFactor);
    234         children = animationSet.getAnimations();
    235         for (int i = 0; i < children.size(); i++) {
    236             assertEquals((long) (originDurations[i] * scaleFactor), children.get(i).getDuration());
    237         }
    238     }
    239 
    240     @Test
    241     public void testAccessRepeatMode() {
    242         final AnimationSet animationSet = createAnimationSet();
    243         animationSet.setRepeatMode(Animation.RESTART);
    244         animationSet.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    245         assertEquals(Animation.RESTART, animationSet.getRepeatMode());
    246         List<Animation> children = animationSet.getAnimations();
    247         for (int i = 0; i < children.size(); i++) {
    248             assertEquals(Animation.RESTART, children.get(i).getRepeatMode());
    249         }
    250 
    251         animationSet.setRepeatMode(Animation.REVERSE);
    252         animationSet.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    253         assertEquals(Animation.REVERSE, animationSet.getRepeatMode());
    254         children = animationSet.getAnimations();
    255         for (int i = 0; i < children.size(); i++) {
    256             assertEquals(Animation.REVERSE, children.get(i).getRepeatMode());
    257         }
    258     }
    259 
    260     @Test
    261     public void testAccessStartOffset() {
    262         final AnimationSet animationSet = createAnimationSet();
    263         assertEquals(0, animationSet.getStartOffset());
    264         List<Animation> children = animationSet.getAnimations();
    265         final long[] originStartOffset = new long[children.size()];
    266         for (int i = 0; i < children.size(); i++) {
    267             originStartOffset[i] = children.get(i).getStartOffset();
    268         }
    269 
    270         animationSet.setStartOffset(100);
    271         animationSet.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    272         assertEquals(100, animationSet.getStartOffset());
    273         children = animationSet.getAnimations();
    274         for (int i = 0; i < children.size(); i++) {
    275             assertEquals(originStartOffset[i] + animationSet.getStartOffset(),
    276                     children.get(i).getStartOffset());
    277         }
    278 
    279         assertTrue(animationSet.isInitialized());
    280         animationSet.reset();
    281         assertFalse(animationSet.isInitialized());
    282         children = animationSet.getAnimations();
    283         for (int i = 0; i < children.size(); i++) {
    284             assertEquals(originStartOffset[i], children.get(i).getStartOffset());
    285         }
    286     }
    287 
    288     @Test
    289     public void testAccessStartTime() {
    290         final AnimationSet animationSet = createAnimationSet();
    291         final long[] originChildStartTime = {1000, 2000, 3000};
    292         List<Animation> children = animationSet.getAnimations();
    293         for (int i = 0; i < children.size(); i++) {
    294             children.get(i).setStartTime(originChildStartTime[i]);
    295         }
    296 
    297         // Get earliest start time of children animations
    298         assertEquals(1000, animationSet.getStartTime());
    299 
    300         final long startTime = 200;
    301         animationSet.setStartTime(startTime);
    302         assertEquals(startTime, animationSet.getStartTime());
    303 
    304         children = animationSet.getAnimations();
    305         for (int i = 0; i < children.size(); i++) {
    306             assertEquals(startTime, children.get(i).getStartTime());
    307         }
    308     }
    309 
    310     @Test
    311     public void testGetTransformation() throws Throwable {
    312         final View animWindowParent = mActivity.findViewById(R.id.anim_window_parent);
    313         final View animWindow = mActivity.findViewById(R.id.anim_window);
    314         final AnimationSet animationSet = createAnimationSet();
    315         animationSet.setDuration(2000);
    316         animationSet.initialize(animWindow.getWidth(), animWindow.getHeight(),
    317                 animWindowParent.getWidth(), animWindowParent.getHeight());
    318 
    319         AnimationTestUtils.assertRunAnimation(mInstrumentation, mActivityRule, animWindow,
    320                 animationSet);
    321         final long startTime = animationSet.getStartTime();
    322 
    323         assertGetTransformation(animationSet, startTime, true);
    324         assertGetTransformation(animationSet, startTime + 100, true);
    325         assertGetTransformation(animationSet, startTime + animationSet.getDuration(), false);
    326     }
    327 
    328     private void assertGetTransformation(final AnimationSet animationSet,
    329             final long currentTime, final boolean result) {
    330         final Transformation transformation = new Transformation();
    331         final Transformation expectedTransformation = new Transformation();
    332         final Transformation tempTransformation = new Transformation();
    333 
    334         assertEquals(result, animationSet.getTransformation(currentTime, transformation));
    335         final List<Animation> children = animationSet.getAnimations();
    336         for (int i = children.size() - 1; i >= 0; i--) {
    337             tempTransformation.clear();
    338             children.get(i).getTransformation(currentTime, tempTransformation);
    339             expectedTransformation.compose(tempTransformation);
    340         }
    341         assertTransformationEquals(expectedTransformation, transformation);
    342     }
    343 
    344     private void assertTransformationEquals(final Transformation expected,
    345             final Transformation actual) {
    346         assertEquals(expected.getAlpha(), actual.getAlpha(), DELTA);
    347         final float[] expectedValues = new float[9];
    348         final float[] actualValues = new float[9];
    349         expected.getMatrix().getValues(expectedValues);
    350         actual.getMatrix().getValues(actualValues);
    351         for (int i = 0; i < expectedValues.length; i++) {
    352             assertEquals(expectedValues[i], actualValues[i], DELTA);
    353         }
    354     }
    355 
    356     @Test
    357     public void testAccessAnimations() {
    358         final AnimationSet animationSet = new AnimationSet(true);
    359         final Animation animation1 = new AlphaAnimation(0.0f, 1.0f);
    360         animationSet.addAnimation(animation1);
    361         final Animation animation2 = new AlphaAnimation(0.5f, 1.0f);
    362         animationSet.addAnimation(animation2);
    363         final Animation animation3 = new AlphaAnimation(1.0f, 0.5f);
    364         animationSet.addAnimation(animation3);
    365 
    366         final List<Animation> children = animationSet.getAnimations();
    367         assertEquals(3, children.size());
    368         assertSame(animation1, children.get(0));
    369         assertSame(animation2, children.get(1));
    370         assertSame(animation3, children.get(2));
    371     }
    372 
    373     @Test
    374     public void testWillChangeTransformationMatrix() {
    375         final AnimationSet animationSet = new AnimationSet(true);
    376         assertFalse(animationSet.willChangeTransformationMatrix());
    377 
    378         // Add first animation, this is an alpha animation and will not change
    379         // the transformation matrix.
    380         animationSet.addAnimation(new AlphaAnimation(0.0f, 1.0f));
    381         assertFalse(animationSet.willChangeTransformationMatrix());
    382         assertFalse(animationSet.willChangeBounds());
    383 
    384         // Add second animation, this is an scale animation and will change
    385         // the transformation matrix.
    386         animationSet.addAnimation(new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f));
    387         assertTrue(animationSet.willChangeTransformationMatrix());
    388         assertTrue(animationSet.willChangeBounds());
    389     }
    390 
    391     @Test
    392     public void testClone() throws CloneNotSupportedException {
    393         final MyAnimationSet animationSet = new MyAnimationSet(false);
    394         final Animation alpha = new AlphaAnimation(0.0f, 1.0f);
    395         alpha.setInterpolator(new AccelerateInterpolator());
    396         alpha.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    397         final Animation scale = new ScaleAnimation(1.0f, 2.0f, 1.0f, 3.0f);
    398         scale.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    399         animationSet.addAnimation(alpha);
    400         animationSet.addAnimation(scale);
    401         final long startTime = 0;
    402         animationSet.setStartTime(startTime);
    403         animationSet.setDuration(ANIMATIONSET_DURATION);
    404         animationSet.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    405 
    406         final AnimationSet clone = animationSet.clone();
    407         clone.initialize(INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE, INITIAL_SIZE);
    408         final List<Animation> children = animationSet.getAnimations();
    409         final List<Animation> cloneChildren = clone.getAnimations();
    410         assertEquals(children.size(), cloneChildren.size());
    411         final Transformation expectedTransformation = new Transformation();
    412         final Transformation transformation = new Transformation();
    413         for (int i = 0; i < children.size(); i++) {
    414             children.get(i).getTransformation(startTime, expectedTransformation);
    415             cloneChildren.get(i).getTransformation(startTime, transformation);
    416             assertTransformationEquals(expectedTransformation, transformation);
    417 
    418             children.get(i).getTransformation(startTime + ANIMATIONSET_DURATION / 2,
    419                     expectedTransformation);
    420             cloneChildren.get(i).getTransformation(startTime  + ANIMATIONSET_DURATION /2,
    421                     transformation);
    422             assertTransformationEquals(expectedTransformation, transformation);
    423 
    424             children.get(i).getTransformation(startTime + ANIMATIONSET_DURATION,
    425                     expectedTransformation);
    426             cloneChildren.get(i).getTransformation(startTime  + ANIMATIONSET_DURATION,
    427                     transformation);
    428             assertTransformationEquals(expectedTransformation, transformation);
    429         }
    430     }
    431 
    432     private static class MyAnimationSet extends AnimationSet {
    433 
    434         public MyAnimationSet(boolean shareInterpolator) {
    435             super(shareInterpolator);
    436         }
    437 
    438         @Override
    439         protected AnimationSet clone() throws CloneNotSupportedException {
    440             return super.clone();
    441         }
    442     }
    443 }
    444