// Copyright 2013 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/auto_reset.h" #include "base/command_line.h" #include "base/location.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/browser/gpu/compositor_util.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/input/synthetic_web_input_event_builders.h" #include "content/common/input_messages.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/common/content_switches.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/shell/browser/shell.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/events/event_switches.h" #include "ui/events/latency_info.h" using blink::WebInputEvent; namespace { void GiveItSomeTime() { base::RunLoop run_loop; base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMilliseconds(10)); run_loop.Run(); } const char kTouchEventDataURL[] = "data:text/html;charset=utf-8," #if defined(OS_ANDROID) "" "" "" #endif "" "
" "" ""; } // namespace namespace content { class TouchInputBrowserTest : public ContentBrowserTest { public: TouchInputBrowserTest() {} ~TouchInputBrowserTest() override {} RenderWidgetHostImpl* GetWidgetHost() { return RenderWidgetHostImpl::From( shell()->web_contents()->GetRenderViewHost()->GetWidget()); } scoped_refptr AddFilter(blink::WebInputEvent::Type type) { return new InputMsgWatcher(GetWidgetHost(), type); } protected: void LoadURL() { const GURL data_url(kTouchEventDataURL); NavigateToURL(shell(), data_url); RenderWidgetHostImpl* host = GetWidgetHost(); host->GetView()->SetSize(gfx::Size(400, 400)); // The page is loaded in the renderer, wait for a new frame to arrive. while (!host->ScheduleComposite()) GiveItSomeTime(); } void SetUpCommandLine(base::CommandLine* cmd) override { cmd->AppendSwitchASCII(switches::kTouchEvents, switches::kTouchEventsEnabled); } }; #if defined(OS_MACOSX) // TODO(ccameron): Failing on mac: crbug.com/346363 #define MAYBE_TouchNoHandler DISABLED_TouchNoHandler #else #define MAYBE_TouchNoHandler TouchNoHandler #endif IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchNoHandler) { LoadURL(); SyntheticWebTouchEvent touch; // A press on |first| should be acked with NO_CONSUMER_EXISTS since there is // no touch-handler on it. touch.PressPoint(25, 25); scoped_refptr filter = AddFilter(WebInputEvent::TouchStart); GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, filter->WaitForAck()); // If a touch-press is acked with NO_CONSUMER_EXISTS, then subsequent // touch-points don't need to be dispatched until the touch point is released. touch.ReleasePoint(0); GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); touch.ResetPoints(); } #if defined(OS_CHROMEOS) // crbug.com/514456 #define MAYBE_TouchHandlerNoConsume DISABLED_TouchHandlerNoConsume #else #define MAYBE_TouchHandlerNoConsume TouchHandlerNoConsume #endif IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchHandlerNoConsume) { LoadURL(); SyntheticWebTouchEvent touch; // Press on |second| should be acked with NOT_CONSUMED since there is a // touch-handler on |second|, but it doesn't consume the event. touch.PressPoint(125, 25); scoped_refptr filter = AddFilter(WebInputEvent::TouchStart); GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter->WaitForAck()); filter = AddFilter(WebInputEvent::TouchEnd); touch.ReleasePoint(0); GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); touch.ResetPoints(); filter->WaitForAck(); } #if defined(OS_CHROMEOS) // crbug.com/514456 #define MAYBE_TouchHandlerConsume DISABLED_TouchHandlerConsume #else #define MAYBE_TouchHandlerConsume TouchHandlerConsume #endif IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_TouchHandlerConsume) { LoadURL(); SyntheticWebTouchEvent touch; // Press on |third| should be acked with CONSUMED since the touch-handler on // |third| consimes the event. touch.PressPoint(25, 125); scoped_refptr filter = AddFilter(WebInputEvent::TouchStart); GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter->WaitForAck()); touch.ReleasePoint(0); filter = AddFilter(WebInputEvent::TouchEnd); GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); filter->WaitForAck(); } #if defined(OS_CHROMEOS) // crbug.com/514456 #define MAYBE_MultiPointTouchPress DISABLED_MultiPointTouchPress #elif defined(OS_MACOSX) // TODO(ccameron): Failing on mac: crbug.com/346363 #define MAYBE_MultiPointTouchPress DISABLED_MultiPointTouchPress #else #define MAYBE_MultiPointTouchPress MultiPointTouchPress #endif IN_PROC_BROWSER_TEST_F(TouchInputBrowserTest, MAYBE_MultiPointTouchPress) { LoadURL(); SyntheticWebTouchEvent touch; // Press on |first|, which sould be acked with NO_CONSUMER_EXISTS. Then press // on |third|. That point should be acked with CONSUMED. touch.PressPoint(25, 25); scoped_refptr filter = AddFilter(WebInputEvent::TouchStart); GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, filter->WaitForAck()); touch.PressPoint(25, 125); filter = AddFilter(WebInputEvent::TouchStart); GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch, ui::LatencyInfo()); EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, filter->WaitForAck()); } } // namespace content