0

[headless] Add full screen request handling to old headless

This CL adds support for element.requestFullscreen() and associated
calls which were previously ignored in old headless mode.

Since there is no concept of screen in headless mode, calling
requestFullscreen() just doubles the size of the associated view
whereas document.exitFullscreen() restores the view size to
the original.

Bug: 335520870
Change-Id: I77caa1a05240aac072b1c59805aae90c27a29a62
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5530090
Commit-Queue: Peter Kvitek <kvitekp@chromium.org>
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1299604}
This commit is contained in:
Peter Kvitek
2024-05-10 23:52:48 +00:00
committed by Chromium LUCI CQ
parent 88f1566bc3
commit 9ba43ac31f
4 changed files with 113 additions and 0 deletions

@ -50,6 +50,7 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/ui_base_features.h"
#include "ui/compositor/compositor.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/switches.h"
#if BUILDFLAG(ENABLE_PRINTING)
@ -214,10 +215,61 @@ class HeadlessWebContentsImpl::Delegate : public content::WebContentsDelegate {
blink::mojom::PointerLockResult::kSuccess);
}
void EnterFullscreenModeForTab(
content::RenderFrameHost* requesting_frame,
const blink::mojom::FullscreenOptions& options) override {
SetFullscreenModeForTab(
content::WebContents::FromRenderFrameHost(requesting_frame),
/*fullscreen=*/true);
}
void ExitFullscreenModeForTab(content::WebContents* web_contents) override {
SetFullscreenModeForTab(web_contents, /*fullscreen=*/false);
}
bool IsFullscreenForTabOrPending(
const content::WebContents* web_contents) override {
return is_fullscreen_;
}
private:
HeadlessBrowserImpl* browser() { return headless_web_contents_->browser(); }
void SetFullscreenModeForTab(content::WebContents* web_contents,
bool fullscreen) {
if (is_fullscreen_ == fullscreen) {
return;
}
is_fullscreen_ = fullscreen;
content::RenderViewHost* rvh =
web_contents->GetPrimaryMainFrame()->GetRenderViewHost();
CHECK(rvh);
content::RenderWidgetHostView* view = rvh->GetWidget()->GetView();
if (view) {
if (fullscreen) {
// Headless chrome does not have screen to set the view bounds to, so
// just double the size of the existing view to trigger the expected
// window size change notifications.
before_fullscreen_bounds_ = view->GetViewBounds();
gfx::Rect bounds = before_fullscreen_bounds_;
bounds.set_width(bounds.width() * 2);
bounds.set_height(bounds.height() * 2);
view->SetBounds(bounds);
} else {
view->SetBounds(before_fullscreen_bounds_);
}
}
rvh->GetWidget()->SynchronizeVisualProperties();
}
raw_ptr<HeadlessWebContentsImpl> headless_web_contents_; // Not owned.
bool is_fullscreen_ = false;
gfx::Rect before_fullscreen_bounds_;
};
namespace {

@ -0,0 +1,2 @@
Tests element requestFullscreen.
Entered fullscreen mode: fullscreen-div

@ -0,0 +1,51 @@
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(async function(testRunner) {
const html = `
<html>
<body>
<div id="fullscreen-div">The element.</div>
</body>
<script>
function toggleFullscreen() {
const element = document.getElementById("fullscreen-div");
if (!document.fullscreenElement) {
element.requestFullscreen();
} else {
document.exitFullscreen();
}
}
function fullscreenchanged(event) {
if (document.fullscreenElement) {
console.log("Entered fullscreen mode: "
+ document.fullscreenElement.id);
}
}
document.getElementById("fullscreen-div")
.addEventListener("fullscreenchange", fullscreenchanged);
</script>
</html>
`;
const {session, dp} =
await testRunner.startHTML(html, 'Tests element requestFullscreen.');
await dp.Runtime.enable();
dp.Runtime.onConsoleAPICalled(data => {
const text = data.params.args[0].value;
testRunner.log(text);
});
await dp.Page.enable();
session.evaluateAsyncWithUserGesture('window.toggleFullscreen();');
await dp.Page.onceFrameResized();
session.evaluateAsyncWithUserGesture('window.toggleFullscreen();');
await dp.Page.onceFrameResized();
testRunner.completeTest();
})

@ -370,6 +370,14 @@ HEADLESS_PROTOCOL_TEST(LargeBrowserWindowSize,
HEADLESS_PROTOCOL_TEST(ScreencastBasics, "sanity/screencast-basics.js")
HEADLESS_PROTOCOL_TEST(ScreencastViewport, "sanity/screencast-viewport.js")
// https://crbug.com/339788212
#if BUILDFLAG(IS_MAC)
#define MAYBE_RequestFullscreen DISABLED_RequestFullscreen
#else
#define MAYBE_RequestFullscreen RequestFullscreen
#endif
HEADLESS_PROTOCOL_TEST(MAYBE_RequestFullscreen, "sanity/request-fullscreen.js")
class HeadlessProtocolBrowserTestWithProxy
: public HeadlessProtocolBrowserTest {
public: