| 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/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "mojo/public/cpp/application/application.h" | 10 #include "mojo/public/cpp/application/application.h" |
| 11 #include "mojo/service_manager/service_manager.h" | 11 #include "mojo/service_manager/service_manager.h" |
| 12 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h" | 12 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h" |
| 13 #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h" | 13 #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h" |
| 14 #include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h" | 14 #include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h" |
| 15 #include "mojo/services/public/cpp/view_manager/util.h" | 15 #include "mojo/services/public/cpp/view_manager/util.h" |
| 16 #include "mojo/services/public/cpp/view_manager/view.h" | 16 #include "mojo/services/public/cpp/view_manager/view.h" |
| 17 #include "mojo/services/public/cpp/view_manager/view_observer.h" | 17 #include "mojo/services/public/cpp/view_manager/view_observer.h" |
| 18 #include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h" | 18 #include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h" |
| 19 #include "mojo/shell/shell_test_helper.h" | 19 #include "mojo/shell/shell_test_helper.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 21 |
| 22 namespace mojo { | 22 namespace mojo { |
| 23 namespace view_manager { | 23 namespace view_manager { |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 const char kTestServiceURL[] = "mojo:test_url"; | 26 const char kWindowManagerURL[] = "mojo:window_manager"; |
| 27 const char kTestServiceURL2[] = "mojo:test_url2"; | 27 const char kEmbeddedApp1URL[] = "mojo:embedded_app_1"; |
| 28 | 28 |
| 29 base::RunLoop* current_run_loop = NULL; | 29 base::RunLoop* current_run_loop = NULL; |
| 30 | 30 |
| 31 void DoRunLoop() { | 31 void DoRunLoop() { |
| 32 base::RunLoop run_loop; | 32 base::RunLoop run_loop; |
| 33 current_run_loop = &run_loop; | 33 current_run_loop = &run_loop; |
| 34 current_run_loop->Run(); | 34 current_run_loop->Run(); |
| 35 current_run_loop = NULL; | 35 current_run_loop = NULL; |
| 36 } | 36 } |
| 37 | 37 |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 ViewTreeNode* CreateNodeInParent(ViewTreeNode* parent) { | 297 ViewTreeNode* CreateNodeInParent(ViewTreeNode* parent) { |
| 298 ViewManager* parent_manager = ViewTreeNodePrivate(parent).view_manager(); | 298 ViewManager* parent_manager = ViewTreeNodePrivate(parent).view_manager(); |
| 299 ViewTreeNode* node = ViewTreeNode::Create(parent_manager); | 299 ViewTreeNode* node = ViewTreeNode::Create(parent_manager); |
| 300 parent->AddChild(node); | 300 parent->AddChild(node); |
| 301 return node; | 301 return node; |
| 302 } | 302 } |
| 303 | 303 |
| 304 // Embeds another version of the test app @ node. | 304 // Embeds another version of the test app @ node. |
| 305 ViewManager* Embed(ViewManager* view_manager, ViewTreeNode* node) { | 305 ViewManager* Embed(ViewManager* view_manager, ViewTreeNode* node) { |
| 306 DCHECK_EQ(view_manager, ViewTreeNodePrivate(node).view_manager()); | 306 DCHECK_EQ(view_manager, ViewTreeNodePrivate(node).view_manager()); |
| 307 view_manager->Embed(kTestServiceURL2, node); | 307 node->Embed(kEmbeddedApp1URL); |
| 308 RunRunLoop(); | 308 RunRunLoop(); |
| 309 return GetLoadedViewManager(); | 309 return GetLoadedViewManager(); |
| 310 } | 310 } |
| 311 | 311 |
| 312 // TODO(beng): remove these methods once all the tests are migrated. | 312 // TODO(beng): remove these methods once all the tests are migrated. |
| 313 void DestroyViewManager1() {} | 313 void DestroyViewManager1() {} |
| 314 ViewManager* view_manager_1() { return NULL; } | 314 ViewManager* view_manager_1() { return NULL; } |
| 315 ViewManager* view_manager_2() { return NULL; } | 315 ViewManager* view_manager_2() { return NULL; } |
| 316 | 316 |
| 317 ViewManager* GetLoadedViewManager() { | 317 ViewManager* GetLoadedViewManager() { |
| 318 ViewManager* view_manager = loaded_view_manager_; | 318 ViewManager* view_manager = loaded_view_manager_; |
| 319 loaded_view_manager_ = NULL; | 319 loaded_view_manager_ = NULL; |
| 320 return view_manager; | 320 return view_manager; |
| 321 } | 321 } |
| 322 | 322 |
| 323 void UnloadApplication(const GURL& url) { | 323 void UnloadApplication(const GURL& url) { |
| 324 test_helper_.SetLoaderForURL(scoped_ptr<ServiceLoader>(), url); | 324 test_helper_.SetLoaderForURL(scoped_ptr<ServiceLoader>(), url); |
| 325 } | 325 } |
| 326 | 326 |
| 327 private: | 327 private: |
| 328 // Overridden from testing::Test: | 328 // Overridden from testing::Test: |
| 329 virtual void SetUp() OVERRIDE { | 329 virtual void SetUp() OVERRIDE { |
| 330 base::Callback<void(ViewManager*)> ready_callback = |
| 331 base::Bind(&ViewManagerTest::OnViewManagerLoaded, |
| 332 base::Unretained(this)); |
| 330 test_helper_.Init(); | 333 test_helper_.Init(); |
| 331 test_helper_.SetLoaderForURL( | 334 test_helper_.SetLoaderForURL( |
| 332 scoped_ptr<ServiceLoader>(new ConnectServiceLoader( | 335 scoped_ptr<ServiceLoader>(new ConnectServiceLoader(ready_callback)), |
| 333 base::Bind(&ViewManagerTest::OnViewManagerLoaded, | 336 GURL(kWindowManagerURL)); |
| 334 base::Unretained(this)))), | |
| 335 GURL(kTestServiceURL)); | |
| 336 test_helper_.SetLoaderForURL( | 337 test_helper_.SetLoaderForURL( |
| 337 scoped_ptr<ServiceLoader>(new ConnectServiceLoader( | 338 scoped_ptr<ServiceLoader>(new ConnectServiceLoader(ready_callback)), |
| 338 base::Bind(&ViewManagerTest::OnViewManagerLoaded, | 339 GURL(kEmbeddedApp1URL)); |
| 339 base::Unretained(this)))), | |
| 340 GURL(kTestServiceURL2)); | |
| 341 | 340 |
| 342 ConnectToService(test_helper_.service_provider(), | 341 ConnectToService(test_helper_.service_provider(), |
| 343 "mojo:mojo_view_manager", | 342 "mojo:mojo_view_manager", |
| 344 &view_manager_init_); | 343 &view_manager_init_); |
| 345 ASSERT_TRUE(ViewManagerInitConnect(view_manager_init_.get(), | 344 ASSERT_TRUE(ViewManagerInitConnect(view_manager_init_.get(), |
| 346 kTestServiceURL)); | 345 kWindowManagerURL)); |
| 347 } | 346 } |
| 348 | 347 |
| 349 void ViewManagerInitConnectCallback(bool* result_cache, | 348 void ViewManagerInitConnectCallback(bool* result_cache, |
| 350 bool result) { | 349 bool result) { |
| 351 *result_cache = result; | 350 *result_cache = result; |
| 352 } | 351 } |
| 353 | 352 |
| 354 bool ViewManagerInitConnect(IViewManagerInit* view_manager_init, | 353 bool ViewManagerInitConnect(IViewManagerInit* view_manager_init, |
| 355 const std::string& url) { | 354 const std::string& url) { |
| 356 bool result = false; | 355 bool result = false; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 386 ViewManager* window_manager_; | 385 ViewManager* window_manager_; |
| 387 int commit_count_; | 386 int commit_count_; |
| 388 | 387 |
| 389 DISALLOW_COPY_AND_ASSIGN(ViewManagerTest); | 388 DISALLOW_COPY_AND_ASSIGN(ViewManagerTest); |
| 390 }; | 389 }; |
| 391 | 390 |
| 392 TEST_F(ViewManagerTest, SetUp) {} | 391 TEST_F(ViewManagerTest, SetUp) {} |
| 393 | 392 |
| 394 TEST_F(ViewManagerTest, Embed) { | 393 TEST_F(ViewManagerTest, Embed) { |
| 395 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 394 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 396 window_manager()->tree()->AddChild(node); | 395 window_manager()->roots().front()->AddChild(node); |
| 397 ViewManager* embedded = Embed(window_manager(), node); | 396 ViewManager* embedded = Embed(window_manager(), node); |
| 398 EXPECT_TRUE(NULL != embedded); | 397 EXPECT_TRUE(NULL != embedded); |
| 398 |
| 399 ViewTreeNode* node_in_embedded = embedded->roots().front(); |
| 400 EXPECT_EQ(node->parent(), window_manager()->roots().front()); |
| 401 EXPECT_EQ(NULL, node_in_embedded->parent()); |
| 399 } | 402 } |
| 400 | 403 |
| 401 // When Window Manager embeds A @ N, then creates N2 and parents to N, N becomes | 404 // When Window Manager embeds A @ N, then creates N2 and parents to N, N becomes |
| 402 // visible to A. | 405 // visible to A. |
| 403 // TODO(beng): verify whether or not this is a policy we like. | 406 // TODO(beng): verify whether or not this is a policy we like. |
| 404 TEST_F(ViewManagerTest, HierarchyChanged_NodeAdded) { | 407 TEST_F(ViewManagerTest, HierarchyChanged_NodeAdded) { |
| 405 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 408 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 406 window_manager()->tree()->AddChild(node); | 409 window_manager()->roots().front()->AddChild(node); |
| 407 ViewManager* embedded = Embed(window_manager(), node); | 410 ViewManager* embedded = Embed(window_manager(), node); |
| 408 ViewTreeNode* nested = ViewTreeNode::Create(window_manager()); | 411 ViewTreeNode* nested = ViewTreeNode::Create(window_manager()); |
| 409 node->AddChild(nested); | 412 node->AddChild(nested); |
| 410 WaitForTreeSizeToMatch(embedded->tree(), 2); | 413 WaitForTreeSizeToMatch(embedded->roots().front(), 2); |
| 411 EXPECT_EQ(embedded->tree()->children().front()->id(), nested->id()); | 414 EXPECT_EQ(embedded->roots().front()->children().front()->id(), nested->id()); |
| 412 } | 415 } |
| 413 | 416 |
| 414 // Window manager has two nodes, N1 & N2. Embeds A at N1. Creates node N21, | 417 // Window manager has two nodes, N1 & N2. Embeds A at N1. Creates node N21, |
| 415 // a child of N2. Reparents N2 to N1. N1 should become visible to A. | 418 // a child of N2. Reparents N2 to N1. N1 should become visible to A. |
| 416 // TODO(beng): verify whether or not this is a policy we like. | 419 // TODO(beng): verify whether or not this is a policy we like. |
| 417 TEST_F(ViewManagerTest, HierarchyChanged_NodeMoved) { | 420 TEST_F(ViewManagerTest, HierarchyChanged_NodeMoved) { |
| 418 ViewTreeNode* node1 = ViewTreeNode::Create(window_manager()); | 421 ViewTreeNode* node1 = ViewTreeNode::Create(window_manager()); |
| 419 window_manager()->tree()->AddChild(node1); | 422 window_manager()->roots().front()->AddChild(node1); |
| 420 ViewManager* embedded = Embed(window_manager(), node1); | 423 ViewManager* embedded = Embed(window_manager(), node1); |
| 421 WaitForTreeSizeToMatch(embedded->tree(), 1); | 424 WaitForTreeSizeToMatch(embedded->roots().front(), 1); |
| 422 | 425 |
| 423 ViewTreeNode* node2 = ViewTreeNode::Create(window_manager()); | 426 ViewTreeNode* node2 = ViewTreeNode::Create(window_manager()); |
| 424 window_manager()->tree()->AddChild(node2); | 427 window_manager()->roots().front()->AddChild(node2); |
| 425 WaitForTreeSizeToMatch(embedded->tree(), 1); | 428 WaitForTreeSizeToMatch(embedded->roots().front(), 1); |
| 426 EXPECT_TRUE(embedded->tree()->children().empty()); | 429 EXPECT_TRUE(embedded->roots().front()->children().empty()); |
| 427 | 430 |
| 428 ViewTreeNode* node21 = ViewTreeNode::Create(window_manager()); | 431 ViewTreeNode* node21 = ViewTreeNode::Create(window_manager()); |
| 429 node2->AddChild(node21); | 432 node2->AddChild(node21); |
| 430 WaitForTreeSizeToMatch(embedded->tree(), 1); | 433 WaitForTreeSizeToMatch(embedded->roots().front(), 1); |
| 431 EXPECT_TRUE(embedded->tree()->children().empty()); | 434 EXPECT_TRUE(embedded->roots().front()->children().empty()); |
| 432 | 435 |
| 433 // Makes node21 visible to |embedded|. | 436 // Makes node21 visible to |embedded|. |
| 434 node1->AddChild(node21); | 437 node1->AddChild(node21); |
| 435 WaitForTreeSizeToMatch(embedded->tree(), 2); | 438 WaitForTreeSizeToMatch(embedded->roots().front(), 2); |
| 436 EXPECT_FALSE(embedded->tree()->children().empty()); | 439 EXPECT_FALSE(embedded->roots().front()->children().empty()); |
| 437 EXPECT_EQ(embedded->tree()->children().front()->id(), node21->id()); | 440 EXPECT_EQ(embedded->roots().front()->children().front()->id(), node21->id()); |
| 438 } | 441 } |
| 439 | 442 |
| 440 // Window manager has two nodes, N1 and N11. Embeds A at N1. Removes N11 from | 443 // Window manager has two nodes, N1 and N11. Embeds A at N1. Removes N11 from |
| 441 // N1. N11 should disappear from A. | 444 // N1. N11 should disappear from A. |
| 442 // TODO(beng): verify whether or not this is a policy we like. | 445 // TODO(beng): verify whether or not this is a policy we like. |
| 443 TEST_F(ViewManagerTest, HierarchyChanged_NodeRemoved) { | 446 TEST_F(ViewManagerTest, HierarchyChanged_NodeRemoved) { |
| 444 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 447 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 445 window_manager()->tree()->AddChild(node); | 448 window_manager()->roots().front()->AddChild(node); |
| 446 ViewTreeNode* nested = ViewTreeNode::Create(window_manager()); | 449 ViewTreeNode* nested = ViewTreeNode::Create(window_manager()); |
| 447 node->AddChild(nested); | 450 node->AddChild(nested); |
| 448 | 451 |
| 449 ViewManager* embedded = Embed(window_manager(), node); | 452 ViewManager* embedded = Embed(window_manager(), node); |
| 450 EXPECT_EQ(embedded->tree()->children().front()->id(), nested->id()); | 453 EXPECT_EQ(embedded->roots().front()->children().front()->id(), nested->id()); |
| 451 | 454 |
| 452 node->RemoveChild(nested); | 455 node->RemoveChild(nested); |
| 453 WaitForTreeSizeToMatch(embedded->tree(), 1); | 456 WaitForTreeSizeToMatch(embedded->roots().front(), 1); |
| 454 EXPECT_TRUE(embedded->tree()->children().empty()); | 457 EXPECT_TRUE(embedded->roots().front()->children().empty()); |
| 455 } | 458 } |
| 456 | 459 |
| 457 // Window manager has two nodes, N1 and N11. Embeds A at N1. Destroys N11. | 460 // Window manager has two nodes, N1 and N11. Embeds A at N1. Destroys N11. |
| 458 // N11 should disappear from A. | 461 // N11 should disappear from A. |
| 459 // TODO(beng): verify whether or not this is a policy we like. | 462 // TODO(beng): verify whether or not this is a policy we like. |
| 460 TEST_F(ViewManagerTest, NodeDestroyed) { | 463 TEST_F(ViewManagerTest, NodeDestroyed) { |
| 461 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 464 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 462 window_manager()->tree()->AddChild(node); | 465 window_manager()->roots().front()->AddChild(node); |
| 463 ViewTreeNode* nested = ViewTreeNode::Create(window_manager()); | 466 ViewTreeNode* nested = ViewTreeNode::Create(window_manager()); |
| 464 node->AddChild(nested); | 467 node->AddChild(nested); |
| 465 | 468 |
| 466 ViewManager* embedded = Embed(window_manager(), node); | 469 ViewManager* embedded = Embed(window_manager(), node); |
| 467 EXPECT_EQ(embedded->tree()->children().front()->id(), nested->id()); | 470 EXPECT_EQ(embedded->roots().front()->children().front()->id(), nested->id()); |
| 468 | 471 |
| 469 // |nested| will be deleted after calling Destroy() below. | 472 // |nested| will be deleted after calling Destroy() below. |
| 470 TransportNodeId id = nested->id(); | 473 TransportNodeId id = nested->id(); |
| 471 nested->Destroy(); | 474 nested->Destroy(); |
| 472 | 475 |
| 473 std::set<TransportNodeId> nodes; | 476 std::set<TransportNodeId> nodes; |
| 474 nodes.insert(id); | 477 nodes.insert(id); |
| 475 WaitForDestruction(embedded, &nodes, NULL); | 478 WaitForDestruction(embedded, &nodes, NULL); |
| 476 | 479 |
| 477 EXPECT_TRUE(embedded->tree()->children().empty()); | 480 EXPECT_TRUE(embedded->roots().front()->children().empty()); |
| 478 EXPECT_EQ(NULL, embedded->GetNodeById(id)); | 481 EXPECT_EQ(NULL, embedded->GetNodeById(id)); |
| 479 } | 482 } |
| 480 | 483 |
| 481 TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNode) { | 484 TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNode) { |
| 482 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 485 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 483 window_manager()->tree()->AddChild(node); | 486 window_manager()->roots().front()->AddChild(node); |
| 484 ViewManager* embedded = Embed(window_manager(), node); | 487 ViewManager* embedded = Embed(window_manager(), node); |
| 485 | 488 |
| 486 TransportNodeId node_id = node->id(); | 489 TransportNodeId node_id = node->id(); |
| 487 | 490 |
| 488 UnloadApplication(GURL(kTestServiceURL)); | 491 UnloadApplication(GURL(kWindowManagerURL)); |
| 489 | 492 |
| 490 std::set<TransportNodeId> nodes; | 493 std::set<TransportNodeId> nodes; |
| 491 nodes.insert(node_id); | 494 nodes.insert(node_id); |
| 492 WaitForDestruction(embedded, &nodes, NULL); | 495 WaitForDestruction(embedded, &nodes, NULL); |
| 493 | 496 |
| 494 EXPECT_EQ(NULL, embedded->tree()); | 497 EXPECT_TRUE(embedded->roots().empty()); |
| 495 } | 498 } |
| 496 | 499 |
| 497 TEST_F(ViewManagerTest, SetActiveView) { | 500 TEST_F(ViewManagerTest, SetActiveView) { |
| 498 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 501 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 499 window_manager()->tree()->AddChild(node); | 502 window_manager()->roots().front()->AddChild(node); |
| 500 ViewManager* embedded = Embed(window_manager(), node); | 503 ViewManager* embedded = Embed(window_manager(), node); |
| 501 | 504 |
| 502 View* view = View::Create(window_manager()); | 505 View* view = View::Create(window_manager()); |
| 503 node->SetActiveView(view); | 506 node->SetActiveView(view); |
| 504 | 507 |
| 505 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); | 508 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); |
| 506 WaitForActiveViewToChange(node_in_embedded); | 509 WaitForActiveViewToChange(node_in_embedded); |
| 507 | 510 |
| 508 EXPECT_EQ(node_in_embedded->active_view()->id(), view->id()); | 511 EXPECT_EQ(node_in_embedded->active_view()->id(), view->id()); |
| 509 } | 512 } |
| 510 | 513 |
| 511 TEST_F(ViewManagerTest, DestroyView) { | 514 TEST_F(ViewManagerTest, DestroyView) { |
| 512 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 515 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 513 window_manager()->tree()->AddChild(node); | 516 window_manager()->roots().front()->AddChild(node); |
| 514 ViewManager* embedded = Embed(window_manager(), node); | 517 ViewManager* embedded = Embed(window_manager(), node); |
| 515 | 518 |
| 516 View* view = View::Create(window_manager()); | 519 View* view = View::Create(window_manager()); |
| 517 node->SetActiveView(view); | 520 node->SetActiveView(view); |
| 518 | 521 |
| 519 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); | 522 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); |
| 520 WaitForActiveViewToChange(node_in_embedded); | 523 WaitForActiveViewToChange(node_in_embedded); |
| 521 | 524 |
| 522 EXPECT_EQ(node_in_embedded->active_view()->id(), view->id()); | 525 EXPECT_EQ(node_in_embedded->active_view()->id(), view->id()); |
| 523 | 526 |
| 524 TransportViewId view_id = view->id(); | 527 TransportViewId view_id = view->id(); |
| 525 view->Destroy(); | 528 view->Destroy(); |
| 526 | 529 |
| 527 std::set<TransportViewId> views; | 530 std::set<TransportViewId> views; |
| 528 views.insert(view_id); | 531 views.insert(view_id); |
| 529 WaitForDestruction(embedded, NULL, &views); | 532 WaitForDestruction(embedded, NULL, &views); |
| 530 EXPECT_EQ(NULL, node_in_embedded->active_view()); | 533 EXPECT_EQ(NULL, node_in_embedded->active_view()); |
| 531 EXPECT_EQ(NULL, embedded->GetViewById(view_id)); | 534 EXPECT_EQ(NULL, embedded->GetViewById(view_id)); |
| 532 } | 535 } |
| 533 | 536 |
| 534 // Destroying the connection that created a node and view should result in that | 537 // Destroying the connection that created a node and view should result in that |
| 535 // node and view disappearing from all connections that see them. | 538 // node and view disappearing from all connections that see them. |
| 536 TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNodeAndView) { | 539 TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNodeAndView) { |
| 537 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 540 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 538 window_manager()->tree()->AddChild(node); | 541 window_manager()->roots().front()->AddChild(node); |
| 539 View* view = View::Create(window_manager()); | 542 View* view = View::Create(window_manager()); |
| 540 node->SetActiveView(view); | 543 node->SetActiveView(view); |
| 541 ViewManager* embedded = Embed(window_manager(), node); | 544 ViewManager* embedded = Embed(window_manager(), node); |
| 542 | 545 |
| 543 TransportNodeId node_id = node->id(); | 546 TransportNodeId node_id = node->id(); |
| 544 TransportViewId view_id = view->id(); | 547 TransportViewId view_id = view->id(); |
| 545 | 548 |
| 546 UnloadApplication(GURL(kTestServiceURL)); | 549 UnloadApplication(GURL(kWindowManagerURL)); |
| 547 | 550 |
| 548 std::set<TransportNodeId> observed_nodes; | 551 std::set<TransportNodeId> observed_nodes; |
| 549 observed_nodes.insert(node_id); | 552 observed_nodes.insert(node_id); |
| 550 std::set<TransportViewId> observed_views; | 553 std::set<TransportViewId> observed_views; |
| 551 observed_views.insert(view_id); | 554 observed_views.insert(view_id); |
| 552 WaitForDestruction(embedded, &observed_nodes, &observed_views); | 555 WaitForDestruction(embedded, &observed_nodes, &observed_views); |
| 553 | 556 |
| 554 EXPECT_EQ(NULL, embedded->tree()); | 557 EXPECT_TRUE(embedded->roots().empty()); |
| 555 EXPECT_EQ(NULL, embedded->GetNodeById(node_id)); | 558 EXPECT_EQ(NULL, embedded->GetNodeById(node_id)); |
| 556 EXPECT_EQ(NULL, embedded->GetViewById(view_id)); | 559 EXPECT_EQ(NULL, embedded->GetViewById(view_id)); |
| 557 } | 560 } |
| 558 | 561 |
| 559 // This test validates the following scenario: | 562 // This test validates the following scenario: |
| 560 // - a node originating from one connection | 563 // - a node originating from one connection |
| 561 // - a view originating from a second connection | 564 // - a view originating from a second connection |
| 562 // + the connection originating the node is destroyed | 565 // + the connection originating the node is destroyed |
| 563 // -> the view should still exist (since the second connection is live) but | 566 // -> the view should still exist (since the second connection is live) but |
| 564 // should be disconnected from any nodes. | 567 // should be disconnected from any nodes. |
| 565 TEST_F(ViewManagerTest, | 568 TEST_F(ViewManagerTest, |
| 566 ViewManagerDestroyed_CleanupNodeAndViewFromDifferentConnections) { | 569 ViewManagerDestroyed_CleanupNodeAndViewFromDifferentConnections) { |
| 567 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 570 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 568 window_manager()->tree()->AddChild(node); | 571 window_manager()->roots().front()->AddChild(node); |
| 569 ViewManager* embedded = Embed(window_manager(), node); | 572 ViewManager* embedded = Embed(window_manager(), node); |
| 570 View* view_in_embedded = View::Create(embedded); | 573 View* view_in_embedded = View::Create(embedded); |
| 571 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); | 574 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); |
| 572 node_in_embedded->SetActiveView(view_in_embedded); | 575 node_in_embedded->SetActiveView(view_in_embedded); |
| 573 | 576 |
| 574 WaitForActiveViewToChange(node); | 577 WaitForActiveViewToChange(node); |
| 575 | 578 |
| 576 TransportNodeId node_id = node->id(); | 579 TransportNodeId node_id = node->id(); |
| 577 TransportViewId view_id = view_in_embedded->id(); | 580 TransportViewId view_id = view_in_embedded->id(); |
| 578 | 581 |
| 579 UnloadApplication(GURL(kTestServiceURL)); | 582 UnloadApplication(GURL(kWindowManagerURL)); |
| 580 std::set<TransportNodeId> nodes; | 583 std::set<TransportNodeId> nodes; |
| 581 nodes.insert(node_id); | 584 nodes.insert(node_id); |
| 582 WaitForDestruction(embedded, &nodes, NULL); | 585 WaitForDestruction(embedded, &nodes, NULL); |
| 583 | 586 |
| 584 EXPECT_EQ(NULL, embedded->tree()); | 587 EXPECT_TRUE(embedded->roots().empty()); |
| 585 // node was owned by the window manager, so it should be gone. | 588 // node was owned by the window manager, so it should be gone. |
| 586 EXPECT_EQ(NULL, embedded->GetNodeById(node_id)); | 589 EXPECT_EQ(NULL, embedded->GetNodeById(node_id)); |
| 587 // view_in_embedded was owned by the embedded app, so it should still exist, | 590 // view_in_embedded was owned by the embedded app, so it should still exist, |
| 588 // but disconnected from the node tree. | 591 // but disconnected from the node tree. |
| 589 EXPECT_EQ(view_in_embedded, embedded->GetViewById(view_id)); | 592 EXPECT_EQ(view_in_embedded, embedded->GetViewById(view_id)); |
| 590 EXPECT_EQ(NULL, view_in_embedded->node()); | 593 EXPECT_EQ(NULL, view_in_embedded->node()); |
| 591 } | 594 } |
| 592 | 595 |
| 593 // This test verifies that it is not possible to set the active view to a view | 596 // This test verifies that it is not possible to set the active view to a view |
| 594 // defined in a different connection. | 597 // defined in a different connection. |
| 595 // TODO(beng): write these tests for ViewTreeNode::AddChild(), RemoveChild() and | 598 // TODO(beng): write these tests for ViewTreeNode::AddChild(), RemoveChild() and |
| 596 // Contains(). | 599 // Contains(). |
| 597 TEST_F(ViewManagerTest, SetActiveViewAcrossConnection) { | 600 TEST_F(ViewManagerTest, SetActiveViewAcrossConnection) { |
| 598 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 601 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 599 window_manager()->tree()->AddChild(node); | 602 window_manager()->roots().front()->AddChild(node); |
| 600 ViewManager* embedded = Embed(window_manager(), node); | 603 ViewManager* embedded = Embed(window_manager(), node); |
| 601 | 604 |
| 602 View* view_in_embedded = View::Create(embedded); | 605 View* view_in_embedded = View::Create(embedded); |
| 603 EXPECT_DEATH(node->SetActiveView(view_in_embedded), ""); | 606 EXPECT_DEATH(node->SetActiveView(view_in_embedded), ""); |
| 604 } | 607 } |
| 605 | 608 |
| 606 // This test verifies that a node hierarchy constructed in one connection | 609 // This test verifies that a node hierarchy constructed in one connection |
| 607 // becomes entirely visible to the second connection when the hierarchy is | 610 // becomes entirely visible to the second connection when the hierarchy is |
| 608 // attached. | 611 // attached. |
| 609 TEST_F(ViewManagerTest, MapSubtreeOnAttach) { | 612 TEST_F(ViewManagerTest, MapSubtreeOnAttach) { |
| 610 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 613 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 611 window_manager()->tree()->AddChild(node); | 614 window_manager()->roots().front()->AddChild(node); |
| 612 ViewManager* embedded = Embed(window_manager(), node); | 615 ViewManager* embedded = Embed(window_manager(), node); |
| 613 | 616 |
| 614 // Create a subtree private to the window manager and make some changes to it. | 617 // Create a subtree private to the window manager and make some changes to it. |
| 615 ViewTreeNode* child1 = ViewTreeNode::Create(window_manager()); | 618 ViewTreeNode* child1 = ViewTreeNode::Create(window_manager()); |
| 616 ViewTreeNode* child11 = ViewTreeNode::Create(window_manager()); | 619 ViewTreeNode* child11 = ViewTreeNode::Create(window_manager()); |
| 617 child1->AddChild(child11); | 620 child1->AddChild(child11); |
| 618 gfx::Rect child11_bounds(800, 600); | 621 gfx::Rect child11_bounds(800, 600); |
| 619 child11->SetBounds(child11_bounds); | 622 child11->SetBounds(child11_bounds); |
| 620 View* view11 = View::Create(window_manager()); | 623 View* view11 = View::Create(window_manager()); |
| 621 child11->SetActiveView(view11); | 624 child11->SetActiveView(view11); |
| 622 WaitForAllChangesToBeAcked(window_manager()); | 625 WaitForAllChangesToBeAcked(window_manager()); |
| 623 | 626 |
| 624 // When added to the shared node, the entire hierarchy and all property | 627 // When added to the shared node, the entire hierarchy and all property |
| 625 // changes should become visible to the embedded app. | 628 // changes should become visible to the embedded app. |
| 626 node->AddChild(child1); | 629 node->AddChild(child1); |
| 627 WaitForTreeSizeToMatch(embedded->tree(), 3); | 630 WaitForTreeSizeToMatch(embedded->roots().front(), 3); |
| 628 | 631 |
| 629 ViewTreeNode* child11_in_embedded = embedded->GetNodeById(child11->id()); | 632 ViewTreeNode* child11_in_embedded = embedded->GetNodeById(child11->id()); |
| 630 View* view11_in_embedded = embedded->GetViewById(view11->id()); | 633 View* view11_in_embedded = embedded->GetViewById(view11->id()); |
| 631 EXPECT_TRUE(child11_in_embedded != NULL); | 634 EXPECT_TRUE(child11_in_embedded != NULL); |
| 632 EXPECT_EQ(view11_in_embedded, child11_in_embedded->active_view()); | 635 EXPECT_EQ(view11_in_embedded, child11_in_embedded->active_view()); |
| 633 EXPECT_EQ(child11_bounds, child11_in_embedded->bounds()); | 636 EXPECT_EQ(child11_bounds, child11_in_embedded->bounds()); |
| 634 } | 637 } |
| 635 | 638 |
| 636 // Verifies that bounds changes applied to a node hierarchy in one connection | 639 // Verifies that bounds changes applied to a node hierarchy in one connection |
| 637 // are reflected to another. | 640 // are reflected to another. |
| 638 TEST_F(ViewManagerTest, SetBounds) { | 641 TEST_F(ViewManagerTest, SetBounds) { |
| 639 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 642 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 640 window_manager()->tree()->AddChild(node); | 643 window_manager()->roots().front()->AddChild(node); |
| 641 ViewManager* embedded = Embed(window_manager(), node); | 644 ViewManager* embedded = Embed(window_manager(), node); |
| 642 | 645 |
| 643 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); | 646 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); |
| 644 EXPECT_EQ(node->bounds(), node_in_embedded->bounds()); | 647 EXPECT_EQ(node->bounds(), node_in_embedded->bounds()); |
| 645 | 648 |
| 646 node->SetBounds(gfx::Rect(100, 100)); | 649 node->SetBounds(gfx::Rect(100, 100)); |
| 647 EXPECT_NE(node->bounds(), node_in_embedded->bounds()); | 650 EXPECT_NE(node->bounds(), node_in_embedded->bounds()); |
| 648 WaitForBoundsToChange(node_in_embedded); | 651 WaitForBoundsToChange(node_in_embedded); |
| 649 EXPECT_EQ(node->bounds(), node_in_embedded->bounds()); | 652 EXPECT_EQ(node->bounds(), node_in_embedded->bounds()); |
| 650 } | 653 } |
| 651 | 654 |
| 652 // Verifies that bounds changes applied to a node owned by a different | 655 // Verifies that bounds changes applied to a node owned by a different |
| 653 // connection are refused. | 656 // connection are refused. |
| 654 TEST_F(ViewManagerTest, SetBoundsSecurity) { | 657 TEST_F(ViewManagerTest, SetBoundsSecurity) { |
| 655 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 658 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 656 window_manager()->tree()->AddChild(node); | 659 window_manager()->roots().front()->AddChild(node); |
| 657 ViewManager* embedded = Embed(window_manager(), node); | 660 ViewManager* embedded = Embed(window_manager(), node); |
| 658 | 661 |
| 659 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); | 662 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); |
| 660 node->SetBounds(gfx::Rect(800, 600)); | 663 node->SetBounds(gfx::Rect(800, 600)); |
| 661 WaitForBoundsToChange(node_in_embedded); | 664 WaitForBoundsToChange(node_in_embedded); |
| 662 | 665 |
| 663 node_in_embedded->SetBounds(gfx::Rect(1024, 768)); | 666 node_in_embedded->SetBounds(gfx::Rect(1024, 768)); |
| 664 // Bounds change should have been rejected. | 667 // Bounds change should have been rejected. |
| 665 EXPECT_EQ(node->bounds(), node_in_embedded->bounds()); | 668 EXPECT_EQ(node->bounds(), node_in_embedded->bounds()); |
| 666 } | 669 } |
| 667 | 670 |
| 668 // Verifies that a node can only be destroyed by the connection that created it. | 671 // Verifies that a node can only be destroyed by the connection that created it. |
| 669 TEST_F(ViewManagerTest, DestroySecurity) { | 672 TEST_F(ViewManagerTest, DestroySecurity) { |
| 670 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); | 673 ViewTreeNode* node = ViewTreeNode::Create(window_manager()); |
| 671 window_manager()->tree()->AddChild(node); | 674 window_manager()->roots().front()->AddChild(node); |
| 672 ViewManager* embedded = Embed(window_manager(), node); | 675 ViewManager* embedded = Embed(window_manager(), node); |
| 673 | 676 |
| 674 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); | 677 ViewTreeNode* node_in_embedded = embedded->GetNodeById(node->id()); |
| 675 | 678 |
| 676 NodeTracker tracker2(node_in_embedded); | 679 NodeTracker tracker2(node_in_embedded); |
| 677 node_in_embedded->Destroy(); | 680 node_in_embedded->Destroy(); |
| 678 // Node should not have been destroyed. | 681 // Node should not have been destroyed. |
| 679 EXPECT_TRUE(tracker2.is_valid()); | 682 EXPECT_TRUE(tracker2.is_valid()); |
| 680 | 683 |
| 681 NodeTracker tracker1(node); | 684 NodeTracker tracker1(node); |
| 682 node->Destroy(); | 685 node->Destroy(); |
| 683 EXPECT_FALSE(tracker1.is_valid()); | 686 EXPECT_FALSE(tracker1.is_valid()); |
| 684 } | 687 } |
| 685 | 688 |
| 689 TEST_F(ViewManagerTest, MultiRoots) { |
| 690 ViewTreeNode* node1 = ViewTreeNode::Create(window_manager()); |
| 691 window_manager()->roots().front()->AddChild(node1); |
| 692 ViewTreeNode* node2 = ViewTreeNode::Create(window_manager()); |
| 693 window_manager()->roots().front()->AddChild(node2); |
| 694 ViewManager* embedded1 = Embed(window_manager(), node1); |
| 695 ViewManager* embedded2 = Embed(window_manager(), node2); |
| 696 EXPECT_EQ(embedded1, embedded2); |
| 697 } |
| 698 |
| 686 } // namespace view_manager | 699 } // namespace view_manager |
| 687 } // namespace mojo | 700 } // namespace mojo |
| OLD | NEW |