Commit cb0954cc authored by Dave Tapuska's avatar Dave Tapuska Committed by Commit Bot

Add support for showing the navigation bar in fullscreen mode.

Adjust the flags so that the FullscreenOptions object is read and the
system ui visibility flags are set appropriately.

BUG=829937

Change-Id: I698f0dabd4ca9acfad27f1efc4ffb75361e7df69
Reviewed-on: https://chromium-review.googlesource.com/1034600
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarPhilip Jägenstedt <foolip@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555856}
parent e25744d6
......@@ -12,6 +12,7 @@ import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.util.ObjectsCompat;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
......@@ -124,10 +125,8 @@ public class FullscreenHtmlApiHandler {
== SYSTEM_UI_FLAG_FULLSCREEN) {
return;
}
systemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
systemUiVisibility |= SYSTEM_UI_FLAG_LOW_PROFILE;
systemUiVisibility |=
getExtraFullscreenUIFlags(fullscreenHtmlApiHandler.mFullscreenOptions);
systemUiVisibility = fullscreenHtmlApiHandler.applyEnterFullscreenUIFlags(
systemUiVisibility);
contentView.setSystemUiVisibility(systemUiVisibility);
// Trigger a update to clear the SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN flag
......@@ -189,7 +188,9 @@ public class FullscreenHtmlApiHandler {
* @param options Options to choose mode of fullscreen.
*/
public void enterPersistentFullscreenMode(FullscreenOptions options) {
if (mIsPersistentMode) return;
if (mIsPersistentMode && ObjectsCompat.equals(mFullscreenOptions, options)) {
return;
}
mIsPersistentMode = true;
mDelegate.onEnterFullscreen(options);
......@@ -213,6 +214,7 @@ public class FullscreenHtmlApiHandler {
}
mWebContentsInFullscreen = null;
mTabInFullscreen = null;
mFullscreenOptions = null;
}
/**
......@@ -230,12 +232,11 @@ public class FullscreenHtmlApiHandler {
mHandler.removeMessages(MSG_ID_CLEAR_LAYOUT_FULLSCREEN_FLAG);
int systemUiVisibility = contentView.getSystemUiVisibility();
systemUiVisibility &= ~SYSTEM_UI_FLAG_LOW_PROFILE;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
systemUiVisibility &= ~SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
systemUiVisibility &= ~SYSTEM_UI_FLAG_FULLSCREEN;
systemUiVisibility &= ~getExtraFullscreenUIFlags(null);
systemUiVisibility = applyExitFullscreenUIFlags(systemUiVisibility);
} else {
systemUiVisibility &= ~SYSTEM_UI_FLAG_LOW_PROFILE;
mWindow.addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
......@@ -266,18 +267,23 @@ public class FullscreenHtmlApiHandler {
public void enterFullscreen(final Tab tab, FullscreenOptions options) {
WebContents webContents = tab.getWebContents();
if (webContents == null) return;
mFullscreenOptions = options;
final View contentView = tab.getContentView();
int systemUiVisibility = contentView.getSystemUiVisibility();
systemUiVisibility |= SYSTEM_UI_FLAG_LOW_PROFILE;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
if ((systemUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
if ((systemUiVisibility & SYSTEM_UI_FLAG_FULLSCREEN) == SYSTEM_UI_FLAG_FULLSCREEN) {
// Already in full screen mode; just changed options. Mask off old
// ones and apply new ones.
systemUiVisibility = applyExitFullscreenUIFlags(systemUiVisibility);
systemUiVisibility = applyEnterFullscreenUIFlags(systemUiVisibility);
} else if ((systemUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
== SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) {
systemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
systemUiVisibility |= getExtraFullscreenUIFlags(options);
systemUiVisibility = applyEnterFullscreenUIFlags(systemUiVisibility);
} else {
systemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
}
} else {
systemUiVisibility |= SYSTEM_UI_FLAG_LOW_PROFILE;
mWindow.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
}
......@@ -369,16 +375,36 @@ public class FullscreenHtmlApiHandler {
}
/*
* Helper method to return extra fullscreen UI flags for Kitkat devices.
* Returns system ui flags to enable fullscreen mode based on the current options.
* @return fullscreen flags to be applied to system UI visibility.
*/
private static int getExtraFullscreenUIFlags(FullscreenOptions options) {
int flags = 0;
private int applyEnterFullscreenUIFlags(int systemUiVisibility) {
boolean showNavigationBar =
mFullscreenOptions != null ? mFullscreenOptions.showNavigationBar() : false;
int flags = SYSTEM_UI_FLAG_FULLSCREEN;
if (!showNavigationBar) {
flags |= SYSTEM_UI_FLAG_LOW_PROFILE;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
flags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
return flags;
}
return flags | systemUiVisibility;
}
/*
* Returns system ui flags with any flags that might have been set during
* applyEnterFullscreenUIFlags masked off.
* @return fullscreen flags to be applied to system UI visibility.
*/
private static int applyExitFullscreenUIFlags(int systemUiVisibility) {
int maskOffFlags = SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
maskOffFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
maskOffFlags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
maskOffFlags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
return systemUiVisibility & ~maskOffFlags;
}
}
......@@ -29,6 +29,15 @@ public class FullscreenOptions implements Parcelable {
return mShowNavigationBar;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof FullscreenOptions)) {
return false;
}
FullscreenOptions options = (FullscreenOptions) obj;
return mShowNavigationBar == options.mShowNavigationBar;
}
/**
* The Parcelable interface.
* */
......
......@@ -28,6 +28,7 @@ import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.MinAndroidSdkLevel;
import org.chromium.base.test.util.RetryOnFailure;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.chrome.R;
......@@ -61,6 +62,7 @@ import java.util.concurrent.atomic.AtomicInteger;
@CommandLineFlags.Add({
ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
"disable-features=" + ChromeFeatureList.FULLSCREEN_ACTIVITY,
"enable-blink-features=FullscreenUnprefixed,FullscreenOptions",
})
@RetryOnFailure
public class FullscreenManagerTest {
......@@ -99,6 +101,33 @@ public class FullscreenManagerTest {
+ "<body style='height:10000px;' onclick='toggleFullScreen();'>"
+ "</body>"
+ "</html>");
private static final String LONG_FULLSCREEN_API_HTML_WITH_OPTIONS_TEST_PAGE =
UrlUtils.encodeHtmlDataUri("<html>"
+ "<head>"
+ " <meta name=\"viewport\" "
+ " content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" />"
+ " <script>"
+ " var mode = 0;"
+ " function toggleFullScreen() {"
+ " if (mode == 0) {"
+ " document.body.requestFullscreen({prefersNavigationBar: true});"
+ " mode++;"
+ " } else if (mode == 2) {"
+ " document.body.requestFullscreen({prefersNavigationBar: false});"
+ " mode++;"
+ " } else if (mode == 1 || mode == 3) {"
+ " document.exitFullscreen();"
+ " mode++;"
+ " }"
+ " };"
+ " </script>"
+ " <style>"
+ " body:-webkit-full-screen { background: red; width: 100%; }"
+ " </style>"
+ "</head>"
+ "<body style='height:10000px;' onclick='toggleFullScreen();'>"
+ "</body>"
+ "</html>");
@Before
public void setUp() throws Exception {
......@@ -402,6 +431,59 @@ public class FullscreenManagerTest {
mActivityTestRule, mActivityTestRule.getActivity().getActivityTab());
}
@Test
@LargeTest
@MinAndroidSdkLevel(Build.VERSION_CODES.KITKAT)
@Feature({"Fullscreen"})
public void testPersistentFullscreenWithOptions() throws InterruptedException {
FullscreenManagerTestUtils.disableBrowserOverrides();
mActivityTestRule.startMainActivityWithURL(LONG_FULLSCREEN_API_HTML_WITH_OPTIONS_TEST_PAGE);
ChromeFullscreenManager fullscreenManager =
mActivityTestRule.getActivity().getFullscreenManager();
int browserControlsHeight = fullscreenManager.getTopControlsHeight();
Tab tab = mActivityTestRule.getActivity().getActivityTab();
View view = tab.getView();
final TabWebContentsDelegateAndroid delegate = tab.getTabWebContentsDelegateAndroid();
TouchCommon.singleClickView(view);
FullscreenTestUtils.waitForPersistentFullscreen(delegate, true);
FullscreenManagerTestUtils.waitForBrowserControlsPosition(
mActivityTestRule, -browserControlsHeight);
ThreadUtils.runOnUiThreadBlocking(() -> {
Assert.assertTrue("Navigation bar not hidden.",
(view.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
== 0);
});
TestTouchUtils.sleepForDoubleTapTimeout(InstrumentationRegistry.getInstrumentation());
TouchCommon.singleClickView(view);
FullscreenTestUtils.waitForPersistentFullscreen(delegate, false);
FullscreenManagerTestUtils.waitForBrowserControlsPosition(mActivityTestRule, 0);
FullscreenManagerTestUtils.scrollBrowserControls(mActivityTestRule, false);
FullscreenManagerTestUtils.scrollBrowserControls(mActivityTestRule, true);
TestTouchUtils.sleepForDoubleTapTimeout(InstrumentationRegistry.getInstrumentation());
TouchCommon.singleClickView(view);
FullscreenTestUtils.waitForPersistentFullscreen(delegate, true);
FullscreenManagerTestUtils.waitForBrowserControlsPosition(
mActivityTestRule, -browserControlsHeight);
ThreadUtils.runOnUiThreadBlocking(() -> {
Assert.assertTrue("Navigation bar hidden.",
(view.getSystemUiVisibility() & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
!= 0);
});
TestTouchUtils.sleepForDoubleTapTimeout(InstrumentationRegistry.getInstrumentation());
TouchCommon.singleClickView(view);
FullscreenTestUtils.waitForPersistentFullscreen(delegate, false);
FullscreenManagerTestUtils.waitForBrowserControlsPosition(mActivityTestRule, 0);
}
private void waitForEditableNodeToLoseFocus(final Tab tab) {
CriteriaHelper.pollUiThread(new Criteria() {
@Override
......
......@@ -12,6 +12,10 @@ struct WebFullscreenOptions {
// Prefer that the bottom navigation bar be shown when in fullscreen
// mode on devices with overlay navigation bars.
bool prefers_navigation_bar = false;
bool operator==(const WebFullscreenOptions& rhs) {
return prefers_navigation_bar == rhs.prefers_navigation_bar;
}
};
} // namespace blink
......
......@@ -137,6 +137,9 @@ void FullscreenController::DidExitFullscreen() {
void FullscreenController::EnterFullscreen(LocalFrame& frame,
const FullscreenOptions& options) {
// TODO(dtapuska): If we are already in fullscreen. If the options are
// different than the currently requested one we may wish to request
// fullscreen mode again.
// If already fullscreen or exiting fullscreen, synchronously call
// |DidEnterFullscreen()|. When exiting, the coming |DidExitFullscreen()| call
// will again notify all frames.
......
......@@ -538,7 +538,7 @@
},
{
name: "FullscreenOptions",
status: "test",
status: "experimental",
},
{
name: "FullscreenUnprefixed",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment