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.
5 package org.chromium.content.browser;
7 import android.app.Activity;
8 import android.content.pm.ActivityInfo;
9 import android.test.suitebuilder.annotation.MediumTest;
11 import org.chromium.base.ThreadUtils;
12 import org.chromium.base.test.util.Feature;
13 import org.chromium.base.test.util.UrlUtils;
14 import org.chromium.content.browser.test.util.CriteriaHelper;
15 import org.chromium.content.browser.test.util.MockOrientationObserver;
16 import org.chromium.content.browser.test.util.OrientationChangeObserverCriteria;
17 import org.chromium.content_shell_apk.ContentShellActivity;
18 import org.chromium.content_shell_apk.ContentShellTestBase;
19 import org.chromium.ui.gfx.DeviceDisplayInfo;
22 * Tests for ScreenOrientationListener and its implementations.
24 public class ScreenOrientationListenerTest extends ContentShellTestBase {
26 // For some reasons build bots are not able to lock to 180 degrees. This
27 // boolean is here to make the false negative go away in that situation.
28 private static final boolean ALLOW_0_FOR_180 = true;
30 private static final String DEFAULT_URL =
31 UrlUtils.encodeHtmlDataUri("<html><body>foo</body></html>");
33 private MockOrientationObserver mObserver;
35 private int mNaturalOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
38 * Checks does the device orientation match the requested one.
40 private boolean checkOrientationForLock(int orientation) {
41 int expectedOrientation = orientationTypeToAngle(orientation);
42 int currentOrientation = mObserver.mOrientation;
43 switch (orientation) {
44 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
45 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
46 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
47 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
48 if (expectedOrientation == currentOrientation)
50 else if (ALLOW_0_FOR_180 && expectedOrientation == 180
51 && currentOrientation == 0)
60 * Returns the expected orientation angle based on the orientation type.
62 private int orientationTypeToAngle(int orientation) {
63 if (mNaturalOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
64 switch (orientation) {
65 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
67 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
69 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
71 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
74 fail("Should not be there!");
77 } else { // mNaturalOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
78 switch (orientation) {
79 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
81 case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
83 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
85 case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
88 fail("Should not be there!");
95 * Retrieves device natural orientation.
97 private int getNaturalOrientation(Activity activity) {
98 DeviceDisplayInfo displayInfo = DeviceDisplayInfo.create(activity);
99 int rotation = displayInfo.getRotationDegrees();
100 if (rotation == 0 || rotation == 180) {
101 if (displayInfo.getDisplayHeight() >= displayInfo.getDisplayWidth()) {
102 return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
104 return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
106 if (displayInfo.getDisplayHeight() < displayInfo.getDisplayWidth()) {
107 return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
109 return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
114 * Locks the screen orientation to the predefined orientation type then wait
115 * for the orientation change to happen.
117 private void lockOrientationAndWait(final int orientation) throws InterruptedException {
118 OrientationChangeObserverCriteria criteria =
119 new OrientationChangeObserverCriteria(mObserver,
120 orientationTypeToAngle(orientation));
121 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
124 getActivity().setRequestedOrientation(orientation);
127 getInstrumentation().waitForIdleSync();
129 CriteriaHelper.pollForCriteria(criteria);
133 public void setUp() throws Exception {
136 mObserver = new MockOrientationObserver();
138 final ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
139 waitForActiveShellToBeDoneLoading();
141 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
144 ScreenOrientationListener.getInstance().addObserver(mObserver, activity);
145 ScreenOrientationListener.getInstance().startAccurateListening();
149 // Calculate device natural orientation, as mObserver.mOrientation
150 // is difference between current and natural orientation in degrees.
151 mNaturalOrientation = getNaturalOrientation(activity);
153 // Make sure we start all the tests with the same orientation.
154 lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
158 public void tearDown() throws Exception {
159 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
162 getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
163 ScreenOrientationListener.getInstance().startAccurateListening();
172 @Feature({"ScreenOrientation"})
173 public void testVariousOrientationChanges() throws Exception {
174 lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
175 assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE));
177 lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
178 assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT));
180 lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
181 assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE));
183 lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
184 assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT));
188 @Feature({"ScreenOrientation"})
189 public void testFlipPortrait() throws Exception {
190 lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
191 assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT));
193 lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
194 assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT));
198 @Feature({"ScreenOrientation"})
199 public void testFlipLandscape() throws Exception {
200 lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
201 assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE));
203 lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
204 assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE));