1/* 2 * Copyright (C) 2016 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 17package android.support.transition; 18 19import static org.hamcrest.CoreMatchers.is; 20import static org.hamcrest.CoreMatchers.notNullValue; 21import static org.hamcrest.MatcherAssert.assertThat; 22import static org.hamcrest.Matchers.sameInstance; 23 24import android.support.test.InstrumentationRegistry; 25import android.support.test.annotation.UiThreadTest; 26import android.support.transition.test.R; 27import android.test.suitebuilder.annotation.MediumTest; 28import android.view.ViewGroup; 29 30import org.junit.Before; 31import org.junit.Test; 32 33import java.util.concurrent.CountDownLatch; 34import java.util.concurrent.TimeUnit; 35 36@MediumTest 37public class TransitionManagerTest extends BaseTest { 38 39 private Scene[] mScenes = new Scene[2]; 40 41 @Before 42 public void prepareScenes() { 43 TransitionActivity activity = rule.getActivity(); 44 ViewGroup root = activity.getRoot(); 45 mScenes[0] = Scene.getSceneForLayout(root, R.layout.scene0, activity); 46 mScenes[1] = Scene.getSceneForLayout(root, R.layout.scene1, activity); 47 } 48 49 @Test 50 public void testSetup() { 51 assertThat(mScenes[0], is(notNullValue())); 52 assertThat(mScenes[1], is(notNullValue())); 53 } 54 55 @Test 56 @UiThreadTest 57 public void testGo_enterAction() { 58 CheckCalledRunnable runnable = new CheckCalledRunnable(); 59 mScenes[0].setEnterAction(runnable); 60 assertThat(runnable.wasCalled(), is(false)); 61 TransitionManager.go(mScenes[0]); 62 assertThat(runnable.wasCalled(), is(true)); 63 } 64 65 @Test 66 public void testGo_exitAction() { 67 final CheckCalledRunnable enter = new CheckCalledRunnable(); 68 final CheckCalledRunnable exit = new CheckCalledRunnable(); 69 mScenes[0].setEnterAction(enter); 70 mScenes[0].setExitAction(exit); 71 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 72 @Override 73 public void run() { 74 assertThat(enter.wasCalled(), is(false)); 75 assertThat(exit.wasCalled(), is(false)); 76 TransitionManager.go(mScenes[0]); 77 assertThat(enter.wasCalled(), is(true)); 78 assertThat(exit.wasCalled(), is(false)); 79 } 80 }); 81 // Let the main thread catch up with the scene change 82 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 83 @Override 84 public void run() { 85 TransitionManager.go(mScenes[1]); 86 assertThat(exit.wasCalled(), is(true)); 87 } 88 }); 89 } 90 91 @Test 92 public void testGo_transitionListenerStart() { 93 final SyncTransitionListener listener 94 = new SyncTransitionListener(SyncTransitionListener.EVENT_START); 95 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 96 @Override 97 public void run() { 98 Transition transition = new AutoTransition(); 99 transition.setDuration(0); 100 assertThat(transition.addListener(listener), is(sameInstance(transition))); 101 TransitionManager.go(mScenes[0], transition); 102 } 103 }); 104 assertThat("Timed out waiting for the TransitionListener", 105 listener.await(), is(true)); 106 } 107 108 @Test 109 public void testGo_transitionListenerEnd() { 110 final SyncTransitionListener listener 111 = new SyncTransitionListener(SyncTransitionListener.EVENT_END); 112 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 113 @Override 114 public void run() { 115 Transition transition = new AutoTransition(); 116 transition.setDuration(0); 117 assertThat(transition.addListener(listener), is(sameInstance(transition))); 118 TransitionManager.go(mScenes[0], transition); 119 } 120 }); 121 assertThat("Timed out waiting for the TransitionListener", 122 listener.await(), is(true)); 123 } 124 125 /** 126 * This {@link Transition.TransitionListener} synchronously waits for the specified callback. 127 */ 128 private static class SyncTransitionListener implements Transition.TransitionListener { 129 130 static final int EVENT_START = 1; 131 static final int EVENT_END = 2; 132 static final int EVENT_CANCEL = 3; 133 static final int EVENT_PAUSE = 4; 134 static final int EVENT_RESUME = 5; 135 136 private final int mTargetEvent; 137 private final CountDownLatch mLatch = new CountDownLatch(1); 138 139 SyncTransitionListener(int event) { 140 mTargetEvent = event; 141 } 142 143 boolean await() { 144 try { 145 return mLatch.await(3000, TimeUnit.MILLISECONDS); 146 } catch (InterruptedException e) { 147 return false; 148 } 149 } 150 151 @Override 152 public void onTransitionStart(Transition transition) { 153 if (mTargetEvent == EVENT_START) { 154 mLatch.countDown(); 155 } 156 } 157 158 @Override 159 public void onTransitionEnd(Transition transition) { 160 if (mTargetEvent == EVENT_END) { 161 mLatch.countDown(); 162 } 163 } 164 165 @Override 166 public void onTransitionCancel(Transition transition) { 167 if (mTargetEvent == EVENT_CANCEL) { 168 mLatch.countDown(); 169 } 170 } 171 172 @Override 173 public void onTransitionPause(Transition transition) { 174 if (mTargetEvent == EVENT_PAUSE) { 175 mLatch.countDown(); 176 } 177 } 178 179 @Override 180 public void onTransitionResume(Transition transition) { 181 if (mTargetEvent == EVENT_RESUME) { 182 mLatch.countDown(); 183 } 184 } 185 } 186 187} 188