| 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 "components/view_manager/public/cpp/view_manager.h" | 5 #include "components/view_manager/public/cpp/view_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 } | 217 } |
| 218 | 218 |
| 219 // ApplicationDelegate implementation. | 219 // ApplicationDelegate implementation. |
| 220 bool ConfigureIncomingConnection(ApplicationConnection* connection) override { | 220 bool ConfigureIncomingConnection(ApplicationConnection* connection) override { |
| 221 connection->AddService(view_manager_client_factory_.get()); | 221 connection->AddService(view_manager_client_factory_.get()); |
| 222 return true; | 222 return true; |
| 223 } | 223 } |
| 224 | 224 |
| 225 ViewManager* window_manager() { return window_manager_; } | 225 ViewManager* window_manager() { return window_manager_; } |
| 226 | 226 |
| 227 // Embeds another version of the test app @ view; returns nullptr on timeout. | 227 // Embeds another version of the test app @ view. This runs a run loop until |
| 228 ViewManager* Embed(ViewManager* view_manager, View* view) { | 228 // a response is received, or a timeout. On success the new ViewManager is |
| 229 return EmbedImpl(view_manager, view, EmbedType::NO_REEMBED); | 229 // returned. |
| 230 ViewManager* Embed(View* view) { |
| 231 return EmbedImpl(view, EmbedType::NO_REEMBED); |
| 230 } | 232 } |
| 231 | 233 |
| 232 ViewManager* EmbedAllowingReembed(ViewManager* view_manager, View* view) { | 234 // Same as Embed(), but uses EmbedAllowingReembed(). |
| 233 return EmbedImpl(view_manager, view, EmbedType::ALLOW_REEMBED); | 235 ViewManager* EmbedAllowingReembed(View* view) { |
| 236 return EmbedImpl(view, EmbedType::ALLOW_REEMBED); |
| 237 } |
| 238 |
| 239 // Establishes a connection to this application and asks for a |
| 240 // ViewManagerClient. The ViewManagerClient is then embedded in |view|. |
| 241 // This does *not* wait for the connection to complete. |
| 242 void ConnectToApplicationAndEmbed(View* view) { |
| 243 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| 244 request->url = mojo::String::From(application_impl()->url()); |
| 245 ApplicationConnection* connection = |
| 246 application_impl()->ConnectToApplication(request.Pass()); |
| 247 mojo::ViewManagerClientPtr client; |
| 248 connection->ConnectToService(&client); |
| 249 view->Embed(client.Pass()); |
| 234 } | 250 } |
| 235 | 251 |
| 236 bool got_disconnect() const { return got_disconnect_; } | 252 bool got_disconnect() const { return got_disconnect_; } |
| 237 | 253 |
| 238 ApplicationDelegate* GetApplicationDelegate() override { return this; } | 254 ApplicationDelegate* GetApplicationDelegate() override { return this; } |
| 239 | 255 |
| 240 // Overridden from ViewManagerDelegate: | 256 // Overridden from ViewManagerDelegate: |
| 241 void OnEmbed(View* root, | 257 void OnEmbed(View* root) override { |
| 242 InterfaceRequest<ServiceProvider> services, | |
| 243 ServiceProviderPtr exposed_services) override { | |
| 244 most_recent_view_manager_ = root->view_manager(); | 258 most_recent_view_manager_ = root->view_manager(); |
| 245 QuitRunLoop(); | 259 QuitRunLoop(); |
| 246 } | 260 } |
| 247 bool OnWillEmbed(View* view, | 261 void OnEmbedForDescendant(View* view, |
| 248 InterfaceRequest<ServiceProvider>* services, | 262 mojo::URLRequestPtr request, |
| 249 ServiceProviderPtr* exposed_services) override { | 263 mojo::ViewManagerClientPtr* client) override { |
| 250 if (!on_will_embed_return_value_) | 264 on_will_embed_count_++; |
| 265 if (on_will_embed_return_value_) { |
| 266 ApplicationConnection* connection = |
| 267 application_impl()->ConnectToApplication(request.Pass()); |
| 268 connection->ConnectToService(client); |
| 269 } else { |
| 251 QuitRunLoop(); | 270 QuitRunLoop(); |
| 252 on_will_embed_count_++; | 271 } |
| 253 return on_will_embed_return_value_; | |
| 254 } | 272 } |
| 255 void OnViewManagerDestroyed(ViewManager* view_manager) override { | 273 void OnViewManagerDestroyed(ViewManager* view_manager) override { |
| 256 got_disconnect_ = true; | 274 got_disconnect_ = true; |
| 257 } | 275 } |
| 258 | 276 |
| 259 private: | 277 private: |
| 260 enum class EmbedType { | 278 enum class EmbedType { |
| 261 ALLOW_REEMBED, | 279 ALLOW_REEMBED, |
| 262 NO_REEMBED, | 280 NO_REEMBED, |
| 263 }; | 281 }; |
| 264 | 282 |
| 265 ViewManager* EmbedImpl(ViewManager* view_manager, | 283 ViewManager* EmbedImpl(View* view, EmbedType type) { |
| 266 View* view, | |
| 267 EmbedType type) { | |
| 268 DCHECK_EQ(view_manager, view->view_manager()); | |
| 269 most_recent_view_manager_ = nullptr; | 284 most_recent_view_manager_ = nullptr; |
| 270 if (type == EmbedType::ALLOW_REEMBED) { | 285 if (type == EmbedType::ALLOW_REEMBED) { |
| 271 mojo::URLRequestPtr request(mojo::URLRequest::New()); | 286 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| 272 request->url = mojo::String::From(application_impl()->url()); | 287 request->url = mojo::String::From(application_impl()->url()); |
| 273 view->EmbedAllowingReembed(request.Pass()); | 288 view->EmbedAllowingReembed(request.Pass()); |
| 274 } else { | 289 } else { |
| 275 view->Embed(application_impl()->url()); | 290 ConnectToApplicationAndEmbed(view); |
| 276 } | 291 } |
| 277 if (!DoRunLoopWithTimeout()) | 292 if (!DoRunLoopWithTimeout()) |
| 278 return nullptr; | 293 return nullptr; |
| 279 ViewManager* vm = nullptr; | 294 ViewManager* vm = nullptr; |
| 280 std::swap(vm, most_recent_view_manager_); | 295 std::swap(vm, most_recent_view_manager_); |
| 281 return vm; | 296 return vm; |
| 282 } | 297 } |
| 283 | 298 |
| 284 // Overridden from testing::Test: | 299 // Overridden from testing::Test: |
| 285 void SetUp() override { | 300 void SetUp() override { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 314 | 329 |
| 315 // Value OnWillEmbed() should return. | 330 // Value OnWillEmbed() should return. |
| 316 bool on_will_embed_return_value_; | 331 bool on_will_embed_return_value_; |
| 317 | 332 |
| 318 MOJO_DISALLOW_COPY_AND_ASSIGN(ViewManagerTest); | 333 MOJO_DISALLOW_COPY_AND_ASSIGN(ViewManagerTest); |
| 319 }; | 334 }; |
| 320 | 335 |
| 321 TEST_F(ViewManagerTest, RootView) { | 336 TEST_F(ViewManagerTest, RootView) { |
| 322 ASSERT_NE(nullptr, window_manager()); | 337 ASSERT_NE(nullptr, window_manager()); |
| 323 EXPECT_NE(nullptr, window_manager()->GetRoot()); | 338 EXPECT_NE(nullptr, window_manager()->GetRoot()); |
| 324 // No one embedded the window_manager(), so it has no url. | |
| 325 EXPECT_TRUE(window_manager()->GetEmbedderURL().empty()); | |
| 326 } | 339 } |
| 327 | 340 |
| 328 TEST_F(ViewManagerTest, Embed) { | 341 TEST_F(ViewManagerTest, Embed) { |
| 329 View* view = window_manager()->CreateView(); | 342 View* view = window_manager()->CreateView(); |
| 330 ASSERT_NE(nullptr, view); | 343 ASSERT_NE(nullptr, view); |
| 331 view->SetVisible(true); | 344 view->SetVisible(true); |
| 332 window_manager()->GetRoot()->AddChild(view); | 345 window_manager()->GetRoot()->AddChild(view); |
| 333 ViewManager* embedded = Embed(window_manager(), view); | 346 ViewManager* embedded = Embed(view); |
| 334 ASSERT_NE(nullptr, embedded); | 347 ASSERT_NE(nullptr, embedded); |
| 335 | 348 |
| 336 View* view_in_embedded = embedded->GetRoot(); | 349 View* view_in_embedded = embedded->GetRoot(); |
| 337 ASSERT_NE(nullptr, view_in_embedded); | 350 ASSERT_NE(nullptr, view_in_embedded); |
| 338 EXPECT_EQ(view->id(), view_in_embedded->id()); | 351 EXPECT_EQ(view->id(), view_in_embedded->id()); |
| 339 EXPECT_EQ(nullptr, view_in_embedded->parent()); | 352 EXPECT_EQ(nullptr, view_in_embedded->parent()); |
| 340 EXPECT_TRUE(view_in_embedded->children().empty()); | 353 EXPECT_TRUE(view_in_embedded->children().empty()); |
| 341 } | 354 } |
| 342 | 355 |
| 343 // Window manager has two views, N1 and N11. Embeds A at N1. A should not see | 356 // Window manager has two views, N1 and N11. Embeds A at N1. A should not see |
| 344 // N11. | 357 // N11. |
| 345 TEST_F(ViewManagerTest, EmbeddedDoesntSeeChild) { | 358 TEST_F(ViewManagerTest, EmbeddedDoesntSeeChild) { |
| 346 View* view = window_manager()->CreateView(); | 359 View* view = window_manager()->CreateView(); |
| 347 ASSERT_NE(nullptr, view); | 360 ASSERT_NE(nullptr, view); |
| 348 view->SetVisible(true); | 361 view->SetVisible(true); |
| 349 window_manager()->GetRoot()->AddChild(view); | 362 window_manager()->GetRoot()->AddChild(view); |
| 350 View* nested = window_manager()->CreateView(); | 363 View* nested = window_manager()->CreateView(); |
| 351 ASSERT_NE(nullptr, nested); | 364 ASSERT_NE(nullptr, nested); |
| 352 nested->SetVisible(true); | 365 nested->SetVisible(true); |
| 353 view->AddChild(nested); | 366 view->AddChild(nested); |
| 354 | 367 |
| 355 ViewManager* embedded = Embed(window_manager(), view); | 368 ViewManager* embedded = Embed(view); |
| 356 ASSERT_NE(nullptr, embedded); | 369 ASSERT_NE(nullptr, embedded); |
| 357 View* view_in_embedded = embedded->GetRoot(); | 370 View* view_in_embedded = embedded->GetRoot(); |
| 358 EXPECT_EQ(view->id(), view_in_embedded->id()); | 371 EXPECT_EQ(view->id(), view_in_embedded->id()); |
| 359 EXPECT_EQ(nullptr, view_in_embedded->parent()); | 372 EXPECT_EQ(nullptr, view_in_embedded->parent()); |
| 360 EXPECT_TRUE(view_in_embedded->children().empty()); | 373 EXPECT_TRUE(view_in_embedded->children().empty()); |
| 361 } | 374 } |
| 362 | 375 |
| 363 // TODO(beng): write a replacement test for the one that once existed here: | 376 // TODO(beng): write a replacement test for the one that once existed here: |
| 364 // This test validates the following scenario: | 377 // This test validates the following scenario: |
| 365 // - a view originating from one connection | 378 // - a view originating from one connection |
| 366 // - a view originating from a second connection | 379 // - a view originating from a second connection |
| 367 // + the connection originating the view is destroyed | 380 // + the connection originating the view is destroyed |
| 368 // -> the view should still exist (since the second connection is live) but | 381 // -> the view should still exist (since the second connection is live) but |
| 369 // should be disconnected from any views. | 382 // should be disconnected from any views. |
| 370 // http://crbug.com/396300 | 383 // http://crbug.com/396300 |
| 371 // | 384 // |
| 372 // TODO(beng): The new test should validate the scenario as described above | 385 // TODO(beng): The new test should validate the scenario as described above |
| 373 // except that the second connection still has a valid tree. | 386 // except that the second connection still has a valid tree. |
| 374 | 387 |
| 375 // Verifies that bounds changes applied to a view hierarchy in one connection | 388 // Verifies that bounds changes applied to a view hierarchy in one connection |
| 376 // are reflected to another. | 389 // are reflected to another. |
| 377 TEST_F(ViewManagerTest, SetBounds) { | 390 TEST_F(ViewManagerTest, SetBounds) { |
| 378 View* view = window_manager()->CreateView(); | 391 View* view = window_manager()->CreateView(); |
| 379 view->SetVisible(true); | 392 view->SetVisible(true); |
| 380 window_manager()->GetRoot()->AddChild(view); | 393 window_manager()->GetRoot()->AddChild(view); |
| 381 ViewManager* embedded = Embed(window_manager(), view); | 394 ViewManager* embedded = Embed(view); |
| 382 ASSERT_NE(nullptr, embedded); | 395 ASSERT_NE(nullptr, embedded); |
| 383 | 396 |
| 384 View* view_in_embedded = embedded->GetViewById(view->id()); | 397 View* view_in_embedded = embedded->GetViewById(view->id()); |
| 385 EXPECT_EQ(view->bounds(), view_in_embedded->bounds()); | 398 EXPECT_EQ(view->bounds(), view_in_embedded->bounds()); |
| 386 | 399 |
| 387 Rect rect; | 400 Rect rect; |
| 388 rect.width = rect.height = 100; | 401 rect.width = rect.height = 100; |
| 389 view->SetBounds(rect); | 402 view->SetBounds(rect); |
| 390 ASSERT_TRUE(WaitForBoundsToChange(view_in_embedded)); | 403 ASSERT_TRUE(WaitForBoundsToChange(view_in_embedded)); |
| 391 EXPECT_EQ(view->bounds(), view_in_embedded->bounds()); | 404 EXPECT_EQ(view->bounds(), view_in_embedded->bounds()); |
| 392 } | 405 } |
| 393 | 406 |
| 394 // Verifies that bounds changes applied to a view owned by a different | 407 // Verifies that bounds changes applied to a view owned by a different |
| 395 // connection are refused. | 408 // connection are refused. |
| 396 TEST_F(ViewManagerTest, SetBoundsSecurity) { | 409 TEST_F(ViewManagerTest, SetBoundsSecurity) { |
| 397 View* view = window_manager()->CreateView(); | 410 View* view = window_manager()->CreateView(); |
| 398 view->SetVisible(true); | 411 view->SetVisible(true); |
| 399 window_manager()->GetRoot()->AddChild(view); | 412 window_manager()->GetRoot()->AddChild(view); |
| 400 ViewManager* embedded = Embed(window_manager(), view); | 413 ViewManager* embedded = Embed(view); |
| 401 ASSERT_NE(nullptr, embedded); | 414 ASSERT_NE(nullptr, embedded); |
| 402 | 415 |
| 403 View* view_in_embedded = embedded->GetViewById(view->id()); | 416 View* view_in_embedded = embedded->GetViewById(view->id()); |
| 404 Rect rect; | 417 Rect rect; |
| 405 rect.width = 800; | 418 rect.width = 800; |
| 406 rect.height = 600; | 419 rect.height = 600; |
| 407 view->SetBounds(rect); | 420 view->SetBounds(rect); |
| 408 ASSERT_TRUE(WaitForBoundsToChange(view_in_embedded)); | 421 ASSERT_TRUE(WaitForBoundsToChange(view_in_embedded)); |
| 409 | 422 |
| 410 rect.width = 1024; | 423 rect.width = 1024; |
| 411 rect.height = 768; | 424 rect.height = 768; |
| 412 view_in_embedded->SetBounds(rect); | 425 view_in_embedded->SetBounds(rect); |
| 413 // Bounds change should have been rejected. | 426 // Bounds change should have been rejected. |
| 414 EXPECT_EQ(view->bounds(), view_in_embedded->bounds()); | 427 EXPECT_EQ(view->bounds(), view_in_embedded->bounds()); |
| 415 } | 428 } |
| 416 | 429 |
| 417 // Verifies that a view can only be destroyed by the connection that created it. | 430 // Verifies that a view can only be destroyed by the connection that created it. |
| 418 TEST_F(ViewManagerTest, DestroySecurity) { | 431 TEST_F(ViewManagerTest, DestroySecurity) { |
| 419 View* view = window_manager()->CreateView(); | 432 View* view = window_manager()->CreateView(); |
| 420 view->SetVisible(true); | 433 view->SetVisible(true); |
| 421 window_manager()->GetRoot()->AddChild(view); | 434 window_manager()->GetRoot()->AddChild(view); |
| 422 ViewManager* embedded = Embed(window_manager(), view); | 435 ViewManager* embedded = Embed(view); |
| 423 ASSERT_NE(nullptr, embedded); | 436 ASSERT_NE(nullptr, embedded); |
| 424 | 437 |
| 425 View* view_in_embedded = embedded->GetViewById(view->id()); | 438 View* view_in_embedded = embedded->GetViewById(view->id()); |
| 426 | 439 |
| 427 ViewTracker tracker2(view_in_embedded); | 440 ViewTracker tracker2(view_in_embedded); |
| 428 view_in_embedded->Destroy(); | 441 view_in_embedded->Destroy(); |
| 429 // View should not have been destroyed. | 442 // View should not have been destroyed. |
| 430 EXPECT_TRUE(tracker2.is_valid()); | 443 EXPECT_TRUE(tracker2.is_valid()); |
| 431 | 444 |
| 432 ViewTracker tracker1(view); | 445 ViewTracker tracker1(view); |
| 433 view->Destroy(); | 446 view->Destroy(); |
| 434 EXPECT_FALSE(tracker1.is_valid()); | 447 EXPECT_FALSE(tracker1.is_valid()); |
| 435 } | 448 } |
| 436 | 449 |
| 437 TEST_F(ViewManagerTest, MultiRoots) { | 450 TEST_F(ViewManagerTest, MultiRoots) { |
| 438 View* view1 = window_manager()->CreateView(); | 451 View* view1 = window_manager()->CreateView(); |
| 439 view1->SetVisible(true); | 452 view1->SetVisible(true); |
| 440 window_manager()->GetRoot()->AddChild(view1); | 453 window_manager()->GetRoot()->AddChild(view1); |
| 441 View* view2 = window_manager()->CreateView(); | 454 View* view2 = window_manager()->CreateView(); |
| 442 view2->SetVisible(true); | 455 view2->SetVisible(true); |
| 443 window_manager()->GetRoot()->AddChild(view2); | 456 window_manager()->GetRoot()->AddChild(view2); |
| 444 ViewManager* embedded1 = Embed(window_manager(), view1); | 457 ViewManager* embedded1 = Embed(view1); |
| 445 ASSERT_NE(nullptr, embedded1); | 458 ASSERT_NE(nullptr, embedded1); |
| 446 ViewManager* embedded2 = Embed(window_manager(), view2); | 459 ViewManager* embedded2 = Embed(view2); |
| 447 ASSERT_NE(nullptr, embedded2); | 460 ASSERT_NE(nullptr, embedded2); |
| 448 EXPECT_NE(embedded1, embedded2); | 461 EXPECT_NE(embedded1, embedded2); |
| 449 } | 462 } |
| 450 | 463 |
| 451 TEST_F(ViewManagerTest, EmbeddingIdentity) { | |
| 452 View* view = window_manager()->CreateView(); | |
| 453 view->SetVisible(true); | |
| 454 window_manager()->GetRoot()->AddChild(view); | |
| 455 ViewManager* embedded = Embed(window_manager(), view); | |
| 456 ASSERT_NE(nullptr, embedded); | |
| 457 EXPECT_EQ(application_impl()->url(), embedded->GetEmbedderURL()); | |
| 458 } | |
| 459 | |
| 460 // TODO(alhaad): Currently, the RunLoop gets stuck waiting for order change. | 464 // TODO(alhaad): Currently, the RunLoop gets stuck waiting for order change. |
| 461 // Debug and re-enable this. | 465 // Debug and re-enable this. |
| 462 TEST_F(ViewManagerTest, DISABLED_Reorder) { | 466 TEST_F(ViewManagerTest, DISABLED_Reorder) { |
| 463 View* view1 = window_manager()->CreateView(); | 467 View* view1 = window_manager()->CreateView(); |
| 464 view1->SetVisible(true); | 468 view1->SetVisible(true); |
| 465 window_manager()->GetRoot()->AddChild(view1); | 469 window_manager()->GetRoot()->AddChild(view1); |
| 466 | 470 |
| 467 ViewManager* embedded = Embed(window_manager(), view1); | 471 ViewManager* embedded = Embed(view1); |
| 468 ASSERT_NE(nullptr, embedded); | 472 ASSERT_NE(nullptr, embedded); |
| 469 | 473 |
| 470 View* view11 = embedded->CreateView(); | 474 View* view11 = embedded->CreateView(); |
| 471 view11->SetVisible(true); | 475 view11->SetVisible(true); |
| 472 embedded->GetRoot()->AddChild(view11); | 476 embedded->GetRoot()->AddChild(view11); |
| 473 View* view12 = embedded->CreateView(); | 477 View* view12 = embedded->CreateView(); |
| 474 view12->SetVisible(true); | 478 view12->SetVisible(true); |
| 475 embedded->GetRoot()->AddChild(view12); | 479 embedded->GetRoot()->AddChild(view12); |
| 476 | 480 |
| 477 View* root_in_embedded = embedded->GetRoot(); | 481 View* root_in_embedded = embedded->GetRoot(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 }; | 525 }; |
| 522 | 526 |
| 523 } // namespace | 527 } // namespace |
| 524 | 528 |
| 525 TEST_F(ViewManagerTest, Visible) { | 529 TEST_F(ViewManagerTest, Visible) { |
| 526 View* view1 = window_manager()->CreateView(); | 530 View* view1 = window_manager()->CreateView(); |
| 527 view1->SetVisible(true); | 531 view1->SetVisible(true); |
| 528 window_manager()->GetRoot()->AddChild(view1); | 532 window_manager()->GetRoot()->AddChild(view1); |
| 529 | 533 |
| 530 // Embed another app and verify initial state. | 534 // Embed another app and verify initial state. |
| 531 ViewManager* embedded = Embed(window_manager(), view1); | 535 ViewManager* embedded = Embed(view1); |
| 532 ASSERT_NE(nullptr, embedded); | 536 ASSERT_NE(nullptr, embedded); |
| 533 ASSERT_NE(nullptr, embedded->GetRoot()); | 537 ASSERT_NE(nullptr, embedded->GetRoot()); |
| 534 View* embedded_root = embedded->GetRoot(); | 538 View* embedded_root = embedded->GetRoot(); |
| 535 EXPECT_TRUE(embedded_root->visible()); | 539 EXPECT_TRUE(embedded_root->visible()); |
| 536 EXPECT_TRUE(embedded_root->IsDrawn()); | 540 EXPECT_TRUE(embedded_root->IsDrawn()); |
| 537 | 541 |
| 538 // Change the visible state from the first connection and verify its mirrored | 542 // Change the visible state from the first connection and verify its mirrored |
| 539 // correctly to the embedded app. | 543 // correctly to the embedded app. |
| 540 { | 544 { |
| 541 VisibilityChangeObserver observer(embedded_root); | 545 VisibilityChangeObserver observer(embedded_root); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 }; | 589 }; |
| 586 | 590 |
| 587 } // namespace | 591 } // namespace |
| 588 | 592 |
| 589 TEST_F(ViewManagerTest, Drawn) { | 593 TEST_F(ViewManagerTest, Drawn) { |
| 590 View* view1 = window_manager()->CreateView(); | 594 View* view1 = window_manager()->CreateView(); |
| 591 view1->SetVisible(true); | 595 view1->SetVisible(true); |
| 592 window_manager()->GetRoot()->AddChild(view1); | 596 window_manager()->GetRoot()->AddChild(view1); |
| 593 | 597 |
| 594 // Embed another app and verify initial state. | 598 // Embed another app and verify initial state. |
| 595 ViewManager* embedded = Embed(window_manager(), view1); | 599 ViewManager* embedded = Embed(view1); |
| 596 ASSERT_NE(nullptr, embedded); | 600 ASSERT_NE(nullptr, embedded); |
| 597 ASSERT_NE(nullptr, embedded->GetRoot()); | 601 ASSERT_NE(nullptr, embedded->GetRoot()); |
| 598 View* embedded_root = embedded->GetRoot(); | 602 View* embedded_root = embedded->GetRoot(); |
| 599 EXPECT_TRUE(embedded_root->visible()); | 603 EXPECT_TRUE(embedded_root->visible()); |
| 600 EXPECT_TRUE(embedded_root->IsDrawn()); | 604 EXPECT_TRUE(embedded_root->IsDrawn()); |
| 601 | 605 |
| 602 // Change the visibility of the root, this should propagate a drawn state | 606 // Change the visibility of the root, this should propagate a drawn state |
| 603 // change to |embedded|. | 607 // change to |embedded|. |
| 604 { | 608 { |
| 605 DrawnChangeObserver observer(embedded_root); | 609 DrawnChangeObserver observer(embedded_root); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 MOJO_DISALLOW_COPY_AND_ASSIGN(FocusChangeObserver); | 650 MOJO_DISALLOW_COPY_AND_ASSIGN(FocusChangeObserver); |
| 647 }; | 651 }; |
| 648 | 652 |
| 649 } // namespace | 653 } // namespace |
| 650 | 654 |
| 651 TEST_F(ViewManagerTest, Focus) { | 655 TEST_F(ViewManagerTest, Focus) { |
| 652 View* view1 = window_manager()->CreateView(); | 656 View* view1 = window_manager()->CreateView(); |
| 653 view1->SetVisible(true); | 657 view1->SetVisible(true); |
| 654 window_manager()->GetRoot()->AddChild(view1); | 658 window_manager()->GetRoot()->AddChild(view1); |
| 655 | 659 |
| 656 ViewManager* embedded = Embed(window_manager(), view1); | 660 ViewManager* embedded = Embed(view1); |
| 657 ASSERT_NE(nullptr, embedded); | 661 ASSERT_NE(nullptr, embedded); |
| 658 View* view11 = embedded->CreateView(); | 662 View* view11 = embedded->CreateView(); |
| 659 view11->SetVisible(true); | 663 view11->SetVisible(true); |
| 660 embedded->GetRoot()->AddChild(view11); | 664 embedded->GetRoot()->AddChild(view11); |
| 661 | 665 |
| 662 // TODO(alhaad): Figure out why switching focus between views from different | 666 // TODO(alhaad): Figure out why switching focus between views from different |
| 663 // connections is causing the tests to crash and add tests for that. | 667 // connections is causing the tests to crash and add tests for that. |
| 664 { | 668 { |
| 665 View* embedded_root = embedded->GetRoot(); | 669 View* embedded_root = embedded->GetRoot(); |
| 666 FocusChangeObserver observer(embedded_root); | 670 FocusChangeObserver observer(embedded_root); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 }; | 714 }; |
| 711 | 715 |
| 712 } // namespace | 716 } // namespace |
| 713 | 717 |
| 714 // Verifies deleting a ViewManager sends the right notifications. | 718 // Verifies deleting a ViewManager sends the right notifications. |
| 715 TEST_F(ViewManagerTest, DeleteViewManager) { | 719 TEST_F(ViewManagerTest, DeleteViewManager) { |
| 716 View* view = window_manager()->CreateView(); | 720 View* view = window_manager()->CreateView(); |
| 717 ASSERT_NE(nullptr, view); | 721 ASSERT_NE(nullptr, view); |
| 718 view->SetVisible(true); | 722 view->SetVisible(true); |
| 719 window_manager()->GetRoot()->AddChild(view); | 723 window_manager()->GetRoot()->AddChild(view); |
| 720 ViewManager* view_manager = Embed(window_manager(), view); | 724 ViewManager* view_manager = Embed(view); |
| 721 ASSERT_TRUE(view_manager); | 725 ASSERT_TRUE(view_manager); |
| 722 bool got_destroy = false; | 726 bool got_destroy = false; |
| 723 DestroyedChangedObserver observer(view_manager->GetRoot(), &got_destroy); | 727 DestroyedChangedObserver observer(view_manager->GetRoot(), &got_destroy); |
| 724 delete view_manager; | 728 delete view_manager; |
| 725 EXPECT_TRUE(got_disconnect()); | 729 EXPECT_TRUE(got_disconnect()); |
| 726 EXPECT_TRUE(got_destroy); | 730 EXPECT_TRUE(got_destroy); |
| 727 } | 731 } |
| 728 | 732 |
| 729 // Verifies two Embed()s in the same view trigger deletion of the first | 733 // Verifies two Embed()s in the same view trigger deletion of the first |
| 730 // ViewManager. | 734 // ViewManager. |
| 731 TEST_F(ViewManagerTest, DisconnectTriggersDelete) { | 735 TEST_F(ViewManagerTest, DisconnectTriggersDelete) { |
| 732 View* view = window_manager()->CreateView(); | 736 View* view = window_manager()->CreateView(); |
| 733 ASSERT_NE(nullptr, view); | 737 ASSERT_NE(nullptr, view); |
| 734 view->SetVisible(true); | 738 view->SetVisible(true); |
| 735 window_manager()->GetRoot()->AddChild(view); | 739 window_manager()->GetRoot()->AddChild(view); |
| 736 ViewManager* view_manager = Embed(window_manager(), view); | 740 ViewManager* view_manager = Embed(view); |
| 737 EXPECT_NE(view_manager, window_manager()); | 741 EXPECT_NE(view_manager, window_manager()); |
| 738 View* embedded_view = view_manager->CreateView(); | 742 View* embedded_view = view_manager->CreateView(); |
| 739 // Embed again, this should trigger disconnect and deletion of view_manager. | 743 // Embed again, this should trigger disconnect and deletion of view_manager. |
| 740 bool got_destroy; | 744 bool got_destroy; |
| 741 DestroyedChangedObserver observer(embedded_view, &got_destroy); | 745 DestroyedChangedObserver observer(embedded_view, &got_destroy); |
| 742 EXPECT_FALSE(got_disconnect()); | 746 EXPECT_FALSE(got_disconnect()); |
| 743 Embed(window_manager(), view); | 747 Embed(view); |
| 744 EXPECT_TRUE(got_disconnect()); | 748 EXPECT_TRUE(got_disconnect()); |
| 745 } | 749 } |
| 746 | 750 |
| 747 class ViewRemovedFromParentObserver : public ViewObserver { | 751 class ViewRemovedFromParentObserver : public ViewObserver { |
| 748 public: | 752 public: |
| 749 explicit ViewRemovedFromParentObserver(View* view) | 753 explicit ViewRemovedFromParentObserver(View* view) |
| 750 : view_(view), was_removed_(false) { | 754 : view_(view), was_removed_(false) { |
| 751 view_->AddObserver(this); | 755 view_->AddObserver(this); |
| 752 } | 756 } |
| 753 ~ViewRemovedFromParentObserver() override { view_->RemoveObserver(this); } | 757 ~ViewRemovedFromParentObserver() override { view_->RemoveObserver(this); } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 767 MOJO_DISALLOW_COPY_AND_ASSIGN(ViewRemovedFromParentObserver); | 771 MOJO_DISALLOW_COPY_AND_ASSIGN(ViewRemovedFromParentObserver); |
| 768 }; | 772 }; |
| 769 | 773 |
| 770 TEST_F(ViewManagerTest, EmbedRemovesChildren) { | 774 TEST_F(ViewManagerTest, EmbedRemovesChildren) { |
| 771 View* view1 = window_manager()->CreateView(); | 775 View* view1 = window_manager()->CreateView(); |
| 772 View* view2 = window_manager()->CreateView(); | 776 View* view2 = window_manager()->CreateView(); |
| 773 window_manager()->GetRoot()->AddChild(view1); | 777 window_manager()->GetRoot()->AddChild(view1); |
| 774 view1->AddChild(view2); | 778 view1->AddChild(view2); |
| 775 | 779 |
| 776 ViewRemovedFromParentObserver observer(view2); | 780 ViewRemovedFromParentObserver observer(view2); |
| 777 view1->Embed(application_impl()->url()); | 781 ConnectToApplicationAndEmbed(view1); |
| 778 EXPECT_TRUE(observer.was_removed()); | 782 EXPECT_TRUE(observer.was_removed()); |
| 779 EXPECT_EQ(nullptr, view2->parent()); | 783 EXPECT_EQ(nullptr, view2->parent()); |
| 780 EXPECT_TRUE(view1->children().empty()); | 784 EXPECT_TRUE(view1->children().empty()); |
| 781 | 785 |
| 782 // Run the message loop so the Embed() call above completes. Without this | 786 // Run the message loop so the Embed() call above completes. Without this |
| 783 // we may end up reconnecting to the test and rerunning the test, which is | 787 // we may end up reconnecting to the test and rerunning the test, which is |
| 784 // problematic since the other services don't shut down. | 788 // problematic since the other services don't shut down. |
| 785 ASSERT_TRUE(DoRunLoopWithTimeout()); | 789 ASSERT_TRUE(DoRunLoopWithTimeout()); |
| 786 } | 790 } |
| 787 | 791 |
| 788 TEST_F(ViewManagerTest, OnWillEmbed) { | 792 TEST_F(ViewManagerTest, OnWillEmbed) { |
| 789 window_manager()->SetEmbedRoot(); | 793 window_manager()->SetEmbedRoot(); |
| 790 | 794 |
| 791 View* view1 = window_manager()->CreateView(); | 795 View* view1 = window_manager()->CreateView(); |
| 792 window_manager()->GetRoot()->AddChild(view1); | 796 window_manager()->GetRoot()->AddChild(view1); |
| 793 | 797 |
| 794 ViewManager* view_manager = Embed(window_manager(), view1); | 798 ViewManager* view_manager = EmbedAllowingReembed(view1); |
| 795 View* view2 = view_manager->CreateView(); | 799 View* view2 = view_manager->CreateView(); |
| 796 view_manager->GetRoot()->AddChild(view2); | 800 view_manager->GetRoot()->AddChild(view2); |
| 797 | 801 |
| 798 Embed(view_manager, view2); | 802 EmbedAllowingReembed(view2); |
| 799 EXPECT_EQ(1u, on_will_embed_count()); | 803 EXPECT_EQ(1u, on_will_embed_count()); |
| 800 } | 804 } |
| 801 | 805 |
| 802 // Verifies Embed() doesn't succeed if OnWillEmbed() returns false. | 806 // Verifies Embed() doesn't succeed if OnWillEmbed() returns false. |
| 803 TEST_F(ViewManagerTest, OnWillEmbedFails) { | 807 TEST_F(ViewManagerTest, OnWillEmbedFails) { |
| 804 window_manager()->SetEmbedRoot(); | 808 window_manager()->SetEmbedRoot(); |
| 805 | 809 |
| 806 View* view1 = window_manager()->CreateView(); | 810 View* view1 = window_manager()->CreateView(); |
| 807 window_manager()->GetRoot()->AddChild(view1); | 811 window_manager()->GetRoot()->AddChild(view1); |
| 808 | 812 |
| 809 ViewManager* view_manager = Embed(window_manager(), view1); | 813 ViewManager* view_manager = Embed(view1); |
| 810 View* view2 = view_manager->CreateView(); | 814 View* view2 = view_manager->CreateView(); |
| 811 view_manager->GetRoot()->AddChild(view2); | 815 view_manager->GetRoot()->AddChild(view2); |
| 812 | 816 |
| 813 clear_on_will_embed_count(); | 817 clear_on_will_embed_count(); |
| 814 set_on_will_embed_return_value(false); | 818 set_on_will_embed_return_value(false); |
| 815 view2->Embed(application_impl()->url()); | 819 mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| 820 request->url = application_impl()->url(); |
| 821 view2->EmbedAllowingReembed(request.Pass()); |
| 816 | 822 |
| 817 EXPECT_TRUE(DoRunLoopWithTimeout()); | 823 EXPECT_TRUE(DoRunLoopWithTimeout()); |
| 818 EXPECT_EQ(1u, on_will_embed_count()); | 824 EXPECT_EQ(1u, on_will_embed_count()); |
| 819 | 825 |
| 820 // The run loop above quits when OnWillEmbed() returns, which means it's | 826 // The run loop above quits when OnWillEmbed() returns, which means it's |
| 821 // possible there is still an OnEmbed() message in flight. Sets the bounds of | 827 // possible there is still an OnEmbed() message in flight. Sets the bounds of |
| 822 // |view1| and wait for it to the change in |view_manager|, that way we know | 828 // |view1| and wait for it to the change in |view_manager|, that way we know |
| 823 // |view_manager| has processed all messages for it. | 829 // |view_manager| has processed all messages for it. |
| 824 EXPECT_TRUE(IncrementWidthAndWaitForChange(view1, view_manager)); | 830 EXPECT_TRUE(IncrementWidthAndWaitForChange(view1, view_manager)); |
| 825 | 831 |
| 826 EXPECT_EQ(1u, on_will_embed_count()); | 832 EXPECT_EQ(1u, on_will_embed_count()); |
| 827 } | 833 } |
| 828 | 834 |
| 829 // Verify an Embed() from an ancestor is not allowed. | 835 // Verify an Embed() from an ancestor is not allowed. |
| 830 TEST_F(ViewManagerTest, ReembedFails) { | 836 TEST_F(ViewManagerTest, ReembedFails) { |
| 831 window_manager()->SetEmbedRoot(); | 837 window_manager()->SetEmbedRoot(); |
| 832 | 838 |
| 833 View* view1 = window_manager()->CreateView(); | 839 View* view1 = window_manager()->CreateView(); |
| 834 window_manager()->GetRoot()->AddChild(view1); | 840 window_manager()->GetRoot()->AddChild(view1); |
| 835 | 841 |
| 836 ViewManager* view_manager = Embed(window_manager(), view1); | 842 ViewManager* view_manager = Embed(view1); |
| 837 ASSERT_TRUE(view_manager); | 843 ASSERT_TRUE(view_manager); |
| 838 View* view2 = view_manager->CreateView(); | 844 View* view2 = view_manager->CreateView(); |
| 839 view_manager->GetRoot()->AddChild(view2); | 845 view_manager->GetRoot()->AddChild(view2); |
| 840 Embed(view_manager, view2); | 846 Embed(view2); |
| 841 | 847 |
| 842 // Try to embed in view2 from the window_manager. This should fail as the | 848 // Try to embed in view2 from the window_manager. This should fail as the |
| 843 // Embed() didn't grab reembed. | 849 // Embed() didn't grab reembed. |
| 844 View* view2_in_wm = window_manager()->GetViewById(view2->id()); | 850 View* view2_in_wm = window_manager()->GetViewById(view2->id()); |
| 845 view2_in_wm->Embed(application_impl()->url()); | 851 ConnectToApplicationAndEmbed(view2_in_wm); |
| 846 | 852 |
| 847 // The Embed() call above returns immediately. To ensure the server has | 853 // The Embed() call above returns immediately. To ensure the server has |
| 848 // processed it nudge the bounds and wait for it to be processed. | 854 // processed it nudge the bounds and wait for it to be processed. |
| 849 EXPECT_TRUE(IncrementWidthAndWaitForChange(view1, view_manager)); | 855 EXPECT_TRUE(IncrementWidthAndWaitForChange(view1, view_manager)); |
| 850 | 856 |
| 851 EXPECT_EQ(nullptr, most_recent_view_manager()); | 857 EXPECT_EQ(nullptr, most_recent_view_manager()); |
| 852 } | 858 } |
| 853 | 859 |
| 854 // Verify an Embed() from an ancestor is allowed if the ancestor is an embed | 860 // Verify an Embed() from an ancestor is allowed if the ancestor is an embed |
| 855 // root and Embed was done by way of EmbedAllowingReembed(). | 861 // root and Embed was done by way of EmbedAllowingReembed(). |
| 856 TEST_F(ViewManagerTest, ReembedSucceeds) { | 862 TEST_F(ViewManagerTest, ReembedSucceeds) { |
| 857 window_manager()->SetEmbedRoot(); | 863 window_manager()->SetEmbedRoot(); |
| 858 | 864 |
| 859 View* view1 = window_manager()->CreateView(); | 865 View* view1 = window_manager()->CreateView(); |
| 860 window_manager()->GetRoot()->AddChild(view1); | 866 window_manager()->GetRoot()->AddChild(view1); |
| 861 | 867 |
| 862 ViewManager* view_manager = Embed(window_manager(), view1); | 868 ViewManager* view_manager = Embed(view1); |
| 863 View* view2 = view_manager->CreateView(); | 869 View* view2 = view_manager->CreateView(); |
| 864 view_manager->GetRoot()->AddChild(view2); | 870 view_manager->GetRoot()->AddChild(view2); |
| 865 EmbedAllowingReembed(view_manager, view2); | 871 EmbedAllowingReembed(view2); |
| 866 | 872 |
| 867 View* view2_in_wm = window_manager()->GetViewById(view2->id()); | 873 View* view2_in_wm = window_manager()->GetViewById(view2->id()); |
| 868 ViewManager* view_manager2 = Embed(window_manager(), view2_in_wm); | 874 ViewManager* view_manager2 = Embed(view2_in_wm); |
| 869 ASSERT_TRUE(view_manager2); | 875 ASSERT_TRUE(view_manager2); |
| 870 | 876 |
| 871 // The Embed() call above returns immediately. To ensure the server has | 877 // The Embed() call above returns immediately. To ensure the server has |
| 872 // processed it nudge the bounds and wait for it to be processed. | 878 // processed it nudge the bounds and wait for it to be processed. |
| 873 EXPECT_TRUE(IncrementWidthAndWaitForChange(view1, view_manager)); | 879 EXPECT_TRUE(IncrementWidthAndWaitForChange(view1, view_manager)); |
| 874 | 880 |
| 875 EXPECT_EQ(nullptr, most_recent_view_manager()); | 881 EXPECT_EQ(nullptr, most_recent_view_manager()); |
| 876 } | 882 } |
| 877 | 883 |
| 878 } // namespace mojo | 884 } // namespace mojo |
| OLD | NEW |