| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package android.transition.cts; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.mockito.Matchers.any; |
| import static org.mockito.Mockito.never; |
| import static org.mockito.Mockito.reset; |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| |
| import android.graphics.Rect; |
| import android.os.SystemClock; |
| import android.transition.Scene; |
| import android.transition.Transition; |
| import android.transition.TransitionManager; |
| import android.view.View; |
| import android.view.ViewTreeObserver; |
| |
| import androidx.test.filters.MediumTest; |
| import androidx.test.runner.AndroidJUnit4; |
| |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.mockito.ArgumentCaptor; |
| |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| |
| @MediumTest |
| @RunWith(AndroidJUnit4.class) |
| public class TransitionManagerTest extends BaseTransitionTest { |
| @Test |
| public void testBeginDelayedTransition() throws Throwable { |
| mActivityRule.runOnUiThread(() -> { |
| TransitionManager.beginDelayedTransition(mSceneRoot, mTransition); |
| View view = mActivity.getLayoutInflater().inflate(R.layout.scene1, mSceneRoot, |
| false); |
| mSceneRoot.addView(view); |
| }); |
| |
| waitForStart(); |
| waitForEnd(800); |
| verify(mListener, never()).onTransitionResume(any()); |
| verify(mListener, never()).onTransitionPause(any()); |
| verify(mListener, never()).onTransitionCancel(any()); |
| ArgumentCaptor<Transition> transitionArgumentCaptor = |
| ArgumentCaptor.forClass(Transition.class); |
| verify(mListener, times(1)).onTransitionStart(transitionArgumentCaptor.capture()); |
| assertEquals(TestTransition.class, transitionArgumentCaptor.getValue().getClass()); |
| assertTrue(mTransition != transitionArgumentCaptor.getValue()); |
| mActivityRule.runOnUiThread(() -> { |
| assertNotNull(mActivity.findViewById(R.id.redSquare)); |
| assertNotNull(mActivity.findViewById(R.id.greenSquare)); |
| }); |
| } |
| |
| @Test |
| public void testDefaultBeginDelayedTransition() throws Throwable { |
| enterScene(R.layout.scene1); |
| final CountDownLatch startLatch = new CountDownLatch(1); |
| final Scene scene6 = loadScene(R.layout.scene6); |
| mActivityRule.runOnUiThread(() -> { |
| mSceneRoot.getViewTreeObserver().addOnPreDrawListener( |
| new ViewTreeObserver.OnPreDrawListener() { |
| @Override |
| public boolean onPreDraw() { |
| mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this); |
| startLatch.countDown(); |
| return true; |
| } |
| }); |
| TransitionManager.beginDelayedTransition(mSceneRoot); |
| scene6.enter(); |
| }); |
| assertTrue(startLatch.await(500, TimeUnit.MILLISECONDS)); |
| ensureRedSquareIsMoving(); |
| endTransition(); |
| } |
| |
| private void ensureRedSquareIsMoving() throws InterruptedException { |
| final View view = mActivity.findViewById(R.id.redSquare); |
| assertNotNull(view); |
| // We should see a ChangeBounds on redSquare |
| final Rect position = new Rect(view.getLeft(), view.getTop(), view.getRight(), |
| view.getBottom()); |
| |
| final CountDownLatch latch = new CountDownLatch(1); |
| final Rect[] nextArr = new Rect[1]; |
| view.postOnAnimation(new Runnable() { |
| // Wait at most 10 frames for the position to change |
| int mFramesToChange = 10; |
| |
| @Override |
| public void run() { |
| nextArr[0] = new Rect(view.getLeft(), view.getTop(), view.getRight(), |
| view.getBottom()); |
| mFramesToChange--; |
| if (nextArr[0].equals(position) && mFramesToChange > 0) { |
| view.postOnAnimation(this); |
| } else { |
| latch.countDown(); |
| } |
| } |
| }); |
| assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); |
| assertNotEquals(position, nextArr[0]); |
| } |
| |
| @Test |
| public void testGo() throws Throwable { |
| startTransition(R.layout.scene1); |
| waitForStart(); |
| waitForEnd(800); |
| |
| verify(mListener, never()).onTransitionResume(any()); |
| verify(mListener, never()).onTransitionPause(any()); |
| verify(mListener, never()).onTransitionCancel(any()); |
| ArgumentCaptor<Transition> transitionArgumentCaptor = |
| ArgumentCaptor.forClass(Transition.class); |
| verify(mListener, times(1)).onTransitionStart(transitionArgumentCaptor.capture()); |
| assertEquals(TestTransition.class, transitionArgumentCaptor.getValue().getClass()); |
| assertTrue(mTransition != transitionArgumentCaptor.getValue()); |
| mActivityRule.runOnUiThread(() -> { |
| assertNotNull(mActivity.findViewById(R.id.redSquare)); |
| assertNotNull(mActivity.findViewById(R.id.greenSquare)); |
| }); |
| } |
| |
| @Test |
| public void testDefaultGo() throws Throwable { |
| enterScene(R.layout.scene1); |
| final CountDownLatch startLatch = new CountDownLatch(1); |
| final Scene scene6 = loadScene(R.layout.scene6); |
| mActivityRule.runOnUiThread(() -> { |
| mSceneRoot.getViewTreeObserver().addOnPreDrawListener( |
| new ViewTreeObserver.OnPreDrawListener() { |
| @Override |
| public boolean onPreDraw() { |
| mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this); |
| startLatch.countDown(); |
| return true; |
| } |
| }); |
| TransitionManager.go(scene6); |
| }); |
| assertTrue(startLatch.await(500, TimeUnit.MILLISECONDS)); |
| ensureRedSquareIsMoving(); |
| endTransition(); |
| } |
| |
| @Test |
| public void testSetTransition1() throws Throwable { |
| final TransitionManager transitionManager = new TransitionManager(); |
| |
| mActivityRule.runOnUiThread(() -> { |
| Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, mActivity); |
| transitionManager.setTransition(scene, mTransition); |
| transitionManager.transitionTo(scene); |
| }); |
| |
| waitForStart(); |
| waitForEnd(800); |
| verify(mListener, never()).onTransitionResume(any()); |
| verify(mListener, never()).onTransitionPause(any()); |
| verify(mListener, never()).onTransitionCancel(any()); |
| ArgumentCaptor<Transition> transitionArgumentCaptor = |
| ArgumentCaptor.forClass(Transition.class); |
| verify(mListener, times(1)).onTransitionStart(transitionArgumentCaptor.capture()); |
| assertEquals(TestTransition.class, transitionArgumentCaptor.getValue().getClass()); |
| assertTrue(mTransition != transitionArgumentCaptor.getValue()); |
| mActivityRule.runOnUiThread(() -> { |
| reset(mListener); |
| assertNotNull(mActivity.findViewById(R.id.redSquare)); |
| assertNotNull(mActivity.findViewById(R.id.greenSquare)); |
| Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity); |
| transitionManager.transitionTo(scene); |
| }); |
| SystemClock.sleep(50); |
| verify(mListener, never()).onTransitionStart(any()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testSetTransition2() throws Throwable { |
| final TransitionManager transitionManager = new TransitionManager(); |
| final Scene[] scenes = new Scene[3]; |
| |
| mActivityRule.runOnUiThread(() -> { |
| scenes[0] = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, mActivity); |
| scenes[1] = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity); |
| scenes[2] = Scene.getSceneForLayout(mSceneRoot, R.layout.scene3, mActivity); |
| transitionManager.setTransition(scenes[0], scenes[1], mTransition); |
| transitionManager.transitionTo(scenes[0]); |
| }); |
| SystemClock.sleep(100); |
| verify(mListener, never()).onTransitionStart(any()); |
| |
| mActivityRule.runOnUiThread(() -> transitionManager.transitionTo(scenes[1])); |
| |
| waitForStart(); |
| waitForEnd(800); |
| verify(mListener, never()).onTransitionResume(any()); |
| verify(mListener, never()).onTransitionPause(any()); |
| verify(mListener, never()).onTransitionCancel(any()); |
| ArgumentCaptor<Transition> transitionArgumentCaptor = |
| ArgumentCaptor.forClass(Transition.class); |
| verify(mListener, times(1)).onTransitionStart(transitionArgumentCaptor.capture()); |
| assertEquals(TestTransition.class, transitionArgumentCaptor.getValue().getClass()); |
| assertTrue(mTransition != transitionArgumentCaptor.getValue()); |
| mActivityRule.runOnUiThread(() -> { |
| reset(mListener); |
| transitionManager.transitionTo(scenes[2]); |
| }); |
| SystemClock.sleep(50); |
| verify(mListener, never()).onTransitionStart(any()); |
| endTransition(); |
| } |
| |
| @Test |
| public void testEndTransitions() throws Throwable { |
| mTransition.setDuration(400); |
| |
| startTransition(R.layout.scene1); |
| waitForStart(); |
| endTransition(); |
| waitForEnd(400); |
| } |
| |
| @Test |
| public void testEndTransitionsBeforeStarted() throws Throwable { |
| mTransition.setDuration(400); |
| |
| mActivityRule.runOnUiThread(() -> { |
| Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, mActivity); |
| TransitionManager.go(scene, mTransition); |
| TransitionManager.endTransitions(mSceneRoot); |
| }); |
| SystemClock.sleep(100); |
| verify(mListener, never()).onTransitionStart(any()); |
| SystemClock.sleep(10); |
| verify(mListener, never()).onTransitionEnd(any()); |
| } |
| } |
| |