ScreenOrientationListenerTest.java revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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.content.pm.ActivityInfo;
8import android.os.Build;
9import android.test.suitebuilder.annotation.MediumTest;
10import android.test.suitebuilder.annotation.SmallTest;
11
12import org.chromium.base.test.util.Feature;
13import org.chromium.base.test.util.UrlUtils;
14import org.chromium.content.browser.test.util.CriteriaHelper;
15import org.chromium.content.browser.test.util.MockOrientationObserver;
16import org.chromium.content.browser.test.util.OrientationChangeObserverCriteria;
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 ScreenOrientationListenerTest 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
34    /**
35     * Returns the expected orientation angle based on the orientation type.
36     */
37    private static int orientationTypeToAngle(int orientation) {
38        switch (orientation) {
39            case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
40                return 0;
41            case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
42                return 90;
43            case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
44                return 180;
45            case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
46                return 270;
47            default:
48                fail("Should not be there!");
49                return 0;
50        }
51    }
52
53    /**
54     * Locks the screen orientation to the predefined orientation type.
55     */
56    private void lockOrientation(int orientation) {
57        getActivity().setRequestedOrientation(orientation);
58    }
59
60    /**
61     * Locks the screen orientation to the predefined orientation type then wait
62     * for the orientation change to happen.
63     */
64    private boolean lockOrientationAndWait(int orientation)
65            throws InterruptedException {
66        OrientationChangeObserverCriteria criteria = new OrientationChangeObserverCriteria(
67                mObserver, orientationTypeToAngle(orientation));
68
69        lockOrientation(orientation);
70
71        return CriteriaHelper.pollForCriteria(criteria);
72    }
73
74    /**
75     * Unlock the screen orientation. Equivalent to locking to unspecified.
76     */
77    private void unlockOrientation() {
78        getActivity().setRequestedOrientation(
79                ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
80    }
81
82    @Override
83    public void setUp() throws Exception {
84        super.setUp();
85
86        mObserver = new MockOrientationObserver();
87    }
88
89    @Override
90    public void tearDown() throws Exception {
91        unlockOrientation();
92
93        mObserver = null;
94        super.tearDown();
95    }
96
97    private void setUpForConfigurationListener() throws InterruptedException {
98        ScreenOrientationListener.getInstance().injectConfigurationListenerBackendForTest();
99
100        ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
101        waitForActiveShellToBeDoneLoading();
102
103        ScreenOrientationListener.getInstance().addObserver(
104                mObserver, getInstrumentation().getTargetContext());
105    }
106
107    private boolean setUpForDisplayListener() throws InterruptedException {
108        // This can't work for pre JB-MR1 SDKs.
109        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
110            return false;
111
112        ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
113        waitForActiveShellToBeDoneLoading();
114
115        ScreenOrientationListener.getInstance().addObserver(
116                mObserver, getInstrumentation().getTargetContext());
117        return true;
118    }
119
120    @SmallTest
121    @Feature({"ScreenOrientation"})
122    public void testConfigurationListenerDefault() throws Exception {
123        setUpForConfigurationListener();
124
125        assertFalse(mObserver.mHasChanged);
126        assertEquals(-1, mObserver.mOrientation);
127    }
128
129    @SmallTest
130    @Feature({"ScreenOrientation"})
131    public void testConfigurationListenerAsyncSetup() throws Exception {
132        setUpForConfigurationListener();
133
134        // We should get a onScreenOrientationChange call asynchronously.
135        CriteriaHelper.pollForCriteria(new OrientationChangeObserverCriteria(
136                mObserver));
137
138        assertTrue(mObserver.mHasChanged);
139        assertTrue(mObserver.mOrientation != -1);
140    }
141
142    @MediumTest
143    @Feature({"ScreenOrientation"})
144    public void testConfigurationListenerChanges() throws Exception {
145        setUpForConfigurationListener();
146
147        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
148        assertEquals(90, mObserver.mOrientation);
149
150        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
151        assertTrue(mObserver.mOrientation == 180 ||
152                   (ALLOW_0_FOR_180 && mObserver.mOrientation == 0));
153
154        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
155        assertEquals(-90, mObserver.mOrientation);
156
157        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
158        assertEquals(0, mObserver.mOrientation);
159    }
160
161    @MediumTest
162    @Feature({"ScreenOrientation"})
163    public void testConfigurationListenerFlipPortrait() throws Exception {
164        setUpForConfigurationListener();
165
166        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
167        assertEquals(0, mObserver.mOrientation);
168
169        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
170        assertEquals(0, mObserver.mOrientation);
171    }
172
173    @MediumTest
174    @Feature({"ScreenOrientation"})
175    public void testConfigurationListenerFlipLandscape() throws Exception {
176        setUpForConfigurationListener();
177
178        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
179        assertEquals(90, mObserver.mOrientation);
180
181        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
182        assertEquals(90, mObserver.mOrientation);
183    }
184
185    @SmallTest
186    @Feature({"ScreenOrientation"})
187    public void testDisplayListenerDefault() throws Exception {
188        if (!setUpForDisplayListener())
189            return;
190
191        assertEquals(-1, mObserver.mOrientation);
192    }
193
194    @SmallTest
195    @Feature({"ScreenOrientation"})
196    public void testDisplayListenerAsyncSetup() throws Exception {
197        if (!setUpForDisplayListener())
198            return;
199
200        // We should get a onScreenOrientationChange call asynchronously.
201        CriteriaHelper.pollForCriteria(new OrientationChangeObserverCriteria(
202                mObserver));
203
204        assertTrue(mObserver.mOrientation != -1);
205    }
206
207    @MediumTest
208    @Feature({"ScreenOrientation"})
209    public void testDisplayListenerChanges() throws Exception {
210        if (!setUpForDisplayListener())
211            return;
212
213        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
214        assertEquals(90, mObserver.mOrientation);
215
216        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
217        assertTrue(mObserver.mOrientation == 180 ||
218                   (ALLOW_0_FOR_180 && mObserver.mOrientation == 0));
219
220        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
221        assertEquals(-90, mObserver.mOrientation);
222
223        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
224        assertEquals(0, mObserver.mOrientation);
225    }
226
227    @SmallTest
228    @Feature({"ScreenOrientation"})
229    public void testDisplayListenerFlipPortrait() throws Exception {
230        if (!setUpForDisplayListener())
231            return;
232
233        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
234        assertTrue(mObserver.mOrientation == 180 ||
235                   (ALLOW_0_FOR_180 && mObserver.mOrientation == 0));
236
237        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
238        assertEquals(0, mObserver.mOrientation);
239    }
240
241    @SmallTest
242    @Feature({"ScreenOrientation"})
243    public void testDisplayListenerFlipLandscape() throws Exception {
244        if (!setUpForDisplayListener())
245            return;
246
247        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
248        assertEquals(90, mObserver.mOrientation);
249
250        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
251        assertEquals(-90, mObserver.mOrientation);
252    }
253
254}
255