Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: components/mus/ws/window_tree_unittest.cc

Issue 1909733002: mus: Add EventObserver to allow passively listening to UI events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/mus/ws/window_tree.h" 5 #include "components/mus/ws/window_tree.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 return ui::PointerEvent( 82 return ui::PointerEvent(
83 ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(x, y), gfx::Point(x, y), 83 ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(x, y), gfx::Point(x, y),
84 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 84 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
85 ui::EF_LEFT_MOUSE_BUTTON)); 85 ui::EF_LEFT_MOUSE_BUTTON));
86 } 86 }
87 87
88 ServerWindow* GetCaptureWindow(Display* display) { 88 ServerWindow* GetCaptureWindow(Display* display) {
89 return display->GetActiveWindowManagerState()->capture_window(); 89 return display->GetActiveWindowManagerState()->capture_window();
90 } 90 }
91 91
92 mojom::EventMatcherPtr CreateEventMatcher(mojom::EventType type) {
93 mojom::EventMatcherPtr matcher = mojom::EventMatcher::New();
94 matcher->type_matcher = mojom::EventTypeMatcher::New();
95 matcher->type_matcher->type = type;
96 return matcher;
97 }
98
92 } // namespace 99 } // namespace
93 100
94 // ----------------------------------------------------------------------------- 101 // -----------------------------------------------------------------------------
95 102
96 class WindowTreeTest : public testing::Test { 103 class WindowTreeTest : public testing::Test {
97 public: 104 public:
98 WindowTreeTest() 105 WindowTreeTest()
99 : wm_client_(nullptr), 106 : wm_client_(nullptr),
100 cursor_id_(0), 107 cursor_id_(0),
101 platform_display_factory_(&cursor_id_), 108 platform_display_factory_(&cursor_id_),
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // testing::Test: 170 // testing::Test:
164 void SetUp() override { 171 void SetUp() override {
165 PlatformDisplay::set_factory_for_testing(&platform_display_factory_); 172 PlatformDisplay::set_factory_for_testing(&platform_display_factory_);
166 window_server_.reset(new WindowServer(&delegate_, surfaces_state_)); 173 window_server_.reset(new WindowServer(&delegate_, surfaces_state_));
167 PlatformDisplayInitParams display_init_params; 174 PlatformDisplayInitParams display_init_params;
168 display_init_params.surfaces_state = surfaces_state_; 175 display_init_params.surfaces_state = surfaces_state_;
169 display_ = new Display(window_server_.get(), display_init_params); 176 display_ = new Display(window_server_.get(), display_init_params);
170 display_binding_ = new TestDisplayBinding(display_, window_server_.get()); 177 display_binding_ = new TestDisplayBinding(display_, window_server_.get());
171 display_->Init(base::WrapUnique(display_binding_)); 178 display_->Init(base::WrapUnique(display_binding_));
172 wm_client_ = delegate_.last_client(); 179 wm_client_ = delegate_.last_client();
180 wm_client_->tracker()->changes()->clear();
173 } 181 }
174 182
175 protected: 183 protected:
176 // TestWindowTreeClient that is used for the WM connection. 184 // TestWindowTreeClient that is used for the WM connection.
177 TestWindowTreeClient* wm_client_; 185 TestWindowTreeClient* wm_client_;
178 int32_t cursor_id_; 186 int32_t cursor_id_;
179 TestPlatformDisplayFactory platform_display_factory_; 187 TestPlatformDisplayFactory platform_display_factory_;
180 TestWindowServerDelegate delegate_; 188 TestWindowServerDelegate delegate_;
181 // Owned by WindowServer. 189 // Owned by WindowServer.
182 TestDisplayBinding* display_binding_; 190 TestDisplayBinding* display_binding_;
(...skipping 18 matching lines...) Expand all
201 EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id)); 209 EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id));
202 display_->root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); 210 display_->root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
203 mojom::WindowTreeClientPtr client; 211 mojom::WindowTreeClientPtr client;
204 mojom::WindowTreeClientRequest client_request = GetProxy(&client); 212 mojom::WindowTreeClientRequest client_request = GetProxy(&client);
205 wm_client()->Bind(std::move(client_request)); 213 wm_client()->Bind(std::move(client_request));
206 wm_tree()->Embed(embed_window_id, std::move(client)); 214 wm_tree()->Embed(embed_window_id, std::move(client));
207 ServerWindow* embed_window = wm_tree()->GetWindowByClientId(embed_window_id); 215 ServerWindow* embed_window = wm_tree()->GetWindowByClientId(embed_window_id);
208 WindowTree* tree1 = window_server()->GetTreeWithRoot(embed_window); 216 WindowTree* tree1 = window_server()->GetTreeWithRoot(embed_window);
209 ASSERT_TRUE(tree1 != nullptr); 217 ASSERT_TRUE(tree1 != nullptr);
210 ASSERT_NE(tree1, wm_tree()); 218 ASSERT_NE(tree1, wm_tree());
219 WindowTreeTestApi(tree1).set_user_id(wm_tree()->user_id());
211 220
212 embed_window->SetBounds(gfx::Rect(0, 0, 50, 50)); 221 embed_window->SetBounds(gfx::Rect(0, 0, 50, 50));
213 222
214 const ClientWindowId child1_id(BuildClientWindowId(tree1, 1)); 223 const ClientWindowId child1_id(BuildClientWindowId(tree1, 1));
215 EXPECT_TRUE(tree1->NewWindow(child1_id, ServerWindow::Properties())); 224 EXPECT_TRUE(tree1->NewWindow(child1_id, ServerWindow::Properties()));
216 ServerWindow* child1 = tree1->GetWindowByClientId(child1_id); 225 ServerWindow* child1 = tree1->GetWindowByClientId(child1_id);
217 ASSERT_TRUE(child1); 226 ASSERT_TRUE(child1);
218 EXPECT_TRUE(tree1->AddWindow(ClientWindowIdForWindow(tree1, embed_window), 227 EXPECT_TRUE(tree1->AddWindow(ClientWindowIdForWindow(tree1, embed_window),
219 child1_id)); 228 child1_id));
220 tree1->GetDisplay(embed_window)->AddActivationParent(embed_window); 229 tree1->GetDisplay(embed_window)->AddActivationParent(embed_window);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()); 336 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
328 EXPECT_EQ("Focused id=2,1", 337 EXPECT_EQ("Focused id=2,1",
329 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); 338 ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
330 ASSERT_EQ(2u, embed_connection->tracker()->changes()->size()); 339 ASSERT_EQ(2u, embed_connection->tracker()->changes()->size());
331 EXPECT_EQ("Focused id=2,1", 340 EXPECT_EQ("Focused id=2,1",
332 ChangesToDescription1(*embed_connection->tracker()->changes())[0]); 341 ChangesToDescription1(*embed_connection->tracker()->changes())[0]);
333 EXPECT_EQ("InputEvent window=2,1 event_action=4", 342 EXPECT_EQ("InputEvent window=2,1 event_action=4",
334 ChangesToDescription1(*embed_connection->tracker()->changes())[1]); 343 ChangesToDescription1(*embed_connection->tracker()->changes())[1]);
335 } 344 }
336 345
346 // Tests that a client can observe events outside its bounds.
347 TEST_F(WindowTreeTest, SetEventObserver) {
348 // Create an embedded client.
349 TestWindowTreeClient* client = nullptr;
350 WindowTree* tree = nullptr;
351 ServerWindow* window = nullptr;
352 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&client, &tree, &window));
353
354 // Create an event outside the bounds of the client.
355 ui::PointerEvent pointer_down = CreatePointerDownEvent(5, 5);
356
357 // Events are not observed before setting an observer.
358 DispatchEventAndAckImmediately(pointer_down);
359 ASSERT_EQ(0u, client->tracker()->changes()->size());
360
361 // Create an observer for pointer-down events.
362 WindowTreeTestApi(tree).SetEventObserver(
363 CreateEventMatcher(mojom::EventType::POINTER_DOWN), 111u);
364
365 // Pointer-down events are sent to the client.
366 DispatchEventAndAckImmediately(pointer_down);
367 ASSERT_EQ(1u, client->tracker()->changes()->size());
368 EXPECT_EQ("EventObserved event_action=4 event_observer_id=111",
369 ChangesToDescription1(*client->tracker()->changes())[0]);
370 client->tracker()->changes()->clear();
371
372 // Clearing the observer stops sending events to the client.
373 WindowTreeTestApi(tree).SetEventObserver(nullptr, 0u);
374 DispatchEventAndAckImmediately(pointer_down);
375 ASSERT_EQ(0u, client->tracker()->changes()->size());
376 }
377
378 // Tests that a client using an event observer does not receive events that
379 // don't match the EventMatcher spec.
380 TEST_F(WindowTreeTest, SetEventObserverNonMatching) {
381 // Create an embedded client.
382 TestWindowTreeClient* client = nullptr;
383 WindowTree* tree = nullptr;
384 ServerWindow* window = nullptr;
385 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&client, &tree, &window));
386
387 // Create an observer for pointer-down events.
388 WindowTreeTestApi(tree).SetEventObserver(
389 CreateEventMatcher(mojom::EventType::POINTER_DOWN), 111u);
390
391 // Pointer-up events are not sent to the client, since they don't match.
392 DispatchEventAndAckImmediately(CreatePointerUpEvent(5, 5));
393 ASSERT_EQ(0u, client->tracker()->changes()->size());
394 }
395
396 // Tests that an event that both hits a client window and matches an event
397 // observer is sent only once to the client.
398 TEST_F(WindowTreeTest, SetEventObserverSendsOnce) {
399 // Create an embedded client.
400 TestWindowTreeClient* client = nullptr;
401 WindowTree* tree = nullptr;
402 ServerWindow* window = nullptr;
403 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&client, &tree, &window));
404
405 // Create an observer for pointer-up events (which do not cause focus
406 // changes).
407 WindowTreeTestApi(tree).SetEventObserver(
408 CreateEventMatcher(mojom::EventType::POINTER_UP), 111u);
409
410 // Create an event inside the bounds of the client.
411 ui::PointerEvent pointer_up = CreatePointerUpEvent(25, 25);
412
413 // The event is dispatched once, with a flag set that it matched the event
414 // observer.
415 DispatchEventAndAckImmediately(pointer_up);
416 ASSERT_EQ(1u, client->tracker()->changes()->size());
417 EXPECT_EQ("InputEvent window=2,1 event_action=6 event_observer_id=111",
418 SingleChangeToDescription(*client->tracker()->changes()));
419 }
420
421 // Tests that events generated by user A are not observed by event observers for
422 // user B.
423 TEST_F(WindowTreeTest, SetEventObserverWrongUser) {
424 // Embed a window tree belonging to a different user.
425 TestWindowTreeBinding* other_binding;
426 WindowTree* other_tree = CreateNewTree("other_user", &other_binding);
427 other_binding->client()->tracker()->changes()->clear();
428
429 // Set event observers on both the wm tree and the other user's tree.
430 WindowTreeTestApi(wm_tree()).SetEventObserver(
431 CreateEventMatcher(mojom::EventType::POINTER_UP), 111u);
432 WindowTreeTestApi(other_tree)
433 .SetEventObserver(CreateEventMatcher(mojom::EventType::POINTER_UP), 222u);
434
435 // An event is observed by the wm tree, but not by the other user's tree.
436 DispatchEventAndAckImmediately(CreatePointerUpEvent(5, 5));
437 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
438 EXPECT_EQ("InputEvent window=0,3 event_action=6 event_observer_id=111",
439 SingleChangeToDescription(*wm_client()->tracker()->changes()));
440 ASSERT_EQ(0u, other_binding->client()->tracker()->changes()->size());
441 }
442
443 // Tests that an event observer can receive events that have no target window.
444 TEST_F(WindowTreeTest, SetEventObserverNoTarget) {
445 WindowTreeTestApi(wm_tree()).SetEventObserver(
446 CreateEventMatcher(mojom::EventType::KEY_RELEASED), 111u);
447 ui::KeyEvent key(ui::ET_KEY_RELEASED, ui::VKEY_A, ui::EF_NONE);
448 DispatchEventAndAckImmediately(key);
449 EXPECT_EQ("EventObserved event_action=2 event_observer_id=111",
450 SingleChangeToDescription(*wm_client()->tracker()->changes()));
451 }
452
337 TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) { 453 TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) {
338 TestWindowTreeClient* embed_connection = nullptr; 454 TestWindowTreeClient* embed_connection = nullptr;
339 WindowTree* tree = nullptr; 455 WindowTree* tree = nullptr;
340 ServerWindow* window = nullptr; 456 ServerWindow* window = nullptr;
341 EXPECT_NO_FATAL_FAILURE( 457 EXPECT_NO_FATAL_FAILURE(
342 SetupEventTargeting(&embed_connection, &tree, &window)); 458 SetupEventTargeting(&embed_connection, &tree, &window));
343 459
344 // Like in BasicInputEventTarget, we send a pointer down event to be 460 // Like in BasicInputEventTarget, we send a pointer down event to be
345 // dispatched. This is only to place the mouse cursor over that window though. 461 // dispatched. This is only to place the mouse cursor over that window though.
346 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); 462 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22));
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 ASSERT_NE(new_opacity, unknown_window.opacity()); 991 ASSERT_NE(new_opacity, unknown_window.opacity());
876 992
877 EXPECT_FALSE(tree->SetWindowOpacity( 993 EXPECT_FALSE(tree->SetWindowOpacity(
878 ClientWindowId(WindowIdToTransportId(window_id)), new_opacity)); 994 ClientWindowId(WindowIdToTransportId(window_id)), new_opacity));
879 EXPECT_NE(new_opacity, unknown_window.opacity()); 995 EXPECT_NE(new_opacity, unknown_window.opacity());
880 } 996 }
881 997
882 } // namespace test 998 } // namespace test
883 } // namespace ws 999 } // namespace ws
884 } // namespace mus 1000 } // namespace mus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698