ScreenOrientationListenerTest.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.content.pm.ActivityInfo;
8import android.test.suitebuilder.annotation.MediumTest;
9
10import org.chromium.base.ThreadUtils;
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_shell_apk.ContentShellActivity;
17import org.chromium.content_shell_apk.ContentShellTestBase;
18
19/**
20 * Tests for ScreenOrientationListener and its implementations.
21 */
22public class ScreenOrientationListenerTest 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    /**
34     * Returns the expected orientation angle based on the orientation type.
35     */
36    private static int orientationTypeToAngle(int orientation) {
37        switch (orientation) {
38            case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
39                return 0;
40            case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
41                return 90;
42            case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
43                return 180;
44            case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
45                return 270;
46            default:
47                fail("Should not be there!");
48                return 0;
49        }
50    }
51
52    /**
53     * Locks the screen orientation to the predefined orientation type then wait
54     * for the orientation change to happen.
55     */
56    private void lockOrientationAndWait(final int orientation) throws InterruptedException {
57        OrientationChangeObserverCriteria criteria =
58                new OrientationChangeObserverCriteria(mObserver,
59                                                      orientationTypeToAngle(orientation));
60        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
61            @Override
62            public void run() {
63                getActivity().setRequestedOrientation(orientation);
64            }
65        });
66        getInstrumentation().waitForIdleSync();
67
68        CriteriaHelper.pollForCriteria(criteria);
69    }
70
71    @Override
72    public void setUp() throws Exception {
73        super.setUp();
74
75        mObserver = new MockOrientationObserver();
76
77        final ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
78        waitForActiveShellToBeDoneLoading();
79
80        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
81            @Override
82            public void run() {
83                ScreenOrientationListener.getInstance().addObserver(mObserver, activity);
84                ScreenOrientationListener.getInstance().startAccurateListening();
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                ScreenOrientationListener.getInstance().startAccurateListening();
99            }
100        });
101
102        mObserver = null;
103        super.tearDown();
104    }
105
106    @MediumTest
107    @Feature({"ScreenOrientation"})
108    public void testVariousOrientationChanges() throws Exception {
109        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
110        assertEquals(90, mObserver.mOrientation);
111
112        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
113        assertTrue(mObserver.mOrientation == 180 ||
114                   (ALLOW_0_FOR_180 && mObserver.mOrientation == 0));
115
116        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
117        assertEquals(-90, mObserver.mOrientation);
118
119        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
120        assertEquals(0, mObserver.mOrientation);
121    }
122
123    @MediumTest
124    @Feature({"ScreenOrientation"})
125    public void testFlipPortrait() throws Exception {
126        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
127        assertEquals(0, mObserver.mOrientation);
128
129        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
130        assertTrue(mObserver.mOrientation == 180 ||
131                   (ALLOW_0_FOR_180 && mObserver.mOrientation == 0));
132    }
133
134    @MediumTest
135    @Feature({"ScreenOrientation"})
136    public void testFlipLandscape() throws Exception {
137        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
138        assertEquals(90, mObserver.mOrientation);
139
140        lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
141        assertEquals(-90, mObserver.mOrientation);
142    }
143}
144