| // 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 |