ScreenOrientationProviderTest.java revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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.test.suitebuilder.annotation.MediumTest;
8
9import org.chromium.base.ThreadUtils;
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
33    private boolean checkOrientationForLock(int orientations) {
34        switch (orientations) {
35            case ScreenOrientationValues.PORTRAIT_PRIMARY:
36                return mObserver.mOrientation == 0;
37            case ScreenOrientationValues.PORTRAIT_SECONDARY:
38                return mObserver.mOrientation == 180 ||
39                       (ALLOW_0_FOR_180 && mObserver.mOrientation == 0);
40            case ScreenOrientationValues.LANDSCAPE_PRIMARY:
41                return mObserver.mOrientation == 90;
42            case ScreenOrientationValues.LANDSCAPE_SECONDARY:
43                return mObserver.mOrientation == -90;
44            case ScreenOrientationValues.PORTRAIT:
45                return mObserver.mOrientation == 0 || mObserver.mOrientation == 180;
46            case ScreenOrientationValues.LANDSCAPE:
47                return mObserver.mOrientation == 90 || mObserver.mOrientation == -90;
48            case ScreenOrientationValues.ANY:
49                // The orientation should not change but might and the value could be anything.
50                return true;
51            default:
52                return mObserver.mHasChanged == false;
53        }
54    }
55
56    /**
57     * Call |lockOrientation| and wait for an orientation change.
58     */
59    private boolean lockOrientationAndWait(final int orientations) throws InterruptedException {
60        OrientationChangeObserverCriteria criteria =
61                new OrientationChangeObserverCriteria(mObserver);
62
63        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
64            @Override
65            public void run() {
66                ScreenOrientationProvider.lockOrientation((byte)orientations);
67            }
68        });
69        getInstrumentation().waitForIdleSync();
70
71        return CriteriaHelper.pollForCriteria(criteria);
72    }
73
74    @Override
75    public void setUp() throws Exception {
76        super.setUp();
77
78        mObserver = new MockOrientationObserver();
79        OrientationChangeObserverCriteria criteria =
80                new OrientationChangeObserverCriteria(mObserver);
81
82        final ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
83        waitForActiveShellToBeDoneLoading();
84
85        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
86            @Override
87            public void run() {
88                ScreenOrientationListener.getInstance().addObserver(mObserver, activity);
89                ScreenOrientationProvider.startAccurateListening();
90            }
91        });
92
93        // Make sure we start all the tests with the same orientation.
94        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY);
95
96        // Make sure mObserver is updated before we start the tests.
97        CriteriaHelper.pollForCriteria(criteria);
98    }
99
100    @Override
101    public void tearDown() throws Exception {
102        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
103            @Override
104            public void run() {
105                ScreenOrientationProvider.unlockOrientation();
106                ScreenOrientationProvider.startAccurateListening();
107            }
108        });
109
110        mObserver = null;
111        super.tearDown();
112    }
113
114    @MediumTest
115    @Feature({"ScreenOrientation"})
116    public void testBasicValues() throws Exception {
117        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY);
118        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY));
119
120        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY);
121        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY));
122
123        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_SECONDARY);
124        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_SECONDARY));
125
126        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_SECONDARY);
127        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_SECONDARY));
128    }
129
130    @MediumTest
131    @Feature({"ScreenOrientation"})
132    public void testPortrait() throws Exception {
133        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY);
134        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY));
135
136        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY |
137                ScreenOrientationValues.PORTRAIT_SECONDARY);
138        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY |
139                ScreenOrientationValues.PORTRAIT_SECONDARY));
140
141        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_SECONDARY);
142        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_SECONDARY));
143
144        lockOrientationAndWait(ScreenOrientationValues.PORTRAIT_PRIMARY |
145                ScreenOrientationValues.PORTRAIT_SECONDARY);
146        assertTrue(checkOrientationForLock(ScreenOrientationValues.PORTRAIT_PRIMARY |
147                ScreenOrientationValues.PORTRAIT_SECONDARY));
148    }
149
150    @MediumTest
151    @Feature({"ScreenOrientation"})
152    public void testLandscape() throws Exception {
153        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY);
154        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY));
155
156        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY |
157                ScreenOrientationValues.LANDSCAPE_SECONDARY);
158        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY |
159                ScreenOrientationValues.LANDSCAPE_SECONDARY));
160
161        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_SECONDARY);
162        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_SECONDARY));
163
164        lockOrientationAndWait(ScreenOrientationValues.LANDSCAPE_PRIMARY |
165                ScreenOrientationValues.LANDSCAPE_SECONDARY);
166        assertTrue(checkOrientationForLock(ScreenOrientationValues.LANDSCAPE_PRIMARY |
167                ScreenOrientationValues.LANDSCAPE_SECONDARY));
168    }
169
170    // There is no point in testing the case where we try to lock to
171    // PORTRAIT_PRIMARY | PORTRAIT_SECONDARY | LANDSCAPE_PRIMARY | LANDSCAPE_SECONDARY
172    // because with the device being likely flat during the test, locking to that
173    // will be a no-op.
174
175    // We can't test unlock because the device is likely flat during the test
176    // and in that situation unlocking is a no-op.
177}
178