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

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: review comments 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 <stdint.h> 5 #include <stdint.h>
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 return ui::PointerEvent( 80 return ui::PointerEvent(
81 ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(x, y), gfx::Point(x, y), 81 ui::MouseEvent(ui::ET_MOUSE_RELEASED, gfx::Point(x, y), gfx::Point(x, y),
82 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, 82 ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON,
83 ui::EF_LEFT_MOUSE_BUTTON)); 83 ui::EF_LEFT_MOUSE_BUTTON));
84 } 84 }
85 85
86 ServerWindow* GetCaptureWindow(Display* display) { 86 ServerWindow* GetCaptureWindow(Display* display) {
87 return display->GetActiveWindowManagerState()->capture_window(); 87 return display->GetActiveWindowManagerState()->capture_window();
88 } 88 }
89 89
90 mojom::EventMatcherPtr CreateEventMatcher(mojom::EventType type) {
91 mojom::EventMatcherPtr matcher = mojom::EventMatcher::New();
92 matcher->type_matcher = mojom::EventTypeMatcher::New();
93 matcher->type_matcher->type = type;
94 return matcher;
95 }
96
90 } // namespace 97 } // namespace
91 98
92 // ----------------------------------------------------------------------------- 99 // -----------------------------------------------------------------------------
93 100
94 class WindowTreeTest : public testing::Test { 101 class WindowTreeTest : public testing::Test {
95 public: 102 public:
96 WindowTreeTest() 103 WindowTreeTest()
97 : wm_client_(nullptr), 104 : wm_client_(nullptr),
98 cursor_id_(0), 105 cursor_id_(0),
99 platform_display_factory_(&cursor_id_), 106 platform_display_factory_(&cursor_id_),
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 // testing::Test: 167 // testing::Test:
161 void SetUp() override { 168 void SetUp() override {
162 PlatformDisplay::set_factory_for_testing(&platform_display_factory_); 169 PlatformDisplay::set_factory_for_testing(&platform_display_factory_);
163 window_server_.reset(new WindowServer(&delegate_, surfaces_state_)); 170 window_server_.reset(new WindowServer(&delegate_, surfaces_state_));
164 PlatformDisplayInitParams display_init_params; 171 PlatformDisplayInitParams display_init_params;
165 display_init_params.surfaces_state = surfaces_state_; 172 display_init_params.surfaces_state = surfaces_state_;
166 display_ = new Display(window_server_.get(), display_init_params); 173 display_ = new Display(window_server_.get(), display_init_params);
167 display_binding_ = new TestDisplayBinding(display_, window_server_.get()); 174 display_binding_ = new TestDisplayBinding(display_, window_server_.get());
168 display_->Init(make_scoped_ptr(display_binding_)); 175 display_->Init(make_scoped_ptr(display_binding_));
169 wm_client_ = delegate_.last_client(); 176 wm_client_ = delegate_.last_client();
177 wm_client_->tracker()->changes()->clear();
170 } 178 }
171 179
172 protected: 180 protected:
173 // TestWindowTreeClient that is used for the WM connection. 181 // TestWindowTreeClient that is used for the WM connection.
174 TestWindowTreeClient* wm_client_; 182 TestWindowTreeClient* wm_client_;
175 int32_t cursor_id_; 183 int32_t cursor_id_;
176 TestPlatformDisplayFactory platform_display_factory_; 184 TestPlatformDisplayFactory platform_display_factory_;
177 TestWindowServerDelegate delegate_; 185 TestWindowServerDelegate delegate_;
178 // Owned by WindowServer. 186 // Owned by WindowServer.
179 TestDisplayBinding* display_binding_; 187 TestDisplayBinding* display_binding_;
(...skipping 18 matching lines...) Expand all
198 EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id)); 206 EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id));
199 display_->root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); 207 display_->root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
200 mojom::WindowTreeClientPtr client; 208 mojom::WindowTreeClientPtr client;
201 mojom::WindowTreeClientRequest client_request = GetProxy(&client); 209 mojom::WindowTreeClientRequest client_request = GetProxy(&client);
202 wm_client()->Bind(std::move(client_request)); 210 wm_client()->Bind(std::move(client_request));
203 wm_tree()->Embed(embed_window_id, std::move(client)); 211 wm_tree()->Embed(embed_window_id, std::move(client));
204 ServerWindow* embed_window = wm_tree()->GetWindowByClientId(embed_window_id); 212 ServerWindow* embed_window = wm_tree()->GetWindowByClientId(embed_window_id);
205 WindowTree* tree1 = window_server()->GetTreeWithRoot(embed_window); 213 WindowTree* tree1 = window_server()->GetTreeWithRoot(embed_window);
206 ASSERT_TRUE(tree1 != nullptr); 214 ASSERT_TRUE(tree1 != nullptr);
207 ASSERT_NE(tree1, wm_tree()); 215 ASSERT_NE(tree1, wm_tree());
216 WindowTreeTestApi(tree1).set_user_id(wm_tree()->user_id());
208 217
209 embed_window->SetBounds(gfx::Rect(0, 0, 50, 50)); 218 embed_window->SetBounds(gfx::Rect(0, 0, 50, 50));
210 219
211 const ClientWindowId child1_id(BuildClientWindowId(tree1, 1)); 220 const ClientWindowId child1_id(BuildClientWindowId(tree1, 1));
212 EXPECT_TRUE(tree1->NewWindow(child1_id, ServerWindow::Properties())); 221 EXPECT_TRUE(tree1->NewWindow(child1_id, ServerWindow::Properties()));
213 ServerWindow* child1 = tree1->GetWindowByClientId(child1_id); 222 ServerWindow* child1 = tree1->GetWindowByClientId(child1_id);
214 ASSERT_TRUE(child1); 223 ASSERT_TRUE(child1);
215 EXPECT_TRUE(tree1->AddWindow(ClientWindowIdForWindow(tree1, embed_window), 224 EXPECT_TRUE(tree1->AddWindow(ClientWindowIdForWindow(tree1, embed_window),
216 child1_id)); 225 child1_id));
217 tree1->GetDisplay(embed_window)->AddActivationParent(embed_window); 226 tree1->GetDisplay(embed_window)->AddActivationParent(embed_window);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 DispatchEventAndAckImmediately(CreatePointerUpEvent(21, 22)); 308 DispatchEventAndAckImmediately(CreatePointerUpEvent(21, 22));
300 wm_client()->tracker()->changes()->clear(); 309 wm_client()->tracker()->changes()->clear();
301 tree1_client->tracker()->changes()->clear(); 310 tree1_client->tracker()->changes()->clear();
302 311
303 // Press in the same location. Should not get a focus change event (only input 312 // Press in the same location. Should not get a focus change event (only input
304 // event). 313 // event).
305 DispatchEventAndAckImmediately(CreatePointerDownEvent(61, 22)); 314 DispatchEventAndAckImmediately(CreatePointerDownEvent(61, 22));
306 EXPECT_EQ(child1, display_->GetFocusedWindow()); 315 EXPECT_EQ(child1, display_->GetFocusedWindow());
307 ASSERT_EQ(wm_client()->tracker()->changes()->size(), 1u) 316 ASSERT_EQ(wm_client()->tracker()->changes()->size(), 1u)
308 << SingleChangeToDescription(*wm_client()->tracker()->changes()); 317 << SingleChangeToDescription(*wm_client()->tracker()->changes());
309 EXPECT_EQ("InputEvent window=0,3 event_action=4", 318 EXPECT_EQ("InputEvent window=0,3 event_action=4 matched_observer=false",
310 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); 319 ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
311 EXPECT_TRUE(tree1_client->tracker()->changes()->empty()); 320 EXPECT_TRUE(tree1_client->tracker()->changes()->empty());
312 } 321 }
313 322
314 TEST_F(WindowTreeTest, BasicInputEventTarget) { 323 TEST_F(WindowTreeTest, BasicInputEventTarget) {
315 TestWindowTreeClient* embed_connection = nullptr; 324 TestWindowTreeClient* embed_connection = nullptr;
316 WindowTree* tree = nullptr; 325 WindowTree* tree = nullptr;
317 ServerWindow* window = nullptr; 326 ServerWindow* window = nullptr;
318 EXPECT_NO_FATAL_FAILURE( 327 EXPECT_NO_FATAL_FAILURE(
319 SetupEventTargeting(&embed_connection, &tree, &window)); 328 SetupEventTargeting(&embed_connection, &tree, &window));
320 329
321 // Send an event to |v1|. |embed_connection| should get the event, not 330 // Send an event to |v1|. |embed_connection| should get the event, not
322 // |wm_client|, since |v1| lives inside an embedded window. 331 // |wm_client|, since |v1| lives inside an embedded window.
323 DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22)); 332 DispatchEventAndAckImmediately(CreatePointerDownEvent(21, 22));
324 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()); 333 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
325 EXPECT_EQ("Focused id=2,1", 334 EXPECT_EQ("Focused id=2,1",
326 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); 335 ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
327 ASSERT_EQ(2u, embed_connection->tracker()->changes()->size()); 336 ASSERT_EQ(2u, embed_connection->tracker()->changes()->size());
328 EXPECT_EQ("Focused id=2,1", 337 EXPECT_EQ("Focused id=2,1",
329 ChangesToDescription1(*embed_connection->tracker()->changes())[0]); 338 ChangesToDescription1(*embed_connection->tracker()->changes())[0]);
330 EXPECT_EQ("InputEvent window=2,1 event_action=4", 339 EXPECT_EQ("InputEvent window=2,1 event_action=4 matched_observer=false",
331 ChangesToDescription1(*embed_connection->tracker()->changes())[1]); 340 ChangesToDescription1(*embed_connection->tracker()->changes())[1]);
332 } 341 }
333 342
343 // Tests that a client can observe events outside its bounds.
344 TEST_F(WindowTreeTest, SetEventObserver) {
345 // Create an embedded client.
346 TestWindowTreeClient* client = nullptr;
347 WindowTree* tree = nullptr;
348 ServerWindow* window = nullptr;
349 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&client, &tree, &window));
350
351 // Create an event outside the bounds of the client.
352 ui::PointerEvent pointer_down = CreatePointerDownEvent(5, 5);
353
354 // Events are not observed before setting an observer.
355 DispatchEventAndAckImmediately(pointer_down);
356 ASSERT_EQ(0u, client->tracker()->changes()->size());
357
358 // Create an observer for pointer-down events.
359 WindowTreeTestApi(tree).SetEventObserver(
360 CreateEventMatcher(mojom::EventType::POINTER_DOWN));
361
362 // Pointer-down events are sent to the client.
363 DispatchEventAndAckImmediately(pointer_down);
364 ASSERT_EQ(1u, client->tracker()->changes()->size());
365 EXPECT_EQ("EventObserved event_action=4",
366 ChangesToDescription1(*client->tracker()->changes())[0]);
367 client->tracker()->changes()->clear();
368
369 // Clearing the observer stops sending events to the client.
370 WindowTreeTestApi(tree).SetEventObserver(nullptr);
371 DispatchEventAndAckImmediately(pointer_down);
372 ASSERT_EQ(0u, client->tracker()->changes()->size());
373 }
374
375 // Tests that a client using an event observer does not receive events that
376 // don't match the EventMatcher spec.
377 TEST_F(WindowTreeTest, SetEventObserverNonMatching) {
378 // Create an embedded client.
379 TestWindowTreeClient* client = nullptr;
380 WindowTree* tree = nullptr;
381 ServerWindow* window = nullptr;
382 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&client, &tree, &window));
383
384 // Create an observer for pointer-down events.
385 WindowTreeTestApi(tree).SetEventObserver(
386 CreateEventMatcher(mojom::EventType::POINTER_DOWN));
387
388 // Pointer-up events are not sent to the client, since they don't match.
389 DispatchEventAndAckImmediately(CreatePointerUpEvent(5, 5));
390 ASSERT_EQ(0u, client->tracker()->changes()->size());
391 }
392
393 // Tests that an event that both hits a client window and matches an event
394 // observer is sent only once to the client.
395 TEST_F(WindowTreeTest, SetEventObserverSendsOnce) {
396 // Create an embedded client.
397 TestWindowTreeClient* client = nullptr;
398 WindowTree* tree = nullptr;
399 ServerWindow* window = nullptr;
400 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&client, &tree, &window));
401
402 // Create an observer for pointer-up events (which do not cause focus
403 // changes).
404 WindowTreeTestApi(tree).SetEventObserver(
405 CreateEventMatcher(mojom::EventType::POINTER_UP));
406
407 // Create an event inside the bounds of the client.
408 ui::PointerEvent pointer_up = CreatePointerUpEvent(25, 25);
409
410 // The event is dispatched once, with a flag set that it matched the event
411 // observer.
412 DispatchEventAndAckImmediately(pointer_up);
413 ASSERT_EQ(1u, client->tracker()->changes()->size());
414 EXPECT_EQ("InputEvent window=2,1 event_action=6 matched_observer=true",
415 SingleChangeToDescription(*client->tracker()->changes()));
416 }
417
418 // Tests that events generated by user A are not observed by event observers for
419 // user B.
420 TEST_F(WindowTreeTest, SetEventObserverWrongUser) {
421 // Embed a window tree belonging to a different user.
422 TestWindowTreeBinding* other_binding;
423 WindowTree* other_tree = CreateNewTree("other_user", &other_binding);
424 other_binding->client()->tracker()->changes()->clear();
425
426 // Set event observers on both the wm tree and the other user's tree.
427 WindowTreeTestApi(wm_tree()).SetEventObserver(
428 CreateEventMatcher(mojom::EventType::POINTER_UP));
429 WindowTreeTestApi(other_tree)
430 .SetEventObserver(CreateEventMatcher(mojom::EventType::POINTER_UP));
431
432 // An event is observed by the wm tree, but not by the other user's tree.
433 DispatchEventAndAckImmediately(CreatePointerUpEvent(5, 5));
434 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
435 EXPECT_EQ("InputEvent window=0,3 event_action=6 matched_observer=true",
436 SingleChangeToDescription(*wm_client()->tracker()->changes()));
437 ASSERT_EQ(0u, other_binding->client()->tracker()->changes()->size());
438 }
439
440 // Tests that an event observer can receive events that have no target window.
441 TEST_F(WindowTreeTest, SetEventObserverNoTarget) {
442 WindowTreeTestApi(wm_tree()).SetEventObserver(
443 CreateEventMatcher(mojom::EventType::KEY_RELEASED));
444 ui::KeyEvent key(ui::ET_KEY_RELEASED, ui::VKEY_A, ui::EF_NONE);
445 DispatchEventAndAckImmediately(key);
446 EXPECT_EQ("EventObserved event_action=2",
447 SingleChangeToDescription(*wm_client()->tracker()->changes()));
448 }
449
334 TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) { 450 TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) {
335 TestWindowTreeClient* embed_connection = nullptr; 451 TestWindowTreeClient* embed_connection = nullptr;
336 WindowTree* tree = nullptr; 452 WindowTree* tree = nullptr;
337 ServerWindow* window = nullptr; 453 ServerWindow* window = nullptr;
338 EXPECT_NO_FATAL_FAILURE( 454 EXPECT_NO_FATAL_FAILURE(
339 SetupEventTargeting(&embed_connection, &tree, &window)); 455 SetupEventTargeting(&embed_connection, &tree, &window));
340 456
341 // Like in BasicInputEventTarget, we send a pointer down event to be 457 // Like in BasicInputEventTarget, we send a pointer down event to be
342 // dispatched. This is only to place the mouse cursor over that window though. 458 // dispatched. This is only to place the mouse cursor over that window though.
343 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); 459 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22));
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 EXPECT_TRUE( 589 EXPECT_TRUE(
474 wm_tree()->NewWindow(embed_window_id, ServerWindow::Properties())); 590 wm_tree()->NewWindow(embed_window_id, ServerWindow::Properties()));
475 EXPECT_TRUE(wm_tree()->SetWindowVisibility(embed_window_id, true)); 591 EXPECT_TRUE(wm_tree()->SetWindowVisibility(embed_window_id, true));
476 ASSERT_TRUE(FirstRoot(wm_tree())); 592 ASSERT_TRUE(FirstRoot(wm_tree()));
477 EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id)); 593 EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id));
478 display_->root_window()->SetBounds(gfx::Rect(0, 0, 100, 100)); 594 display_->root_window()->SetBounds(gfx::Rect(0, 0, 100, 100));
479 595
480 wm_client()->tracker()->changes()->clear(); 596 wm_client()->tracker()->changes()->clear();
481 DispatchEventWithoutAck(CreateMouseMoveEvent(21, 22)); 597 DispatchEventWithoutAck(CreateMouseMoveEvent(21, 22));
482 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()); 598 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
483 EXPECT_EQ("InputEvent window=0,3 event_action=5", 599 EXPECT_EQ("InputEvent window=0,3 event_action=5 matched_observer=false",
484 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); 600 ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
485 wm_client()->tracker()->changes()->clear(); 601 wm_client()->tracker()->changes()->clear();
486 602
487 // Send another event. This event shouldn't reach the client. 603 // Send another event. This event shouldn't reach the client.
488 DispatchEventWithoutAck(CreateMouseMoveEvent(21, 22)); 604 DispatchEventWithoutAck(CreateMouseMoveEvent(21, 22));
489 ASSERT_EQ(0u, wm_client()->tracker()->changes()->size()); 605 ASSERT_EQ(0u, wm_client()->tracker()->changes()->size());
490 606
491 // Ack the first event. That should trigger the dispatch of the second event. 607 // Ack the first event. That should trigger the dispatch of the second event.
492 AckPreviousEvent(); 608 AckPreviousEvent();
493 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size()); 609 ASSERT_EQ(1u, wm_client()->tracker()->changes()->size());
494 EXPECT_EQ("InputEvent window=0,3 event_action=5", 610 EXPECT_EQ("InputEvent window=0,3 event_action=5 matched_observer=false",
495 ChangesToDescription1(*wm_client()->tracker()->changes())[0]); 611 ChangesToDescription1(*wm_client()->tracker()->changes())[0]);
496 } 612 }
497 613
498 // Establish connection, call NewTopLevelWindow(), make sure get id, and make 614 // Establish connection, call NewTopLevelWindow(), make sure get id, and make
499 // sure client paused. 615 // sure client paused.
500 TEST_F(WindowTreeTest, NewTopLevelWindow) { 616 TEST_F(WindowTreeTest, NewTopLevelWindow) {
501 TestWindowManager wm_internal; 617 TestWindowManager wm_internal;
502 set_window_manager_internal(wm_tree(), &wm_internal); 618 set_window_manager_internal(wm_tree(), &wm_internal);
503 619
504 TestWindowTreeBinding* child_binding; 620 TestWindowTreeBinding* child_binding;
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 ASSERT_NE(new_opacity, unknown_window.opacity()); 988 ASSERT_NE(new_opacity, unknown_window.opacity());
873 989
874 EXPECT_FALSE(tree->SetWindowOpacity( 990 EXPECT_FALSE(tree->SetWindowOpacity(
875 ClientWindowId(WindowIdToTransportId(window_id)), new_opacity)); 991 ClientWindowId(WindowIdToTransportId(window_id)), new_opacity));
876 EXPECT_NE(new_opacity, unknown_window.opacity()); 992 EXPECT_NE(new_opacity, unknown_window.opacity());
877 } 993 }
878 994
879 } // namespace test 995 } // namespace test
880 } // namespace ws 996 } // namespace ws
881 } // namespace mus 997 } // namespace mus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698