blob: af0b0c226dee4cd4c55e2f55ab59b9dedf9b3b5a [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.content.browser;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.test.suitebuilder.annotation.MediumTest;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.MockOrientationObserver;
import org.chromium.content.browser.test.util.OrientationChangeObserverCriteria;
import org.chromium.content_shell_apk.ContentShellActivity;
import org.chromium.content_shell_apk.ContentShellTestBase;
import org.chromium.ui.gfx.DeviceDisplayInfo;
/**
* Tests for ScreenOrientationListener and its implementations.
*/
public class ScreenOrientationListenerTest extends ContentShellTestBase {
// For some reasons build bots are not able to lock to 180 degrees. This
// boolean is here to make the false negative go away in that situation.
private static final boolean ALLOW_0_FOR_180 = true;
private static final String DEFAULT_URL =
UrlUtils.encodeHtmlDataUri("<html><body>foo</body></html>");
private MockOrientationObserver mObserver;
private int mNaturalOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
/**
* Checks does the device orientation match the requested one.
*/
private boolean checkOrientationForLock(int orientation) {
int expectedOrientation = orientationTypeToAngle(orientation);
int currentOrientation = mObserver.mOrientation;
switch (orientation) {
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
if (expectedOrientation == currentOrientation)
return true;
else if (ALLOW_0_FOR_180 && expectedOrientation == 180
&& currentOrientation == 0)
return true;
return false;
default:
return false;
}
}
/**
* Returns the expected orientation angle based on the orientation type.
*/
private int orientationTypeToAngle(int orientation) {
if (mNaturalOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
switch (orientation) {
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
return 0;
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
return 90;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
return 180;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
return -90;
default:
fail("Should not be there!");
return 0;
}
} else { // mNaturalOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
switch (orientation) {
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
return -90;
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
return 0;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
return 90;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
return 180;
default:
fail("Should not be there!");
return 0;
}
}
}
/**
* Retrieves device natural orientation.
*/
private int getNaturalOrientation(Activity activity) {
DeviceDisplayInfo displayInfo = DeviceDisplayInfo.create(activity);
int rotation = displayInfo.getRotationDegrees();
if (rotation == 0 || rotation == 180) {
if (displayInfo.getDisplayHeight() >= displayInfo.getDisplayWidth()) {
return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
} else {
if (displayInfo.getDisplayHeight() < displayInfo.getDisplayWidth()) {
return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
}
}
/**
* Locks the screen orientation to the predefined orientation type then wait
* for the orientation change to happen.
*/
private void lockOrientationAndWait(final int orientation) throws InterruptedException {
OrientationChangeObserverCriteria criteria =
new OrientationChangeObserverCriteria(mObserver,
orientationTypeToAngle(orientation));
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
getActivity().setRequestedOrientation(orientation);
}
});
getInstrumentation().waitForIdleSync();
CriteriaHelper.pollForCriteria(criteria);
}
@Override
public void setUp() throws Exception {
super.setUp();
mObserver = new MockOrientationObserver();
final ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL);
waitForActiveShellToBeDoneLoading();
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
ScreenOrientationListener.getInstance().addObserver(mObserver, activity);
ScreenOrientationListener.getInstance().startAccurateListening();
}
});
// Calculate device natural orientation, as mObserver.mOrientation
// is difference between current and natural orientation in degrees.
mNaturalOrientation = getNaturalOrientation(activity);
// Make sure we start all the tests with the same orientation.
lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
@Override
public void tearDown() throws Exception {
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override
public void run() {
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
ScreenOrientationListener.getInstance().startAccurateListening();
}
});
mObserver = null;
super.tearDown();
}
@MediumTest
@Feature({"ScreenOrientation"})
public void testVariousOrientationChanges() throws Exception {
lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE));
lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT));
lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE));
lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT));
}
@MediumTest
@Feature({"ScreenOrientation"})
public void testFlipPortrait() throws Exception {
lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT));
lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT));
}
@MediumTest
@Feature({"ScreenOrientation"})
public void testFlipLandscape() throws Exception {
lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE));
lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
assertTrue(checkOrientationForLock(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE));
}
}