Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2015 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 package android.transition.cts;
     17 
     18 import static com.android.compatibility.common.util.CtsMockitoUtils.within;
     19 
     20 import static org.mockito.Matchers.any;
     21 import static org.mockito.Mockito.mock;
     22 import static org.mockito.Mockito.times;
     23 import static org.mockito.Mockito.verify;
     24 
     25 import android.animation.Animator;
     26 import android.animation.ObjectAnimator;
     27 import android.app.Instrumentation;
     28 import android.support.test.InstrumentationRegistry;
     29 import android.support.test.rule.ActivityTestRule;
     30 import android.transition.Scene;
     31 import android.transition.Transition;
     32 import android.transition.TransitionManager;
     33 import android.transition.TransitionValues;
     34 import android.transition.Visibility;
     35 import android.view.View;
     36 import android.view.ViewGroup;
     37 import android.widget.FrameLayout;
     38 
     39 import com.android.compatibility.common.util.WidgetTestUtils;
     40 
     41 import org.junit.Before;
     42 import org.junit.Rule;
     43 
     44 import java.util.ArrayList;
     45 
     46 public abstract class BaseTransitionTest {
     47     protected Instrumentation mInstrumentation;
     48     protected TransitionActivity mActivity;
     49     protected FrameLayout mSceneRoot;
     50     private float mAnimatedValue;
     51     protected ArrayList<View> mTargets = new ArrayList<>();
     52     protected Transition mTransition;
     53     protected Transition.TransitionListener mListener;
     54 
     55     @Rule
     56     public ActivityTestRule<TransitionActivity> mActivityRule =
     57             new ActivityTestRule<>(TransitionActivity.class);
     58 
     59     @Before
     60     public void setup() {
     61         mInstrumentation = InstrumentationRegistry.getInstrumentation();
     62         mInstrumentation.setInTouchMode(false);
     63         mActivity = mActivityRule.getActivity();
     64         mSceneRoot = (FrameLayout) mActivity.findViewById(R.id.container);
     65         mTargets.clear();
     66         mTransition = new TestTransition();
     67         mListener = mock(Transition.TransitionListener.class);
     68         mTransition.addListener(mListener);
     69     }
     70 
     71     protected void waitForStart() throws InterruptedException {
     72         waitForStart(mListener);
     73     }
     74 
     75     protected static void waitForStart(Transition.TransitionListener listener) {
     76         verify(listener, within(4000)).onTransitionStart(any());
     77     }
     78 
     79     protected void waitForEnd(long waitMillis) {
     80         waitForEnd(mListener, waitMillis);
     81         mInstrumentation.waitForIdleSync();
     82     }
     83 
     84     protected static void waitForEnd(Transition.TransitionListener listener, long waitMillis) {
     85         if (waitMillis == 0) {
     86             verify(listener, times(1)).onTransitionEnd(any());
     87         } else {
     88             verify(listener, within(waitMillis)).onTransitionEnd(any());
     89         }
     90     }
     91 
     92     protected View loadLayout(final int layout) throws Throwable {
     93         View[] root = new View[1];
     94 
     95         mActivityRule.runOnUiThread(
     96                 () -> root[0] = mActivity.getLayoutInflater().inflate(layout, mSceneRoot, false));
     97 
     98         return root[0];
     99     }
    100 
    101     protected Scene loadScene(final View layout) throws Throwable {
    102         final Scene[] scene = new Scene[1];
    103         mActivityRule.runOnUiThread(() -> scene[0] = new Scene(mSceneRoot, layout));
    104 
    105         return scene[0];
    106     }
    107 
    108     protected Scene loadScene(final int layoutId) throws Throwable {
    109         final Scene scene[] = new Scene[1];
    110         mActivityRule.runOnUiThread(
    111                 () -> scene[0] = Scene.getSceneForLayout(mSceneRoot, layoutId, mActivity));
    112         return scene[0];
    113     }
    114 
    115     protected void startTransition(final int layoutId) throws Throwable {
    116         startTransition(loadScene(layoutId));
    117     }
    118 
    119     protected void startTransition(final Scene scene) throws Throwable {
    120         mActivityRule.runOnUiThread(() -> TransitionManager.go(scene, mTransition));
    121         waitForStart();
    122     }
    123 
    124     protected void endTransition() throws Throwable {
    125         mActivityRule.runOnUiThread(() -> TransitionManager.endTransitions(mSceneRoot));
    126     }
    127 
    128     protected void enterScene(final int layoutId) throws Throwable {
    129         enterScene(loadScene(layoutId));
    130     }
    131 
    132     protected void enterScene(final Scene scene) throws Throwable {
    133         WidgetTestUtils.runOnMainAndLayoutSync(mActivityRule, scene::enter, false);
    134     }
    135 
    136     protected void exitScene(final Scene scene) throws Throwable {
    137         mActivityRule.runOnUiThread(scene::exit);
    138         mInstrumentation.waitForIdleSync();
    139     }
    140 
    141     protected void resetListener() {
    142         mTransition.removeListener(mListener);
    143         mListener = mock(Transition.TransitionListener.class);
    144         mTransition.addListener(mListener);
    145     }
    146 
    147     public void setAnimatedValue(float animatedValue) {
    148         mAnimatedValue = animatedValue;
    149     }
    150 
    151     public class TestTransition extends Visibility {
    152 
    153         public TestTransition() {
    154         }
    155 
    156         @Override
    157         public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
    158                 TransitionValues endValues) {
    159             mTargets.add(endValues.view);
    160             return ObjectAnimator.ofFloat(BaseTransitionTest.this, "animatedValue", 0, 1);
    161         }
    162 
    163         @Override
    164         public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
    165                 TransitionValues endValues) {
    166             mTargets.add(startValues.view);
    167             return ObjectAnimator.ofFloat(BaseTransitionTest.this, "animatedValue", 1, 0);
    168         }
    169     }
    170 }
    171