ScreenOrientationListenerTest.java revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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;
10
11import org.chromium.base.ThreadUtils;
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 then wait
55     * for the orientation change to happen.
56     */
57    private void lockOrientationAndWait(final int orientation) throws InterruptedException {
58        OrientationChangeObserverCriteria criteria =
59                new OrientationChangeObserverCriteria(mObserver,
60                                                      orientationTypeToAngle(orientation));
61        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
62            @Override
63            public void run() {
64                getActivity().setRequestedOrientation(orientation);
65            }
66        });
67        getInstrumentation().waitForIdleSync();
68
69        CriteriaHelper.pollForCriteria(criteria);
70    }
71
72    @Override
73    public void setUp() throws Exception {
74        super.setUp();
75
76        mObserver = new MockOrientationObserver();
77
78        final ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
79        waitForActiveShellToBeDoneLoading();
80
81        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
82            @Override
83            public void run() {
84                ScreenOrientationListener.getInstance().addObserver(mObserver, activity);
85            }
86        });
87
88        // Make sure we start all the tests with the same orientation.
89        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
90    }
91
92    @Override
93    public void tearDown() throws Exception {
94        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
95            @Override
96            public void run() {
97                getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
98            }
99        });
100
101        mObserver = null;
102        super.tearDown();
103    }
104
105    @MediumTest
106    @Feature({"ScreenOrientation"})
107    public void testVariousOrientationChanges() throws Exception {
108        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
109        assertEquals(90, mObserver.mOrientation);
110
111        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
112        assertTrue(mObserver.mOrientation == 180 ||
113                   (ALLOW_0_FOR_180 && mObserver.mOrientation == 0));
114
115        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
116        assertEquals(-90, mObserver.mOrientation);
117
118        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
119        assertEquals(0, mObserver.mOrientation);
120    }
121
122    @MediumTest
123    @Feature({"ScreenOrientation"})
124    public void testFlipPortrait() throws Exception {
125        // This can't work for pre JB-MR1 SDKs for the moment. We will whether
126        // disable the feature entirely on that platform or add an "accurate"
127        // mode.
128        // See http://crbug.com/400158
129        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
130            return;
131
132        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
133        assertEquals(0, mObserver.mOrientation);
134
135        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
136        assertTrue(mObserver.mOrientation == 180 ||
137                   (ALLOW_0_FOR_180 && mObserver.mOrientation == 0));
138    }
139
140    @MediumTest
141    @Feature({"ScreenOrientation"})
142    public void testFlipLandscape() throws Exception {
143        // This can't work for pre JB-MR1 SDKs for the moment. We will whether
144        // disable the feature entirely on that platform or add an "accurate"
145        // mode.
146        // See http://crbug.com/400158
147        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
148            return;
149
150        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
151        assertEquals(90, mObserver.mOrientation);
152
153        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
154        assertEquals(-90, mObserver.mOrientation);
155    }
156}
157