OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/web_contents/render_view_host_manager.h" | 5 #include "content/browser/web_contents/render_view_host_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "content/browser/child_process_security_policy_impl.h" | |
12 #include "content/browser/debugger/devtools_manager_impl.h" | 11 #include "content/browser/debugger/devtools_manager_impl.h" |
13 #include "content/browser/renderer_host/render_view_host_factory.h" | 12 #include "content/browser/renderer_host/render_view_host_factory.h" |
14 #include "content/browser/renderer_host/render_view_host_impl.h" | 13 #include "content/browser/renderer_host/render_view_host_impl.h" |
15 #include "content/browser/site_instance_impl.h" | 14 #include "content/browser/site_instance_impl.h" |
16 #include "content/browser/web_contents/navigation_controller_impl.h" | 15 #include "content/browser/web_contents/navigation_controller_impl.h" |
17 #include "content/browser/web_contents/navigation_entry_impl.h" | 16 #include "content/browser/web_contents/navigation_entry_impl.h" |
18 #include "content/browser/webui/web_ui_impl.h" | 17 #include "content/browser/webui/web_ui_impl.h" |
19 #include "content/common/view_messages.h" | 18 #include "content/common/view_messages.h" |
20 #include "content/port/browser/render_widget_host_view_port.h" | 19 #include "content/port/browser/render_widget_host_view_port.h" |
21 #include "content/public/browser/content_browser_client.h" | 20 #include "content/public/browser/content_browser_client.h" |
22 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
23 #include "content/public/browser/notification_types.h" | 22 #include "content/public/browser/notification_types.h" |
24 #include "content/public/browser/web_contents_view.h" | 23 #include "content/public/browser/web_contents_view.h" |
25 #include "content/public/browser/web_ui_controller.h" | 24 #include "content/public/browser/web_ui_controller.h" |
26 #include "content/public/browser/web_ui_controller_factory.h" | 25 #include "content/public/browser/web_ui_controller_factory.h" |
27 #include "content/public/common/bindings_policy.h" | |
28 #include "content/public/common/content_switches.h" | 26 #include "content/public/common/content_switches.h" |
29 #include "content/public/common/url_constants.h" | 27 #include "content/public/common/url_constants.h" |
30 | 28 |
31 using content::NavigationController; | 29 using content::NavigationController; |
32 using content::NavigationEntry; | 30 using content::NavigationEntry; |
33 using content::NavigationEntryImpl; | 31 using content::NavigationEntryImpl; |
34 using content::RenderViewHost; | 32 using content::RenderViewHost; |
35 using content::RenderViewHostImpl; | 33 using content::RenderViewHostImpl; |
36 using content::RenderWidgetHostView; | 34 using content::RenderWidgetHostView; |
37 using content::RenderWidgetHostViewPort; | 35 using content::RenderWidgetHostViewPort; |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 NOTREACHED(); | 351 NOTREACHED(); |
354 } | 352 } |
355 } | 353 } |
356 | 354 |
357 bool RenderViewHostManager::ShouldTransitionCrossSite() { | 355 bool RenderViewHostManager::ShouldTransitionCrossSite() { |
358 // True if we are using process-per-site-instance (default) or | 356 // True if we are using process-per-site-instance (default) or |
359 // process-per-site (kProcessPerSite). | 357 // process-per-site (kProcessPerSite). |
360 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); | 358 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); |
361 } | 359 } |
362 | 360 |
363 bool RenderViewHostManager::ShouldSwapBrowsingInstanceForNavigation( | 361 bool RenderViewHostManager::ShouldSwapProcessesForNavigation( |
364 const NavigationEntry* current_entry, | 362 const NavigationEntry* curr_entry, |
365 const NavigationEntryImpl* new_entry) const { | 363 const NavigationEntryImpl* new_entry) const { |
366 DCHECK(new_entry); | 364 DCHECK(new_entry); |
367 | 365 |
368 // If new_entry already has a SiteInstance, assume it is correct and use it. | |
369 if (new_entry->site_instance()) | |
370 return false; | |
371 | |
372 // Check for reasons to swap processes even if we are in a process model that | 366 // Check for reasons to swap processes even if we are in a process model that |
373 // doesn't usually swap (e.g., process-per-tab). Any time we return true, | 367 // doesn't usually swap (e.g., process-per-tab). |
374 // the new_entry will be rendered in a new SiteInstance AND BrowsingInstance. | |
375 | 368 |
376 // For security, we should transition between processes when one is a Web UI | 369 // For security, we should transition between processes when one is a Web UI |
377 // page and one isn't. If there's no current_entry, check the current RVH's | 370 // page and one isn't. If there's no curr_entry, check the current RVH's |
378 // site, which might already be committed to a Web UI URL (such as the NTP). | 371 // site, which might already be committed to a Web UI URL (such as the NTP). |
379 const GURL& current_url = current_entry ? current_entry->GetURL() : | 372 const GURL& current_url = (curr_entry) ? curr_entry->GetURL() : |
380 render_view_host_->GetSiteInstance()->GetSite(); | 373 render_view_host_->GetSiteInstance()->GetSite(); |
381 const GURL& new_url = new_entry->GetURL(); | |
382 content::BrowserContext* browser_context = | 374 content::BrowserContext* browser_context = |
383 delegate_->GetControllerForRenderManager().GetBrowserContext(); | 375 delegate_->GetControllerForRenderManager().GetBrowserContext(); |
384 const WebUIControllerFactory* web_ui_factory = | 376 const WebUIControllerFactory* web_ui_factory = |
385 content::GetContentClient()->browser()->GetWebUIControllerFactory(); | 377 content::GetContentClient()->browser()->GetWebUIControllerFactory(); |
386 if (web_ui_factory) { | 378 if (web_ui_factory) { |
387 int enabled_bindings = render_view_host_->GetEnabledBindings(); | 379 if (web_ui_factory->UseWebUIForURL(browser_context, current_url)) { |
388 | 380 // Force swap if it's not an acceptable URL for Web UI. |
389 // Check if we're currently in a WebUI RenderViewHost, based on either URL | |
390 // or bindings. | |
391 if (enabled_bindings & content::BINDINGS_POLICY_WEB_UI || | |
392 web_ui_factory->UseWebUIForURL(browser_context, current_url)) { | |
393 // If so, force a swap if destination not an acceptable URL for Web UI. | |
394 // Here, data URLs are never allowed. | 381 // Here, data URLs are never allowed. |
395 if (!web_ui_factory->IsURLAcceptableForWebUI(browser_context, new_url, | 382 if (!web_ui_factory->IsURLAcceptableForWebUI(browser_context, |
396 false)) | 383 new_entry->GetURL(), false)) |
397 return true; | 384 return true; |
398 } else { | 385 } else { |
399 // Force a swap if it's a Web UI URL. | 386 // Force swap if it's a Web UI URL. |
400 if (web_ui_factory->UseWebUIForURL(browser_context, new_url)) | 387 if (web_ui_factory->UseWebUIForURL(browser_context, new_entry->GetURL())) |
401 return true; | 388 return true; |
402 } | 389 } |
403 } | 390 } |
404 | 391 |
405 // Also let the embedder decide if a BrowsingInstance swap is required. | 392 if (content::GetContentClient()->browser()->ShouldSwapProcessesForNavigation( |
406 if (content::GetContentClient()->browser()-> | 393 curr_entry ? curr_entry->GetURL() : GURL(), new_entry->GetURL())) { |
407 ShouldSwapBrowsingInstanceForNavigation(browser_context, | |
408 current_url, new_url)) { | |
409 return true; | 394 return true; |
410 } | 395 } |
411 | 396 |
| 397 if (!curr_entry) |
| 398 return false; |
| 399 |
412 // We can't switch a RenderView between view source and non-view source mode | 400 // We can't switch a RenderView between view source and non-view source mode |
413 // without screwing up the session history sometimes (when navigating between | 401 // without screwing up the session history sometimes (when navigating between |
414 // "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat | 402 // "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat |
415 // it as a new navigation). So require a BrowsingInstance switch. | 403 // it as a new navigation). So require a view switch. |
416 if (current_entry && | 404 if (curr_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) |
417 current_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) { | |
418 return true; | 405 return true; |
419 } | |
420 | 406 |
421 return false; | 407 return false; |
422 } | 408 } |
423 | 409 |
424 bool RenderViewHostManager::ShouldReuseWebUI( | 410 bool RenderViewHostManager::ShouldReuseWebUI( |
425 const NavigationEntry* curr_entry, | 411 const NavigationEntry* curr_entry, |
426 const NavigationEntryImpl* new_entry) const { | 412 const NavigationEntryImpl* new_entry) const { |
427 NavigationControllerImpl& controller = | 413 NavigationControllerImpl& controller = |
428 delegate_->GetControllerForRenderManager(); | 414 delegate_->GetControllerForRenderManager(); |
429 WebUIControllerFactory* factory = | 415 WebUIControllerFactory* factory = |
430 content::GetContentClient()->browser()->GetWebUIControllerFactory(); | 416 content::GetContentClient()->browser()->GetWebUIControllerFactory(); |
431 return curr_entry && web_ui_.get() && | 417 return curr_entry && web_ui_.get() && |
432 (factory->GetWebUIType(controller.GetBrowserContext(), | 418 (factory->GetWebUIType(controller.GetBrowserContext(), |
433 curr_entry->GetURL()) == | 419 curr_entry->GetURL()) == |
434 factory->GetWebUIType(controller.GetBrowserContext(), | 420 factory->GetWebUIType(controller.GetBrowserContext(), |
435 new_entry->GetURL())); | 421 new_entry->GetURL())); |
436 } | 422 } |
437 | 423 |
438 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( | 424 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( |
439 const NavigationEntryImpl& entry, | 425 const NavigationEntryImpl& entry, |
440 SiteInstance* curr_instance, | 426 SiteInstance* curr_instance) { |
441 bool force_swap) { | 427 // NOTE: This is only called when ShouldTransitionCrossSite is true. |
442 // Determine which SiteInstance to use for navigating to |entry|. | 428 |
443 const GURL& dest_url = entry.GetURL(); | 429 const GURL& dest_url = entry.GetURL(); |
444 NavigationControllerImpl& controller = | 430 NavigationControllerImpl& controller = |
445 delegate_->GetControllerForRenderManager(); | 431 delegate_->GetControllerForRenderManager(); |
446 content::BrowserContext* browser_context = controller.GetBrowserContext(); | 432 content::BrowserContext* browser_context = controller.GetBrowserContext(); |
447 | 433 |
448 // If a swap is required, we need to force the SiteInstance AND | |
449 // BrowsingInstance to be different ones. This addresses special cases where | |
450 // we use a single BrowsingInstance for all pages of a certain type (e.g., New | |
451 // Tab Pages), keeping them in the same process. When you navigate away from | |
452 // that page, we want to explicity ignore that BrowsingInstance and group this | |
453 // page into the appropriate SiteInstance for its URL. | |
454 if (force_swap) { | |
455 // We shouldn't be forcing a swap if an entry already has a SiteInstance. | |
456 DCHECK(!entry.site_instance()); | |
457 return SiteInstance::CreateForURL(browser_context, dest_url); | |
458 } | |
459 | |
460 // If the entry has an instance already we should use it. | 434 // If the entry has an instance already we should use it. |
461 if (entry.site_instance()) | 435 if (entry.site_instance()) |
462 return entry.site_instance(); | 436 return entry.site_instance(); |
463 | 437 |
464 // (UGLY) HEURISTIC, process-per-site only: | 438 // (UGLY) HEURISTIC, process-per-site only: |
| 439 // |
465 // If this navigation is generated, then it probably corresponds to a search | 440 // If this navigation is generated, then it probably corresponds to a search |
466 // query. Given that search results typically lead to users navigating to | 441 // query. Given that search results typically lead to users navigating to |
467 // other sites, we don't really want to use the search engine hostname to | 442 // other sites, we don't really want to use the search engine hostname to |
468 // determine the site instance for this navigation. | 443 // determine the site instance for this navigation. |
| 444 // |
469 // NOTE: This can be removed once we have a way to transition between | 445 // NOTE: This can be removed once we have a way to transition between |
470 // RenderViews in response to a link click. | 446 // RenderViews in response to a link click. |
| 447 // |
471 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && | 448 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && |
472 entry.GetTransitionType() == content::PAGE_TRANSITION_GENERATED) | 449 entry.GetTransitionType() == content::PAGE_TRANSITION_GENERATED) |
473 return curr_instance; | 450 return curr_instance; |
474 | 451 |
475 SiteInstanceImpl* curr_site_instance = | 452 SiteInstanceImpl* curr_site_instance = |
476 static_cast<SiteInstanceImpl*>(curr_instance); | 453 static_cast<SiteInstanceImpl*>(curr_instance); |
477 | 454 |
478 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it | 455 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it |
479 // for this entry. We won't commit the SiteInstance to this site until the | 456 // for this entry. We won't commit the SiteInstance to this site until the |
480 // navigation commits (in DidNavigate), unless the navigation entry was | 457 // navigation commits (in DidNavigate), unless the navigation entry was |
(...skipping 22 matching lines...) Expand all Loading... |
503 // | 480 // |
504 // In the case of session restore, as it loads all the pages immediately | 481 // In the case of session restore, as it loads all the pages immediately |
505 // we need to set the site first, otherwise after a restore none of the | 482 // we need to set the site first, otherwise after a restore none of the |
506 // pages would share renderers in process-per-site. | 483 // pages would share renderers in process-per-site. |
507 if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE) | 484 if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE) |
508 curr_site_instance->SetSite(dest_url); | 485 curr_site_instance->SetSite(dest_url); |
509 | 486 |
510 return curr_site_instance; | 487 return curr_site_instance; |
511 } | 488 } |
512 | 489 |
513 // Otherwise, only create a new SiteInstance for a cross-site navigation. | 490 // Otherwise, only create a new SiteInstance for cross-site navigation. |
514 | 491 |
515 // TODO(creis): Once we intercept links and script-based navigations, we | 492 // TODO(creis): Once we intercept links and script-based navigations, we |
516 // will be able to enforce that all entries in a SiteInstance actually have | 493 // will be able to enforce that all entries in a SiteInstance actually have |
517 // the same site, and it will be safe to compare the URL against the | 494 // the same site, and it will be safe to compare the URL against the |
518 // SiteInstance's site, as follows: | 495 // SiteInstance's site, as follows: |
519 // const GURL& current_url = curr_instance->site(); | 496 // const GURL& current_url = curr_instance->site(); |
520 // For now, though, we're in a hybrid model where you only switch | 497 // For now, though, we're in a hybrid model where you only switch |
521 // SiteInstances if you type in a cross-site URL. This means we have to | 498 // SiteInstances if you type in a cross-site URL. This means we have to |
522 // compare the entry's URL to the last committed entry's URL. | 499 // compare the entry's URL to the last committed entry's URL. |
523 NavigationEntry* curr_entry = controller.GetLastCommittedEntry(); | 500 NavigationEntry* curr_entry = controller.GetLastCommittedEntry(); |
(...skipping 20 matching lines...) Expand all Loading... |
544 // See http://crbug.com/123007. | 521 // See http://crbug.com/123007. |
545 if (curr_entry && | 522 if (curr_entry && |
546 curr_entry->IsViewSourceMode() != entry.IsViewSourceMode()) { | 523 curr_entry->IsViewSourceMode() != entry.IsViewSourceMode()) { |
547 return SiteInstance::CreateForURL(browser_context, dest_url); | 524 return SiteInstance::CreateForURL(browser_context, dest_url); |
548 } | 525 } |
549 | 526 |
550 // Use the current SiteInstance for same site navigations, as long as the | 527 // Use the current SiteInstance for same site navigations, as long as the |
551 // process type is correct. (The URL may have been installed as an app since | 528 // process type is correct. (The URL may have been installed as an app since |
552 // the last time we visited it.) | 529 // the last time we visited it.) |
553 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && | 530 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && |
554 !curr_site_instance->HasWrongProcessForURL(dest_url)) { | 531 !static_cast<SiteInstanceImpl*>(curr_instance)->HasWrongProcessForURL( |
| 532 dest_url)) { |
555 return curr_instance; | 533 return curr_instance; |
| 534 } else if (ShouldSwapProcessesForNavigation(curr_entry, &entry)) { |
| 535 // When we're swapping, we need to force the site instance AND browsing |
| 536 // instance to be different ones. This addresses special cases where we use |
| 537 // a single BrowsingInstance for all pages of a certain type (e.g., New Tab |
| 538 // Pages), keeping them in the same process. When you navigate away from |
| 539 // that page, we want to explicity ignore that BrowsingInstance and group |
| 540 // this page into the appropriate SiteInstance for its URL. |
| 541 return SiteInstance::CreateForURL(browser_context, dest_url); |
| 542 } else { |
| 543 // Start the new renderer in a new SiteInstance, but in the current |
| 544 // BrowsingInstance. It is important to immediately give this new |
| 545 // SiteInstance to a RenderViewHost (if it is different than our current |
| 546 // SiteInstance), so that it is ref counted. This will happen in |
| 547 // CreateRenderView. |
| 548 return curr_instance->GetRelatedSiteInstance(dest_url); |
556 } | 549 } |
557 | |
558 // Otherwise start the new renderer in a new SiteInstance, but in the current | |
559 // BrowsingInstance. It is important to immediately give this new | |
560 // SiteInstance to a RenderViewHost (if it is different than our current | |
561 // SiteInstance), so that it is ref counted. This will happen in | |
562 // CreateRenderView. | |
563 return curr_instance->GetRelatedSiteInstance(dest_url); | |
564 } | 550 } |
565 | 551 |
566 int RenderViewHostManager::CreateRenderView( | 552 int RenderViewHostManager::CreateRenderView( |
567 SiteInstance* instance, | 553 SiteInstance* instance, |
568 int opener_route_id, | 554 int opener_route_id, |
569 bool swapped_out) { | 555 bool swapped_out) { |
570 CHECK(instance); | 556 CHECK(instance); |
571 | 557 |
572 // Check if we've already created an RVH for this SiteInstance. If so, try | 558 // Check if we've already created an RVH for this SiteInstance. If so, try |
573 // to re-use the existing one, which has already been initialized. We'll | 559 // to re-use the existing one, which has already been initialized. We'll |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 if (!swapped_out) | 593 if (!swapped_out) |
608 pending_render_view_host_ = new_render_view_host; | 594 pending_render_view_host_ = new_render_view_host; |
609 | 595 |
610 return new_render_view_host->GetRoutingID(); | 596 return new_render_view_host->GetRoutingID(); |
611 } | 597 } |
612 | 598 |
613 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, | 599 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, |
614 int opener_route_id) { | 600 int opener_route_id) { |
615 // If the pending navigation is to a WebUI, tell the RenderView about any | 601 // If the pending navigation is to a WebUI, tell the RenderView about any |
616 // bindings it will need enabled. | 602 // bindings it will need enabled. |
617 if (pending_web_ui()) { | 603 if (pending_web_ui()) |
618 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); | 604 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); |
619 } else { | |
620 // Ensure that we don't create an unprivileged view in a WebUI-enabled | |
621 // process. | |
622 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | |
623 render_view_host->GetProcess()->GetID())); | |
624 } | |
625 | 605 |
626 return delegate_->CreateRenderViewForRenderManager(render_view_host, | 606 return delegate_->CreateRenderViewForRenderManager(render_view_host, |
627 opener_route_id); | 607 opener_route_id); |
628 } | 608 } |
629 | 609 |
630 void RenderViewHostManager::CommitPending() { | 610 void RenderViewHostManager::CommitPending() { |
631 // First check whether we're going to want to focus the location bar after | 611 // First check whether we're going to want to focus the location bar after |
632 // this commit. We do this now because the navigation hasn't formally | 612 // this commit. We do this now because the navigation hasn't formally |
633 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 613 // committed yet, so if we've already cleared |pending_web_ui_| the call chain |
634 // this triggers won't be able to figure out what's going on. | 614 // this triggers won't be able to figure out what's going on. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 old_render_view_host->Shutdown(); | 700 old_render_view_host->Shutdown(); |
721 } | 701 } |
722 | 702 |
723 // Let the task manager know that we've swapped RenderViewHosts, since it | 703 // Let the task manager know that we've swapped RenderViewHosts, since it |
724 // might need to update its process groupings. | 704 // might need to update its process groupings. |
725 delegate_->NotifySwappedFromRenderManager(); | 705 delegate_->NotifySwappedFromRenderManager(); |
726 } | 706 } |
727 | 707 |
728 RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate( | 708 RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate( |
729 const NavigationEntryImpl& entry) { | 709 const NavigationEntryImpl& entry) { |
730 // If we are currently navigating cross-process, we want to get back to normal | 710 // If we are cross-navigating, then we want to get back to normal and navigate |
731 // and then navigate as usual. | 711 // as usual. |
732 if (cross_navigation_pending_) { | 712 if (cross_navigation_pending_) { |
733 if (pending_render_view_host_) | 713 if (pending_render_view_host_) |
734 CancelPending(); | 714 CancelPending(); |
735 cross_navigation_pending_ = false; | 715 cross_navigation_pending_ = false; |
736 } | 716 } |
737 | 717 |
738 // render_view_host_'s SiteInstance and new_instance will not be deleted | 718 // render_view_host_ will not be deleted before the end of this method, so we |
739 // before the end of this method, so we don't have to worry about their ref | 719 // don't have to worry about this SiteInstance's ref count dropping to zero. |
740 // counts dropping to zero. | |
741 SiteInstance* curr_instance = render_view_host_->GetSiteInstance(); | 720 SiteInstance* curr_instance = render_view_host_->GetSiteInstance(); |
| 721 |
| 722 // Determine if we need a new SiteInstance for this entry. |
| 723 // Again, new_instance won't be deleted before the end of this method, so it |
| 724 // is safe to use a normal pointer here. |
742 SiteInstance* new_instance = curr_instance; | 725 SiteInstance* new_instance = curr_instance; |
743 | |
744 // Determine if we need a new BrowsingInstance for this entry. If true, | |
745 // this implies it will get a new SiteInstance (and likely process), and | |
746 // that other tabs in the current BrowsingInstance will be unable to script | |
747 // it. This is used for cases that require a process swap even in the | |
748 // process-per-tab model, such as WebUI pages. | |
749 const content::NavigationEntry* curr_entry = | 726 const content::NavigationEntry* curr_entry = |
750 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | 727 delegate_->GetLastCommittedNavigationEntryForRenderManager(); |
751 bool force_swap = ShouldSwapBrowsingInstanceForNavigation(curr_entry, | 728 bool force_swap = ShouldSwapProcessesForNavigation(curr_entry, &entry); |
752 &entry); | |
753 if (ShouldTransitionCrossSite() || force_swap) | 729 if (ShouldTransitionCrossSite() || force_swap) |
754 new_instance = GetSiteInstanceForEntry(entry, curr_instance, force_swap); | 730 new_instance = GetSiteInstanceForEntry(entry, curr_instance); |
755 | 731 |
756 // If force_swap is true, we must use a different SiteInstance. If we didn't, | 732 if (new_instance != curr_instance || force_swap) { |
757 // we would have two RenderViewHosts in the same SiteInstance and the same | 733 // New SiteInstance. |
758 // tab, resulting in page_id conflicts for their NavigationEntries. | |
759 if (force_swap) | |
760 CHECK_NE(new_instance, curr_instance); | |
761 | |
762 if (new_instance != curr_instance) { | |
763 // New SiteInstance: create a pending RVH to navigate. | |
764 DCHECK(!cross_navigation_pending_); | 734 DCHECK(!cross_navigation_pending_); |
765 | 735 |
766 // This will possibly create (set to NULL) a Web UI object for the pending | 736 // This will possibly create (set to NULL) a Web UI object for the pending |
767 // page. We'll use this later to give the page special access. This must | 737 // page. We'll use this later to give the page special access. This must |
768 // happen before the new renderer is created below so it will get bindings. | 738 // happen before the new renderer is created below so it will get bindings. |
769 // It must also happen after the above conditional call to CancelPending(), | 739 // It must also happen after the above conditional call to CancelPending(), |
770 // otherwise CancelPending may clear the pending_web_ui_ and the page will | 740 // otherwise CancelPending may clear the pending_web_ui_ and the page will |
771 // not have its bindings set appropriately. | 741 // not have its bindings set appropriately. |
772 pending_web_ui_.reset( | 742 pending_web_ui_.reset( |
773 delegate_->CreateWebUIForRenderManager(entry.GetURL())); | 743 delegate_->CreateWebUIForRenderManager(entry.GetURL())); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 // We now have a pending RVH. | 794 // We now have a pending RVH. |
825 DCHECK(!cross_navigation_pending_); | 795 DCHECK(!cross_navigation_pending_); |
826 cross_navigation_pending_ = true; | 796 cross_navigation_pending_ = true; |
827 | 797 |
828 // Tell the old render view to run its onbeforeunload handler, since it | 798 // Tell the old render view to run its onbeforeunload handler, since it |
829 // doesn't otherwise know that the cross-site request is happening. This | 799 // doesn't otherwise know that the cross-site request is happening. This |
830 // will trigger a call to ShouldClosePage with the reply. | 800 // will trigger a call to ShouldClosePage with the reply. |
831 render_view_host_->FirePageBeforeUnload(true); | 801 render_view_host_->FirePageBeforeUnload(true); |
832 | 802 |
833 return pending_render_view_host_; | 803 return pending_render_view_host_; |
| 804 } else { |
| 805 if (ShouldReuseWebUI(curr_entry, &entry)) { |
| 806 pending_web_ui_.reset(); |
| 807 pending_and_current_web_ui_ = web_ui_->AsWeakPtr(); |
| 808 } else { |
| 809 pending_and_current_web_ui_.reset(); |
| 810 pending_web_ui_.reset( |
| 811 delegate_->CreateWebUIForRenderManager(entry.GetURL())); |
| 812 } |
| 813 |
| 814 if (pending_web_ui() && render_view_host_->IsRenderViewLive()) |
| 815 pending_web_ui()->GetController()->RenderViewReused(render_view_host_); |
| 816 |
| 817 // The renderer can exit view source mode when any error or cancellation |
| 818 // happen. We must overwrite to recover the mode. |
| 819 if (entry.IsViewSourceMode()) { |
| 820 render_view_host_->Send( |
| 821 new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID())); |
| 822 } |
834 } | 823 } |
835 | 824 |
836 // Otherwise the same SiteInstance can be used. Navigate render_view_host_. | 825 // Same SiteInstance can be used. Navigate render_view_host_ if we are not |
| 826 // cross navigating. |
837 DCHECK(!cross_navigation_pending_); | 827 DCHECK(!cross_navigation_pending_); |
838 if (ShouldReuseWebUI(curr_entry, &entry)) { | |
839 pending_web_ui_.reset(); | |
840 pending_and_current_web_ui_ = web_ui_->AsWeakPtr(); | |
841 } else { | |
842 pending_and_current_web_ui_.reset(); | |
843 pending_web_ui_.reset( | |
844 delegate_->CreateWebUIForRenderManager(entry.GetURL())); | |
845 } | |
846 | |
847 if (pending_web_ui() && render_view_host_->IsRenderViewLive()) | |
848 pending_web_ui()->GetController()->RenderViewReused(render_view_host_); | |
849 | |
850 // The renderer can exit view source mode when any error or cancellation | |
851 // happen. We must overwrite to recover the mode. | |
852 if (entry.IsViewSourceMode()) { | |
853 render_view_host_->Send( | |
854 new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID())); | |
855 } | |
856 | |
857 return render_view_host_; | 828 return render_view_host_; |
858 } | 829 } |
859 | 830 |
860 void RenderViewHostManager::CancelPending() { | 831 void RenderViewHostManager::CancelPending() { |
861 RenderViewHostImpl* pending_render_view_host = pending_render_view_host_; | 832 RenderViewHostImpl* pending_render_view_host = pending_render_view_host_; |
862 pending_render_view_host_ = NULL; | 833 pending_render_view_host_ = NULL; |
863 | 834 |
864 content::DevToolsManagerImpl::GetInstance()->OnCancelPendingNavigation( | 835 content::DevToolsManagerImpl::GetInstance()->OnCancelPendingNavigation( |
865 pending_render_view_host, | 836 pending_render_view_host, |
866 render_view_host_); | 837 render_view_host_); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 } | 896 } |
926 | 897 |
927 RenderViewHost* RenderViewHostManager::GetSwappedOutRenderViewHost( | 898 RenderViewHost* RenderViewHostManager::GetSwappedOutRenderViewHost( |
928 SiteInstance* instance) { | 899 SiteInstance* instance) { |
929 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId()); | 900 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId()); |
930 if (iter != swapped_out_hosts_.end()) | 901 if (iter != swapped_out_hosts_.end()) |
931 return iter->second; | 902 return iter->second; |
932 | 903 |
933 return NULL; | 904 return NULL; |
934 } | 905 } |
OLD | NEW |