blob: 8f72ca6dd732665810c0775f64217fc5428266de [file] [log] [blame]
// Copyright 2019 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 "base/command_line.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/base/switches.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "net/dns/mock_host_resolver.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/platform/web_touch_event.h"
#include "ui/display/display_switches.h"
namespace {
// This test verifies renderer event injection works. That is, it verifies
// a renderer can inject events and that they're received by content. It's in
// the Chrome side (not content) so that it can verify events work correctly
// when all of Chrome is brought up. This is especially important for ChromeOS,
// as content tests do not bring up the ChromeOS window-manager (ash).
//
// The parameter is how the display is configured, and is only applicable to
// ChromeOS.
class RendererEventInjectionTest
: public InProcessBrowserTest,
public ::testing::WithParamInterface<const char*> {
public:
RendererEventInjectionTest() {}
~RendererEventInjectionTest() override {}
// InProcessBrowserTest:
void SetUp() override {
scoped_feature_list_.InitAndEnableFeature(
features::kSyntheticPointerActions);
InProcessBrowserTest::SetUp();
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(switches::kDisableRendererBackgrounding);
command_line->AppendSwitch(cc::switches::kEnableGpuBenchmarking);
// kHostWindowBounds is unique to ChromeOS.
#if defined(OS_CHROMEOS)
command_line->AppendSwitchASCII(switches::kHostWindowBounds, GetParam());
#endif
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(embedded_test_server()->Start());
}
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
DISALLOW_COPY_AND_ASSIGN(RendererEventInjectionTest);
};
// Detects when a touch press is received.
class TouchEventObserver
: public content::RenderWidgetHost::InputEventObserver {
public:
TouchEventObserver(const gfx::Point& location,
base::RepeatingClosure quit_closure)
: expected_location_(location), quit_closure_(std::move(quit_closure)) {}
~TouchEventObserver() override = default;
private:
// content::RenderWidgetHost::InputEventObserver:
void OnInputEvent(const blink::WebInputEvent& event) override {
if (blink::WebInputEvent::IsTouchEventType(event.GetType())) {
const blink::WebTouchEvent& web_touch =
static_cast<const blink::WebTouchEvent&>(event);
if (event.GetType() == blink::WebInputEvent::kTouchStart) {
for (unsigned i = 0; i < web_touch.touches_length; i++) {
const blink::WebTouchPoint& touch_point = web_touch.touches[i];
const gfx::Point location(
static_cast<int>(touch_point.PositionInWidget().x),
static_cast<int>(touch_point.PositionInWidget().y));
if (touch_point.state == blink::WebTouchPoint::kStatePressed &&
location == expected_location_) {
quit_closure_.Run();
}
}
}
}
}
const gfx::Point expected_location_;
base::RepeatingClosure quit_closure_;
DISALLOW_COPY_AND_ASSIGN(TouchEventObserver);
};
IN_PROC_BROWSER_TEST_P(RendererEventInjectionTest, TestRootTransform) {
content::WebContents* main_contents =
browser()->tab_strip_model()->GetActiveWebContents();
GURL url = embedded_test_server()->GetURL("/title1.html");
ui_test_utils::NavigateToURL(browser(), url);
base::RunLoop run_loop;
content::RenderWidgetHost* rwh =
main_contents->GetRenderWidgetHostView()->GetRenderWidgetHost();
TouchEventObserver touch_observer(gfx::Point(100, 150),
run_loop.QuitClosure());
rwh->AddInputEventObserver(&touch_observer);
EXPECT_TRUE(ExecJs(main_contents,
"chrome.gpuBenchmarking.tap(100, 150, ()=>{}, "
"50, chrome.gpuBenchmarking.TOUCH_INPUT);"));
run_loop.Run();
rwh->RemoveInputEventObserver(&touch_observer);
}
#if defined(OS_CHROMEOS)
// This configures the display in various interesting ways for ChromeOS. In
// particular, it tests rotation "/r" and a scale factor of 2 "*2".
INSTANTIATE_TEST_SUITE_P(
,
RendererEventInjectionTest,
::testing::Values("1200x800", "1200x800/r", "1200x800*2", "1200x800*2/r"));
#else
INSTANTIATE_TEST_SUITE_P(, RendererEventInjectionTest, ::testing::Values(""));
#endif
} // namespace