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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 } | 108 } |
109 | 109 |
110 std::string WindowParentToString(Id window, Id parent) { | 110 std::string WindowParentToString(Id window, Id parent) { |
111 return base::StringPrintf("window=%s parent=%s", IdToString(window).c_str(), | 111 return base::StringPrintf("window=%s parent=%s", IdToString(window).c_str(), |
112 IdToString(parent).c_str()); | 112 IdToString(parent).c_str()); |
113 } | 113 } |
114 | 114 |
115 // ----------------------------------------------------------------------------- | 115 // ----------------------------------------------------------------------------- |
116 | 116 |
117 // A WindowTreeClient implementation that logs all changes to a tracker. | 117 // A WindowTreeClient implementation that logs all changes to a tracker. |
118 class TestWindowTreeClientImpl : public mojom::WindowTreeClient, | 118 class TestWindowTreeClient : public mojom::WindowTreeClient, |
119 public TestChangeTracker::Delegate, | 119 public TestChangeTracker::Delegate, |
120 public mojom::WindowManager { | 120 public mojom::WindowManager { |
121 public: | 121 public: |
122 TestWindowTreeClientImpl() | 122 TestWindowTreeClient() |
123 : binding_(this), | 123 : binding_(this), |
124 client_id_(0), | 124 client_id_(0), |
125 root_window_id_(0), | 125 root_window_id_(0), |
126 // Start with a random large number so tests can use lower ids if they | 126 // Start with a random large number so tests can use lower ids if they |
127 // want. | 127 // want. |
128 next_change_id_(10000), | 128 next_change_id_(10000), |
129 waiting_change_id_(0), | 129 waiting_change_id_(0), |
130 on_change_completed_result_(false), | 130 on_change_completed_result_(false), |
131 track_root_bounds_changes_(false) { | 131 track_root_bounds_changes_(false) { |
132 tracker_.set_delegate(this); | 132 tracker_.set_delegate(this); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 uint32_t next_change_id_; | 430 uint32_t next_change_id_; |
431 uint32_t waiting_change_id_; | 431 uint32_t waiting_change_id_; |
432 bool on_change_completed_result_; | 432 bool on_change_completed_result_; |
433 bool track_root_bounds_changes_; | 433 bool track_root_bounds_changes_; |
434 std::unique_ptr<base::RunLoop> change_completed_run_loop_; | 434 std::unique_ptr<base::RunLoop> change_completed_run_loop_; |
435 | 435 |
436 std::unique_ptr<mojo::AssociatedBinding<mojom::WindowManager>> | 436 std::unique_ptr<mojo::AssociatedBinding<mojom::WindowManager>> |
437 window_manager_binding_; | 437 window_manager_binding_; |
438 mojom::WindowManagerClientAssociatedPtr window_manager_client_; | 438 mojom::WindowManagerClientAssociatedPtr window_manager_client_; |
439 | 439 |
440 DISALLOW_COPY_AND_ASSIGN(TestWindowTreeClientImpl); | 440 DISALLOW_COPY_AND_ASSIGN(TestWindowTreeClient); |
441 }; | 441 }; |
442 | 442 |
443 // ----------------------------------------------------------------------------- | 443 // ----------------------------------------------------------------------------- |
444 | 444 |
445 // InterfaceFactory for vending TestWindowTreeClientImpls. | 445 // InterfaceFactory for vending TestWindowTreeClients. |
446 class WindowTreeClientFactory | 446 class WindowTreeClientFactory |
447 : public shell::InterfaceFactory<WindowTreeClient> { | 447 : public shell::InterfaceFactory<WindowTreeClient> { |
448 public: | 448 public: |
449 WindowTreeClientFactory() {} | 449 WindowTreeClientFactory() {} |
450 ~WindowTreeClientFactory() override {} | 450 ~WindowTreeClientFactory() override {} |
451 | 451 |
452 // Runs a nested MessageLoop until a new instance has been created. | 452 // Runs a nested MessageLoop until a new instance has been created. |
453 std::unique_ptr<TestWindowTreeClientImpl> WaitForInstance() { | 453 std::unique_ptr<TestWindowTreeClient> WaitForInstance() { |
454 if (!client_impl_.get()) { | 454 if (!client_impl_.get()) { |
455 DCHECK(!run_loop_); | 455 DCHECK(!run_loop_); |
456 run_loop_.reset(new base::RunLoop); | 456 run_loop_.reset(new base::RunLoop); |
457 run_loop_->Run(); | 457 run_loop_->Run(); |
458 run_loop_.reset(); | 458 run_loop_.reset(); |
459 } | 459 } |
460 return std::move(client_impl_); | 460 return std::move(client_impl_); |
461 } | 461 } |
462 | 462 |
463 private: | 463 private: |
464 // InterfaceFactory<WindowTreeClient>: | 464 // InterfaceFactory<WindowTreeClient>: |
465 void Create(Connection* connection, | 465 void Create(Connection* connection, |
466 InterfaceRequest<WindowTreeClient> request) override { | 466 InterfaceRequest<WindowTreeClient> request) override { |
467 client_impl_.reset(new TestWindowTreeClientImpl()); | 467 client_impl_.reset(new TestWindowTreeClient()); |
468 client_impl_->Bind(std::move(request)); | 468 client_impl_->Bind(std::move(request)); |
469 if (run_loop_.get()) | 469 if (run_loop_.get()) |
470 run_loop_->Quit(); | 470 run_loop_->Quit(); |
471 } | 471 } |
472 | 472 |
473 std::unique_ptr<TestWindowTreeClientImpl> client_impl_; | 473 std::unique_ptr<TestWindowTreeClient> client_impl_; |
474 std::unique_ptr<base::RunLoop> run_loop_; | 474 std::unique_ptr<base::RunLoop> run_loop_; |
475 | 475 |
476 DISALLOW_COPY_AND_ASSIGN(WindowTreeClientFactory); | 476 DISALLOW_COPY_AND_ASSIGN(WindowTreeClientFactory); |
477 }; | 477 }; |
478 | 478 |
479 } // namespace | 479 } // namespace |
480 | 480 |
481 class WindowTreeClientTest : public WindowServerShellTestBase { | 481 class WindowTreeClientTest : public WindowServerShellTestBase { |
482 public: | 482 public: |
483 WindowTreeClientTest() | 483 WindowTreeClientTest() |
484 : client_id_1_(0), client_id_2_(0), root_window_id_(0) {} | 484 : client_id_1_(0), client_id_2_(0), root_window_id_(0) {} |
485 | 485 |
486 ~WindowTreeClientTest() override {} | 486 ~WindowTreeClientTest() override {} |
487 | 487 |
488 protected: | 488 protected: |
489 // Returns the changes from the various clients. | 489 // Returns the changes from the various clients. |
490 std::vector<Change>* changes1() { return wt_client1_->tracker()->changes(); } | 490 std::vector<Change>* changes1() { return wt_client1_->tracker()->changes(); } |
491 std::vector<Change>* changes2() { return wt_client2_->tracker()->changes(); } | 491 std::vector<Change>* changes2() { return wt_client2_->tracker()->changes(); } |
492 std::vector<Change>* changes3() { return wt_client3_->tracker()->changes(); } | 492 std::vector<Change>* changes3() { return wt_client3_->tracker()->changes(); } |
493 | 493 |
494 // Various clients. |wt1()|, being the first client, has special permissions | 494 // Various clients. |wt1()|, being the first client, has special permissions |
495 // (it's treated as the window manager). | 495 // (it's treated as the window manager). |
496 WindowTree* wt1() { return wt_client1_->tree(); } | 496 WindowTree* wt1() { return wt_client1_->tree(); } |
497 WindowTree* wt2() { return wt_client2_->tree(); } | 497 WindowTree* wt2() { return wt_client2_->tree(); } |
498 WindowTree* wt3() { return wt_client3_->tree(); } | 498 WindowTree* wt3() { return wt_client3_->tree(); } |
499 | 499 |
500 TestWindowTreeClientImpl* wt_client1() { return wt_client1_.get(); } | 500 TestWindowTreeClient* wt_client1() { return wt_client1_.get(); } |
501 TestWindowTreeClientImpl* wt_client2() { return wt_client2_.get(); } | 501 TestWindowTreeClient* wt_client2() { return wt_client2_.get(); } |
502 TestWindowTreeClientImpl* wt_client3() { return wt_client3_.get(); } | 502 TestWindowTreeClient* wt_client3() { return wt_client3_.get(); } |
503 | 503 |
504 Id root_window_id() const { return root_window_id_; } | 504 Id root_window_id() const { return root_window_id_; } |
505 | 505 |
506 int client_id_1() const { return client_id_1_; } | 506 int client_id_1() const { return client_id_1_; } |
507 int client_id_2() const { return client_id_2_; } | 507 int client_id_2() const { return client_id_2_; } |
508 | 508 |
509 void EstablishSecondClientWithRoot(Id root_id) { | 509 void EstablishSecondClientWithRoot(Id root_id) { |
510 ASSERT_TRUE(wt_client2_.get() == nullptr); | 510 ASSERT_TRUE(wt_client2_.get() == nullptr); |
511 wt_client2_ = | 511 wt_client2_ = |
512 EstablishClientViaEmbed(wt1(), root_id, &client_id_2_); | 512 EstablishClientViaEmbed(wt1(), root_id, &client_id_2_); |
(...skipping 15 matching lines...) Expand all Loading... |
528 ChangeWindowDescription(*changes2())); | 528 ChangeWindowDescription(*changes2())); |
529 } | 529 } |
530 } | 530 } |
531 | 531 |
532 void EstablishThirdClient(WindowTree* owner, Id root_id) { | 532 void EstablishThirdClient(WindowTree* owner, Id root_id) { |
533 ASSERT_TRUE(wt_client3_.get() == nullptr); | 533 ASSERT_TRUE(wt_client3_.get() == nullptr); |
534 wt_client3_ = EstablishClientViaEmbed(owner, root_id, nullptr); | 534 wt_client3_ = EstablishClientViaEmbed(owner, root_id, nullptr); |
535 ASSERT_TRUE(wt_client3_.get() != nullptr); | 535 ASSERT_TRUE(wt_client3_.get() != nullptr); |
536 } | 536 } |
537 | 537 |
538 std::unique_ptr<TestWindowTreeClientImpl> WaitForWindowTreeClient() { | 538 std::unique_ptr<TestWindowTreeClient> WaitForWindowTreeClient() { |
539 return client_factory_->WaitForInstance(); | 539 return client_factory_->WaitForInstance(); |
540 } | 540 } |
541 | 541 |
542 // Establishes a new client by way of Embed() on the specified WindowTree. | 542 // Establishes a new client by way of Embed() on the specified WindowTree. |
543 std::unique_ptr<TestWindowTreeClientImpl> EstablishClientViaEmbed( | 543 std::unique_ptr<TestWindowTreeClient> EstablishClientViaEmbed( |
544 WindowTree* owner, | 544 WindowTree* owner, |
545 Id root_id, | 545 Id root_id, |
546 int* client_id) { | 546 int* client_id) { |
547 return EstablishClientViaEmbedWithPolicyBitmask(owner, root_id, client_id); | 547 return EstablishClientViaEmbedWithPolicyBitmask(owner, root_id, client_id); |
548 } | 548 } |
549 | 549 |
550 std::unique_ptr<TestWindowTreeClientImpl> | 550 std::unique_ptr<TestWindowTreeClient> |
551 EstablishClientViaEmbedWithPolicyBitmask(WindowTree* owner, | 551 EstablishClientViaEmbedWithPolicyBitmask(WindowTree* owner, |
552 Id root_id, | 552 Id root_id, |
553 int* client_id) { | 553 int* client_id) { |
554 if (!EmbedUrl(connector(), owner, test_name(), root_id)) { | 554 if (!EmbedUrl(connector(), owner, test_name(), root_id)) { |
555 ADD_FAILURE() << "Embed() failed"; | 555 ADD_FAILURE() << "Embed() failed"; |
556 return nullptr; | 556 return nullptr; |
557 } | 557 } |
558 std::unique_ptr<TestWindowTreeClientImpl> client = | 558 std::unique_ptr<TestWindowTreeClient> client = |
559 client_factory_->WaitForInstance(); | 559 client_factory_->WaitForInstance(); |
560 if (!client.get()) { | 560 if (!client.get()) { |
561 ADD_FAILURE() << "WaitForInstance failed"; | 561 ADD_FAILURE() << "WaitForInstance failed"; |
562 return nullptr; | 562 return nullptr; |
563 } | 563 } |
564 client->WaitForOnEmbed(); | 564 client->WaitForOnEmbed(); |
565 | 565 |
566 EXPECT_EQ("OnEmbed", | 566 EXPECT_EQ("OnEmbed", |
567 SingleChangeToDescription(*client->tracker()->changes())); | 567 SingleChangeToDescription(*client->tracker()->changes())); |
568 if (client_id) | 568 if (client_id) |
569 *client_id = (*client->tracker()->changes())[0].client_id; | 569 *client_id = (*client->tracker()->changes())[0].client_id; |
570 return client; | 570 return client; |
571 } | 571 } |
572 | 572 |
573 // WindowServerShellTestBase: | 573 // WindowServerShellTestBase: |
574 bool AcceptConnection(shell::Connection* connection) override { | 574 bool AcceptConnection(shell::Connection* connection) override { |
575 connection->AddInterface(client_factory_.get()); | 575 connection->AddInterface(client_factory_.get()); |
576 return true; | 576 return true; |
577 } | 577 } |
578 | 578 |
579 void SetUp() override { | 579 void SetUp() override { |
580 client_factory_.reset(new WindowTreeClientFactory()); | 580 client_factory_.reset(new WindowTreeClientFactory()); |
581 | 581 |
582 WindowServerShellTestBase::SetUp(); | 582 WindowServerShellTestBase::SetUp(); |
583 | 583 |
584 mojom::WindowTreeHostFactoryPtr factory; | 584 mojom::WindowTreeHostFactoryPtr factory; |
585 connector()->ConnectToInterface("mojo:mus", &factory); | 585 connector()->ConnectToInterface("mojo:mus", &factory); |
586 | 586 |
587 mojom::WindowTreeClientPtr tree_client_ptr; | 587 mojom::WindowTreeClientPtr tree_client_ptr; |
588 wt_client1_.reset(new TestWindowTreeClientImpl()); | 588 wt_client1_.reset(new TestWindowTreeClient()); |
589 wt_client1_->Bind(GetProxy(&tree_client_ptr)); | 589 wt_client1_->Bind(GetProxy(&tree_client_ptr)); |
590 | 590 |
591 factory->CreateWindowTreeHost(GetProxy(&host_), | 591 factory->CreateWindowTreeHost(GetProxy(&host_), |
592 std::move(tree_client_ptr)); | 592 std::move(tree_client_ptr)); |
593 | 593 |
594 // Next we should get an embed call on the "window manager" client. | 594 // Next we should get an embed call on the "window manager" client. |
595 wt_client1_->WaitForOnEmbed(); | 595 wt_client1_->WaitForOnEmbed(); |
596 | 596 |
597 ASSERT_EQ(1u, changes1()->size()); | 597 ASSERT_EQ(1u, changes1()->size()); |
598 EXPECT_EQ(CHANGE_TYPE_EMBED, (*changes1())[0].type); | 598 EXPECT_EQ(CHANGE_TYPE_EMBED, (*changes1())[0].type); |
(...skipping 11 matching lines...) Expand all Loading... |
610 void TearDown() override { | 610 void TearDown() override { |
611 // Destroy these before the message loop is destroyed (happens in | 611 // Destroy these before the message loop is destroyed (happens in |
612 // WindowServerShellTestBase::TearDown). | 612 // WindowServerShellTestBase::TearDown). |
613 wt_client1_.reset(); | 613 wt_client1_.reset(); |
614 wt_client2_.reset(); | 614 wt_client2_.reset(); |
615 wt_client3_.reset(); | 615 wt_client3_.reset(); |
616 client_factory_.reset(); | 616 client_factory_.reset(); |
617 WindowServerShellTestBase::TearDown(); | 617 WindowServerShellTestBase::TearDown(); |
618 } | 618 } |
619 | 619 |
620 std::unique_ptr<TestWindowTreeClientImpl> wt_client1_; | 620 std::unique_ptr<TestWindowTreeClient> wt_client1_; |
621 std::unique_ptr<TestWindowTreeClientImpl> wt_client2_; | 621 std::unique_ptr<TestWindowTreeClient> wt_client2_; |
622 std::unique_ptr<TestWindowTreeClientImpl> wt_client3_; | 622 std::unique_ptr<TestWindowTreeClient> wt_client3_; |
623 | 623 |
624 mojom::WindowTreeHostPtr host_; | 624 mojom::WindowTreeHostPtr host_; |
625 | 625 |
626 private: | 626 private: |
627 std::unique_ptr<WindowTreeClientFactory> client_factory_; | 627 std::unique_ptr<WindowTreeClientFactory> client_factory_; |
628 int client_id_1_; | 628 int client_id_1_; |
629 int client_id_2_; | 629 int client_id_2_; |
630 Id root_window_id_; | 630 Id root_window_id_; |
631 | 631 |
632 DISALLOW_COPY_AND_ASSIGN(WindowTreeClientTest); | 632 DISALLOW_COPY_AND_ASSIGN(WindowTreeClientTest); |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 EXPECT_EQ("HierarchyChanged window=" + IdToString(window_3_1) + | 1361 EXPECT_EQ("HierarchyChanged window=" + IdToString(window_3_1) + |
1362 " old_parent=null new_parent=" + IdToString(window_1_1), | 1362 " old_parent=null new_parent=" + IdToString(window_1_1), |
1363 SingleChangeToDescription(*changes1())); | 1363 SingleChangeToDescription(*changes1())); |
1364 } | 1364 } |
1365 | 1365 |
1366 // Embed 1,1 again. | 1366 // Embed 1,1 again. |
1367 { | 1367 { |
1368 changes3()->clear(); | 1368 changes3()->clear(); |
1369 | 1369 |
1370 // We should get a new client for the new embedding. | 1370 // We should get a new client for the new embedding. |
1371 std::unique_ptr<TestWindowTreeClientImpl> client4( | 1371 std::unique_ptr<TestWindowTreeClient> client4( |
1372 EstablishClientViaEmbed(wt1(), window_1_1, nullptr)); | 1372 EstablishClientViaEmbed(wt1(), window_1_1, nullptr)); |
1373 ASSERT_TRUE(client4.get()); | 1373 ASSERT_TRUE(client4.get()); |
1374 EXPECT_EQ("[" + WindowParentToString(window_1_1, kNullParentId) + "]", | 1374 EXPECT_EQ("[" + WindowParentToString(window_1_1, kNullParentId) + "]", |
1375 ChangeWindowDescription(*client4->tracker()->changes())); | 1375 ChangeWindowDescription(*client4->tracker()->changes())); |
1376 | 1376 |
1377 // And 3 should get an unembed and delete. | 1377 // And 3 should get an unembed and delete. |
1378 wt_client3_->WaitForChangeCount(2); | 1378 wt_client3_->WaitForChangeCount(2); |
1379 EXPECT_EQ("OnUnembed window=" + IdToString(window_1_1), | 1379 EXPECT_EQ("OnUnembed window=" + IdToString(window_1_1), |
1380 ChangesToDescription1(*changes3())[0]); | 1380 ChangesToDescription1(*changes3())[0]); |
1381 EXPECT_EQ("WindowDeleted window=" + IdToString(window_1_1), | 1381 EXPECT_EQ("WindowDeleted window=" + IdToString(window_1_1), |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1799 SingleChangeToDescription(*changes1())); | 1799 SingleChangeToDescription(*changes1())); |
1800 std::vector<TestWindow> windows; | 1800 std::vector<TestWindow> windows; |
1801 GetWindowTree(wt1(), window_1_1, &windows); | 1801 GetWindowTree(wt1(), window_1_1, &windows); |
1802 EXPECT_FALSE(windows.empty()); | 1802 EXPECT_FALSE(windows.empty()); |
1803 } | 1803 } |
1804 | 1804 |
1805 // Verifies Embed() works when supplying a WindowTreeClient. | 1805 // Verifies Embed() works when supplying a WindowTreeClient. |
1806 TEST_F(WindowTreeClientTest, EmbedSupplyingWindowTreeClient) { | 1806 TEST_F(WindowTreeClientTest, EmbedSupplyingWindowTreeClient) { |
1807 ASSERT_TRUE(wt_client1()->NewWindow(1)); | 1807 ASSERT_TRUE(wt_client1()->NewWindow(1)); |
1808 | 1808 |
1809 TestWindowTreeClientImpl client2; | 1809 TestWindowTreeClient client2; |
1810 mojom::WindowTreeClientPtr client2_ptr; | 1810 mojom::WindowTreeClientPtr client2_ptr; |
1811 mojo::Binding<WindowTreeClient> client2_binding(&client2, &client2_ptr); | 1811 mojo::Binding<WindowTreeClient> client2_binding(&client2, &client2_ptr); |
1812 ASSERT_TRUE(Embed(wt1(), BuildWindowId(client_id_1(), 1), | 1812 ASSERT_TRUE(Embed(wt1(), BuildWindowId(client_id_1(), 1), |
1813 std::move(client2_ptr))); | 1813 std::move(client2_ptr))); |
1814 client2.WaitForOnEmbed(); | 1814 client2.WaitForOnEmbed(); |
1815 EXPECT_EQ("OnEmbed", | 1815 EXPECT_EQ("OnEmbed", |
1816 SingleChangeToDescription(*client2.tracker()->changes())); | 1816 SingleChangeToDescription(*client2.tracker()->changes())); |
1817 } | 1817 } |
1818 | 1818 |
1819 TEST_F(WindowTreeClientTest, EmbedFailsFromOtherClient) { | 1819 TEST_F(WindowTreeClientTest, EmbedFailsFromOtherClient) { |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 | 2031 |
2032 // TODO(sky): make sure coverage of what was | 2032 // TODO(sky): make sure coverage of what was |
2033 // WindowManagerTest.SecondEmbedRoot_InitService and | 2033 // WindowManagerTest.SecondEmbedRoot_InitService and |
2034 // WindowManagerTest.MultipleEmbedRootsBeforeWTHReady gets added to window | 2034 // WindowManagerTest.MultipleEmbedRootsBeforeWTHReady gets added to window |
2035 // manager | 2035 // manager |
2036 // tests. | 2036 // tests. |
2037 | 2037 |
2038 } // namespace test | 2038 } // namespace test |
2039 } // namespace ws | 2039 } // namespace ws |
2040 } // namespace mus | 2040 } // namespace mus |
OLD | NEW |