Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7eacd5c0 authored by George Mount's avatar George Mount Committed by Android (Google) Code Review
Browse files

Merge "Fix Fade transition interrupt."

parents 6f639741 3cf9fa3d
Loading
Loading
Loading
Loading
+21 −16
Original line number Diff line number Diff line
@@ -57,9 +57,9 @@ import android.view.ViewGroup;
 * tag <code>fade</code>, along with the standard
 * attributes of {@link android.R.styleable#Fade} and
 * {@link android.R.styleable#Transition}.</p>

 */
public class Fade extends Visibility {
    static final String PROPNAME_TRANSITION_ALPHA = "android:fade:transitionAlpha";

    private static boolean DBG = Transition.DBG && false;

@@ -105,6 +105,13 @@ public class Fade extends Visibility {
        setMode(fadingMode);
    }

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        super.captureStartValues(transitionValues);
        transitionValues.values.put(PROPNAME_TRANSITION_ALPHA,
                transitionValues.view.getTransitionAlpha());
    }

    /**
     * Utility method to handle creating and running the Animator.
     */
@@ -119,7 +126,6 @@ public class Fade extends Visibility {
        }
        final FadeAnimatorListener listener = new FadeAnimatorListener(view);
        anim.addListener(listener);
        anim.addPauseListener(listener);
        addListener(new TransitionListenerAdapter() {
            @Override
            public void onTransitionEnd(Transition transition) {
@@ -138,18 +144,28 @@ public class Fade extends Visibility {
            Log.d(LOG_TAG, "Fade.onAppear: startView, startVis, endView, endVis = " +
                    startView + ", " + view);
        }
        return createAnimation(view, 0, 1);
        float startAlpha = 0;
        if (startValues != null) {
            startAlpha = (Float) startValues.values.get(PROPNAME_TRANSITION_ALPHA);
            if (startAlpha == 1) {
                startAlpha = 0;
            }
        }
        return createAnimation(view, startAlpha, 1);
    }

    @Override
    public Animator onDisappear(ViewGroup sceneRoot, final View view, TransitionValues startValues,
            TransitionValues endValues) {
        return createAnimation(view, 1, 0);
        float startAlpha = 1;
        if (startValues != null) {
            startAlpha = (Float) startValues.values.get(PROPNAME_TRANSITION_ALPHA);
        }
        return createAnimation(view, startAlpha, 0);
    }

    private static class FadeAnimatorListener extends AnimatorListenerAdapter {
        private final View mView;
        private float mPausedAlpha = -1;
        private boolean mLayerTypeChanged = false;

        public FadeAnimatorListener(View view) {
@@ -171,16 +187,5 @@ public class Fade extends Visibility {
                mView.setLayerType(View.LAYER_TYPE_NONE, null);
            }
        }

        @Override
        public void onAnimationPause(Animator animator) {
            mPausedAlpha = mView.getTransitionAlpha();
            mView.setTransitionAlpha(1);
        }

        @Override
        public void onAnimationResume(Animator animator) {
            mView.setTransitionAlpha(mPausedAlpha);
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -4,7 +4,8 @@
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/white"
    android:orientation="horizontal">
    android:orientation="horizontal"
    android:id="@+id/container">
    <View
        android:layout_width="50dp"
        android:layout_height="50dp"
+200 −0
Original line number Diff line number Diff line
/*
 * 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.transition.Transition.TransitionListener;
import android.transition.Transition.TransitionListenerAdapter;
import android.view.View;
import android.view.ViewGroup;

import com.android.frameworks.coretests.R;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static android.support.test.espresso.Espresso.onView;

public class FadeTransitionTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> {
    Activity mActivity;
    public FadeTransitionTest() {
        super(AnimatorSetActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        mActivity = getActivity();
    }

    @SmallTest
    public void testFadeOutAndIn() throws Throwable {
        View square1 = mActivity.findViewById(R.id.square1);
        Fade fadeOut = new Fade(Fade.MODE_OUT);
        TransitionLatch latch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
        assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
        assertEquals(View.VISIBLE, square1.getVisibility());
        Thread.sleep(100);
        assertFalse(square1.getTransitionAlpha() == 0 || square1.getTransitionAlpha() == 1);
        assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
        assertEquals(1.0f, square1.getTransitionAlpha());
        assertEquals(View.INVISIBLE, square1.getVisibility());

        Fade fadeIn = new Fade(Fade.MODE_IN);
        latch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
        assertTrue(latch.startLatch.await(200, TimeUnit.MILLISECONDS));
        assertEquals(View.VISIBLE, square1.getVisibility());
        Thread.sleep(100);
        final float transitionAlpha = square1.getTransitionAlpha();
        assertTrue("expecting transitionAlpha to be between 0 and 1. Was " + transitionAlpha,
                transitionAlpha > 0 && transitionAlpha < 1);
        assertTrue(latch.endLatch.await(400, TimeUnit.MILLISECONDS));
        assertEquals(1.0f, square1.getTransitionAlpha());
        assertEquals(View.VISIBLE, square1.getVisibility());
    }

    @SmallTest
    public void testFadeOutInterrupt() throws Throwable {
        View square1 = mActivity.findViewById(R.id.square1);
        Fade fadeOut = new Fade(Fade.MODE_OUT);
        FadeValueCheck fadeOutValueCheck = new FadeValueCheck(square1);
        fadeOut.addListener(fadeOutValueCheck);
        TransitionLatch outLatch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
        assertTrue(outLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
        Thread.sleep(100);

        Fade fadeIn = new Fade(Fade.MODE_IN);
        FadeValueCheck fadeInValueCheck = new FadeValueCheck(square1);
        fadeIn.addListener(fadeInValueCheck);
        TransitionLatch inLatch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
        assertTrue(inLatch.startLatch.await(200, TimeUnit.MILLISECONDS));

        assertEquals(fadeOutValueCheck.pauseTransitionAlpha, fadeInValueCheck.startTransitionAlpha);
        assertTrue("expecting transitionAlpha to be between 0 and 1. Was " +
                fadeOutValueCheck.pauseTransitionAlpha,
                fadeOutValueCheck.pauseTransitionAlpha > 0 &&
                        fadeOutValueCheck.pauseTransitionAlpha < 1);

        assertTrue(inLatch.endLatch.await(400, TimeUnit.MILLISECONDS));
        assertEquals(1.0f, square1.getTransitionAlpha());
        assertEquals(View.VISIBLE, square1.getVisibility());
    }

    @SmallTest
    public void testFadeInInterrupt() throws Throwable {
        final View square1 = mActivity.findViewById(R.id.square1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                square1.setVisibility(View.INVISIBLE);
            }
        });
        Fade fadeIn = new Fade(Fade.MODE_IN);
        FadeValueCheck fadeInValueCheck = new FadeValueCheck(square1);
        fadeIn.addListener(fadeInValueCheck);
        TransitionLatch inLatch = setVisibilityInTransition(fadeIn, R.id.square1, View.VISIBLE);
        assertTrue(inLatch.startLatch.await(200, TimeUnit.MILLISECONDS));
        Thread.sleep(100);

        Fade fadeOut = new Fade(Fade.MODE_OUT);
        FadeValueCheck fadeOutValueCheck = new FadeValueCheck(square1);
        fadeOut.addListener(fadeOutValueCheck);
        TransitionLatch outLatch = setVisibilityInTransition(fadeOut, R.id.square1, View.INVISIBLE);
        assertTrue(outLatch.startLatch.await(200, TimeUnit.MILLISECONDS));

        assertEquals(fadeOutValueCheck.pauseTransitionAlpha, fadeInValueCheck.startTransitionAlpha);
        assertTrue("expecting transitionAlpha to be between 0 and 1. Was " +
                        fadeInValueCheck.pauseTransitionAlpha,
                fadeInValueCheck.pauseTransitionAlpha > 0 &&
                        fadeInValueCheck.pauseTransitionAlpha < 1);

        assertTrue(outLatch.endLatch.await(400, TimeUnit.MILLISECONDS));
        assertEquals(1.0f, square1.getTransitionAlpha());
        assertEquals(View.INVISIBLE, square1.getVisibility());
    }

    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 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 FadeValueCheck extends TransitionListenerAdapter {
        public float startTransitionAlpha;
        public float pauseTransitionAlpha;
        private final View mView;

        public FadeValueCheck(View view) {
            mView = view;
        }
        @Override
        public void onTransitionStart(Transition transition) {
            startTransitionAlpha = mView.getTransitionAlpha();
        }

        @Override
        public void onTransitionPause(Transition transition) {
            pauseTransitionAlpha = mView.getTransitionAlpha();
        }
    }
}