| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |