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 "mojo/services/public/cpp/view_manager/view_manager.h" | 5 #include "mojo/services/public/cpp/view_manager/view_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h" | 9 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h" |
10 #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h" | 10 #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h" |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 } | 209 } |
210 if (views) { | 210 if (views) { |
211 for (std::set<TransportViewId>::const_iterator it = views->begin(); | 211 for (std::set<TransportViewId>::const_iterator it = views->begin(); |
212 it != views->end(); ++it) { | 212 it != views->end(); ++it) { |
213 view_manager->GetViewById(*it)->AddObserver(&observer); | 213 view_manager->GetViewById(*it)->AddObserver(&observer); |
214 } | 214 } |
215 } | 215 } |
216 DoRunLoop(); | 216 DoRunLoop(); |
217 } | 217 } |
218 | 218 |
| 219 // Tracks a node's destruction. Query is_valid() for current state. |
| 220 class NodeTracker : public ViewTreeNodeObserver { |
| 221 public: |
| 222 explicit NodeTracker(ViewTreeNode* node) : node_(node) { |
| 223 node_->AddObserver(this); |
| 224 } |
| 225 virtual ~NodeTracker() { |
| 226 if (node_) |
| 227 node_->RemoveObserver(this); |
| 228 } |
| 229 |
| 230 bool is_valid() const { return !!node_; } |
| 231 |
| 232 private: |
| 233 // Overridden from ViewTreeNodeObserver: |
| 234 virtual void OnNodeDestroy( |
| 235 ViewTreeNode* node, |
| 236 ViewTreeNodeObserver::DispositionChangePhase phase) OVERRIDE { |
| 237 if (phase != ViewTreeNodeObserver::DISPOSITION_CHANGED) |
| 238 return; |
| 239 DCHECK_EQ(node, node_); |
| 240 node_ = NULL; |
| 241 } |
| 242 |
| 243 int id_; |
| 244 ViewTreeNode* node_; |
| 245 |
| 246 DISALLOW_COPY_AND_ASSIGN(NodeTracker); |
| 247 }; |
| 248 |
219 } // namespace | 249 } // namespace |
220 | 250 |
221 // ViewManager ----------------------------------------------------------------- | 251 // ViewManager ----------------------------------------------------------------- |
222 | 252 |
223 // These tests model synchronization of two peer connections to the view manager | 253 // These tests model synchronization of two peer connections to the view manager |
224 // service, that are given access to some root node. | 254 // service, that are given access to some root node. |
225 | 255 |
226 class ViewManagerTest : public testing::Test { | 256 class ViewManagerTest : public testing::Test { |
227 public: | 257 public: |
228 ViewManagerTest() : commit_count_(0) {} | 258 ViewManagerTest() : commit_count_(0) {} |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 } | 571 } |
542 | 572 |
543 // This test verifies that a node hierarchy constructed in one connection | 573 // This test verifies that a node hierarchy constructed in one connection |
544 // becomes entirely visible to the second connection when the hierarchy is | 574 // becomes entirely visible to the second connection when the hierarchy is |
545 // attached. | 575 // attached. |
546 TEST_F(ViewManagerTest, MapSubtreeOnAttach) { | 576 TEST_F(ViewManagerTest, MapSubtreeOnAttach) { |
547 ViewTreeNode* node1 = ViewTreeNode::Create(view_manager_1()); | 577 ViewTreeNode* node1 = ViewTreeNode::Create(view_manager_1()); |
548 ViewTreeNode* node11 = CreateNodeInParent(node1); | 578 ViewTreeNode* node11 = CreateNodeInParent(node1); |
549 View* view11 = View::Create(view_manager_1()); | 579 View* view11 = View::Create(view_manager_1()); |
550 node11->SetActiveView(view11); | 580 node11->SetActiveView(view11); |
| 581 gfx::Rect node11_bounds(800, 600); |
| 582 node11->SetBounds(node11_bounds); |
551 WaitForAllChangesToBeAcked(view_manager_1()); | 583 WaitForAllChangesToBeAcked(view_manager_1()); |
552 | 584 |
553 // Now attach this node tree to the root & wait for it to show up in the | 585 // Now attach this node tree to the root & wait for it to show up in the |
554 // second connection. | 586 // second connection. |
555 view_manager_1()->tree()->AddChild(node1); | 587 view_manager_1()->tree()->AddChild(node1); |
556 WaitForTreeSizeToMatch(view_manager_2()->tree(), 3); | 588 WaitForTreeSizeToMatch(view_manager_2()->tree(), 3); |
557 | 589 |
558 ViewTreeNode* node11_2 = view_manager_2()->GetNodeById(node11->id()); | 590 ViewTreeNode* node11_2 = view_manager_2()->GetNodeById(node11->id()); |
559 View* view11_2 = view_manager_2()->GetViewById(view11->id()); | 591 View* view11_2 = view_manager_2()->GetViewById(view11->id()); |
560 EXPECT_TRUE(node11_2 != NULL); | 592 EXPECT_TRUE(node11_2 != NULL); |
561 EXPECT_EQ(view11_2, node11_2->active_view()); | 593 EXPECT_EQ(view11_2, node11_2->active_view()); |
| 594 EXPECT_EQ(node11_bounds, node11_2->bounds()); |
562 } | 595 } |
563 | 596 |
564 // Verifies that bounds changes applied to a node hierarchy in one connection | 597 // Verifies that bounds changes applied to a node hierarchy in one connection |
565 // are reflected to another. | 598 // are reflected to another. |
566 TEST_F(ViewManagerTest, SetBounds) { | 599 TEST_F(ViewManagerTest, SetBounds) { |
567 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); | 600 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); |
568 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2); | 601 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2); |
569 | 602 |
570 ViewTreeNode* node1_2 = view_manager_2()->GetNodeById(node1->id()); | 603 ViewTreeNode* node1_2 = view_manager_2()->GetNodeById(node1->id()); |
571 EXPECT_EQ(node1->bounds(), node1_2->bounds()); | 604 EXPECT_EQ(node1->bounds(), node1_2->bounds()); |
572 | 605 |
573 node1->SetBounds(gfx::Rect(0, 0, 100, 100)); | 606 node1->SetBounds(gfx::Rect(0, 0, 100, 100)); |
574 WaitForBoundsToChange(node1_2); | 607 WaitForBoundsToChange(node1_2); |
575 EXPECT_EQ(node1->bounds(), node1_2->bounds()); | 608 EXPECT_EQ(node1->bounds(), node1_2->bounds()); |
| 609 } |
576 | 610 |
| 611 // Verifies that bounds changes applied to a node owned by a different |
| 612 // connection are refused. |
| 613 TEST_F(ViewManagerTest, SetBoundsSecurity) { |
| 614 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); |
| 615 node1->SetBounds(gfx::Rect(800, 600)); |
| 616 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2); |
577 | 617 |
| 618 ViewTreeNode* node1_2 = view_manager_2()->GetNodeById(node1->id()); |
| 619 node1_2->SetBounds(gfx::Rect(1024, 768)); |
| 620 // Bounds change should have been rejected. |
| 621 EXPECT_EQ(node1->bounds(), node1_2->bounds()); |
| 622 } |
| 623 |
| 624 // Verifies that a node can only be destroyed by the connection that created it. |
| 625 TEST_F(ViewManagerTest, DestroySecurity) { |
| 626 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); |
| 627 WaitForTreeSizeToMatch(view_manager_2()->tree(), 3); |
| 628 |
| 629 ViewTreeNode* node1_2 = view_manager_2()->GetNodeById(node1->id()); |
| 630 NodeTracker tracker2(node1_2); |
| 631 node1_2->Destroy(); |
| 632 // Node should not have been destroyed. |
| 633 EXPECT_TRUE(tracker2.is_valid()); |
| 634 |
| 635 NodeTracker tracker1(node1); |
| 636 node1->Destroy(); |
| 637 EXPECT_FALSE(tracker1.is_valid()); |
578 } | 638 } |
579 | 639 |
580 } // namespace view_manager | 640 } // namespace view_manager |
581 } // namespace mojo | 641 } // namespace mojo |
OLD | NEW |