1be19e030a14c8e398e8af97fa898ea80187704dfChet Haase/* 2be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * Copyright (C) 2013 The Android Open Source Project 3be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * 4be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * Licensed under the Apache License, Version 2.0 (the "License"); 5be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * you may not use this file except in compliance with the License. 6be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * You may obtain a copy of the License at 7be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * 8be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * http://www.apache.org/licenses/LICENSE-2.0 9be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * 10be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * Unless required by applicable law or agreed to in writing, software 11be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * distributed under the License is distributed on an "AS IS" BASIS, 12be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * See the License for the specific language governing permissions and 14be19e030a14c8e398e8af97fa898ea80187704dfChet Haase * limitations under the License. 15be19e030a14c8e398e8af97fa898ea80187704dfChet Haase */ 16be19e030a14c8e398e8af97fa898ea80187704dfChet Haasepackage android.animation; 17be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 18be19e030a14c8e398e8af97fa898ea80187704dfChet Haaseimport android.os.Handler; 19be19e030a14c8e398e8af97fa898ea80187704dfChet Haaseimport android.test.ActivityInstrumentationTestCase2; 20be19e030a14c8e398e8af97fa898ea80187704dfChet Haaseimport android.test.suitebuilder.annotation.SmallTest; 21be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 22be19e030a14c8e398e8af97fa898ea80187704dfChet Haaseimport java.util.HashMap; 23be19e030a14c8e398e8af97fa898ea80187704dfChet Haaseimport java.util.concurrent.TimeUnit; 24be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 25be19e030a14c8e398e8af97fa898ea80187704dfChet Haasepublic class AutoCancelTest extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> { 26be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 27be19e030a14c8e398e8af97fa898ea80187704dfChet Haase boolean mAnimX1Canceled = false; 28be19e030a14c8e398e8af97fa898ea80187704dfChet Haase boolean mAnimXY1Canceled = false; 29be19e030a14c8e398e8af97fa898ea80187704dfChet Haase boolean mAnimX2Canceled = false; 30be19e030a14c8e398e8af97fa898ea80187704dfChet Haase boolean mAnimXY2Canceled = false; 31be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 32be19e030a14c8e398e8af97fa898ea80187704dfChet Haase private static final long START_DELAY = 100; 33be19e030a14c8e398e8af97fa898ea80187704dfChet Haase private static final long DELAYED_START_DURATION = 200; 34be19e030a14c8e398e8af97fa898ea80187704dfChet Haase private static final long FUTURE_TIMEOUT = 1000; 35be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 36be19e030a14c8e398e8af97fa898ea80187704dfChet Haase HashMap<Animator, Boolean> mCanceledMap = new HashMap<Animator, Boolean>(); 37be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 38be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public AutoCancelTest() { 39be19e030a14c8e398e8af97fa898ea80187704dfChet Haase super(BasicAnimatorActivity.class); 40be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 41be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 42be19e030a14c8e398e8af97fa898ea80187704dfChet Haase ObjectAnimator setupAnimator(long startDelay, String... properties) { 43be19e030a14c8e398e8af97fa898ea80187704dfChet Haase ObjectAnimator returnVal; 44be19e030a14c8e398e8af97fa898ea80187704dfChet Haase if (properties.length == 1) { 45be19e030a14c8e398e8af97fa898ea80187704dfChet Haase returnVal = ObjectAnimator.ofFloat(this, properties[0], 0, 1); 46be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } else { 47be19e030a14c8e398e8af97fa898ea80187704dfChet Haase PropertyValuesHolder[] pvhArray = new PropertyValuesHolder[properties.length]; 48be19e030a14c8e398e8af97fa898ea80187704dfChet Haase for (int i = 0; i < properties.length; i++) { 49be19e030a14c8e398e8af97fa898ea80187704dfChet Haase pvhArray[i] = PropertyValuesHolder.ofFloat(properties[i], 0, 1); 50be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 51be19e030a14c8e398e8af97fa898ea80187704dfChet Haase returnVal = ObjectAnimator.ofPropertyValuesHolder(this, pvhArray); 52be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 53be19e030a14c8e398e8af97fa898ea80187704dfChet Haase returnVal.setAutoCancel(true); 54be19e030a14c8e398e8af97fa898ea80187704dfChet Haase returnVal.setStartDelay(startDelay); 55be19e030a14c8e398e8af97fa898ea80187704dfChet Haase returnVal.addListener(mCanceledListener); 56be19e030a14c8e398e8af97fa898ea80187704dfChet Haase return returnVal; 57be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 58be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 59be19e030a14c8e398e8af97fa898ea80187704dfChet Haase private void setupAnimators(long startDelay, boolean startLater, final FutureWaiter future) 60be19e030a14c8e398e8af97fa898ea80187704dfChet Haase throws Exception { 61be19e030a14c8e398e8af97fa898ea80187704dfChet Haase // Animators to be auto-canceled 62be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final ObjectAnimator animX1 = setupAnimator(startDelay, "x"); 63be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final ObjectAnimator animY1 = setupAnimator(startDelay, "y"); 64be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final ObjectAnimator animXY1 = setupAnimator(startDelay, "x", "y"); 65be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final ObjectAnimator animXZ1 = setupAnimator(startDelay, "x", "z"); 66be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 67be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animX1.start(); 68be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animY1.start(); 69be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animXY1.start(); 70be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animXZ1.start(); 71be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 72be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final ObjectAnimator animX2 = setupAnimator(0, "x"); 73be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animX2.addListener(new AnimatorListenerAdapter() { 74be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @Override 75be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void onAnimationStart(Animator animation) { 76be19e030a14c8e398e8af97fa898ea80187704dfChet Haase // We expect only animX1 to be canceled at this point 77be19e030a14c8e398e8af97fa898ea80187704dfChet Haase if (mCanceledMap.get(animX1) == null || 78be19e030a14c8e398e8af97fa898ea80187704dfChet Haase mCanceledMap.get(animX1) != true || 79be19e030a14c8e398e8af97fa898ea80187704dfChet Haase mCanceledMap.get(animY1) != null || 80be19e030a14c8e398e8af97fa898ea80187704dfChet Haase mCanceledMap.get(animXY1) != null || 81be19e030a14c8e398e8af97fa898ea80187704dfChet Haase mCanceledMap.get(animXZ1) != null) { 82be19e030a14c8e398e8af97fa898ea80187704dfChet Haase future.set(false); 83be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 84be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 85be19e030a14c8e398e8af97fa898ea80187704dfChet Haase }); 86be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 87be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final ObjectAnimator animXY2 = setupAnimator(0, "x", "y"); 88be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animXY2.addListener(new AnimatorListenerAdapter() { 89be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @Override 90be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void onAnimationStart(Animator animation) { 91be19e030a14c8e398e8af97fa898ea80187704dfChet Haase // We expect only animXY1 to be canceled at this point 92be19e030a14c8e398e8af97fa898ea80187704dfChet Haase if (mCanceledMap.get(animXY1) == null || 93be19e030a14c8e398e8af97fa898ea80187704dfChet Haase mCanceledMap.get(animXY1) != true || 94be19e030a14c8e398e8af97fa898ea80187704dfChet Haase mCanceledMap.get(animY1) != null || 95be19e030a14c8e398e8af97fa898ea80187704dfChet Haase mCanceledMap.get(animXZ1) != null) { 96be19e030a14c8e398e8af97fa898ea80187704dfChet Haase future.set(false); 97be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 98be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 99be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 100be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 101be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @Override 102be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void onAnimationEnd(Animator animation) { 103be19e030a14c8e398e8af97fa898ea80187704dfChet Haase // Release future if not done already via failures during start 104be19e030a14c8e398e8af97fa898ea80187704dfChet Haase future.release(); 105be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 106be19e030a14c8e398e8af97fa898ea80187704dfChet Haase }); 107be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 108be19e030a14c8e398e8af97fa898ea80187704dfChet Haase if (startLater) { 109be19e030a14c8e398e8af97fa898ea80187704dfChet Haase Handler handler = new Handler(); 110be19e030a14c8e398e8af97fa898ea80187704dfChet Haase handler.postDelayed(new Runnable() { 111be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @Override 112be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void run() { 113be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animX2.start(); 114be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animXY2.start(); 115be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 116be19e030a14c8e398e8af97fa898ea80187704dfChet Haase }, DELAYED_START_DURATION); 117be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } else { 118be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animX2.start(); 119be19e030a14c8e398e8af97fa898ea80187704dfChet Haase animXY2.start(); 120be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 121be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 122be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 123be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @SmallTest 124be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void testAutoCancel() throws Exception { 125be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final FutureWaiter future = new FutureWaiter(); 126be19e030a14c8e398e8af97fa898ea80187704dfChet Haase getActivity().runOnUiThread(new Runnable() { 127be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @Override 128be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void run() { 129be19e030a14c8e398e8af97fa898ea80187704dfChet Haase try { 130be19e030a14c8e398e8af97fa898ea80187704dfChet Haase setupAnimators(0, false, future); 131be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } catch (Exception e) { 132be19e030a14c8e398e8af97fa898ea80187704dfChet Haase future.setException(e); 133be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 134be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 135be19e030a14c8e398e8af97fa898ea80187704dfChet Haase }); 136be19e030a14c8e398e8af97fa898ea80187704dfChet Haase assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS)); 137be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 138be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 139be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @SmallTest 140be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void testAutoCancelDelayed() throws Exception { 141be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final FutureWaiter future = new FutureWaiter(); 142be19e030a14c8e398e8af97fa898ea80187704dfChet Haase getActivity().runOnUiThread(new Runnable() { 143be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @Override 144be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void run() { 145be19e030a14c8e398e8af97fa898ea80187704dfChet Haase try { 146be19e030a14c8e398e8af97fa898ea80187704dfChet Haase setupAnimators(START_DELAY, false, future); 147be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } catch (Exception e) { 148be19e030a14c8e398e8af97fa898ea80187704dfChet Haase future.setException(e); 149be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 150be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 151be19e030a14c8e398e8af97fa898ea80187704dfChet Haase }); 152be19e030a14c8e398e8af97fa898ea80187704dfChet Haase assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS)); 153be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 154be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 155be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @SmallTest 156be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void testAutoCancelTestLater() throws Exception { 157be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final FutureWaiter future = new FutureWaiter(); 158be19e030a14c8e398e8af97fa898ea80187704dfChet Haase getActivity().runOnUiThread(new Runnable() { 159be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @Override 160be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void run() { 161be19e030a14c8e398e8af97fa898ea80187704dfChet Haase try { 162be19e030a14c8e398e8af97fa898ea80187704dfChet Haase setupAnimators(0, true, future); 163be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } catch (Exception e) { 164be19e030a14c8e398e8af97fa898ea80187704dfChet Haase future.setException(e); 165be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 166be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 167be19e030a14c8e398e8af97fa898ea80187704dfChet Haase }); 168be19e030a14c8e398e8af97fa898ea80187704dfChet Haase assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS)); 169be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 170be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 171be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @SmallTest 172be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void testAutoCancelDelayedTestLater() throws Exception { 173be19e030a14c8e398e8af97fa898ea80187704dfChet Haase final FutureWaiter future = new FutureWaiter(); 174be19e030a14c8e398e8af97fa898ea80187704dfChet Haase getActivity().runOnUiThread(new Runnable() { 175be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @Override 176be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void run() { 177be19e030a14c8e398e8af97fa898ea80187704dfChet Haase try { 178be19e030a14c8e398e8af97fa898ea80187704dfChet Haase setupAnimators(START_DELAY, true, future); 179be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } catch (Exception e) { 180be19e030a14c8e398e8af97fa898ea80187704dfChet Haase future.setException(e); 181be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 182be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 183be19e030a14c8e398e8af97fa898ea80187704dfChet Haase }); 184be19e030a14c8e398e8af97fa898ea80187704dfChet Haase assertTrue(future.get(FUTURE_TIMEOUT, TimeUnit.MILLISECONDS)); 185be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 186be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 187be19e030a14c8e398e8af97fa898ea80187704dfChet Haase private AnimatorListenerAdapter mCanceledListener = new AnimatorListenerAdapter() { 188be19e030a14c8e398e8af97fa898ea80187704dfChet Haase @Override 189be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void onAnimationCancel(Animator animation) { 190be19e030a14c8e398e8af97fa898ea80187704dfChet Haase mCanceledMap.put(animation, true); 191be19e030a14c8e398e8af97fa898ea80187704dfChet Haase } 192be19e030a14c8e398e8af97fa898ea80187704dfChet Haase }; 193be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 194be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void setX(float x) {} 195be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 196be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void setY(float y) {} 197be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 198be19e030a14c8e398e8af97fa898ea80187704dfChet Haase public void setZ(float z) {} 199be19e030a14c8e398e8af97fa898ea80187704dfChet Haase} 200be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 201be19e030a14c8e398e8af97fa898ea80187704dfChet Haase 202