1f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki/*
2f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki * Copyright (C) 2016 The Android Open Source Project
3f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki *
4f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki * Licensed under the Apache License, Version 2.0 (the "License");
5f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki * you may not use this file except in compliance with the License.
6f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki * You may obtain a copy of the License at
7f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki *
8f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki *      http://www.apache.org/licenses/LICENSE-2.0
9f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki *
10f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki * Unless required by applicable law or agreed to in writing, software
11f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki * distributed under the License is distributed on an "AS IS" BASIS,
12f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki * See the License for the specific language governing permissions and
14f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki * limitations under the License.
15f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki */
16f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
17f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakipackage android.support.transition;
18f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
19f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport static org.hamcrest.core.Is.is;
20f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport static org.junit.Assert.assertThat;
21f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport static org.junit.Assert.fail;
22f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
23f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport android.graphics.Color;
24f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport android.support.test.annotation.UiThreadTest;
25f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport android.support.test.filters.MediumTest;
26f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport android.view.View;
27f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport android.widget.LinearLayout;
28f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
29f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport org.junit.Before;
30f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakiimport org.junit.Test;
31f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
32f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki@MediumTest
33f43e000b40282b9c270afb427a4e181526452f0aYuichi Arakipublic class AutoTransitionTest extends BaseTest {
34f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
35f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    private LinearLayout mRoot;
36f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    private View mView0;
37f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    private View mView1;
38f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
39f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    @UiThreadTest
40f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    @Before
41f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    public void setUp() {
42f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        mRoot = (LinearLayout) rule.getActivity().getRoot();
43f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        mView0 = new View(rule.getActivity());
44f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        mView0.setBackgroundColor(Color.RED);
45f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        mRoot.addView(mView0, new LinearLayout.LayoutParams(100, 100));
46f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        mView1 = new View(rule.getActivity());
47f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        mView1.setBackgroundColor(Color.BLUE);
48f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        mRoot.addView(mView1, new LinearLayout.LayoutParams(100, 100));
49f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    }
50f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
51f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    @Test
52f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    public void testLayoutBetweenFadeAndChangeBounds() throws Throwable {
53f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        final LayoutCounter counter = new LayoutCounter();
54f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        rule.runOnUiThread(new Runnable() {
55f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            @Override
56f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            public void run() {
57f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                assertThat(mView1.getY(), is(100.f));
58f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                assertThat(mView0.getVisibility(), is(View.VISIBLE));
59f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                mView1.addOnLayoutChangeListener(counter);
60f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            }
61f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        });
62f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        final SyncTransitionListener listener = new SyncTransitionListener(
63f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                SyncTransitionListener.EVENT_END);
64f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        final Transition transition = new AutoTransition();
65f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        transition.addListener(listener);
66f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        rule.runOnUiThread(new Runnable() {
67f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            @Override
68f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            public void run() {
69f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                TransitionManager.beginDelayedTransition(mRoot, transition);
70f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                // This makes view0 fade out and causes view1 to move upwards.
71f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                mView0.setVisibility(View.GONE);
72f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            }
73f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        });
74f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        assertThat("Timed out waiting for the TransitionListener",
75f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                listener.await(), is(true));
76f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        assertThat(mView1.getY(), is(0.f));
77f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        assertThat(mView0.getVisibility(), is(View.GONE));
78f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        counter.reset();
79f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        listener.reset();
80f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        rule.runOnUiThread(new Runnable() {
81f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            @Override
82f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            public void run() {
83f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                TransitionManager.beginDelayedTransition(mRoot, transition);
84f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                // Revert
85f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                mView0.setVisibility(View.VISIBLE);
86f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            }
87f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        });
88f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        assertThat("Timed out waiting for the TransitionListener",
89f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                listener.await(), is(true));
90f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        assertThat(mView1.getY(), is(100.f));
91f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        assertThat(mView0.getVisibility(), is(View.VISIBLE));
92f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    }
93f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
94f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    private static class LayoutCounter implements View.OnLayoutChangeListener {
95f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
96f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        private int mCalledCount;
97f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
98f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        @Override
99f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        public void onLayoutChange(View v, int left, int top, int right, int bottom,
100f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                int oldLeft, int oldTop, int oldRight, int oldBottom) {
101f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            mCalledCount++;
102f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            // There should not be more than one layout request to view1.
103f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            if (mCalledCount > 1) {
104f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki                fail("View layout happened too many times");
105f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            }
106f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        }
107f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
108f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        void reset() {
109f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki            mCalledCount = 0;
110f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki        }
111f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
112f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki    }
113f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki
114f43e000b40282b9c270afb427a4e181526452f0aYuichi Araki}
115