1cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler/* 2cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * Copyright (C) 2016 The Android Open Source Project 3cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * 4cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * Licensed under the Apache License, Version 2.0 (the "License"); 5cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * you may not use this file except in compliance with the License. 6cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * You may obtain a copy of the License at 7cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * 8cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * http://www.apache.org/licenses/LICENSE-2.0 9cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * 10cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * Unless required by applicable law or agreed to in writing, software 11cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * distributed under the License is distributed on an "AS IS" BASIS, 12cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * See the License for the specific language governing permissions and 14cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler * limitations under the License 15cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler */ 16cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 17cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerpackage android.transition; 18cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 19cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport android.animation.AnimatorSetActivity; 20cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport android.app.Activity; 21cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport android.test.ActivityInstrumentationTestCase2; 22cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport android.test.suitebuilder.annotation.SmallTest; 23cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport android.view.Gravity; 24cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport android.view.View; 25cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport android.view.ViewGroup; 26cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport android.view.ViewTreeObserver; 27cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 28cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport com.android.frameworks.coretests.R; 29cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 30cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport java.util.concurrent.CountDownLatch; 31cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerimport java.util.concurrent.TimeUnit; 32cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 33cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 34cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantlerpublic class SlideTransitionTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> { 35cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 36cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler Activity mActivity; 37cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 38cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public SlideTransitionTest() { 39cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler super(AnimatorSetActivity.class); 40cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 41cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 42cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler @Override 43cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler protected void setUp() throws Exception { 44cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler mActivity = getActivity(); 45cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 46cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 47cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler @SmallTest 48cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public void testShortSlide() throws Throwable { 49cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final float slideFraction = 0.5f; 50cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final View square1 = mActivity.findViewById(R.id.square1); 51cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final View sceneRoot = mActivity.findViewById(R.id.container); 52cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final SlideTranslationValueRatchet ratchet = new SlideTranslationValueRatchet(square1); 53cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler square1.getViewTreeObserver().addOnPreDrawListener(ratchet); 54cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 55cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final Slide slideOut = new Slide(Gravity.BOTTOM); 56cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final float finalOffsetOut = sceneRoot.getHeight() * slideFraction; 57cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler slideOut.setSlideFraction(slideFraction); 58cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler TransitionLatch latch = setVisibilityInTransition(slideOut, R.id.square1, View.INVISIBLE); 59cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS)); 60cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertEquals(0f, square1.getTranslationY(), 0.1f); 61cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertEquals(View.VISIBLE, square1.getVisibility()); 62cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler Thread.sleep(100); 63cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertFalse(square1.getTranslationY() < 0.1 64cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler || square1.getTranslationY() > finalOffsetOut - 0.1); 65cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS)); 66cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler // Give this 20% slop in case some frames get dropped. 67cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertTrue(finalOffsetOut * 0.8 < ratchet.maxY); 68cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertTrue(finalOffsetOut + 0.1 > ratchet.maxY); 69cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertEquals(View.INVISIBLE, square1.getVisibility()); 70cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 71cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler ratchet.reset(); 72cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final Slide slideIn = new Slide(Gravity.BOTTOM); 73cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final float initialOffsetIn = sceneRoot.getHeight() * slideFraction; 74cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler slideIn.setSlideFraction(slideFraction); 75cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler latch = setVisibilityInTransition(slideIn, R.id.square1, View.VISIBLE); 76cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS)); 77cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertEquals(initialOffsetIn, square1.getTranslationY(), 0.1f); 78cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertEquals(View.VISIBLE, square1.getVisibility()); 79cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler Thread.sleep(100); 80cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertFalse(square1.getTranslationY() < 0.1 81cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler || square1.getTranslationY() > initialOffsetIn - 0.1); 82cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS)); 83cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertEquals(0f, ratchet.minY, 0.1); 84cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertEquals(0f, square1.getTranslationY(), 0.1); 85cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler assertEquals(View.VISIBLE, square1.getVisibility()); 86cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 87cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler square1.getViewTreeObserver().removeOnPreDrawListener(ratchet); 88cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 89cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 90cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public TransitionLatch setVisibilityInTransition(final Transition transition, int viewId, 91cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final int visibility) throws Throwable { 92cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final ViewGroup sceneRoot = (ViewGroup) mActivity.findViewById(R.id.container); 93cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler final View view = sceneRoot.findViewById(viewId); 94cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler TransitionLatch latch = new TransitionLatch(); 95cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler transition.addListener(latch); 96cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler runTestOnUiThread(new Runnable() { 97cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler @Override 98cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public void run() { 99cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler TransitionManager.beginDelayedTransition(sceneRoot, transition); 100cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler view.setVisibility(visibility); 101cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 102cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler }); 103cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler return latch; 104cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 105cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 106cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public static class TransitionLatch implements Transition.TransitionListener { 107cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public CountDownLatch startLatch = new CountDownLatch(1); 108cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public CountDownLatch endLatch = new CountDownLatch(1); 109cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public CountDownLatch cancelLatch = new CountDownLatch(1); 110cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public CountDownLatch pauseLatch = new CountDownLatch(1); 111cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public CountDownLatch resumeLatch = new CountDownLatch(1); 112cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 113cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler @Override 114cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public void onTransitionStart(Transition transition) { 115cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler startLatch.countDown(); 116cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 117cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 118cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler @Override 119cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public void onTransitionEnd(Transition transition) { 120cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler endLatch.countDown(); 121cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler transition.removeListener(this); 122cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 123cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 124cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler @Override 125cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public void onTransitionCancel(Transition transition) { 126cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler cancelLatch.countDown(); 127cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 128cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 129cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler @Override 130cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public void onTransitionPause(Transition transition) { 131cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler pauseLatch.countDown(); 132cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 133cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 134cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler @Override 135cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public void onTransitionResume(Transition transition) { 136cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler resumeLatch.countDown(); 137cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 138cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 139cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 140cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler private static class SlideTranslationValueRatchet 141cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler implements ViewTreeObserver.OnPreDrawListener { 142cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 143cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler private final View mView; 144cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler private boolean mInitialized; 145cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public float minX = Float.NaN; 146cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public float minY = Float.NaN; 147cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public float maxX = Float.NaN; 148cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public float maxY = Float.NaN; 149cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 150cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public SlideTranslationValueRatchet(View view) { 151cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler mView = view; 152cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 153cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 154cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public void reset() { 155cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler minX = minY = maxX = maxY = Float.NaN; 156cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler mInitialized = false; 157cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 158cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler 159cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler @Override 160cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler public boolean onPreDraw() { 161cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler if (!mInitialized) { 162cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler minX = maxX = mView.getTranslationX(); 163cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler minY = maxY = mView.getTranslationY(); 164cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler mInitialized = true; 165cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } else { 166cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler minX = Math.min(minX, mView.getTranslationX()); 167cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler minY = Math.min(minY, mView.getTranslationY()); 168cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler maxX = Math.max(maxX, mView.getTranslationX()); 169cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler maxY = Math.max(maxY, mView.getTranslationY()); 170cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 171cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler return true; 172cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 173cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler } 174cfa15bd1d532830954a5f9717c05e3fe19bc512aTony Mantler} 175