From 07a19a2bc8560ce5e99cd27a9830089683153046 Mon Sep 17 00:00:00 2001 From: sadrul Date: Mon, 7 Dec 2015 14:57:03 -0800 Subject: mus: Allow a mus app to manually/explicitly ack an event. Instead of dispatching an input event to all mus::WindowObservers of a mus::Window, have an explicit mus::InputEventHandler, which is responsible for processing events for a Window. The InputEventHandler receives the target, the event, and the ack callback. If it wants to explicitly ack the event (possibly asynchronously, e.g. chrome renderer, when it receives the event in the compositor thread, but wants to process the event in the main thread before ack'ing), it can take the ack callback, and return true to notify the client-lib. BUG=none Review URL: https://codereview.chromium.org/1492963003 Cr-Commit-Position: refs/heads/master@{#363617} --- components/mus/public/cpp/tests/BUILD.gn | 2 + .../mus/public/cpp/tests/test_window_tree.cc | 11 +++- components/mus/public/cpp/tests/test_window_tree.h | 5 ++ .../cpp/tests/window_tree_client_impl_unittest.cc | 75 ++++++++++++++++++++++ 4 files changed, 92 insertions(+), 1 deletion(-) (limited to 'components/mus/public/cpp/tests') diff --git a/components/mus/public/cpp/tests/BUILD.gn b/components/mus/public/cpp/tests/BUILD.gn index b9cf72b..a8492a0 100644 --- a/components/mus/public/cpp/tests/BUILD.gn +++ b/components/mus/public/cpp/tests/BUILD.gn @@ -53,11 +53,13 @@ test("mojo_view_manager_lib_unittests") { "//components/mus/public/cpp", "//mojo/application/public/cpp", "//mojo/converters/geometry", + "//mojo/converters/input_events", "//mojo/gles2", "//mojo/platform_handle:platform_handle_impl", "//mojo/public/cpp/system", "//testing/gtest", "//third_party/mojo/src/mojo/edk/system", + "//ui/events", "//ui/gfx:test_support", "//ui/gfx/geometry", "//ui/mojo/geometry:interfaces", diff --git a/components/mus/public/cpp/tests/test_window_tree.cc b/components/mus/public/cpp/tests/test_window_tree.cc index 1d70f32..d1f7945 100644 --- a/components/mus/public/cpp/tests/test_window_tree.cc +++ b/components/mus/public/cpp/tests/test_window_tree.cc @@ -4,6 +4,8 @@ #include "components/mus/public/cpp/tests/test_window_tree.h" +#include "testing/gtest/include/gtest/gtest.h" + namespace mus { TestWindowTree::TestWindowTree() : got_change_(false), change_id_(0) {} @@ -20,6 +22,10 @@ bool TestWindowTree::GetAndClearChangeId(uint32_t* change_id) { return true; } +bool TestWindowTree::WasEventAcked(uint32_t event_id) const { + return acked_events_.count(event_id); +} + void TestWindowTree::NewWindow( uint32_t change_id, uint32_t window_id, @@ -106,7 +112,10 @@ void TestWindowTree::SetImeVisibility(uint32_t window_id, bool visible, mojo::TextInputStatePtr state) {} -void TestWindowTree::OnWindowInputEventAck(uint32_t event_id) {} +void TestWindowTree::OnWindowInputEventAck(uint32_t event_id) { + EXPECT_FALSE(acked_events_.count(event_id)); + acked_events_.insert(event_id); +} void TestWindowTree::WmResponse(uint32_t change_id, bool response) {} } // namespace mus diff --git a/components/mus/public/cpp/tests/test_window_tree.h b/components/mus/public/cpp/tests/test_window_tree.h index 8a35699..a61c8c9 100644 --- a/components/mus/public/cpp/tests/test_window_tree.h +++ b/components/mus/public/cpp/tests/test_window_tree.h @@ -5,6 +5,8 @@ #ifndef COMPONENTS_MUS_PUBLIC_CPP_TESTS_TEST_WINDOW_TREE_H_ #define COMPONENTS_MUS_PUBLIC_CPP_TESTS_TEST_WINDOW_TREE_H_ +#include + #include "base/macros.h" #include "components/mus/public/interfaces/window_tree.mojom.h" @@ -21,6 +23,8 @@ class TestWindowTree : public mojom::WindowTree { // invoked since the last GetAndClearChangeId(). bool GetAndClearChangeId(uint32_t* change_id); + bool WasEventAcked(uint32_t event_id) const; + private: // mojom::WindowTree: void NewWindow( @@ -78,6 +82,7 @@ class TestWindowTree : public mojom::WindowTree { bool got_change_; uint32_t change_id_; + std::set acked_events_; DISALLOW_COPY_AND_ASSIGN(TestWindowTree); }; diff --git a/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc b/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc index 5c61a40..14542b8 100644 --- a/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc +++ b/components/mus/public/cpp/tests/window_tree_client_impl_unittest.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "components/mus/common/util.h" +#include "components/mus/public/cpp/input_event_handler.h" #include "components/mus/public/cpp/lib/window_private.h" #include "components/mus/public/cpp/property_type_converters.h" #include "components/mus/public/cpp/tests/test_window.h" @@ -15,7 +16,10 @@ #include "components/mus/public/cpp/window_property.h" #include "components/mus/public/cpp/window_tree_delegate.h" #include "mojo/converters/geometry/geometry_type_converters.h" +#include "mojo/converters/input_events/input_events_type_converters.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/event.h" +#include "ui/events/event_utils.h" #include "ui/gfx/geometry/rect.h" namespace mus { @@ -96,6 +100,48 @@ class WindowTreeSetup { DISALLOW_COPY_AND_ASSIGN(WindowTreeSetup); }; +class TestInputEventHandler : public InputEventHandler { + public: + TestInputEventHandler() + : received_event_(false), should_manually_ack_(false) {} + ~TestInputEventHandler() override {} + + void set_should_manually_ack() { should_manually_ack_ = true; } + + void AckEvent() { + DCHECK(should_manually_ack_); + DCHECK(!ack_callback_.is_null()); + ack_callback_.Run(); + ack_callback_ = base::Closure(); + } + + void Reset() { + received_event_ = false; + ack_callback_ = base::Closure(); + } + bool received_event() const { return received_event_; } + + private: + // InputEventHandler: + void OnWindowInputEvent(Window* target, + mojom::EventPtr event, + scoped_ptr* ack_callback) override { + EXPECT_FALSE(received_event_) + << "Observer was not reset after receiving event."; + received_event_ = true; + if (should_manually_ack_) { + ack_callback_ = *ack_callback->get(); + ack_callback->reset(); + } + } + + bool received_event_; + bool should_manually_ack_; + base::Closure ack_callback_; + + DISALLOW_COPY_AND_ASSIGN(TestInputEventHandler); +}; + using WindowTreeClientImplTest = testing::Test; // Verifies bounds are reverted if the server replied that the change failed. @@ -276,6 +322,35 @@ TEST_F(WindowTreeClientImplTest, SetVisibleFailedWithPendingChange) { EXPECT_EQ(original_visible, root->visible()); } +TEST_F(WindowTreeClientImplTest, InputEventBasic) { + WindowTreeSetup setup; + Window* root = setup.window_tree_connection()->GetRoot(); + ASSERT_TRUE(root); + + TestInputEventHandler event_handler; + root->set_input_event_handler(&event_handler); + + scoped_ptr ui_event( + new ui::MouseEvent(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), + ui::EventTimeForNow(), ui::EF_NONE, 0)); + mojom::EventPtr mus_event = mojom::Event::From(*ui_event); + setup.window_tree_client()->OnWindowInputEvent(1, root->id(), + std::move(mus_event)); + EXPECT_TRUE(event_handler.received_event()); + EXPECT_TRUE(setup.window_tree()->WasEventAcked(1)); + event_handler.Reset(); + + event_handler.set_should_manually_ack(); + mus_event = mojom::Event::From(*ui_event); + setup.window_tree_client()->OnWindowInputEvent(33, root->id(), + std::move(mus_event)); + EXPECT_TRUE(event_handler.received_event()); + EXPECT_FALSE(setup.window_tree()->WasEventAcked(33)); + + event_handler.AckEvent(); + EXPECT_TRUE(setup.window_tree()->WasEventAcked(33)); +} + // Verifies focus is reverted if the server replied that the change failed. TEST_F(WindowTreeClientImplTest, SetFocusFailed) { WindowTreeSetup setup; -- cgit v1.1