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