diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/renderer/input/input_handler_manager.h | 9 | ||||
-rw-r--r-- | content/renderer/input/render_widget_input_handler.h | 8 | ||||
-rw-r--r-- | content/renderer/mus/compositor_mus_connection.cc | 21 | ||||
-rw-r--r-- | content/renderer/mus/compositor_mus_connection.h | 13 | ||||
-rw-r--r-- | content/renderer/mus/compositor_mus_connection_unittest.cc | 466 | ||||
-rw-r--r-- | content/renderer/mus/render_widget_mus_connection.cc | 8 | ||||
-rw-r--r-- | content/renderer/mus/render_widget_mus_connection.h | 5 | ||||
-rw-r--r-- | content/test/BUILD.gn | 3 |
8 files changed, 508 insertions, 25 deletions
diff --git a/content/renderer/input/input_handler_manager.h b/content/renderer/input/input_handler_manager.h index c8bfb75..a77a67e 100644 --- a/content/renderer/input/input_handler_manager.h +++ b/content/renderer/input/input_handler_manager.h @@ -47,7 +47,7 @@ class InputHandlerManager { const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, InputHandlerManagerClient* client, scheduler::RendererScheduler* renderer_scheduler); - ~InputHandlerManager(); + virtual ~InputHandlerManager(); // Callable from the main thread only. void AddInputHandler(int routing_id, @@ -68,9 +68,10 @@ class InputHandlerManager { void RemoveInputHandler(int routing_id); // Called from the compositor's thread. - InputEventAckState HandleInputEvent(int routing_id, - const blink::WebInputEvent* input_event, - ui::LatencyInfo* latency_info); + virtual InputEventAckState HandleInputEvent( + int routing_id, + const blink::WebInputEvent* input_event, + ui::LatencyInfo* latency_info); // Called from the compositor's thread. void DidOverscroll(int routing_id, const DidOverscrollParams& params); diff --git a/content/renderer/input/render_widget_input_handler.h b/content/renderer/input/render_widget_input_handler.h index 3be968c..a82968b 100644 --- a/content/renderer/input/render_widget_input_handler.h +++ b/content/renderer/input/render_widget_input_handler.h @@ -34,12 +34,12 @@ class CONTENT_EXPORT RenderWidgetInputHandler { public: RenderWidgetInputHandler(RenderWidgetInputHandlerDelegate* delegate, RenderWidget* widget); - ~RenderWidgetInputHandler(); + virtual ~RenderWidgetInputHandler(); // Handle input events from the input event provider. - void HandleInputEvent(const blink::WebInputEvent& input_event, - const ui::LatencyInfo& latency_info, - InputEventDispatchType dispatch_type); + virtual void HandleInputEvent(const blink::WebInputEvent& input_event, + const ui::LatencyInfo& latency_info, + InputEventDispatchType dispatch_type); // Handle overscroll from Blink. void DidOverscrollFromBlink( diff --git a/content/renderer/mus/compositor_mus_connection.cc b/content/renderer/mus/compositor_mus_connection.cc index 6973de6..f469f56 100644 --- a/content/renderer/mus/compositor_mus_connection.cc +++ b/content/renderer/mus/compositor_mus_connection.cc @@ -11,6 +11,12 @@ #include "mojo/converters/blink/blink_input_events_type_converters.h" #include "ui/events/latency_info.h" +namespace { + +void DoNothingBool(bool result) {} + +} // namespace + namespace content { CompositorMusConnection::CompositorMusConnection( @@ -71,21 +77,22 @@ void CompositorMusConnection::OnConnectionLostOnMainThread() { void CompositorMusConnection::OnWindowInputEventOnMainThread( scoped_ptr<blink::WebInputEvent> web_event, - const base::Closure& ack) { + const base::Callback<void(bool)>& ack) { DCHECK(main_task_runner_->BelongsToCurrentThread()); RenderWidgetMusConnection* connection = RenderWidgetMusConnection::Get(routing_id_); if (!connection) { - ack.Run(); + ack.Run(false); return; } connection->OnWindowInputEvent(std::move(web_event), ack); } void CompositorMusConnection::OnWindowInputEventAckOnMainThread( - const base::Closure& ack) { + const base::Callback<void(bool)>& ack, + bool handled) { DCHECK(main_task_runner_->BelongsToCurrentThread()); - compositor_task_runner_->PostTask(FROM_HERE, ack); + compositor_task_runner_->PostTask(FROM_HERE, base::Bind(ack, handled)); } void CompositorMusConnection::OnConnectionLost( @@ -109,7 +116,7 @@ void CompositorMusConnection::OnEmbed(mus::Window* root) { void CompositorMusConnection::OnWindowInputEvent( mus::Window* window, mus::mojom::EventPtr event, - scoped_ptr<base::Closure>* ack_callback) { + scoped_ptr<base::Callback<void(bool)>>* ack_callback) { DCHECK(compositor_task_runner_->BelongsToCurrentThread()); scoped_ptr<blink::WebInputEvent> web_event = event.To<scoped_ptr<blink::WebInputEvent>>(); @@ -117,9 +124,11 @@ void CompositorMusConnection::OnWindowInputEvent( ui::LatencyInfo info; InputEventAckState ack_state = input_handler_manager_->HandleInputEvent( routing_id_, web_event.get(), &info); + // TODO(jonross): We probably need to ack the event based on the consumed + // state. if (ack_state != INPUT_EVENT_ACK_STATE_NOT_CONSUMED) return; - base::Closure ack = base::Bind(&base::DoNothing); + base::Callback<void(bool)> ack = base::Bind(&::DoNothingBool); const bool send_ack = WebInputEventTraits::WillReceiveAckFromRenderer(*web_event); if (send_ack) { diff --git a/content/renderer/mus/compositor_mus_connection.h b/content/renderer/mus/compositor_mus_connection.h index 7b0f696..a2c377e 100644 --- a/content/renderer/mus/compositor_mus_connection.h +++ b/content/renderer/mus/compositor_mus_connection.h @@ -42,6 +42,7 @@ class CompositorMusConnection scoped_ptr<mus::WindowSurfaceBinding> surface_binding); private: + friend class CompositorMusConnectionTest; friend class base::RefCountedThreadSafe<CompositorMusConnection>; ~CompositorMusConnection() override; @@ -56,18 +57,20 @@ class CompositorMusConnection void OnWindowInputEventOnMainThread( scoped_ptr<blink::WebInputEvent> web_event, - const base::Closure& ack); + const base::Callback<void(bool)>& ack); - void OnWindowInputEventAckOnMainThread(const base::Closure& ack); + void OnWindowInputEventAckOnMainThread(const base::Callback<void(bool)>& ack, + bool handled); // WindowTreeDelegate implementation: void OnConnectionLost(mus::WindowTreeConnection* connection) override; void OnEmbed(mus::Window* root) override; // InputEventHandler implementation: - void OnWindowInputEvent(mus::Window* window, - mus::mojom::EventPtr event, - scoped_ptr<base::Closure>* ack_callback) override; + void OnWindowInputEvent( + mus::Window* window, + mus::mojom::EventPtr event, + scoped_ptr<base::Callback<void(bool)>>* ack_callback) override; const int routing_id_; mus::Window* root_; diff --git a/content/renderer/mus/compositor_mus_connection_unittest.cc b/content/renderer/mus/compositor_mus_connection_unittest.cc new file mode 100644 index 0000000..0b75f2f --- /dev/null +++ b/content/renderer/mus/compositor_mus_connection_unittest.cc @@ -0,0 +1,466 @@ +// Copyright 2016 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 "content/renderer/mus/compositor_mus_connection.h" + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/test/test_simple_task_runner.h" +#include "base/time/time.h" +#include "components/mus/public/cpp/tests/test_window.h" +#include "components/mus/public/interfaces/input_event_constants.mojom.h" +#include "components/mus/public/interfaces/input_events.mojom.h" +#include "components/mus/public/interfaces/input_key_codes.mojom.h" +#include "content/common/input/did_overscroll_params.h" +#include "content/common/input/input_event_ack.h" +#include "content/common/input/input_event_ack_state.h" +#include "content/public/test/mock_render_thread.h" +#include "content/renderer/input/input_handler_manager.h" +#include "content/renderer/input/input_handler_manager_client.h" +#include "content/renderer/input/render_widget_input_handler.h" +#include "content/renderer/mus/render_widget_mus_connection.h" +#include "content/renderer/render_widget.h" +#include "content/test/fake_compositor_dependencies.h" +#include "content/test/fake_renderer_scheduler.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +// Wrapper for the callback provided to +// CompositorMusConnection:OnWindowInputEvent. This tracks whether the it was +// called, along with the result. +class TestCallback : public base::RefCounted<TestCallback> { + public: + TestCallback() : called_(false), result_(false) {} + + bool called() { return called_; } + bool result() { return result_; } + + void BoolCallback(bool result) { + called_ = true; + result_ = result; + } + + private: + friend class base::RefCounted<TestCallback>; + + ~TestCallback() {} + + bool called_; + bool result_; + + DISALLOW_COPY_AND_ASSIGN(TestCallback); +}; + +// Allows for overriding the behaviour of HandleInputEvent, to simulate input +// handlers which consume events before they are sent to the renderer. +class TestInputHandlerManager : public content::InputHandlerManager { + public: + TestInputHandlerManager( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + content::InputHandlerManagerClient* client, + scheduler::RendererScheduler* renderer_scheduler) + : InputHandlerManager(task_runner, client, renderer_scheduler), + override_result_(false), + result_(content::InputEventAckState::INPUT_EVENT_ACK_STATE_UNKNOWN) {} + ~TestInputHandlerManager() override {} + + // Stops overriding the behaviour of HandleInputEvent + void ClearHandleInputEventOverride(); + + // Overrides the behaviour of HandleInputEvent, returing |result|. + void SetHandleInputEventResult(content::InputEventAckState result); + + // content::InputHandlerManager: + content::InputEventAckState HandleInputEvent( + int routing_id, + const blink::WebInputEvent* input_event, + ui::LatencyInfo* latency_info) override; + + private: + // If true content::InputHandlerManager::HandleInputEvent is not called. + bool override_result_; + + // The result to return in HandleInputEvent if |override_result_|. + content::InputEventAckState result_; + + DISALLOW_COPY_AND_ASSIGN(TestInputHandlerManager); +}; + +void TestInputHandlerManager::ClearHandleInputEventOverride() { + override_result_ = false; +} + +void TestInputHandlerManager::SetHandleInputEventResult( + content::InputEventAckState result) { + override_result_ = true; + result_ = result; +} + +content::InputEventAckState TestInputHandlerManager::HandleInputEvent( + int routing_id, + const blink::WebInputEvent* input_event, + ui::LatencyInfo* latency_info) { + if (override_result_) + return result_; + return content::InputHandlerManager::HandleInputEvent(routing_id, input_event, + latency_info); +} + +// Empty implementation of InputHandlerManagerClient. +class TestInputHandlerManagerClient + : public content::InputHandlerManagerClient { + public: + TestInputHandlerManagerClient() {} + ~TestInputHandlerManagerClient() override{}; + + // content::InputHandlerManagerClient: + void SetBoundHandler(const Handler& handler) override {} + void DidAddInputHandler( + int routing_id, + ui::SynchronousInputHandlerProxy* synchronous_handler) override {} + void DidRemoveInputHandler(int routing_id) override {} + void DidOverscroll(int routing_id, + const content::DidOverscrollParams& params) override {} + void DidStopFlinging(int routing_id) override {} + void NonBlockingInputEventHandled(int routing_id, + blink::WebInputEvent::Type type) override {} + + private: + DISALLOW_COPY_AND_ASSIGN(TestInputHandlerManagerClient); +}; + +// Implementation of RenderWidget for testing, performs no initialization. +class TestRenderWidget : public content::RenderWidget { + public: + explicit TestRenderWidget(content::CompositorDependencies* compositor_deps) + : content::RenderWidget(compositor_deps, + blink::WebPopupTypeNone, + blink::WebScreenInfo(), + true, + false, + false) {} + + protected: + ~TestRenderWidget() override {} + + private: + DISALLOW_COPY_AND_ASSIGN(TestRenderWidget); +}; + +// Test override of RenderWidgetInputHandler to allow the control of +// HandleInputEvent. This will perform no actions on input until a +// RenderWidgetInputHandlerDelegate is set. Once set this will always ack +// received events. +class TestRenderWidgetInputHandler : public content::RenderWidgetInputHandler { + public: + TestRenderWidgetInputHandler(content::RenderWidget* render_widget); + ~TestRenderWidgetInputHandler() override {} + + void set_delegate(content::RenderWidgetInputHandlerDelegate* delegate) { + delegate_ = delegate; + } + void set_state(content::InputEventAckState state) { state_ = state; } + + // content::RenderWidgetInputHandler: + void HandleInputEvent(const blink::WebInputEvent& input_event, + const ui::LatencyInfo& latency_info, + content::InputEventDispatchType dispatch_type) override; + + private: + // The input delegate which receives event acks. + content::RenderWidgetInputHandlerDelegate* delegate_; + + // The result of input handling to send to |delegate_| during the ack. + content::InputEventAckState state_; + + DISALLOW_COPY_AND_ASSIGN(TestRenderWidgetInputHandler); +}; + +TestRenderWidgetInputHandler::TestRenderWidgetInputHandler( + content::RenderWidget* render_widget) + : content::RenderWidgetInputHandler(render_widget, render_widget), + delegate_(nullptr), + state_(content::InputEventAckState::INPUT_EVENT_ACK_STATE_UNKNOWN) {} + +void TestRenderWidgetInputHandler::HandleInputEvent( + const blink::WebInputEvent& input_event, + const ui::LatencyInfo& latency_info, + content::InputEventDispatchType dispatch_type) { + if (delegate_) { + scoped_ptr<content::InputEventAck> ack( + new content::InputEventAck(input_event.type, state_)); + delegate_->OnInputEventAck(std::move(ack)); + } +} + +} // namespace + +namespace content { + +// Test suite for CompositorMusConnection, this does not setup a full renderer +// environment. This does not establish a connection to a mus server, nor does +// it initialize one. +class CompositorMusConnectionTest : public testing::Test { + public: + CompositorMusConnectionTest() {} + ~CompositorMusConnectionTest() override {} + + // Initializes |event| with valid parameters for a key event, so that it can + // be converted to a web event by CompositorMusConnection. + void GenerateKeyEvent(mus::mojom::EventPtr& event); + + // Calls CompositorMusConnection::OnWindowInputEvent. + void OnWindowInputEvent(mus::Window* window, + mus::mojom::EventPtr event, + scoped_ptr<base::Callback<void(bool)>>* ack_callback); + + // Confirms the state of pending tasks enqueued on each task runner, and runs + // until idle. + void VerifyAndRunQueues(bool main_task_runner_enqueued, + bool compositor_task_runner_enqueued); + + CompositorMusConnection* compositor_connection() { + return compositor_connection_.get(); + } + RenderWidgetMusConnection* connection() { return connection_; } + TestInputHandlerManager* input_handler_manager() { + return input_handler_manager_.get(); + } + TestRenderWidgetInputHandler* render_widget_input_handler() { + return render_widget_input_handler_.get(); + } + + // testing::Test: + void SetUp() override; + void TearDown() override; + + private: + // Mocks/Fakes of the testing environment. + TestInputHandlerManagerClient input_handler_manager_client_; + FakeCompositorDependencies compositor_dependencies_; + FakeRendererScheduler renderer_scheduler_; + MockRenderThread render_thread_; + scoped_refptr<TestRenderWidget> render_widget_; + mojo::InterfaceRequest<mus::mojom::WindowTreeClient> request_; + + // Not owned, RenderWidgetMusConnection tracks in static state. Cleared during + // TearDown. + RenderWidgetMusConnection* connection_; + + // Test versions of task runners, see VerifyAndRunQueues to use in testing. + scoped_refptr<base::TestSimpleTaskRunner> main_task_runner_; + scoped_refptr<base::TestSimpleTaskRunner> compositor_task_runner_; + + // Actual CompositorMusConnection for testing. + scoped_refptr<CompositorMusConnection> compositor_connection_; + + // Test implementations, to control input given to |compositor_connection_|. + scoped_ptr<TestInputHandlerManager> input_handler_manager_; + scoped_ptr<TestRenderWidgetInputHandler> render_widget_input_handler_; + + DISALLOW_COPY_AND_ASSIGN(CompositorMusConnectionTest); +}; + +void CompositorMusConnectionTest::GenerateKeyEvent( + mus::mojom::EventPtr& event) { + event->action = mus::mojom::EventType::KEY_PRESSED; + event->time_stamp = base::TimeTicks::Now().ToInternalValue(); + event->key_data = mus::mojom::KeyData::New(); + event->key_data->is_char = true; + event->key_data->windows_key_code = mus::mojom::KeyboardCode::A; +} + +void CompositorMusConnectionTest::OnWindowInputEvent( + mus::Window* window, + mus::mojom::EventPtr event, + scoped_ptr<base::Callback<void(bool)>>* ack_callback) { + compositor_connection_->OnWindowInputEvent(window, std::move(event), + ack_callback); +} + +void CompositorMusConnectionTest::VerifyAndRunQueues( + bool main_task_runner_enqueued, + bool compositor_task_runner_enqueued) { + // Run through the enqueued actions. + EXPECT_EQ(main_task_runner_enqueued, main_task_runner_->HasPendingTask()); + main_task_runner_->RunUntilIdle(); + + EXPECT_EQ(compositor_task_runner_enqueued, + compositor_task_runner_->HasPendingTask()); + compositor_task_runner_->RunUntilIdle(); +} + +void CompositorMusConnectionTest::SetUp() { + testing::Test::SetUp(); + + main_task_runner_ = new base::TestSimpleTaskRunner(); + compositor_task_runner_ = new base::TestSimpleTaskRunner(); + + input_handler_manager_.reset(new TestInputHandlerManager( + compositor_task_runner_, &input_handler_manager_client_, + &renderer_scheduler_)); + + const int routing_id = 42; + compositor_connection_ = new CompositorMusConnection( + routing_id, main_task_runner_, compositor_task_runner_, + std::move(request_), input_handler_manager_.get()); + + // CompositorMusConnection attempts to create connection to the non-existant + // server. Clear that. + compositor_task_runner_->ClearPendingTasks(); + + render_widget_ = new TestRenderWidget(&compositor_dependencies_); + render_widget_input_handler_.reset( + new TestRenderWidgetInputHandler(render_widget_.get())); + connection_ = RenderWidgetMusConnection::GetOrCreate(routing_id); + connection_->SetInputHandler(render_widget_input_handler_.get()); +} + +void CompositorMusConnectionTest::TearDown() { + // Clear static state. + connection_->OnConnectionLost(); + testing::Test::TearDown(); +} + +// Tests that for events which the renderer will ack, yet not consume, that +// CompositorMusConnection consumes the ack during OnWindowInputEvent, and calls +// it with the correct state once processed. +TEST_F(CompositorMusConnectionTest, NotConsumed) { + TestRenderWidgetInputHandler* input_handler = render_widget_input_handler(); + input_handler->set_delegate(connection()); + input_handler->set_state( + InputEventAckState::INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + + mus::TestWindow test_window; + mus::mojom::EventPtr event = mus::mojom::Event::New(); + GenerateKeyEvent(event); + scoped_refptr<TestCallback> test_callback(new TestCallback); + scoped_ptr<base::Callback<void(bool)>> ack_callback( + new base::Callback<void(bool)>( + base::Bind(&::TestCallback::BoolCallback, test_callback))); + + OnWindowInputEvent(&test_window, std::move(event), &ack_callback); + // OnWindowInputEvent is expected to clear the callback if it plans on + // handling the ack. + EXPECT_FALSE(ack_callback.get()); + + VerifyAndRunQueues(true, true); + + // The ack callback should have been called + EXPECT_TRUE(test_callback->called()); + EXPECT_FALSE(test_callback->result()); +} + +// Tests that for events which the renderer will ack, and consume, that +// CompositorMusConnection consumes the ack during OnWindowInputEvent, and calls +// it with the correct state once processed. +TEST_F(CompositorMusConnectionTest, Consumed) { + TestRenderWidgetInputHandler* input_handler = render_widget_input_handler(); + input_handler->set_delegate(connection()); + input_handler->set_state(InputEventAckState::INPUT_EVENT_ACK_STATE_CONSUMED); + + mus::TestWindow test_window; + mus::mojom::EventPtr event = mus::mojom::Event::New(); + GenerateKeyEvent(event); + scoped_refptr<TestCallback> test_callback(new TestCallback); + scoped_ptr<base::Callback<void(bool)>> ack_callback( + new base::Callback<void(bool)>( + base::Bind(&::TestCallback::BoolCallback, test_callback))); + + OnWindowInputEvent(&test_window, std::move(event), &ack_callback); + // OnWindowInputEvent is expected to clear the callback if it plans on + // handling the ack. + EXPECT_FALSE(ack_callback.get()); + + VerifyAndRunQueues(true, true); + + // The ack callback should have been called + EXPECT_TRUE(test_callback->called()); + EXPECT_TRUE(test_callback->result()); +} + +// Tests that when the RenderWidgetInputHandler does not ack before a new event +// arrives, that only the most recent ack is fired. +TEST_F(CompositorMusConnectionTest, LostAck) { + mus::TestWindow test_window; + mus::mojom::EventPtr event1 = mus::mojom::Event::New(); + GenerateKeyEvent(event1); + scoped_refptr<TestCallback> test_callback1(new TestCallback); + scoped_ptr<base::Callback<void(bool)>> ack_callback1( + new base::Callback<void(bool)>( + base::Bind(&::TestCallback::BoolCallback, test_callback1))); + + OnWindowInputEvent(&test_window, std::move(event1), &ack_callback1); + EXPECT_FALSE(ack_callback1.get()); + // When simulating the timeout the ack is never enqueued + VerifyAndRunQueues(true, false); + + // Setting a delegate will lead to the next event being acked. Having a + // cleared queue simulates the input handler timing out on an event. + TestRenderWidgetInputHandler* input_handler = render_widget_input_handler(); + input_handler->set_delegate(connection()); + input_handler->set_state(InputEventAckState::INPUT_EVENT_ACK_STATE_CONSUMED); + + mus::mojom::EventPtr event2 = mus::mojom::Event::New(); + GenerateKeyEvent(event2); + scoped_refptr<TestCallback> test_callback2(new TestCallback); + scoped_ptr<base::Callback<void(bool)>> ack_callback2( + new base::Callback<void(bool)>( + base::Bind(&::TestCallback::BoolCallback, test_callback2))); + OnWindowInputEvent(&test_window, std::move(event2), &ack_callback2); + EXPECT_FALSE(ack_callback2.get()); + + VerifyAndRunQueues(true, true); + + // Only the most recent ack was called. + EXPECT_FALSE(test_callback1->called()); + EXPECT_TRUE(test_callback2->called()); + EXPECT_TRUE(test_callback2->result()); +} + +// Tests that when an input handler consumes the event, that +// CompositorMusConnection does not consume the ack, nor calls it. +TEST_F(CompositorMusConnectionTest, InputHandlerConsumes) { + input_handler_manager()->SetHandleInputEventResult( + InputEventAckState::INPUT_EVENT_ACK_STATE_CONSUMED); + mus::TestWindow test_window; + mus::mojom::EventPtr event = mus::mojom::Event::New(); + GenerateKeyEvent(event); + scoped_refptr<TestCallback> test_callback(new TestCallback); + scoped_ptr<base::Callback<void(bool)>> ack_callback( + new base::Callback<void(bool)>( + base::Bind(&::TestCallback::BoolCallback, test_callback))); + + OnWindowInputEvent(&test_window, std::move(event), &ack_callback); + + EXPECT_TRUE(ack_callback.get()); + VerifyAndRunQueues(false, false); + EXPECT_FALSE(test_callback->called()); +} + +// Tests that when the renderer will not ack an event, that +// CompositorMusConnection does not consume the ack, nor calls it. +TEST_F(CompositorMusConnectionTest, RendererWillNotSendAck) { + mus::TestWindow test_window; + mus::mojom::EventPtr event = mus::mojom::Event::New(); + event->action = mus::mojom::EventType::POINTER_DOWN; + event->time_stamp = base::TimeTicks::Now().ToInternalValue(); + event->pointer_data = mus::mojom::PointerData::New(); + + scoped_refptr<TestCallback> test_callback(new TestCallback); + scoped_ptr<base::Callback<void(bool)>> ack_callback( + new base::Callback<void(bool)>( + base::Bind(&::TestCallback::BoolCallback, test_callback))); + + OnWindowInputEvent(&test_window, std::move(event), &ack_callback); + EXPECT_TRUE(ack_callback.get()); + + VerifyAndRunQueues(true, false); + EXPECT_FALSE(test_callback->called()); +} + +} // namespace content diff --git a/content/renderer/mus/render_widget_mus_connection.cc b/content/renderer/mus/render_widget_mus_connection.cc index c2dc1d1..bced0df 100644 --- a/content/renderer/mus/render_widget_mus_connection.cc +++ b/content/renderer/mus/render_widget_mus_connection.cc @@ -118,8 +118,8 @@ void RenderWidgetMusConnection::OnDidOverscroll( void RenderWidgetMusConnection::OnInputEventAck( scoped_ptr<InputEventAck> input_event_ack) { DCHECK(!pending_ack_.is_null()); - // TODO(fsamuel): Use the state in |input_event_ack|. - pending_ack_.Run(); + pending_ack_.Run(input_event_ack->state == + InputEventAckState::INPUT_EVENT_ACK_STATE_CONSUMED); pending_ack_.Reset(); } @@ -161,12 +161,12 @@ void RenderWidgetMusConnection::OnConnectionLost() { void RenderWidgetMusConnection::OnWindowInputEvent( scoped_ptr<blink::WebInputEvent> input_event, - const base::Closure& ack) { + const base::Callback<void(bool)>& ack) { DCHECK(thread_checker_.CalledOnValidThread()); // If we don't yet have a RenderWidgetInputHandler then we don't yet have // an initialized RenderWidget. if (!input_handler_) { - ack.Run(); + ack.Run(false); return; } // TODO(fsamuel): It would be nice to add this DCHECK but the reality is an diff --git a/content/renderer/mus/render_widget_mus_connection.h b/content/renderer/mus/render_widget_mus_connection.h index 26f1b4b..1c9bc03 100644 --- a/content/renderer/mus/render_widget_mus_connection.h +++ b/content/renderer/mus/render_widget_mus_connection.h @@ -33,6 +33,7 @@ class RenderWidgetMusConnection : public RenderWidgetInputHandlerDelegate { private: friend class CompositorMusConnection; + friend class CompositorMusConnectionTest; explicit RenderWidgetMusConnection(int routing_id); ~RenderWidgetMusConnection() override; @@ -56,14 +57,14 @@ class RenderWidgetMusConnection : public RenderWidgetInputHandlerDelegate { void OnConnectionLost(); void OnWindowInputEvent(scoped_ptr<blink::WebInputEvent> input_event, - const base::Closure& ack); + const base::Callback<void(bool)>& ack); const int routing_id_; RenderWidgetInputHandler* input_handler_; scoped_ptr<mus::WindowSurfaceBinding> window_surface_binding_; scoped_refptr<CompositorMusConnection> compositor_mus_connection_; - base::Closure pending_ack_; + base::Callback<void(bool)> pending_ack_; // Used to verify single threaded access. base::ThreadChecker thread_checker_; diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 55e264e..1070e26 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn @@ -765,10 +765,13 @@ test("content_unittests") { if (use_aura) { deps += [ + "//content/public/renderer:renderer_sources", + "//content/renderer/mus:mus", "//ui/aura", "//ui/aura_extra", "//ui/wm", ] + sources += [ "../renderer/mus/compositor_mus_connection_unittest.cc" ] } else { sources -= [ "../browser/renderer_host/render_widget_host_view_aura_unittest.cc", |