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 |