// 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.content.pm.ActivityInfo; import android.os.Build; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; 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; /** * 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; /** * Returns the expected orientation angle based on the orientation type. */ private static int orientationTypeToAngle(int orientation) { 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 270; default: fail("Should not be there!"); return 0; } } /** * Locks the screen orientation to the predefined orientation type. */ private void lockOrientation(int orientation) { getActivity().setRequestedOrientation(orientation); } /** * Locks the screen orientation to the predefined orientation type then wait * for the orientation change to happen. */ private boolean lockOrientationAndWait(int orientation) throws InterruptedException { OrientationChangeObserverCriteria criteria = new OrientationChangeObserverCriteria( mObserver, orientationTypeToAngle(orientation)); lockOrientation(orientation); return CriteriaHelper.pollForCriteria(criteria); } /** * Unlock the screen orientation. Equivalent to locking to unspecified. */ private void unlockOrientation() { getActivity().setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } @Override public void setUp() throws Exception { super.setUp(); mObserver = new MockOrientationObserver(); } @Override public void tearDown() throws Exception { unlockOrientation(); mObserver = null; super.tearDown(); } private void setUpForConfigurationListener() throws InterruptedException { ScreenOrientationListener.getInstance().injectConfigurationListenerBackendForTest(); ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL); waitForActiveShellToBeDoneLoading(); ScreenOrientationListener.getInstance().addObserver( mObserver, getInstrumentation().getTargetContext()); } private boolean setUpForDisplayListener() throws InterruptedException { // This can't work for pre JB-MR1 SDKs. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return false; ContentShellActivity activity = launchContentShellWithUrl(DEFAULT_URL); waitForActiveShellToBeDoneLoading(); ScreenOrientationListener.getInstance().addObserver( mObserver, getInstrumentation().getTargetContext()); return true; } // At least one of these tests flakes 50% on all runs of // contentshell_instrumentation_tests. // crbug.com/356483 /* @SmallTest @Feature({"ScreenOrientation"}) public void testConfigurationListenerDefault() throws Exception { setUpForConfigurationListener(); assertFalse(mObserver.mHasChanged); assertEquals(-1, mObserver.mOrientation); } @SmallTest @Feature({"ScreenOrientation"}) public void testConfigurationListenerAsyncSetup() throws Exception { setUpForConfigurationListener(); // We should get a onScreenOrientationChange call asynchronously. CriteriaHelper.pollForCriteria(new OrientationChangeObserverCriteria( mObserver)); assertTrue(mObserver.mHasChanged); assertTrue(mObserver.mOrientation != -1); } @MediumTest @Feature({"ScreenOrientation"}) public void testConfigurationListenerChanges() throws Exception { setUpForConfigurationListener(); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); assertEquals(90, mObserver.mOrientation); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); assertTrue(mObserver.mOrientation == 180 || (ALLOW_0_FOR_180 && mObserver.mOrientation == 0)); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); assertEquals(-90, mObserver.mOrientation); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); assertEquals(0, mObserver.mOrientation); } @MediumTest @Feature({"ScreenOrientation"}) public void testConfigurationListenerFlipPortrait() throws Exception { setUpForConfigurationListener(); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); assertEquals(0, mObserver.mOrientation); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); assertEquals(0, mObserver.mOrientation); } @MediumTest @Feature({"ScreenOrientation"}) public void testConfigurationListenerFlipLandscape() throws Exception { setUpForConfigurationListener(); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); assertEquals(90, mObserver.mOrientation); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); assertEquals(90, mObserver.mOrientation); } @SmallTest @Feature({"ScreenOrientation"}) public void testDisplayListenerDefault() throws Exception { if (!setUpForDisplayListener()) return; assertEquals(-1, mObserver.mOrientation); } @SmallTest @Feature({"ScreenOrientation"}) public void testDisplayListenerAsyncSetup() throws Exception { if (!setUpForDisplayListener()) return; // We should get a onScreenOrientationChange call asynchronously. CriteriaHelper.pollForCriteria(new OrientationChangeObserverCriteria( mObserver)); assertTrue(mObserver.mOrientation != -1); } @MediumTest @Feature({"ScreenOrientation"}) public void testDisplayListenerChanges() throws Exception { if (!setUpForDisplayListener()) return; lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); assertEquals(90, mObserver.mOrientation); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); assertTrue(mObserver.mOrientation == 180 || (ALLOW_0_FOR_180 && mObserver.mOrientation == 0)); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); assertEquals(-90, mObserver.mOrientation); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); assertEquals(0, mObserver.mOrientation); } @SmallTest @Feature({"ScreenOrientation"}) public void testDisplayListenerFlipPortrait() throws Exception { if (!setUpForDisplayListener()) return; lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); assertEquals(0, mObserver.mOrientation); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); assertTrue(mObserver.mOrientation == 180 || (ALLOW_0_FOR_180 && mObserver.mOrientation == 0)); } @SmallTest @Feature({"ScreenOrientation"}) public void testDisplayListenerFlipLandscape() throws Exception { if (!setUpForDisplayListener()) return; lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); assertEquals(90, mObserver.mOrientation); lockOrientationAndWait(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); assertEquals(-90, mObserver.mOrientation); } */ }