Home | History | Annotate | Download | only in animation
      1 /*
      2  * Copyright (C) 2013 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.animation;
     17 
     18 import android.os.Handler;
     19 import android.test.ActivityInstrumentationTestCase2;
     20 import android.test.suitebuilder.annotation.SmallTest;
     21 
     22 import java.util.HashMap;
     23 import java.util.concurrent.TimeUnit;
     24 
     25 public class AutoCancelTest extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
     26 
     27     boolean mAnimX1Canceled = false;
     28     boolean mAnimXY1Canceled = false;
     29     boolean mAnimX2Canceled = false;
     30     boolean mAnimXY2Canceled = false;
     31 
     32     private static final long START_DELAY = 100;
     33     private static final long DELAYED_START_DURATION = 200;
     34     private static final long FUTURE_TIMEOUT = 1000;
     35 
     36     HashMap<Animator, Boolean> mCanceledMap = new HashMap<Animator, Boolean>();
     37 
     38     public AutoCancelTest() {
     39         super(BasicAnimatorActivity.class);
     40     }
     41 
     42     ObjectAnimator setupAnimator(long startDelay, String... properties) {
     43         ObjectAnimator returnVal;
     44         if (properties.length == 1) {
     45             returnVal = ObjectAnimator.ofFloat(this, properties[0], 0, 1);
     46         } else {
     47             PropertyValuesHolder[] pvhArray = new PropertyValuesHolder[properties.length];
     48             for (int i = 0; i < properties.length; i++) {
     49                 pvhArray[i] = PropertyValuesHolder.ofFloat(properties[i], 0, 1);
     50             }
     51             returnVal = ObjectAnimator.ofPropertyValuesHolder(this, pvhArray);
     52         }
     53         returnVal.setAutoCancel(true);
     54         returnVal.setStartDelay(startDelay);
     55         returnVal.addListener(mCanceledListener);
     56         return returnVal;
     57     }
     58 
     59     private void setupAnimators(long startDelay, boolean startLater, final FutureWaiter future)
     60     throws Exception {
     61         // Animators to be auto-canceled
     62         final ObjectAnimator animX1 = setupAnimator(startDelay, "x");
     63         final ObjectAnimator animY1 = setupAnimator(startDelay, "y");
     64         final ObjectAnimator animXY1 = setupAnimator(startDelay, "x", "y");
     65         final ObjectAnimator animXZ1 = setupAnimator(startDelay, "x", "z");
     66 
     67         animX1.start();
     68         animY1.start();
     69         animXY1.start();
     70         animXZ1.start();
     71 
     72         final ObjectAnimator animX2 = setupAnimator(0, "x");
     73         animX2.addListener(new AnimatorListenerAdapter() {
     74             @Override
     75             public void onAnimationStart(Animator animation) {
     76                 // We expect only animX1 to be canceled at this point
     77                 if (mCanceledMap.get(animX1) == null ||
     78                         mCanceledMap.get(animX1) != true ||
     79                         mCanceledMap.get(animY1) != null ||
     80                         mCanceledMap.get(animXY1) != null ||
     81                         mCanceledMap.get(animXZ1) != null) {
     82                     future.set(false);
     83                 }
     84             }
     85         });
     86 
     87         final ObjectAnimator animXY2 = setupAnimator(0, "x", "y");
     88         animXY2.addListener(new AnimatorListenerAdapter() {
     89             @Override
     90             public void onAnimationStart(Animator animation) {
     91                 // We expect only animXY1 to be canceled at this point
     92                 if (mCanceledMap.get(animXY1) == null ||
     93                         mCanceledMap.get(animXY1) != true ||
     94                         mCanceledMap.get(animY1) != null ||
     95                         mCanceledMap.get(animXZ1) != null) {
     96                     future.set(false);
     97                 }
     98 
     99             }
    100 
    101             @Override
    102             public void onAnimationEnd(Animator animation) {
    103                 // Release future if not done already via failures during start
    104                 future.release();
    105             }
    106         });
    107 
    108         if (startLater) {
    109             Handler handler = new Handler();
    110             handler.postDelayed(new Runnable() {
    111                 @Override
    112                 public void run() {
    113                     animX2.start();
    114                     animXY2.start();
    115                 }
    116             }, DELAYED_START_DURATION);
    117         } else {
    118             animX2.start();
    119             animXY2.start();
    120         }
    121     }
    122 
    123     @SmallTest
    124     public void testAutoCancel() throws Exception {
    125         final FutureWaiter future = new FutureWaiter();
    126         getActivity().runOnUiThread(new Runnable() {
    127             @Override
    128             public void run() {
    129                 try {
    130                     setupAnimators(0, false, future);
    131                 } catch (Exception e) {
    132                     future.setException(e);
    133                 }
    134             }
    135         });
    136         assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS));
    137     }
    138 
    139     @SmallTest
    140     public void testAutoCancelDelayed() throws Exception {
    141         final FutureWaiter future = new FutureWaiter();
    142         getActivity().runOnUiThread(new Runnable() {
    143             @Override
    144             public void run() {
    145                 try {
    146                     setupAnimators(START_DELAY, false, future);
    147                 } catch (Exception e) {
    148                     future.setException(e);
    149                 }
    150             }
    151         });
    152         assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS));
    153     }
    154 
    155     @SmallTest
    156     public void testAutoCancelTestLater() throws Exception {
    157         final FutureWaiter future = new FutureWaiter();
    158         getActivity().runOnUiThread(new Runnable() {
    159             @Override
    160             public void run() {
    161                 try {
    162                     setupAnimators(0, true, future);
    163                 } catch (Exception e) {
    164                     future.setException(e);
    165                 }
    166             }
    167         });
    168         assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS));
    169     }
    170 
    171     @SmallTest
    172     public void testAutoCancelDelayedTestLater() throws Exception {
    173         final FutureWaiter future = new FutureWaiter();
    174         getActivity().runOnUiThread(new Runnable() {
    175             @Override
    176             public void run() {
    177                 try {
    178                     setupAnimators(START_DELAY, true, future);
    179                 } catch (Exception e) {
    180                     future.setException(e);
    181                 }
    182             }
    183         });
    184         assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS));
    185     }
    186 
    187     private AnimatorListenerAdapter mCanceledListener = new AnimatorListenerAdapter() {
    188         @Override
    189         public void onAnimationCancel(Animator animation) {
    190             mCanceledMap.put(animation, true);
    191         }
    192     };
    193 
    194     public void setX(float x) {}
    195 
    196     public void setY(float y) {}
    197 
    198     public void setZ(float z) {}
    199 }
    200 
    201 
    202