#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/browser/display_cutout/display_cutout_constants.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h"
#include "third_party/blink/public/mojom/page/display_cutout.mojom.h"
namespace content {
namespace {
#if BUILDFLAG(IS_ANDROID)
const auto kNoCutoutInsets = gfx::Insets();
const auto kCutoutInsets = gfx::Insets::TLBR(1, 0, 1, 0);
const auto kRotatedCutoutInsets = gfx::Insets::TLBR(0, 1, 0, 1);
#endif
class TestWebContentsObserver : public WebContentsObserver { … };
class DisplayCutoutWebContentsDelegate : public WebContentsDelegate { … };
const char kTestHTML[] = …;
}
class DisplayCutoutBrowserTest : public ContentBrowserTest { … };
#if BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, ViewportFit_Fullscreen) {
LoadTestPageWithViewportFitFromMeta("cover");
LoadSubFrameWithViewportFitMetaValue("contain");
{
TestWebContentsObserver observer(web_contents_impl());
SimulateFullscreenStateChanged(MainFrame(), true);
observer.WaitForWantedValue(blink::mojom::ViewportFit::kCover);
web_contents_impl()->SetDisplayCutoutSafeArea(kCutoutInsets);
}
{
TestWebContentsObserver observer(web_contents_impl());
SimulateFullscreenStateChanged(ChildFrame(), true);
observer.WaitForWantedValue(blink::mojom::ViewportFit::kContain);
web_contents_impl()->SetDisplayCutoutSafeArea(kNoCutoutInsets);
}
{
TestWebContentsObserver observer(web_contents_impl());
SimulateFullscreenStateChanged(ChildFrame(), false);
observer.WaitForWantedValue(blink::mojom::ViewportFit::kCover);
web_contents_impl()->SetDisplayCutoutSafeArea(kCutoutInsets);
web_contents_impl()->SetDisplayCutoutSafeArea(kRotatedCutoutInsets);
}
{
TestWebContentsObserver observer(web_contents_impl());
SimulateFullscreenStateChanged(MainFrame(), false);
SimulateFullscreenExit();
observer.WaitForWantedValue(blink::mojom::ViewportFit::kAuto);
web_contents_impl()->SetDisplayCutoutSafeArea(kNoCutoutInsets);
}
shell()->Close();
}
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest,
ViewportFit_Fullscreen_Update) {
LoadTestPageWithViewportFitFromMeta("cover");
{
TestWebContentsObserver observer(web_contents_impl());
SimulateFullscreenStateChanged(MainFrame(), true);
observer.WaitForWantedValue(blink::mojom::ViewportFit::kCover);
web_contents_impl()->SetDisplayCutoutSafeArea(kNoCutoutInsets);
}
{
TestWebContentsObserver observer(web_contents_impl());
ClearViewportFitTag();
observer.WaitForWantedValue(blink::mojom::ViewportFit::kAuto);
web_contents_impl()->SetDisplayCutoutSafeArea(kNoCutoutInsets);
}
shell()->Close();
}
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, ViewportFit_Noop_Navigate) {
{
TestWebContentsObserver observer(web_contents_impl());
LoadTestPageWithViewportFitFromMeta("cover");
EXPECT_FALSE(observer.has_value());
}
LoadTestPageWithData("");
}
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest,
ViewportFit_Noop_WebContentsDestroyed) {
{
TestWebContentsObserver observer(web_contents_impl());
LoadTestPageWithViewportFitFromMeta("cover");
EXPECT_FALSE(observer.has_value());
}
shell()->Close();
}
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, WebDisplayMode) {
std::unique_ptr<DisplayCutoutWebContentsDelegate> delegate(
new DisplayCutoutWebContentsDelegate());
web_contents_impl()->SetDelegate(delegate.get());
EXPECT_EQ(delegate.get(), web_contents_impl()->GetDelegate());
{
TestWebContentsObserver observer(web_contents_impl());
LoadTestPageWithViewportFitFromMeta("cover");
EXPECT_FALSE(observer.has_value());
}
}
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, WebDisplayMode_Fullscreen) {
std::unique_ptr<DisplayCutoutWebContentsDelegate> delegate(
new DisplayCutoutWebContentsDelegate());
delegate->SetDisplayMode(blink::mojom::DisplayMode::kFullscreen);
web_contents_impl()->SetDelegate(delegate.get());
EXPECT_EQ(delegate.get(), web_contents_impl()->GetDelegate());
{
TestWebContentsObserver observer(web_contents_impl());
LoadTestPageWithViewportFitFromMeta("cover");
observer.WaitForWantedValue(blink::mojom::ViewportFit::kCover);
}
}
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, WebDisplayMode_Standalone) {
std::unique_ptr<DisplayCutoutWebContentsDelegate> delegate(
new DisplayCutoutWebContentsDelegate());
delegate->SetDisplayMode(blink::mojom::DisplayMode::kStandalone);
web_contents_impl()->SetDelegate(delegate.get());
EXPECT_EQ(delegate.get(), web_contents_impl()->GetDelegate());
{
TestWebContentsObserver observer(web_contents_impl());
LoadTestPageWithViewportFitFromMeta("cover");
EXPECT_FALSE(observer.has_value());
}
}
#endif
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, PublishSafeAreaVariables) { … }
#if BUILDFLAG(IS_ANDROID)
class DisplayCutoutBrowserWithEdgeToEdgeTest : public DisplayCutoutBrowserTest {
public:
DisplayCutoutBrowserWithEdgeToEdgeTest() = default;
DisplayCutoutBrowserWithEdgeToEdgeTest(
const DisplayCutoutBrowserWithEdgeToEdgeTest&) = delete;
DisplayCutoutBrowserWithEdgeToEdgeTest& operator=(
const DisplayCutoutBrowserWithEdgeToEdgeTest&) = delete;
void SetUp() override {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
{features::kDrawCutoutEdgeToEdge},
{});
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
embedded_test_server()->ServeFilesFromDirectory(temp_dir_.GetPath());
ASSERT_TRUE(embedded_test_server()->Start());
ContentBrowserTest::SetUp();
}
};
IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserWithEdgeToEdgeTest,
FullscreenExitBeforeNavigationCompletes) {
TestWebContentsObserver observer(web_contents_impl());
SimulateFullscreenExit();
}
#endif
}