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 */ 16package android.animation; 17 18import android.os.Handler; 19import android.test.ActivityInstrumentationTestCase2; 20import android.test.suitebuilder.annotation.SmallTest; 21 22import java.util.HashMap; 23import java.util.concurrent.TimeUnit; 24 25public 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