Commit aadcb29e authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Display Cutout] Expose safe area through CSS

Add a DisplayCutoutClient mojo interface that is bound to a
frame and called from the browser. This will set safe-area*
CSS env() variables that websites can use to layout their
content based on the safe area.

DisplayCutoutClient will be called from Android in a future
CL.

BUG=847652

Change-Id: I6180aa5337e182fd1794586c47caef0f19fab718
Reviewed-on: https://chromium-review.googlesource.com/1083291Reviewed-by: default avatarBo <boliu@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569427}
parent 27522f43
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h" #include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h" #include "content/test/content_browser_test_utils_internal.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/mojom/page/display_cutout.mojom.h" #include "third_party/blink/public/mojom/page/display_cutout.mojom.h"
namespace content { namespace content {
...@@ -50,6 +51,18 @@ class TestWebContentsObserver : public WebContentsObserver { ...@@ -50,6 +51,18 @@ class TestWebContentsObserver : public WebContentsObserver {
DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver); DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver);
}; };
const char kTestHTML[] =
"<!DOCTYPE html>"
"<style>"
" #target {"
" margin-top: env(safe-area-inset-top);"
" margin-left: env(safe-area-inset-left);"
" margin-bottom: env(safe-area-inset-bottom);"
" margin-right: env(safe-area-inset-right);"
" }"
"</style>"
"<div id=target></div>";
} // namespace } // namespace
class DisplayCutoutBrowserTest : public ContentBrowserTest { class DisplayCutoutBrowserTest : public ContentBrowserTest {
...@@ -57,8 +70,13 @@ class DisplayCutoutBrowserTest : public ContentBrowserTest { ...@@ -57,8 +70,13 @@ class DisplayCutoutBrowserTest : public ContentBrowserTest {
DisplayCutoutBrowserTest() {} DisplayCutoutBrowserTest() {}
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII("enable-blink-features", command_line->AppendSwitchASCII(
"DisplayCutoutAPI,CSSViewport"); "enable-blink-features",
"DisplayCutoutAPI,CSSViewport,CSSEnvironmentVariables");
}
content::RenderFrameHost* MainFrame() {
return shell()->web_contents()->GetMainFrame();
} }
void LoadTestPageWithViewportFitFromMeta(const std::string& value) { void LoadTestPageWithViewportFitFromMeta(const std::string& value) {
...@@ -97,6 +115,41 @@ class DisplayCutoutBrowserTest : public ContentBrowserTest { ...@@ -97,6 +115,41 @@ class DisplayCutoutBrowserTest : public ContentBrowserTest {
"document.getElementsByTagName('meta')[0].content = ''"); "document.getElementsByTagName('meta')[0].content = ''");
} }
void SendSafeAreaToFrame(int top, int left, int bottom, int right) {
blink::mojom::DisplayCutoutClientAssociatedPtr client;
MainFrame()->GetRemoteAssociatedInterfaces()->GetInterface(&client);
client->SetSafeArea(
blink::mojom::DisplayCutoutSafeArea::New(top, left, bottom, right));
}
std::string GetCurrentSafeAreaValue(const std::string& name) {
std::string value;
EXPECT_TRUE(ExecuteScriptAndExtractString(
MainFrame(),
"(() => {"
"const e = document.getElementById('target');"
"const style = window.getComputedStyle(e, null);"
"window.domAutomationController.send("
" style.getPropertyValue('margin-" +
name +
"'));"
"})();",
&value));
return value;
}
void LoadTestPageWithData(const std::string& data) {
GURL url("https://www.example.com");
TestNavigationObserver same_tab_observer(shell()->web_contents(), 1);
#if defined(OS_ANDROID)
shell()->LoadDataAsStringWithBaseURL(url, data, url);
#else
shell()->LoadDataWithBaseURL(url, data, url);
#endif
same_tab_observer.Wait();
}
private: private:
void LoadSubFrameWithData(const std::string& html_data) { void LoadSubFrameWithData(const std::string& html_data) {
const std::string data = const std::string data =
...@@ -116,18 +169,6 @@ class DisplayCutoutBrowserTest : public ContentBrowserTest { ...@@ -116,18 +169,6 @@ class DisplayCutoutBrowserTest : public ContentBrowserTest {
web_contents->Focus(); web_contents->Focus();
} }
void LoadTestPageWithData(const std::string& data) {
GURL url("https://www.example.com");
TestNavigationObserver same_tab_observer(shell()->web_contents(), 1);
#if defined(OS_ANDROID)
shell()->LoadDataAsStringWithBaseURL(url, data, url);
#else
shell()->LoadDataWithBaseURL(url, data, url);
#endif
same_tab_observer.Wait();
}
DISALLOW_COPY_AND_ASSIGN(DisplayCutoutBrowserTest); DISALLOW_COPY_AND_ASSIGN(DisplayCutoutBrowserTest);
}; };
...@@ -238,4 +279,22 @@ IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, ViewportFit_CSS_Invalid) { ...@@ -238,4 +279,22 @@ IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, ViewportFit_CSS_Invalid) {
observer.WaitForWantedValue(blink::mojom::ViewportFit::kAuto); observer.WaitForWantedValue(blink::mojom::ViewportFit::kAuto);
} }
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, PublishSafeAreaVariables) {
LoadTestPageWithData(kTestHTML);
// Make sure all the safe areas are currently zero.
EXPECT_EQ("0px", GetCurrentSafeAreaValue("top"));
EXPECT_EQ("0px", GetCurrentSafeAreaValue("left"));
EXPECT_EQ("0px", GetCurrentSafeAreaValue("bottom"));
EXPECT_EQ("0px", GetCurrentSafeAreaValue("right"));
SendSafeAreaToFrame(1, 2, 3, 4);
// Make sure all the safe ares are correctly set.
EXPECT_EQ("1px", GetCurrentSafeAreaValue("top"));
EXPECT_EQ("2px", GetCurrentSafeAreaValue("left"));
EXPECT_EQ("3px", GetCurrentSafeAreaValue("bottom"));
EXPECT_EQ("4px", GetCurrentSafeAreaValue("right"));
}
} // namespace content } // namespace content
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
module blink.mojom; module blink.mojom;
import "ui/gfx/geometry/mojo/geometry.mojom";
enum ViewportFit { enum ViewportFit {
// No effect - the whole web page is viewable (default). // No effect - the whole web page is viewable (default).
kAuto, kAuto,
...@@ -22,3 +24,20 @@ interface DisplayCutoutHost { ...@@ -22,3 +24,20 @@ interface DisplayCutoutHost {
// Notify the browser that the ViewportFit for the renderer has changed. // Notify the browser that the ViewportFit for the renderer has changed.
ViewportFitChanged(blink.mojom.ViewportFit value); ViewportFitChanged(blink.mojom.ViewportFit value);
}; };
// Contains the four safe areas for the display cutout. These are insets from
// each edge of the display measured in pixels.
// TODO(beccahughes): Replace with gfx::Insets
struct DisplayCutoutSafeArea {
int32 top;
int32 left;
int32 bottom;
int32 right;
};
// Used for browser -> renderer calls about display cutout. This is associated
// with a frame.
interface DisplayCutoutClient {
// Notify the renderer that the safe areas have changed.
SetSafeArea(DisplayCutoutSafeArea safe_area);
};
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "third_party/blink/renderer/controller/bloated_renderer_detector.h" #include "third_party/blink/renderer/controller/bloated_renderer_detector.h"
#include "third_party/blink/renderer/controller/dev_tools_frontend_impl.h" #include "third_party/blink/renderer/controller/dev_tools_frontend_impl.h"
#include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/animation_clock.h"
#include "third_party/blink/renderer/core/frame/display_cutout_client_impl.h"
#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h" #include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
...@@ -158,6 +159,11 @@ void BlinkInitializer::RegisterInterfaces( ...@@ -158,6 +159,11 @@ void BlinkInitializer::RegisterInterfaces(
} }
void BlinkInitializer::InitLocalFrame(LocalFrame& frame) const { void BlinkInitializer::InitLocalFrame(LocalFrame& frame) const {
if (frame.IsMainFrame() &&
RuntimeEnabledFeatures::DisplayCutoutAPIEnabled()) {
frame.GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating(
&DisplayCutoutClientImpl::BindMojoRequest, WrapWeakPersistent(&frame)));
}
frame.GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating( frame.GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating(
&DevToolsFrontendImpl::BindMojoRequest, WrapWeakPersistent(&frame))); &DevToolsFrontendImpl::BindMojoRequest, WrapWeakPersistent(&frame)));
frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating( frame.GetInterfaceRegistry()->AddInterface(WTF::BindRepeating(
......
...@@ -32,6 +32,8 @@ blink_core_sources("frame") { ...@@ -32,6 +32,8 @@ blink_core_sources("frame") {
"deprecation_report_body.h", "deprecation_report_body.h",
"device_single_window_event_controller.cc", "device_single_window_event_controller.cc",
"device_single_window_event_controller.h", "device_single_window_event_controller.h",
"display_cutout_client_impl.cc",
"display_cutout_client_impl.h",
"dom_timer.cc", "dom_timer.cc",
"dom_timer.h", "dom_timer.h",
"dom_timer_coordinator.cc", "dom_timer_coordinator.cc",
......
// Copyright 2018 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.
#include "third_party/blink/renderer/core/frame/display_cutout_client_impl.h"
#include "third_party/blink/renderer/core/css/document_style_environment_variables.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
namespace blink {
namespace {
const char kSafeAreaInsetTopName[] = "safe-area-inset-top";
const char kSafeAreaInsetLeftName[] = "safe-area-inset-left";
const char kSafeAreaInsetBottomName[] = "safe-area-inset-bottom";
const char kSafeAreaInsetRightName[] = "safe-area-inset-right";
String GetPx(int value) {
return String::Format("%dpx", value);
}
} // namespace
DisplayCutoutClientImpl::DisplayCutoutClientImpl(
LocalFrame* frame,
mojom::blink::DisplayCutoutClientAssociatedRequest request)
: frame_(frame), binding_(this, std::move(request)) {}
void DisplayCutoutClientImpl::BindMojoRequest(
LocalFrame* frame,
mojom::blink::DisplayCutoutClientAssociatedRequest request) {
if (!frame)
return;
new DisplayCutoutClientImpl(frame, std::move(request));
}
void DisplayCutoutClientImpl::SetSafeArea(
mojom::blink::DisplayCutoutSafeAreaPtr safe_area) {
DocumentStyleEnvironmentVariables& vars =
frame_->GetDocument()->GetStyleEngine().EnsureEnvironmentVariables();
vars.SetVariable(kSafeAreaInsetTopName, GetPx(safe_area->top));
vars.SetVariable(kSafeAreaInsetLeftName, GetPx(safe_area->left));
vars.SetVariable(kSafeAreaInsetBottomName, GetPx(safe_area->bottom));
vars.SetVariable(kSafeAreaInsetRightName, GetPx(safe_area->right));
}
void DisplayCutoutClientImpl::Trace(Visitor* visitor) {
visitor->Trace(frame_);
}
} // namespace blink
// Copyright 2018 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DISPLAY_CUTOUT_CLIENT_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DISPLAY_CUTOUT_CLIENT_IMPL_H_
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "third_party/blink/public/mojom/page/display_cutout.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/heap/member.h"
namespace blink {
class LocalFrame;
// Mojo interface to set CSS environment variables for display cutout.
class CORE_EXPORT DisplayCutoutClientImpl final
: public GarbageCollectedFinalized<DisplayCutoutClientImpl>,
public mojom::blink::DisplayCutoutClient {
public:
static void BindMojoRequest(
LocalFrame*,
mojom::blink::DisplayCutoutClientAssociatedRequest);
// Notify the renderer that the safe areas have changed.
void SetSafeArea(mojom::blink::DisplayCutoutSafeAreaPtr safe_area) override;
void Trace(Visitor*);
private:
DisplayCutoutClientImpl(LocalFrame*,
mojom::blink::DisplayCutoutClientAssociatedRequest);
Member<LocalFrame> frame_;
mojo::AssociatedBinding<mojom::blink::DisplayCutoutClient> binding_;
DISALLOW_COPY_AND_ASSIGN(DisplayCutoutClientImpl);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DISPLAY_CUTOUT_CLIENT_IMPL_H_
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