chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/342213636): Remove this and spanify to fix the errors.
#pragma allow_unsafe_buffers
#endif

#include <stdlib.h>

#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "content/browser/preloading/prerender/prerender_final_status.h"
#include "content/browser/preloading/prerender/prerender_host_registry.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/screen_orientation/screen_orientation_provider.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/screen_orientation_delegate.h"
#include "content/public/browser/web_contents.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/prerender_test_util.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/common/shell_switches.h"
#include "net/dns/mock_host_resolver.h"
#include "third_party/blink/public/common/features.h"
#include "ui/compositor/compositor_switches.h"
#include "ui/display/screen.h"

namespace content {

class ScreenOrientationBrowserTest : public ContentBrowserTest  {};

class ScreenOrientationOOPIFBrowserTest : public ScreenOrientationBrowserTest {};

// This test doesn't work on MacOS X but the reason is mostly because it is not
// used Aura. It could be set as !BUILDFLAG(IS_MAC) but the rule below will
// actually support MacOS X if and when it switches to Aura.
#if defined(USE_AURA) || BUILDFLAG(IS_ANDROID)
// Flaky on Chrome OS: http://crbug.com/468259
#if BUILDFLAG(IS_CHROMEOS_ASH)
#define MAYBE_ScreenOrientationChange
#else
#define MAYBE_ScreenOrientationChange
#endif
IN_PROC_BROWSER_TEST_F(ScreenOrientationBrowserTest,
                       MAYBE_ScreenOrientationChange) {}
#endif  // defined(USE_AURA) || BUILDFLAG(IS_ANDROID)

// Flaky on Chrome OS: http://crbug.com/468259
#if BUILDFLAG(IS_CHROMEOS_ASH)
#define MAYBE_WindowOrientationChange
#else
#define MAYBE_WindowOrientationChange
#endif
IN_PROC_BROWSER_TEST_F(ScreenOrientationBrowserTest,
                       MAYBE_WindowOrientationChange) {}

// LockSmoke test seems to have become flaky on all non-ChromeOS platforms.
// The cause is unfortunately unknown. See https://crbug.com/448876
// Chromium Android does not support fullscreen
IN_PROC_BROWSER_TEST_F(ScreenOrientationBrowserTest, DISABLED_LockSmoke) {}

// Check that using screen orientation after a frame is detached doesn't crash
// the renderer process.
// This could be a web test if they were not using a mock screen orientation
// controller.
IN_PROC_BROWSER_TEST_F(ScreenOrientationBrowserTest, CrashTest_UseAfterDetach) {}

#if BUILDFLAG(IS_ANDROID)
class ScreenOrientationLockDisabledBrowserTest : public ContentBrowserTest  {
 public:
  ScreenOrientationLockDisabledBrowserTest() {}
  ~ScreenOrientationLockDisabledBrowserTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kDisableScreenOrientationLock);
  }
};

// Check that when --disable-screen-orientation-lock is passed to the command
// line, screen.orientation.lock() correctly reports to not be supported.
IN_PROC_BROWSER_TEST_F(ScreenOrientationLockDisabledBrowserTest,
    DISABLED_NotSupported) {
  GURL test_url = GetTestUrl("screen_orientation",
                             "screen_orientation_lock_disabled.html");

  {
    TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
    shell()->LoadURL(test_url);
    navigation_observer.Wait();
  }

  {
    ASSERT_TRUE(ExecJs(shell(), "run();"));

    TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
    navigation_observer.Wait();
    EXPECT_EQ("NotSupportedError",
              shell()->web_contents()->GetLastCommittedURL().ref());
  }
}
#endif  // BUILDFLAG(IS_ANDROID)

IN_PROC_BROWSER_TEST_F(ScreenOrientationOOPIFBrowserTest, ScreenOrientation) {}

// Regression test for triggering a screen orientation change for a pending
// main frame RenderFrameHost.  See https://crbug.com/764202.  In the bug, this
// was triggered via the DevTools audit panel and
// blink::mojom::FrameWidget::EnableDeviceEmulation, which calls
// RenderWidget::Resize on the renderer side.  The test fakes this by directly
// sending the resize message to the widget.
#if BUILDFLAG(IS_CHROMEOS_ASH)
#define MAYBE_ScreenOrientationInPendingMainFrame
#else
#define MAYBE_ScreenOrientationInPendingMainFrame
#endif
IN_PROC_BROWSER_TEST_F(ScreenOrientationOOPIFBrowserTest,
                       MAYBE_ScreenOrientationInPendingMainFrame) {}

#if BUILDFLAG(IS_ANDROID)
// This test is disabled because th trybots run in system portrait lock, which
// prevents the test from changing the screen orientation.
IN_PROC_BROWSER_TEST_F(ScreenOrientationOOPIFBrowserTest,
                       DISABLED_ScreenOrientationLock) {
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  WaitForResizeComplete(shell()->web_contents());

  const char* types[] = {"portrait-primary", "portrait-secondary",
                         "landscape-primary", "landscape-secondary"};

  FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root();
  FrameTreeNode* child = root->child_at(0);
  RenderFrameHostImpl* frames[] = {root->current_frame_host(),
                                   child->current_frame_host()};

  EXPECT_TRUE(ExecJs(root->current_frame_host(),
                     "document.body.webkitRequestFullscreen()"));
  for (const char* type : types) {
    std::string script =
        base::StringPrintf("screen.orientation.lock('%s')", type);
    EXPECT_TRUE(ExecJs(child->current_frame_host(), script));

    for (auto* frame : frames) {
      std::string orientation_type;
      while (type != orientation_type) {
        orientation_type =
            EvalJs(frame, "screen.orientation.type").ExtractString();
      }
    }

    EXPECT_TRUE(
        ExecJs(child->current_frame_host(), "screen.orientation.unlock()"));
  }
}
#endif  // BUILDFLAG(IS_ANDROID)

class ScreenOrientationLockForPrerenderBrowserTest
    : public ScreenOrientationBrowserTest {};

class FakeScreenOrientationDelegate : public ScreenOrientationDelegate {};

// Unlock should not triggered the orientation upon the completion of a
// non-primary navigation.
IN_PROC_BROWSER_TEST_F(ScreenOrientationLockForPrerenderBrowserTest,
                       ShouldNotUnlockWhenPrerenderNavigation) {}

// Test for ScreenOrientationProvider::DidToggleFullscreenModeForTab which
// overrides from WebContentsObserver. The prerendered page shouldn't trigger
// unlock the screen orientation in fullscreen mode.
IN_PROC_BROWSER_TEST_F(ScreenOrientationLockForPrerenderBrowserTest,
                       KeepFullscreenLockWhilePrerendering) {}

} // namespace content