blob: 8b9ec74be8dfee73b688ad5193648a645a7b8a4f [file] [log] [blame]
/*
* Copyright (C) 2016 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;
import android.animation.AnimatorSetActivity;
import android.app.Activity;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import com.android.frameworks.coretests.R;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class SlideTransitionTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> {
Activity mActivity;
public SlideTransitionTest() {
super(AnimatorSetActivity.class);
}
@Override
protected void setUp() throws Exception {
mActivity = getActivity();
}
@SmallTest
public void testShortSlide() throws Throwable {
final float slideFraction = 0.5f;
final View square1 = mActivity.findViewById(R.id.square1);
final View sceneRoot = mActivity.findViewById(R.id.container);
final SlideTranslationValueRatchet ratchet = new SlideTranslationValueRatchet(square1);
square1.getViewTreeObserver().addOnPreDrawListener(ratchet);
final Slide slideOut = new Slide(Gravity.BOTTOM);
final float finalOffsetOut = sceneRoot.getHeight() * slideFraction;
slideOut.setSlideFraction(slideFraction);
TransitionLatch latch = setVisibilityInTransition(slideOut, R.id.square1, View.INVISIBLE);
assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
assertEquals(0f, square1.getTranslationY(), 0.1f);
assertEquals(View.VISIBLE, square1.getVisibility());
Thread.sleep(100);
assertFalse(square1.getTranslationY() < 0.1
|| square1.getTranslationY() > finalOffsetOut - 0.1);
assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
// Give this 20% slop in case some frames get dropped.
assertTrue(finalOffsetOut * 0.8 < ratchet.maxY);
assertTrue(finalOffsetOut + 0.1 > ratchet.maxY);
assertEquals(View.INVISIBLE, square1.getVisibility());
ratchet.reset();
final Slide slideIn = new Slide(Gravity.BOTTOM);
final float initialOffsetIn = sceneRoot.getHeight() * slideFraction;
slideIn.setSlideFraction(slideFraction);
latch = setVisibilityInTransition(slideIn, R.id.square1, View.VISIBLE);
assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
assertEquals(initialOffsetIn, square1.getTranslationY(), 0.1f);
assertEquals(View.VISIBLE, square1.getVisibility());
Thread.sleep(100);
assertFalse(square1.getTranslationY() < 0.1
|| square1.getTranslationY() > initialOffsetIn - 0.1);
assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
assertEquals(0f, ratchet.minY, 0.1);
assertEquals(0f, square1.getTranslationY(), 0.1);
assertEquals(View.VISIBLE, square1.getVisibility());
square1.getViewTreeObserver().removeOnPreDrawListener(ratchet);
}
public TransitionLatch setVisibilityInTransition(final Transition transition, int viewId,
final int visibility) throws Throwable {
final ViewGroup sceneRoot = (ViewGroup) mActivity.findViewById(R.id.container);
final View view = sceneRoot.findViewById(viewId);
TransitionLatch latch = new TransitionLatch();
transition.addListener(latch);
runTestOnUiThread(new Runnable() {
@Override
public void run() {
TransitionManager.beginDelayedTransition(sceneRoot, transition);
view.setVisibility(visibility);
}
});
return latch;
}
public static class TransitionLatch implements Transition.TransitionListener {
public CountDownLatch startLatch = new CountDownLatch(1);
public CountDownLatch endLatch = new CountDownLatch(1);
public CountDownLatch cancelLatch = new CountDownLatch(1);
public CountDownLatch pauseLatch = new CountDownLatch(1);
public CountDownLatch resumeLatch = new CountDownLatch(1);
@Override
public void onTransitionStart(Transition transition) {
startLatch.countDown();
}
@Override
public void onTransitionEnd(Transition transition) {
endLatch.countDown();
transition.removeListener(this);
}
@Override
public void onTransitionCancel(Transition transition) {
cancelLatch.countDown();
}
@Override
public void onTransitionPause(Transition transition) {
pauseLatch.countDown();
}
@Override
public void onTransitionResume(Transition transition) {
resumeLatch.countDown();
}
}
private static class SlideTranslationValueRatchet
implements ViewTreeObserver.OnPreDrawListener {
private final View mView;
private boolean mInitialized;
public float minX = Float.NaN;
public float minY = Float.NaN;
public float maxX = Float.NaN;
public float maxY = Float.NaN;
public SlideTranslationValueRatchet(View view) {
mView = view;
}
public void reset() {
minX = minY = maxX = maxY = Float.NaN;
mInitialized = false;
}
@Override
public boolean onPreDraw() {
if (!mInitialized) {
minX = maxX = mView.getTranslationX();
minY = maxY = mView.getTranslationY();
mInitialized = true;
} else {
minX = Math.min(minX, mView.getTranslationX());
minY = Math.min(minY, mView.getTranslationY());
maxX = Math.max(maxX, mView.getTranslationX());
maxY = Math.max(maxY, mView.getTranslationY());
}
return true;
}
}
}