Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(975)

Unified Diff: chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..87386cfd2fad31aaac19ce07860d4803bafbcac4
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTest.java
@@ -0,0 +1,505 @@
+// Copyright 2015 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.chrome.browser.fullscreen;
+
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Build;
+import android.os.SystemClock;
+import android.test.FlakyTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+
+import com.google.android.apps.chrome.R;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.UrlUtils;
+import org.chromium.chrome.browser.ChromeWebContentsDelegateAndroid;
+import org.chromium.chrome.browser.Tab;
+import org.chromium.chrome.browser.omnibox.UrlBar;
+import org.chromium.chrome.browser.tab.ChromeTab;
+import org.chromium.chrome.test.ChromeTabbedActivityTestBase;
+import org.chromium.chrome.test.util.OmniboxTestUtils;
+import org.chromium.chrome.test.util.PrerenderTestHelper;
+import org.chromium.chrome.test.util.TestHttpServerClient;
+import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content.browser.test.util.Criteria;
+import org.chromium.content.browser.test.util.CriteriaHelper;
+import org.chromium.content.browser.test.util.TestTouchUtils;
+import org.chromium.content.browser.test.util.UiUtils;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Test suite for verifying the behavior of various fullscreen actions.
+ */
+public class FullscreenManagerTest extends ChromeTabbedActivityTestBase {
+
+ private static final String LONG_HTML_TEST_PAGE = UrlUtils.encodeHtmlDataUri(
+ "<html><body style='height:10000px;'></body></html>");
+ private static final String LONG_FULLSCREEN_API_HTML_TEST_PAGE = UrlUtils.encodeHtmlDataUri(
+ "<html>"
+ + "<head>"
+ + " <meta name=\"viewport\" "
+ + " content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" />"
+ + " <script>"
+ + " function toggleFullScreen() {"
+ + " if (document.webkitIsFullScreen) {"
+ + " document.webkitCancelFullScreen();"
+ + " } else {"
+ + " document.body.webkitRequestFullScreen();"
+ + " }"
+ + " };"
+ + " </script>"
+ + " <style>"
+ + " body:-webkit-full-screen { background: red; width: 100%; }"
+ + " </style>"
+ + "</head>"
+ + "<body style='height:10000px;' onclick='toggleFullScreen();'>"
+ + "</body>"
+ + "</html>");
+
+ @MediumTest
+ @Feature({"Fullscreen"})
+ public void testTogglePersistentFullscreen() throws InterruptedException {
+ startMainActivityWithURL(LONG_HTML_TEST_PAGE);
+
+ Tab tab = getActivity().getActivityTab();
+ final ChromeWebContentsDelegateAndroid delegate =
+ tab.getChromeWebContentsDelegateAndroid();
+
+ assertTrue(waitForFullscreenFlag(tab, false));
+ assertTrue(waitForPersistentFullscreen(delegate, false));
+
+ togglePersistentFullscreen(delegate, true);
+ assertTrue(waitForFullscreenFlag(tab, true));
+ assertTrue(waitForPersistentFullscreen(delegate, true));
+
+ togglePersistentFullscreen(delegate, false);
+ assertTrue(waitForFullscreenFlag(tab, false));
+ assertTrue(waitForPersistentFullscreen(delegate, false));
+ }
+
+ @LargeTest
+ @Feature({"Fullscreen"})
+ public void testPersistentFullscreenChangingUiFlags() throws InterruptedException {
+ // Exiting fullscreen via UI Flags is not supported in versions prior to MR2.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) return;
+
+ startMainActivityWithURL(LONG_HTML_TEST_PAGE);
+
+ final Tab tab = getActivity().getActivityTab();
+ final ChromeWebContentsDelegateAndroid delegate =
+ tab.getChromeWebContentsDelegateAndroid();
+
+ assertTrue(waitForFullscreenFlag(tab, false));
+ assertTrue(waitForPersistentFullscreen(delegate, false));
+
+ togglePersistentFullscreen(delegate, true);
+ assertTrue(waitForFullscreenFlag(tab, true));
+ assertTrue(waitForPersistentFullscreen(delegate, true));
+
+ // There is a race condition in android when setting various system UI flags.
+ // Adding this wait to allow the animation transitions to complete before continuing
+ // the test (See https://b/10387660)
+ UiUtils.settleDownUI(getInstrumentation());
+
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ View view = tab.getContentViewCore().getContainerView();
+ view.setSystemUiVisibility(
+ view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_FULLSCREEN);
+ }
+ });
+ assertTrue(waitForFullscreenFlag(tab, true));
+ assertTrue(waitForPersistentFullscreen(delegate, true));
+ }
+
+ @LargeTest
+ @Feature({"Fullscreen"})
+ public void testExitPersistentFullscreenAllowsManualFullscreen()
+ throws InterruptedException, ExecutionException {
+ startMainActivityWithURL(LONG_FULLSCREEN_API_HTML_TEST_PAGE);
+
+ ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager();
+ fullscreenManager.setAnimationDurationsForTest(1, 1);
+ int topControlsHeight = fullscreenManager.getTopControlsHeight();
+
+ Tab tab = getActivity().getActivityTab();
+ View view = tab.getView();
+ final ChromeWebContentsDelegateAndroid delegate =
+ tab.getChromeWebContentsDelegateAndroid();
+
+ singleClickView(view, view.getWidth() / 2, view.getHeight() / 2);
+ waitForPersistentFullscreen(delegate, true);
+ assertEquals((float) -topControlsHeight, waitForTopControlsPosition(-topControlsHeight));
+
+ TestTouchUtils.sleepForDoubleTapTimeout(getInstrumentation());
+ singleClickView(view, view.getWidth() / 2, view.getHeight() / 2);
+ waitForPersistentFullscreen(delegate, false);
+ waitForNoBrowserTopControlsOffset();
+ assertEquals((float) 0, waitForTopControlsPosition(0));
+
+ scrollTopControls(false);
+ scrollTopControls(true);
+ }
+
+ /**
+ * Marked flaky on 2015-05-15: http://crbug.com/488393
+ * @LargeTest
+ * @Feature({"Fullscreen"})
+ */
+ @FlakyTest
+ public void testManualHidingShowingTopControls()
+ throws InterruptedException, ExecutionException {
+ startMainActivityWithURL(LONG_HTML_TEST_PAGE);
+
+ ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager();
+ fullscreenManager.disableBrowserOverrideForTest();
+
+ assertEquals(fullscreenManager.getControlOffset(), 0f);
+
+ scrollTopControls(false);
+ // Reverse the scroll and ensure the controls come back into view.
+ scrollTopControls(true);
+ // Check that the URL bar has not grabbed focus (http://crbug/236365)
+ UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
+ assertFalse("Url bar grabbed focus", urlBar.hasFocus());
+ }
+
+ @LargeTest
+ @Feature({"Fullscreen"})
+ public void testHidingTopControlsRemovesSurfaceFlingerOverlay()
+ throws InterruptedException, ExecutionException {
+ startMainActivityWithURL(LONG_HTML_TEST_PAGE);
+
+ ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager();
+ fullscreenManager.disableBrowserOverrideForTest();
+
+ assertEquals(fullscreenManager.getControlOffset(), 0f);
+
+ // Detect layouts. Note this doesn't actually need to be atomic (just final).
+ final AtomicInteger layoutCount = new AtomicInteger();
+ getActivity().getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(
+ new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ layoutCount.incrementAndGet();
+ }
+ });
+
+ // When the top-controls are removed, we need a layout to trigger the
+ // transparent region for the app to be updated.
+ scrollTopControls(false);
+ boolean layoutOccured = CriteriaHelper.pollForUIThreadCriteria(
+ new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ return layoutCount.get() > 0;
+ }
+ });
+ assertTrue(layoutOccured);
+
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ // Check that when the top controls are gone, the entire decorView is contained
+ // in the transparent region of the app.
+ Rect visibleDisplayFrame = new Rect();
+ Region transparentRegion = new Region();
+ ViewGroup decorView = (ViewGroup) getActivity().getWindow().getDecorView();
+ decorView.getWindowVisibleDisplayFrame(visibleDisplayFrame);
+ decorView.gatherTransparentRegion(transparentRegion);
+ assertTrue(transparentRegion.quickContains(visibleDisplayFrame));
+ }
+ });
+
+ // Additional manual test that this is working:
+ // - adb shell dumpsys SurfaceFlinger
+ // - Observe that there is no 'Chrome' related overlay listed, only 'Surfaceview'.
+ }
+
+ @LargeTest
+ @Feature({"Fullscreen"})
+ public void testManualFullscreenDisabledForChromePages()
+ throws InterruptedException, ExecutionException {
+ // The credits page was chosen as it is a chrome:// page that is long and would support
+ // manual fullscreen if it were supported.
+ startMainActivityWithURL("chrome://credits");
+
+ ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager();
+ fullscreenManager.disableBrowserOverrideForTest();
+ int topControlsHeight = fullscreenManager.getTopControlsHeight();
+
+ assertEquals(fullscreenManager.getControlOffset(), 0f);
+
+ float dragX = 50f;
+ float dragStartY = topControlsHeight * 2;
+ float dragFullY = dragStartY - topControlsHeight;
+
+ long downTime = SystemClock.uptimeMillis();
+ dragStart(dragX, dragStartY, downTime);
+ dragTo(dragX, dragX, dragStartY, dragFullY, 100, downTime);
+ assertEquals(0f, waitForTopControlsPosition(0f));
+ dragEnd(dragX, dragFullY, downTime);
+ assertEquals(0f, waitForTopControlsPosition(0f));
+ }
+
+ @LargeTest
+ @Feature({"Fullscreen"})
+ public void testControlsShownOnUnresponsiveRenderer()
+ throws InterruptedException, ExecutionException {
+ startMainActivityWithURL(LONG_HTML_TEST_PAGE);
+
+ ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager();
+ fullscreenManager.setAnimationDurationsForTest(1, 1);
+ assertTrue(waitForNoBrowserTopControlsOffset());
+ assertEquals(fullscreenManager.getControlOffset(), 0f);
+
+ scrollTopControls(false);
+
+ Tab tab = getActivity().getActivityTab();
+ final ChromeWebContentsDelegateAndroid delegate =
+ tab.getChromeWebContentsDelegateAndroid();
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ delegate.rendererUnresponsive();
+ }
+ });
+ assertEquals(0f, waitForTopControlsPosition(0f));
+
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ delegate.rendererResponsive();
+ }
+ });
+ assertTrue(waitForNoBrowserTopControlsOffset());
+ }
+
+ /*
+ @LargeTest
+ @Feature({"Fullscreen"})
+ @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE)
+ crbug.com/339668
+ */
+ @FlakyTest
+ public void testPrerenderedPageSupportsManualHiding()
+ throws InterruptedException, ExecutionException {
+ startMainActivityOnBlankPage();
+
+ ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager();
+ fullscreenManager.disableBrowserOverrideForTest();
+
+ final Tab tab = getActivity().getActivityTab();
+ final String testUrl = TestHttpServerClient.getUrl(
+ "chrome/test/data/android/very_long_google.html");
+ PrerenderTestHelper.trainAutocompleteActionPredictorAndTestPrerender(testUrl, this);
+ assertTrue("loadUrl did not use pre-rendered page.",
+ PrerenderTestHelper.isLoadUrlResultPrerendered(loadUrl(testUrl)));
+
+ UrlBar urlBar = (UrlBar) getActivity().findViewById(R.id.url_bar);
+ OmniboxTestUtils.toggleUrlBarFocus(urlBar, false);
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+ @Override
+ public void run() {
+ ChromeTab.fromTab(tab).processEnableFullscreenRunnableForTest();
+ }
+ });
+
+ scrollTopControls(false);
+ }
+
+ private void scrollTopControls(boolean show) throws InterruptedException, ExecutionException {
+ ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager();
+ int topControlsHeight = fullscreenManager.getTopControlsHeight();
+
+ waitForPageToBeScrollable(getActivity().getActivityTab());
+
+ float dragX = 50f;
+ // Use a larger scroll range than the height of the top controls to ensure we overcome
+ // the delay in a scroll start being sent.
+ float dragStartY = topControlsHeight * 3;
+ float dragEndY = dragStartY - topControlsHeight * 2;
+ float expectedPosition = -topControlsHeight;
+ if (show) {
+ expectedPosition = 0f;
+ float tempDragStartY = dragStartY;
+ dragStartY = dragEndY;
+ dragEndY = tempDragStartY;
+ }
+ long downTime = SystemClock.uptimeMillis();
+ dragStart(dragX, dragStartY, downTime);
+ dragTo(dragX, dragX, dragStartY, dragEndY, 100, downTime);
+ assertEquals(expectedPosition, waitForTopControlsPosition(expectedPosition));
+ dragEnd(dragX, dragEndY, downTime);
+ assertEquals(expectedPosition, waitForTopControlsPosition(expectedPosition));
+ }
+
+ private void togglePersistentFullscreen(final ChromeWebContentsDelegateAndroid delegate,
+ final boolean state) {
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ delegate.toggleFullscreenModeForTab(state);
+ }
+ });
+ }
+
+ private static boolean isFlagSet(int flags, int flag) {
+ return (flags & flag) == flag;
+ }
+
+ private boolean isFullscreenFlagSet(final Tab tab, final boolean state) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ View view = tab.getContentViewCore().getContainerView();
+ int visibility = view.getSystemUiVisibility();
+ // SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN should only be used during the transition between
+ // fullscreen states, so it should always be cleared when fullscreen transitions are
+ // completed.
+ return (!isFlagSet(visibility, View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN))
+ && (isFlagSet(visibility, View.SYSTEM_UI_FLAG_FULLSCREEN) == state);
+ } else {
+ WindowManager.LayoutParams attributes =
+ getActivity().getWindow().getAttributes();
+ return isFlagSet(
+ attributes.flags, WindowManager.LayoutParams.FLAG_FULLSCREEN) == state;
+ }
+ }
+
+ private boolean waitForFullscreenFlag(final Tab tab, final boolean state)
+ throws InterruptedException {
+ return CriteriaHelper.pollForCriteria(new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ try {
+ return ThreadUtils.runOnUiThread(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return isFullscreenFlagSet(tab, state);
+ }
+ }).get();
+ } catch (Exception e) {
+ fail(e.getMessage());
+ return false;
+ }
+ }
+ });
+ }
+
+ private boolean waitForPersistentFullscreen(final ChromeWebContentsDelegateAndroid delegate,
+ final boolean state) throws InterruptedException {
+ return CriteriaHelper.pollForCriteria(new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ try {
+ return ThreadUtils.runOnUiThread(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return state == delegate.isFullscreenForTabOrPending();
+ }
+ }).get();
+ } catch (Exception e) {
+ fail(e.getMessage());
+ return false;
+ }
+ }
+ });
+ }
+
+ private float waitForTopControlsPosition(final float position)
+ throws InterruptedException, ExecutionException {
+ final ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager();
+ CriteriaHelper.pollForCriteria(new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ try {
+ return ThreadUtils.runOnUiThread(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return position == fullscreenManager.getControlOffset();
+ }
+ }).get();
+ } catch (Exception e) {
+ fail(e.getMessage());
+ return false;
+ }
+ }
+ });
+ return ThreadUtils.runOnUiThread(new Callable<Float>() {
+ @Override
+ public Float call() throws Exception {
+ return fullscreenManager.getControlOffset();
+ }
+ }).get();
+ }
+
+ private boolean waitForNoBrowserTopControlsOffset() throws InterruptedException {
+ final ChromeFullscreenManager fullscreenManager = getActivity().getFullscreenManager();
+ return CriteriaHelper.pollForCriteria(new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ try {
+ return ThreadUtils.runOnUiThread(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return !fullscreenManager.hasBrowserControlOffsetOverride();
+ }
+ }).get();
+ } catch (Exception e) {
+ fail(e.getMessage());
+ return false;
+ }
+ }
+ });
+ }
+
+ private boolean waitForPageToBeScrollable(final Tab tab) throws InterruptedException {
+ return CriteriaHelper.pollForCriteria(new Criteria() {
+ @Override
+ public boolean isSatisfied() {
+ try {
+ return ThreadUtils.runOnUiThread(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ ContentViewCore contentViewCore = tab.getContentViewCore();
+ return contentViewCore.computeVerticalScrollRange()
+ > contentViewCore.getContainerView().getHeight();
+ }
+ }).get();
+ } catch (Exception e) {
+ fail(e.getMessage());
+ return false;
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void startMainActivityWithURL(String url) throws InterruptedException {
+ super.startMainActivityWithURL(url);
+ final Tab tab = getActivity().getActivityTab();
+ ThreadUtils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ ChromeTab.fromTab(tab).processEnableFullscreenRunnableForTest();
+ }
+ });
+ }
+
+ @Override
+ public void startMainActivity() throws InterruptedException {
+ // Each test will start itself with the appropriate test page.
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698