blob: 44de05a974652fddefe5f41c71379001af64bed2 [file] [log] [blame]
// Copyright 2016 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.graphics.Rect;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Feature;
import org.chromium.content.browser.test.ContentJUnit4ClassRunner;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
import org.chromium.content.browser.test.util.DOMUtils;
import org.chromium.content.browser.test.util.JavaScriptUtils;
import org.chromium.content.browser.test.util.UiUtils;
import org.chromium.content_shell_apk.ContentShellActivityTestRule;
import org.chromium.media.MediaSwitches;
import org.chromium.ui.base.DeviceFormFactor;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;
/**
* Integration tests for the feature that auto locks the orientation when a video goes fullscreen.
* See also chrome layer org.chromium.chrome.browser.VideoFullscreenOrientationLockChromeTest
*/
@RunWith(ContentJUnit4ClassRunner.class)
@CommandLineFlags.Add({"enable-features=VideoFullscreenOrientationLock",
MediaSwitches.IGNORE_AUTOPLAY_RESTRICTIONS_FOR_TESTS})
public class VideoFullscreenOrientationLockTest {
@Rule
public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule();
private static final String TEST_URL = "content/test/data/media/video-player.html";
private static final String VIDEO_ID = "video";
private void waitForContentsFullscreenState(boolean fullscreenValue) {
CriteriaHelper.pollInstrumentationThread(
Criteria.equals(fullscreenValue, new Callable<Boolean>() {
@Override
public Boolean call() throws InterruptedException, TimeoutException {
return DOMUtils.isFullscreen(mActivityTestRule.getWebContents());
}
})
);
}
private boolean isScreenOrientationLocked() {
return mActivityTestRule.getActivity().getRequestedOrientation()
!= ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
private boolean isScreenOrientationLandscape() throws InterruptedException, TimeoutException {
StringBuilder sb = new StringBuilder();
sb.append("(function() {");
sb.append(" return screen.orientation.type.startsWith('landscape');");
sb.append("})();");
return JavaScriptUtils
.executeJavaScriptAndWaitForResult(
mActivityTestRule.getWebContents(), sb.toString())
.equals("true");
}
private void waitUntilLockedToLandscape() throws InterruptedException {
CriteriaHelper.pollInstrumentationThread(new Criteria() {
@Override
public boolean isSatisfied() {
try {
return isScreenOrientationLocked() && isScreenOrientationLandscape();
} catch (InterruptedException e) {
return false;
} catch (TimeoutException e) {
return false;
}
}
});
}
private void waitUntilUnlocked() throws InterruptedException {
CriteriaHelper.pollInstrumentationThread(new Criteria() {
@Override
public boolean isSatisfied() {
return !isScreenOrientationLocked();
}
});
}
// TODO(mlamouri): move this constants and the controlBar(), fullscreenButton() methods to a
// dedicated helper file for media tests.
private static final int CONTROLS_HEIGHT = 35;
private static final int BUTTON_WIDTH = 35;
private static final int CONTROL_BAR_MARGIN = 5;
private static final int BUTTON_RIGHT_MARGIN = 9;
private static final int FULLSCREEN_BUTTON_LEFT_MARGIN = -5;
private Rect controlBarBounds(Rect videoRect) {
int left = videoRect.left + CONTROL_BAR_MARGIN;
int right = videoRect.right - CONTROL_BAR_MARGIN;
int bottom = videoRect.bottom - CONTROL_BAR_MARGIN;
int top = videoRect.bottom - CONTROLS_HEIGHT;
return new Rect(left, top, right, bottom);
}
private Rect fullscreenButtonBounds(Rect videoRect) {
Rect bar = controlBarBounds(videoRect);
int right = bar.right - BUTTON_RIGHT_MARGIN;
int left = right - BUTTON_WIDTH;
return new Rect(left, bar.top, right, bar.bottom);
}
private boolean clickFullscreenButton() throws InterruptedException, TimeoutException {
return DOMUtils.clickRect(mActivityTestRule.getContentViewCore(),
fullscreenButtonBounds(
DOMUtils.getNodeBounds(mActivityTestRule.getWebContents(), VIDEO_ID)));
}
@Before
public void setUp() throws Exception {
mActivityTestRule.launchContentShellWithUrlSync(TEST_URL);
}
@Test
@MediumTest
@Feature({"VideoFullscreenOrientationLock"})
public void testEnterExitFullscreenWithControlsButton() throws Exception {
// TODO(johnme): Use RESTRICTION_TYPE_PHONE once crbug.com/673917 moves it out of chrome/.
if (DeviceFormFactor.isTablet()) {
return;
}
// Start playback to guarantee it's properly loaded.
Assert.assertTrue(DOMUtils.isMediaPaused(mActivityTestRule.getWebContents(), VIDEO_ID));
DOMUtils.playMedia(mActivityTestRule.getWebContents(), VIDEO_ID);
DOMUtils.waitForMediaPlay(mActivityTestRule.getWebContents(), VIDEO_ID);
// Simulate click on fullscreen button.
Assert.assertTrue(clickFullscreenButton());
waitForContentsFullscreenState(true);
// Should be locked to landscape now, `waitUntilLockedToLandscape` will throw otherwise.
waitUntilLockedToLandscape();
// Because of the fullscreen animation, the click on the exit fullscreen button will fail
// roughly 10% of the time. Settling down the UI reduces the flake to 0%.
UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
// Leave fullscreen by clicking back on the button.
Assert.assertTrue(clickFullscreenButton());
waitForContentsFullscreenState(false);
waitUntilUnlocked();
}
@Test
@MediumTest
@Feature({"VideoFullscreenOrientationLock"})
public void testEnterExitFullscreenWithAPI() throws Exception {
// TODO(johnme): Use RESTRICTION_TYPE_PHONE once crbug.com/673917 moves it out of chrome/.
if (DeviceFormFactor.isTablet()) {
return;
}
// Start playback to guarantee it's properly loaded.
Assert.assertTrue(DOMUtils.isMediaPaused(mActivityTestRule.getWebContents(), VIDEO_ID));
DOMUtils.playMedia(mActivityTestRule.getWebContents(), VIDEO_ID);
DOMUtils.waitForMediaPlay(mActivityTestRule.getWebContents(), VIDEO_ID);
// Trigger requestFullscreen() via a click on a button.
Assert.assertTrue(DOMUtils.clickNode(mActivityTestRule.getContentViewCore(), "fullscreen"));
waitForContentsFullscreenState(true);
// Should be locked to landscape now, `waitUntilLockedToLandscape` will throw otherwise.
waitUntilLockedToLandscape();
// Leave fullscreen from API.
DOMUtils.exitFullscreen(mActivityTestRule.getWebContents());
waitForContentsFullscreenState(false);
waitUntilUnlocked();
}
@Test
@MediumTest
@Feature({"VideoFullscreenOrientationLock"})
public void testExitFullscreenByRemovingVideo() throws Exception {
// TODO(johnme): Use RESTRICTION_TYPE_PHONE once crbug.com/673917 moves it out of chrome/.
if (DeviceFormFactor.isTablet()) {
return;
}
// Start playback to guarantee it's properly loaded.
Assert.assertTrue(DOMUtils.isMediaPaused(mActivityTestRule.getWebContents(), VIDEO_ID));
DOMUtils.playMedia(mActivityTestRule.getWebContents(), VIDEO_ID);
DOMUtils.waitForMediaPlay(mActivityTestRule.getWebContents(), VIDEO_ID);
// Trigger requestFullscreen() via a click on a button.
Assert.assertTrue(DOMUtils.clickNode(mActivityTestRule.getContentViewCore(), "fullscreen"));
waitForContentsFullscreenState(true);
// Should be locked to landscape now, `waitUntilLockedToLandscape` will throw otherwise.
waitUntilLockedToLandscape();
// Leave fullscreen by removing video element from page.
JavaScriptUtils.executeJavaScriptAndWaitForResult(
mActivityTestRule.getWebContents(), "document.body.innerHTML = '';");
waitForContentsFullscreenState(false);
waitUntilUnlocked();
}
@Test
@MediumTest
@Feature({"VideoFullscreenOrientationLock"})
public void testExitFullscreenWithNavigation() throws Exception {
// TODO(johnme): Use RESTRICTION_TYPE_PHONE once crbug.com/673917 moves it out of chrome/.
if (DeviceFormFactor.isTablet()) {
return;
}
// Start playback to guarantee it's properly loaded.
Assert.assertTrue(DOMUtils.isMediaPaused(mActivityTestRule.getWebContents(), VIDEO_ID));
DOMUtils.playMedia(mActivityTestRule.getWebContents(), VIDEO_ID);
DOMUtils.waitForMediaPlay(mActivityTestRule.getWebContents(), VIDEO_ID);
// Trigger requestFullscreen() via a click on a button.
Assert.assertTrue(DOMUtils.clickNode(mActivityTestRule.getContentViewCore(), "fullscreen"));
waitForContentsFullscreenState(true);
// Should be locked to landscape now, `waitUntilLockedToLandscape` will throw otherwise.
waitUntilLockedToLandscape();
// Leave fullscreen by navigating page.
JavaScriptUtils.executeJavaScriptAndWaitForResult(
mActivityTestRule.getWebContents(), "location.reload();");
waitForContentsFullscreenState(false);
waitUntilUnlocked();
}
}