ScreenOrientationProviderTest.java revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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.suitebuilder.annotation.MediumTest;
9import android.test.suitebuilder.annotation.SmallTest;
10
11import org.chromium.base.test.util.Feature;
12import org.chromium.base.test.util.UrlUtils;
13import org.chromium.content.browser.test.util.CriteriaHelper;
14import org.chromium.content.browser.test.util.MockOrientationObserver;
15import org.chromium.content.browser.test.util.OrientationChangeObserverCriteria;
16import org.chromium.content.common.ScreenOrientationValues;
17import org.chromium.content_shell_apk.ContentShellActivity;
18import org.chromium.content_shell_apk.ContentShellTestBase;
19
20/**
21 * Tests for ScreenOrientationListener and its implementations.
22 */
23public class ScreenOrientationProviderTest extends ContentShellTestBase {
24
25    // For some reasons build bots are not able to lock to 180 degrees. This
26    // boolean is here to make the false negative go away in that situation.
27    private static final boolean ALLOW_0_FOR_180 = true;
28
29    private static final String DEFAULT_URL =
30            UrlUtils.encodeHtmlDataUri("<html><body>foo</body></html>");
31
32    private MockOrientationObserver mObserver;
33    private final ScreenOrientationProvider mProvider = ScreenOrientationProvider.create();
34
35    private boolean checkOrientationForLock(int orientations) {
36        switch (orientations) {
37            case ScreenOrientationValues.PORTRAIT_PRIMARY:
38                return mObserver.mOrientation == 0;
39            case ScreenOrientationValues.PORTRAIT_SECONDARY:
40                return mObserver.mOrientation == 180 ||
41                       (ALLOW_0_FOR_180 && mObserver.mOrientation == 0);
42            case ScreenOrientationValues.LANDSCAPE_PRIMARY:
43                return mObserver.mOrientation == 90;
44            case ScreenOrientationValues.LANDSCAPE_SECONDARY:
45                return mObserver.mOrientation == -90;
46            case ScreenOrientationValues.PORTRAIT_PRIMARY |
47                    ScreenOrientationValues.PORTRAIT_SECONDARY:
48                return mObserver.mOrientation == 0 || mObserver.mOrientation == 180;
49            case ScreenOrientationValues.LANDSCAPE_PRIMARY |
50                    ScreenOrientationValues.LANDSCAPE_SECONDARY:
51                return mObserver.mOrientation == 90 || mObserver.mOrientation == -90;
52            case ScreenOrientationValues.PORTRAIT_PRIMARY |
53                    ScreenOrientationValues.PORTRAIT_SECONDARY |
54                    ScreenOrientationValues.LANDSCAPE_PRIMARY |
55                    ScreenOrientationValues.LANDSCAPE_SECONDARY:
56                // The orientation should not change but might and the value could be anything.
57                return true;
58            default:
59                return mObserver.mHasChanged == false;
60        }
61    }
62
63    /**
64     * Locks the screen orientation to |orientations| using ScreenOrientationProvider.
65     */
66    private void lockOrientation(int orientations) {
67        mProvider.lockOrientation((byte)orientations);
68    }
69
70    /**
71     * Call |lockOrientation| and wait for an orientation change.
72     */
73    private boolean lockOrientationAndWait(int orientations)
74            throws InterruptedException {
75        OrientationChangeObserverCriteria criteria =
76                new OrientationChangeObserverCriteria(mObserver);
77
78        lockOrientation(orientations);
79
80        return CriteriaHelper.pollForCriteria(criteria);
81    }
82
83    /**
84     * Unlock the screen orientation using |ScreenOrientationProvider|.
85     */
86    private void unlockOrientation() {
87        mProvider.unlockOrientation();
88    }
89
90    @Override
91    public void setUp() throws Exception {
92        super.setUp();
93
94        ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
95        waitForActiveShellToBeDoneLoading();
96
97        mObserver = new MockOrientationObserver();
98        ScreenOrientationListener.getInstance().addObserver(
99                mObserver, getInstrumentation().getTargetContext());
100
101        // Make sure mObserver is updated before we start the tests.
102        OrientationChangeObserverCriteria criteria =
103                new OrientationChangeObserverCriteria(mObserver);
104        CriteriaHelper.pollForCriteria(criteria);
105    }
106
107    @Override
108    public void tearDown() throws Exception {
109        unlockOrientation();
110
111        mObserver = null;
112        super.tearDown();
113    }
114
115    @SmallTest
116    @Feature({"ScreenOrientation"})
117    public void testBasicValues() throws Exception {
118        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY);
119        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY));
120
121        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY);
122        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY));
123
124        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_SECONDARY);
125        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_SECONDARY));
126
127        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_SECONDARY);
128        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_SECONDARY));
129    }
130
131    @MediumTest
132    @Feature({"ScreenOrientation"})
133    public void testPortrait() throws Exception {
134        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY);
135        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY));
136
137        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY |
138                ScreenOrientationValues.PORTRAIT_SECONDARY);
139        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY |
140                ScreenOrientationValues.PORTRAIT_SECONDARY));
141
142        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_SECONDARY);
143        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_SECONDARY));
144
145        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY |
146                ScreenOrientationValues.PORTRAIT_SECONDARY);
147        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY |
148                ScreenOrientationValues.PORTRAIT_SECONDARY));
149    }
150
151    @MediumTest
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