Home | History | Annotate | Download | only in cts
      1 /*
      2 * Copyright (C) 2014 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 package android.view.animation.cts;
     17 
     18 import android.animation.Animator;
     19 import android.animation.AnimatorInflater;
     20 import android.animation.AnimatorListenerAdapter;
     21 import android.animation.AnimatorSet;
     22 import android.animation.ObjectAnimator;
     23 import android.animation.StateListAnimator;
     24 import android.app.Instrumentation;
     25 import android.app.UiAutomation;
     26 import android.content.Context;
     27 import android.util.Log;
     28 import android.test.ActivityInstrumentationTestCase2;
     29 import android.view.Display;
     30 import android.view.Surface;
     31 import android.view.View;
     32 import android.view.WindowManager;
     33 
     34 import java.util.HashSet;
     35 import java.util.Set;
     36 import java.util.concurrent.CountDownLatch;
     37 import java.util.concurrent.TimeUnit;
     38 
     39 import com.android.cts.view.R;
     40 
     41 public class AnimatorInflaterTest
     42         extends ActivityInstrumentationTestCase2<AnimationTestCtsActivity> {
     43 
     44     private static final String TAG = "AnimatorInflaterTest";
     45     Set<Integer> identityHashes = new HashSet<Integer>();
     46 
     47     public AnimatorInflaterTest() {
     48         super("com.android.cts.view", AnimationTestCtsActivity.class);
     49     }
     50 
     51     private void assertUnique(Object object) {
     52         assertUnique(object, "");
     53     }
     54 
     55     private void assertUnique(Object object, String msg) {
     56         final int code = System.identityHashCode(object);
     57         assertTrue("object should be unique " + msg + ", obj:" + object, identityHashes.add(code));
     58 
     59     }
     60 
     61     public void testLoadAnimatorWithDifferentInterpolators() throws Throwable {
     62         Animator anim1 = AnimatorInflater
     63                 .loadAnimator(getActivity(), R.anim.changing_test_animator);
     64         if (!rotate()) {
     65             return;//cancel test
     66         }
     67         Animator anim2 = AnimatorInflater
     68                 .loadAnimator(getActivity(), R.anim.changing_test_animator);
     69         assertNotSame(anim1, anim2);
     70         assertNotSame("interpolater is orientation dependent, should change",
     71                 anim1.getInterpolator(), anim2.getInterpolator());
     72     }
     73 
     74     /**
     75      * Tests animators with dimension references.
     76      */
     77     public void testLoadAnimator() throws Throwable {
     78         // to identify objects
     79         Animator anim1 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
     80         Animator anim2 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
     81         assertNotSame("a different animation should be returned", anim1, anim2);
     82         assertSame("interpolator should be shallow cloned", anim1.getInterpolator(),
     83                 anim2.getInterpolator());
     84         for (int i = 0; i < 2; i++) {
     85             float targetX = getActivity().getResources()
     86                     .getDimension(R.dimen.test_animator_target_x);
     87             // y value changes in landscape orientation
     88             float targetY = getActivity().getResources()
     89                     .getDimension(R.dimen.test_animator_target_y);
     90             for (Animator anim : new Animator[]{anim1, anim2}) {
     91                 assertTrue(anim instanceof AnimatorSet);
     92                 assertUnique(anim);
     93                 AnimatorSet set = (AnimatorSet) anim;
     94                 assertEquals("should have 3 sub animations", 3, set.getChildAnimations().size());
     95                 for (Animator subAnim : set.getChildAnimations()) {
     96                     assertUnique(subAnim);
     97                     assertTrue(subAnim instanceof ObjectAnimator);
     98                 }
     99                 final ObjectAnimator child1 = (ObjectAnimator) set.getChildAnimations().get(0);
    100                 final ObjectAnimator child2 = (ObjectAnimator) set.getChildAnimations().get(1);
    101                 final DummyObject dummyObject = new DummyObject();
    102                 runTestOnUiThread(new Runnable() {
    103                     @Override
    104                     public void run() {
    105                         for (ObjectAnimator animator : new ObjectAnimator[]{child1, child2}) {
    106                             animator.setTarget(dummyObject);
    107                             animator.setupStartValues();
    108                             animator.start();
    109                             animator.end();
    110                         }
    111                     }
    112                 });
    113                 assertEquals(targetX, dummyObject.x);
    114                 assertEquals(targetY, dummyObject.y);
    115             }
    116             if (i == 0) {
    117                 if (!rotate()) {
    118                     return;//cancel test
    119                 }
    120             }
    121             anim1 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
    122             anim2 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
    123 
    124         }
    125     }
    126 
    127     private boolean rotate() throws Throwable {
    128         WindowManager mWindowManager = (WindowManager) getActivity()
    129                 .getSystemService(Context.WINDOW_SERVICE);
    130         Display display = mWindowManager.getDefaultDisplay();
    131 
    132         Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(
    133                 getActivity().getClass().getName(), null, false);
    134         getInstrumentation().addMonitor(monitor);
    135         int nextRotation = 0;
    136         switch (display.getRotation()) {
    137             case Surface.ROTATION_0:
    138             case Surface.ROTATION_180:
    139                 nextRotation = UiAutomation.ROTATION_FREEZE_90;
    140                 break;
    141             case Surface.ROTATION_90:
    142             case Surface.ROTATION_270:
    143                 nextRotation = UiAutomation.ROTATION_FREEZE_0;
    144                 break;
    145             default:
    146                 Log.e(TAG, "Cannot get rotation, test is canceled");
    147                 return false;
    148         }
    149         boolean rotated = getInstrumentation().getUiAutomation().setRotation(nextRotation);
    150         Thread.sleep(500);
    151         if (!rotated) {
    152             Log.e(TAG, "Rotation failed, test is canceled");
    153         }
    154         getInstrumentation().waitForIdleSync();
    155         if (!getActivity().waitUntilVisible()) {
    156             Log.e(TAG, "Activity failed to complete rotation, canceling test");
    157             return false;
    158         }
    159         if (getActivity().getWindowManager().getDefaultDisplay().getRotation() != nextRotation) {
    160             Log.e(TAG, "New activity orientation does not match. Canceling test");
    161             return false;
    162         }
    163         return true;
    164     }
    165 
    166     /**
    167      * Simple state list animator test that checks for cloning
    168      */
    169     public void testLoadStateListAnimator() {
    170         StateListAnimator sla1 = AnimatorInflater.loadStateListAnimator(getActivity(),
    171                 R.anim.test_state_list_animator);
    172         StateListAnimator sla2 = AnimatorInflater.loadStateListAnimator(getActivity(),
    173                 R.anim.test_state_list_animator);
    174         assertUnique(sla1);
    175         assertUnique(sla2);
    176     }
    177 
    178     /**
    179      * Tests a state list animator which has an @anim reference that has different xmls per
    180      * orientation
    181      */
    182     public void testLoadStateListAnimatorWithChangingResetState() throws Throwable {
    183         loadStateListAnimatorWithChangingResetStateTest();
    184         if (!rotate()) {
    185             return;//cancel test
    186         }
    187 
    188         loadStateListAnimatorWithChangingResetStateTest();
    189     }
    190 
    191     private void loadStateListAnimatorWithChangingResetStateTest() throws Throwable {
    192         final StateListAnimator sla = AnimatorInflater.loadStateListAnimator(getActivity(),
    193                 R.anim.test_state_list_animator_2);
    194         final View testView = getTestView();
    195         runTestOnUiThread(new Runnable() {
    196             @Override
    197             public void run() {
    198                 testView.setStateListAnimator(sla);
    199                 testView.jumpDrawablesToCurrentState();
    200             }
    201         });
    202         float resetValue = getActivity().getResources().getDimension(R.dimen.reset_state_value);
    203         getInstrumentation().waitForIdleSync();
    204         assertEquals(resetValue, testView.getX());
    205         assertEquals(resetValue, testView.getY());
    206         assertEquals(resetValue, testView.getZ());
    207     }
    208 
    209     /**
    210      * Tests a state list animator which has different xml descriptions per orientation.
    211      */
    212     public void testLoadChangingStateListAnimator() throws Throwable {
    213         loadChangingStateListAnimatorTest();
    214         if (!rotate()) {
    215             return;//cancel test
    216         }
    217         loadChangingStateListAnimatorTest();
    218     }
    219 
    220     private void loadChangingStateListAnimatorTest() throws Throwable {
    221         final StateListAnimator sla = AnimatorInflater.loadStateListAnimator(getActivity(),
    222                 R.anim.changing_state_list_animator);
    223         final View testView = getTestView();
    224         runTestOnUiThread(new Runnable() {
    225             @Override
    226             public void run() {
    227                 testView.setStateListAnimator(sla);
    228                 testView.jumpDrawablesToCurrentState();
    229             }
    230         });
    231         float targetValue = getActivity().getResources()
    232                 .getDimension(R.dimen.changing_state_list_anim_target_x_value);
    233         getInstrumentation().waitForIdleSync();
    234         assertEquals(targetValue, testView.getX());
    235     }
    236 
    237     /**
    238      * Tests that makes sure that reloaded animator is not affected by previous changes
    239      */
    240     public void testReloadedAnimatorIsNotModified() throws Throwable {
    241         final Animator anim1 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
    242         final CountDownLatch mStarted = new CountDownLatch(1);
    243         final AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
    244             @Override
    245             public void onAnimationEnd(Animator animation) {
    246                 super.onAnimationEnd(animation);
    247             }
    248 
    249             @Override
    250             public void onAnimationStart(Animator animation) {
    251                 super.onAnimationStart(animation);
    252                 mStarted.countDown();
    253             }
    254         };
    255         runTestOnUiThread(new Runnable() {
    256             @Override
    257             public void run() {
    258                 anim1.setTarget(getTestView());
    259                 anim1.addListener(listener);
    260                 anim1.start();
    261             }
    262         });
    263         Animator anim2 = AnimatorInflater.loadAnimator(getActivity(), R.anim.test_animator);
    264         assertTrue(anim1.isStarted());
    265         assertFalse(anim2.isStarted());
    266         assertFalse("anim2 should not include the listener",
    267                 anim2.getListeners() != null && anim2.getListeners().contains(listener));
    268         assertTrue("animator should start", mStarted.await(10, TimeUnit.SECONDS));
    269         assertFalse(anim2.isRunning());
    270 
    271     }
    272 
    273     public View getTestView() {
    274         return getActivity().findViewById(R.id.anim_window);
    275     }
    276 
    277     class DummyObject {
    278 
    279         float x;
    280         float y;
    281 
    282         public float getX() {
    283             return x;
    284         }
    285 
    286         public void setX(float x) {
    287             this.x = x;
    288         }
    289 
    290         public float getY() {
    291             return y;
    292         }
    293 
    294         public void setY(float y) {
    295             this.y = y;
    296         }
    297     }
    298 }
    299 
    300