1/*
2 * Copyright (C) 2017 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
17package androidx.wear.widget;
18
19import static org.junit.Assert.assertEquals;
20
21import android.app.Activity;
22import android.support.test.InstrumentationRegistry;
23import android.support.test.filters.MediumTest;
24import android.support.test.rule.ActivityTestRule;
25import android.support.test.runner.AndroidJUnit4;
26import android.view.View;
27import android.widget.FrameLayout;
28
29import androidx.wear.test.R;
30import androidx.wear.widget.util.WakeLockRule;
31
32import org.junit.Before;
33import org.junit.Rule;
34import org.junit.Test;
35import org.junit.runner.RunWith;
36
37import java.util.concurrent.atomic.AtomicReference;
38
39@MediumTest
40@RunWith(AndroidJUnit4.class)
41public class WearableLinearLayoutManagerTest {
42
43    @Rule
44    public final WakeLockRule wakeLock = new WakeLockRule();
45
46    @Rule
47    public final ActivityTestRule<WearableRecyclerViewTestActivity> mActivityRule =
48            new ActivityTestRule<>(WearableRecyclerViewTestActivity.class, true, true);
49
50    WearableLinearLayoutManager mWearableLinearLayoutManagerUnderTest;
51
52    @Before
53    public void setUp() throws Throwable {
54        Activity activity = mActivityRule.getActivity();
55        CurvingLayoutCallback mCurvingCallback = new CurvingLayoutCallback(activity);
56        mCurvingCallback.setOffset(10);
57        mWearableLinearLayoutManagerUnderTest =
58                new WearableLinearLayoutManager(mActivityRule.getActivity(), mCurvingCallback);
59    }
60
61    @Test
62    public void testRoundOffsetting() throws Throwable {
63        ((CurvingLayoutCallback) mWearableLinearLayoutManagerUnderTest.getLayoutCallback())
64                .setRound(true);
65        final AtomicReference<WearableRecyclerView> wrvReference = new AtomicReference<>();
66        mActivityRule.runOnUiThread(new Runnable() {
67            @Override
68            public void run() {
69                WearableRecyclerView wrv =
70                        (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
71                // Set a fixed layout so that the test adapts to different device screens.
72                wrv.setLayoutParams(new FrameLayout.LayoutParams(390, 390));
73            }
74        });
75
76        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
77
78        mActivityRule.runOnUiThread(new Runnable() {
79            @Override
80            public void run() {
81                WearableRecyclerView wrv =
82                        (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
83                wrv.setLayoutManager(mWearableLinearLayoutManagerUnderTest);
84                wrvReference.set(wrv);
85            }
86        });
87
88        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
89        WearableRecyclerView wrv = wrvReference.get();
90
91        View child1 = wrv.getChildAt(0);
92        View child2 = wrv.getChildAt(1);
93        View child3 = wrv.getChildAt(2);
94        View child4 = wrv.getChildAt(3);
95        View child5 = wrv.getChildAt(4);
96
97        // The left position and the translation of the child is modified if the screen is round.
98        // Check if the 5th child is not null as some devices will not be able to display 5 views.
99        assertEquals(136, child1.getLeft());
100        assertEquals(-6.3, child1.getTranslationY(), 0.1);
101
102        assertEquals(91, child2.getLeft(), 1);
103        assertEquals(-15.21, child2.getTranslationY(), 0.1);
104
105        assertEquals(58, child3.getLeft(), 1);
106        assertEquals(-13.5, child3.getTranslationY(), 0.1);
107
108        assertEquals(42, child4.getLeft(), 1);
109        assertEquals(-4.5, child4.getTranslationY(), 0.1);
110
111        if (child5 != null) {
112            assertEquals(43, child5.getLeft(), 1);
113            assertEquals(6.7, child5.getTranslationY(), 0.1);
114        }
115    }
116
117    @Test
118    public void testStraightOffsetting() throws Throwable {
119        ((CurvingLayoutCallback) mWearableLinearLayoutManagerUnderTest.getLayoutCallback())
120                .setRound(
121                false);
122        final AtomicReference<WearableRecyclerView> wrvReference = new AtomicReference<>();
123        mActivityRule.runOnUiThread(new Runnable() {
124            @Override
125            public void run() {
126                WearableRecyclerView wrv =
127                        (WearableRecyclerView) mActivityRule.getActivity().findViewById(R.id.wrv);
128                wrv.setLayoutManager(mWearableLinearLayoutManagerUnderTest);
129                wrvReference.set(wrv);
130            }
131        });
132        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
133        WearableRecyclerView wrv = wrvReference.get();
134
135        View child1 = wrv.getChildAt(0);
136        View child2 = wrv.getChildAt(1);
137        View child3 = wrv.getChildAt(2);
138        View child4 = wrv.getChildAt(3);
139        View child5 = wrv.getChildAt(4);
140
141        // The left position and the translation of the child is not modified if the screen is
142        // straight. Check if the 5th child is not null as some devices will not be able to display
143        // 5 views.
144        assertEquals(0, child1.getLeft());
145        assertEquals(0.0f, child1.getTranslationY(), 0);
146
147        assertEquals(0, child2.getLeft());
148        assertEquals(0.0f, child2.getTranslationY(), 0);
149
150        assertEquals(0, child3.getLeft());
151        assertEquals(0.0f, child3.getTranslationY(), 0);
152
153        assertEquals(0, child4.getLeft());
154        assertEquals(0.0f, child4.getTranslationY(), 0);
155
156        if (child5 != null) {
157            assertEquals(0, child5.getLeft());
158            assertEquals(0.0f, child5.getTranslationY(), 0);
159        }
160    }
161}
162