ScreenOrientationProviderTest.java revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.browser;
6
7import android.os.Build;
8import android.test.FlakyTest;
9
10import org.chromium.base.test.util.Feature;
11import org.chromium.base.test.util.UrlUtils;
12import org.chromium.content.browser.test.util.CriteriaHelper;
13import org.chromium.content.browser.test.util.MockOrientationObserver;
14import org.chromium.content.browser.test.util.OrientationChangeObserverCriteria;
15import org.chromium.content.common.ScreenOrientationValues;
16import org.chromium.content_shell_apk.ContentShellActivity;
17import org.chromium.content_shell_apk.ContentShellTestBase;
18
19/**
20 * Tests for ScreenOrientationListener and its implementations.
21 */
22public class ScreenOrientationProviderTest extends ContentShellTestBase {
23
24    // For some reasons build bots are not able to lock to 180 degrees. This
25    // boolean is here to make the false negative go away in that situation.
26    private static final boolean ALLOW_0_FOR_180 = true;
27
28    private static final String DEFAULT_URL =
29            UrlUtils.encodeHtmlDataUri("<html><body>foo</body></html>");
30
31    private MockOrientationObserver mObserver;
32    private final ScreenOrientationProvider mProvider = ScreenOrientationProvider.create();
33
34    private boolean checkOrientationForLock(int orientations) {
35        switch (orientations) {
36            case ScreenOrientationValues.PORTRAIT_PRIMARY:
37                return mObserver.mOrientation == 0;
38            case ScreenOrientationValues.PORTRAIT_SECONDARY:
39                return mObserver.mOrientation == 180 ||
40                       (ALLOW_0_FOR_180 && mObserver.mOrientation == 0);
41            case ScreenOrientationValues.LANDSCAPE_PRIMARY:
42                return mObserver.mOrientation == 90;
43            case ScreenOrientationValues.LANDSCAPE_SECONDARY:
44                return mObserver.mOrientation == -90;
45            case ScreenOrientationValues.PORTRAIT:
46                return mObserver.mOrientation == 0 || mObserver.mOrientation == 180;
47            case ScreenOrientationValues.LANDSCAPE:
48                return mObserver.mOrientation == 90 || mObserver.mOrientation == -90;
49            case ScreenOrientationValues.ANY:
50                // The orientation should not change but might and the value could be anything.
51                return true;
52            default:
53                return mObserver.mHasChanged == false;
54        }
55    }
56
57    /**
58     * Locks the screen orientation to |orientations| using ScreenOrientationProvider.
59     */
60    private void lockOrientation(int orientations) {
61        mProvider.lockOrientation((byte)orientations);
62    }
63
64    /**
65     * Call |lockOrientation| and wait for an orientation change.
66     */
67    private boolean lockOrientationAndWait(int orientations)
68            throws InterruptedException {
69        OrientationChangeObserverCriteria criteria =
70                new OrientationChangeObserverCriteria(mObserver);
71
72        lockOrientation(orientations);
73
74        return CriteriaHelper.pollForCriteria(criteria);
75    }
76
77    /**
78     * Unlock the screen orientation using |ScreenOrientationProvider|.
79     */
80    private void unlockOrientation() {
81        mProvider.unlockOrientation();
82    }
83
84    @Override
85    public void setUp() throws Exception {
86        super.setUp();
87
88        ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
89        waitForActiveShellToBeDoneLoading();
90
91        mObserver = new MockOrientationObserver();
92        ScreenOrientationListener.getInstance().addObserver(
93                mObserver, getInstrumentation().getTargetContext());
94
95        // Make sure mObserver is updated before we start the tests.
96        OrientationChangeObserverCriteria criteria =
97                new OrientationChangeObserverCriteria(mObserver);
98        CriteriaHelper.pollForCriteria(criteria);
99    }
100
101    @Override
102    public void tearDown() throws Exception {
103        unlockOrientation();
104
105        mObserver = null;
106        super.tearDown();
107    }
108
109    // @SmallTest
110    // crbug.com/353500
111    @FlakyTest
112    @Feature({"ScreenOrientation"})
113    public void testBasicValues() throws Exception {
114        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY);
115        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY));
116
117        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY);
118        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY));
119
120        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_SECONDARY);
121        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_SECONDARY));
122
123        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_SECONDARY);
124        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_SECONDARY));
125    }
126
127    // @MediumTest
128    // crbug.com/353500
129    @FlakyTest
130    @Feature({"ScreenOrientation"})
131    public void testPortrait() throws Exception {
132        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY);
133        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY));
134
135        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY |
136                ScreenOrientationValues.PORTRAIT_SECONDARY);
137        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY |
138                ScreenOrientationValues.PORTRAIT_SECONDARY));
139
140        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_SECONDARY);
141        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_SECONDARY));
142
143        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY |
144                ScreenOrientationValues.PORTRAIT_SECONDARY);
145        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY |
146                ScreenOrientationValues.PORTRAIT_SECONDARY));
147    }
148
149    // @MediumTest
150    // crbug.com/353500
151    @FlakyTest
152    @Feature({"ScreenOrientation"})
153    public void testLandscape() throws Exception {
154        int initialOrientation = mObserver.mOrientation;
155
156        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY);
157        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
158            // If we were in LANDSCAPE_SECONDARY (90 degrees), old SDK will not
159            // be able to catch this change correctly. However, we still want to
160            // wait to not break the rest of the test.
161            boolean result = checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY);
162            if (initialOrientation != -90)
163                assertTrue(result);
164        } else {
165            assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY));
166        }
167
168        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY |
169                ScreenOrientationValues.LANDSCAPE_SECONDARY);
170        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY |
171                ScreenOrientationValues.LANDSCAPE_SECONDARY));
172
173        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_SECONDARY);
174        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
175            // Exactly the opposite situation as above.
176            boolean result = checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_SECONDARY);
177            if (initialOrientation == -90)
178                assertTrue(result);
179        } else {
180            assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_SECONDARY));
181        }
182
183        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY |
184                ScreenOrientationValues.LANDSCAPE_SECONDARY);
185        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY |
186                ScreenOrientationValues.LANDSCAPE_SECONDARY));
187    }
188
189    // There is no point in testing the case where we try to lock to
190    // PORTRAIT_PRIMARY | PORTRAIT_SECONDARY | LANDSCAPE_PRIMARY | LANDSCAPE_SECONDARY
191    // because with the device being likely flat during the test, locking to that
192    // will be a no-op.
193
194    // We can't test unlock because the device is likely flat during the test
195    // and in that situation unlocking is a no-op.
196}
197