Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: content/browser/frame_host/render_view_host_manager.cc

Issue 76063007: Clean up RenderViewHostManager swapping logic. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix nits Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/frame_host/render_view_host_manager.h" 5 #include "content/browser/frame_host/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/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "content/browser/child_process_security_policy_impl.h"
12 #include "content/browser/devtools/render_view_devtools_agent_host.h" 13 #include "content/browser/devtools/render_view_devtools_agent_host.h"
13 #include "content/browser/frame_host/interstitial_page_impl.h" 14 #include "content/browser/frame_host/interstitial_page_impl.h"
14 #include "content/browser/frame_host/navigation_controller_impl.h" 15 #include "content/browser/frame_host/navigation_controller_impl.h"
15 #include "content/browser/frame_host/navigation_entry_impl.h" 16 #include "content/browser/frame_host/navigation_entry_impl.h"
16 #include "content/browser/renderer_host/render_process_host_impl.h" 17 #include "content/browser/renderer_host/render_process_host_impl.h"
17 #include "content/browser/renderer_host/render_view_host_factory.h" 18 #include "content/browser/renderer_host/render_view_host_factory.h"
18 #include "content/browser/renderer_host/render_view_host_impl.h" 19 #include "content/browser/renderer_host/render_view_host_impl.h"
19 #include "content/browser/site_instance_impl.h" 20 #include "content/browser/site_instance_impl.h"
20 #include "content/browser/webui/web_ui_controller_factory_registry.h" 21 #include "content/browser/webui/web_ui_controller_factory_registry.h"
21 #include "content/browser/webui/web_ui_impl.h" 22 #include "content/browser/webui/web_ui_impl.h"
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 bool RenderViewHostManager::ShouldTransitionCrossSite() { 485 bool RenderViewHostManager::ShouldTransitionCrossSite() {
485 // False in the single-process mode, as it makes RVHs to accumulate 486 // False in the single-process mode, as it makes RVHs to accumulate
486 // in swapped_out_hosts_. 487 // in swapped_out_hosts_.
487 // True if we are using process-per-site-instance (default) or 488 // True if we are using process-per-site-instance (default) or
488 // process-per-site (kProcessPerSite). 489 // process-per-site (kProcessPerSite).
489 return 490 return
490 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) && 491 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) &&
491 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); 492 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab);
492 } 493 }
493 494
494 bool RenderViewHostManager::ShouldSwapProcessesForNavigation( 495 bool RenderViewHostManager::ShouldSwapBrowsingInstancesForNavigation(
495 const NavigationEntry* curr_entry, 496 const NavigationEntry* current_entry,
496 const NavigationEntryImpl* new_entry) const { 497 const NavigationEntryImpl* new_entry) const {
497 DCHECK(new_entry); 498 DCHECK(new_entry);
498 499
499 // If new_entry already has a SiteInstance, assume it is correct and use it. 500 // If new_entry already has a SiteInstance, assume it is correct and use it.
500 if (new_entry->site_instance()) 501 if (new_entry->site_instance())
501 return false; 502 return false;
502 503
503 // Check for reasons to swap processes even if we are in a process model that 504 // Check for reasons to swap processes even if we are in a process model that
504 // doesn't usually swap (e.g., process-per-tab). 505 // doesn't usually swap (e.g., process-per-tab). Any time we return true,
506 // the new_entry will be rendered in a new SiteInstance AND BrowsingInstance.
505 507
506 // We use the effective URL here, since that's what is used in the 508 // We use the effective URL here, since that's what is used in the
507 // SiteInstance's site and when we later call IsSameWebSite. If there is no 509 // SiteInstance's site and when we later call IsSameWebSite. If there is no
508 // curr_entry, check the current SiteInstance's site, which might already be 510 // current_entry, check the current SiteInstance's site, which might already
509 // committed to a Web UI URL (such as the NTP). 511 // be committed to a Web UI URL (such as the NTP).
510 BrowserContext* browser_context = 512 BrowserContext* browser_context =
511 delegate_->GetControllerForRenderManager().GetBrowserContext(); 513 delegate_->GetControllerForRenderManager().GetBrowserContext();
512 const GURL& current_url = (curr_entry) ? 514 const GURL& current_url = (current_entry) ?
513 SiteInstanceImpl::GetEffectiveURL(browser_context, curr_entry->GetURL()) : 515 SiteInstanceImpl::GetEffectiveURL(browser_context,
516 current_entry->GetURL()) :
514 render_view_host_->GetSiteInstance()->GetSiteURL(); 517 render_view_host_->GetSiteInstance()->GetSiteURL();
515 const GURL& new_url = SiteInstanceImpl::GetEffectiveURL(browser_context, 518 const GURL& new_url = SiteInstanceImpl::GetEffectiveURL(browser_context,
516 new_entry->GetURL()); 519 new_entry->GetURL());
517 520
518 // For security, we should transition between processes when one is a Web UI 521 // For security, we should transition between processes when one is a Web UI
519 // page and one isn't. 522 // page and one isn't.
520 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 523 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
521 browser_context, current_url)) { 524 browser_context, current_url)) {
522 // Force swap if it's not an acceptable URL for Web UI. 525 // If so, force a swap if destination is not an acceptable URL for Web UI.
523 // Here, data URLs are never allowed. 526 // Here, data URLs are never allowed.
524 if (!WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI( 527 if (!WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
525 browser_context, new_url, false)) { 528 browser_context, new_url, false)) {
526 return true; 529 return true;
527 } 530 }
528 } else { 531 } else {
529 // Force swap if it's a Web UI URL. 532 // Force a swap if it's a Web UI URL.
530 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 533 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
531 browser_context, new_url)) { 534 browser_context, new_url)) {
532 return true; 535 return true;
533 } 536 }
534 } 537 }
535 538
536 // Check with the content client as well. Important to pass current_url here, 539 // Check with the content client as well. Important to pass current_url here,
537 // which uses the SiteInstance's site if there is no curr_entry. 540 // which uses the SiteInstance's site if there is no current_entry.
538 if (GetContentClient()->browser()->ShouldSwapProcessesForNavigation( 541 if (GetContentClient()->browser()->ShouldSwapBrowsingInstancesForNavigation(
539 render_view_host_->GetSiteInstance(), current_url, new_url)) { 542 render_view_host_->GetSiteInstance(), current_url, new_url)) {
540 return true; 543 return true;
541 } 544 }
542 545
543 if (!curr_entry)
544 return false;
545
546 // We can't switch a RenderView between view source and non-view source mode 546 // We can't switch a RenderView between view source and non-view source mode
547 // without screwing up the session history sometimes (when navigating between 547 // without screwing up the session history sometimes (when navigating between
548 // "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat 548 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat
549 // it as a new navigation). So require a view switch. 549 // it as a new navigation). So require a BrowsingInstance switch.
550 if (curr_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) 550 if (current_entry &&
551 current_entry->IsViewSourceMode() != new_entry->IsViewSourceMode())
551 return true; 552 return true;
552 553
553 return false; 554 return false;
554 } 555 }
555 556
556 bool RenderViewHostManager::ShouldReuseWebUI( 557 bool RenderViewHostManager::ShouldReuseWebUI(
557 const NavigationEntry* curr_entry, 558 const NavigationEntry* current_entry,
558 const NavigationEntryImpl* new_entry) const { 559 const NavigationEntryImpl* new_entry) const {
559 NavigationControllerImpl& controller = 560 NavigationControllerImpl& controller =
560 delegate_->GetControllerForRenderManager(); 561 delegate_->GetControllerForRenderManager();
561 return curr_entry && web_ui_.get() && 562 return current_entry && web_ui_.get() &&
562 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 563 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
563 controller.GetBrowserContext(), curr_entry->GetURL()) == 564 controller.GetBrowserContext(), current_entry->GetURL()) ==
564 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 565 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
565 controller.GetBrowserContext(), new_entry->GetURL())); 566 controller.GetBrowserContext(), new_entry->GetURL()));
566 } 567 }
567 568
568 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( 569 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
569 const NavigationEntryImpl& entry, 570 const NavigationEntryImpl& entry,
570 SiteInstance* curr_instance, 571 SiteInstance* current_instance,
571 bool force_browsing_instance_swap) { 572 bool force_browsing_instance_swap) {
572 // Determine which SiteInstance to use for navigating to |entry|. 573 // Determine which SiteInstance to use for navigating to |entry|.
573 const GURL& dest_url = entry.GetURL(); 574 const GURL& dest_url = entry.GetURL();
574 NavigationControllerImpl& controller = 575 NavigationControllerImpl& controller =
575 delegate_->GetControllerForRenderManager(); 576 delegate_->GetControllerForRenderManager();
576 BrowserContext* browser_context = controller.GetBrowserContext(); 577 BrowserContext* browser_context = controller.GetBrowserContext();
577 578
578 // If a swap is required, we need to force the SiteInstance AND 579 // If a swap is required, we need to force the SiteInstance AND
579 // BrowsingInstance to be different ones, using CreateForURL. 580 // BrowsingInstance to be different ones, using CreateForURL.
580 if (force_browsing_instance_swap) { 581 if (force_browsing_instance_swap) {
(...skipping 12 matching lines...) Expand all
593 // query. Given that search results typically lead to users navigating to 594 // query. Given that search results typically lead to users navigating to
594 // other sites, we don't really want to use the search engine hostname to 595 // other sites, we don't really want to use the search engine hostname to
595 // determine the site instance for this navigation. 596 // determine the site instance for this navigation.
596 // 597 //
597 // NOTE: This can be removed once we have a way to transition between 598 // NOTE: This can be removed once we have a way to transition between
598 // RenderViews in response to a link click. 599 // RenderViews in response to a link click.
599 // 600 //
600 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && 601 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) &&
601 PageTransitionCoreTypeIs(entry.GetTransitionType(), 602 PageTransitionCoreTypeIs(entry.GetTransitionType(),
602 PAGE_TRANSITION_GENERATED)) { 603 PAGE_TRANSITION_GENERATED)) {
603 return curr_instance; 604 return current_instance;
604 } 605 }
605 606
606 SiteInstanceImpl* curr_site_instance = 607 SiteInstanceImpl* current_site_instance =
607 static_cast<SiteInstanceImpl*>(curr_instance); 608 static_cast<SiteInstanceImpl*>(current_instance);
608 609
609 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it 610 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it
610 // for this entry. We won't commit the SiteInstance to this site until the 611 // for this entry. We won't commit the SiteInstance to this site until the
611 // navigation commits (in DidNavigate), unless the navigation entry was 612 // navigation commits (in DidNavigate), unless the navigation entry was
612 // restored or it's a Web UI as described below. 613 // restored or it's a Web UI as described below.
613 if (!curr_site_instance->HasSite()) { 614 if (!current_site_instance->HasSite()) {
614 // If we've already created a SiteInstance for our destination, we don't 615 // If we've already created a SiteInstance for our destination, we don't
615 // want to use this unused SiteInstance; use the existing one. (We don't 616 // want to use this unused SiteInstance; use the existing one. (We don't
616 // do this check if the curr_instance has a site, because for now, we want 617 // do this check if the current_instance has a site, because for now, we
617 // to compare against the current URL and not the SiteInstance's site. In 618 // want to compare against the current URL and not the SiteInstance's site.
618 // this case, there is no current URL, so comparing against the site is ok. 619 // In this case, there is no current URL, so comparing against the site is
619 // See additional comments below.) 620 // ok. See additional comments below.)
620 // 621 //
621 // Also, if the URL should use process-per-site mode and there is an 622 // Also, if the URL should use process-per-site mode and there is an
622 // existing process for the site, we should use it. We can call 623 // existing process for the site, we should use it. We can call
623 // GetRelatedSiteInstance() for this, which will eagerly set the site and 624 // GetRelatedSiteInstance() for this, which will eagerly set the site and
624 // thus use the correct process. 625 // thus use the correct process.
625 bool use_process_per_site = 626 bool use_process_per_site =
626 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) && 627 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) &&
627 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url); 628 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url);
628 if (curr_site_instance->HasRelatedSiteInstance(dest_url) || 629 if (current_site_instance->HasRelatedSiteInstance(dest_url) ||
629 use_process_per_site) { 630 use_process_per_site) {
630 return curr_site_instance->GetRelatedSiteInstance(dest_url); 631 return current_site_instance->GetRelatedSiteInstance(dest_url);
631 } 632 }
632 633
633 // For extensions, Web UI URLs (such as the new tab page), and apps we do 634 // For extensions, Web UI URLs (such as the new tab page), and apps we do
634 // not want to use the curr_instance if it has no site, since it will have a 635 // not want to use the current_instance if it has no site, since it will
635 // RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for this 636 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for
636 // URL instead (with the correct process type). 637 // this URL instead (with the correct process type).
637 if (curr_site_instance->HasWrongProcessForURL(dest_url)) 638 if (current_site_instance->HasWrongProcessForURL(dest_url))
638 return curr_site_instance->GetRelatedSiteInstance(dest_url); 639 return current_site_instance->GetRelatedSiteInstance(dest_url);
639 640
640 // View-source URLs must use a new SiteInstance and BrowsingInstance. 641 // View-source URLs must use a new SiteInstance and BrowsingInstance.
641 // TODO(nasko): This is the same condition as later in the function. This 642 // TODO(nasko): This is the same condition as later in the function. This
642 // should be taken into account when refactoring this method as part of 643 // should be taken into account when refactoring this method as part of
643 // http://crbug.com/123007. 644 // http://crbug.com/123007.
644 if (entry.IsViewSourceMode()) 645 if (entry.IsViewSourceMode())
645 return SiteInstance::CreateForURL(browser_context, dest_url); 646 return SiteInstance::CreateForURL(browser_context, dest_url);
646 647
647 // If we are navigating from a blank SiteInstance to a WebUI, make sure we 648 // If we are navigating from a blank SiteInstance to a WebUI, make sure we
648 // create a new SiteInstance. 649 // create a new SiteInstance.
649 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 650 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
650 browser_context, dest_url)) { 651 browser_context, dest_url)) {
651 return SiteInstance::CreateForURL(browser_context, dest_url); 652 return SiteInstance::CreateForURL(browser_context, dest_url);
652 } 653 }
653 654
654 // Normally the "site" on the SiteInstance is set lazily when the load 655 // Normally the "site" on the SiteInstance is set lazily when the load
655 // actually commits. This is to support better process sharing in case 656 // actually commits. This is to support better process sharing in case
656 // the site redirects to some other site: we want to use the destination 657 // the site redirects to some other site: we want to use the destination
657 // site in the site instance. 658 // site in the site instance.
658 // 659 //
659 // In the case of session restore, as it loads all the pages immediately 660 // In the case of session restore, as it loads all the pages immediately
660 // we need to set the site first, otherwise after a restore none of the 661 // we need to set the site first, otherwise after a restore none of the
661 // pages would share renderers in process-per-site. 662 // pages would share renderers in process-per-site.
662 if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE) 663 if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE)
663 curr_site_instance->SetSite(dest_url); 664 current_site_instance->SetSite(dest_url);
664 665
665 return curr_site_instance; 666 return current_site_instance;
666 } 667 }
667 668
668 // Otherwise, only create a new SiteInstance for cross-site navigation. 669 // Otherwise, only create a new SiteInstance for a cross-site navigation.
669 670
670 // TODO(creis): Once we intercept links and script-based navigations, we 671 // TODO(creis): Once we intercept links and script-based navigations, we
671 // will be able to enforce that all entries in a SiteInstance actually have 672 // will be able to enforce that all entries in a SiteInstance actually have
672 // the same site, and it will be safe to compare the URL against the 673 // the same site, and it will be safe to compare the URL against the
673 // SiteInstance's site, as follows: 674 // SiteInstance's site, as follows:
674 // const GURL& current_url = curr_instance->site(); 675 // const GURL& current_url = current_instance->site();
675 // For now, though, we're in a hybrid model where you only switch 676 // For now, though, we're in a hybrid model where you only switch
676 // SiteInstances if you type in a cross-site URL. This means we have to 677 // SiteInstances if you type in a cross-site URL. This means we have to
677 // compare the entry's URL to the last committed entry's URL. 678 // compare the entry's URL to the last committed entry's URL.
678 NavigationEntry* curr_entry = controller.GetLastCommittedEntry(); 679 NavigationEntry* current_entry = controller.GetLastCommittedEntry();
679 if (interstitial_page_) { 680 if (interstitial_page_) {
680 // The interstitial is currently the last committed entry, but we want to 681 // The interstitial is currently the last committed entry, but we want to
681 // compare against the last non-interstitial entry. 682 // compare against the last non-interstitial entry.
682 curr_entry = controller.GetEntryAtOffset(-1); 683 current_entry = controller.GetEntryAtOffset(-1);
683 } 684 }
684 // If there is no last non-interstitial entry (and curr_instance already 685 // If there is no last non-interstitial entry (and current_instance already
685 // has a site), then we must have been opened from another tab. We want 686 // has a site), then we must have been opened from another tab. We want
686 // to compare against the URL of the page that opened us, but we can't 687 // to compare against the URL of the page that opened us, but we can't
687 // get to it directly. The best we can do is check against the site of 688 // get to it directly. The best we can do is check against the site of
688 // the SiteInstance. This will be correct when we intercept links and 689 // the SiteInstance. This will be correct when we intercept links and
689 // script-based navigations, but for now, it could place some pages in a 690 // script-based navigations, but for now, it could place some pages in a
690 // new process unnecessarily. We should only hit this case if a page tries 691 // new process unnecessarily. We should only hit this case if a page tries
691 // to open a new tab to an interstitial-inducing URL, and then navigates 692 // to open a new tab to an interstitial-inducing URL, and then navigates
692 // the page to a different same-site URL. (This seems very unlikely in 693 // the page to a different same-site URL. (This seems very unlikely in
693 // practice.) 694 // practice.)
694 const GURL& current_url = (curr_entry) ? curr_entry->GetURL() : 695 const GURL& current_url = (current_entry) ? current_entry->GetURL() :
695 curr_instance->GetSiteURL(); 696 current_instance->GetSiteURL();
696 697
697 // View-source URLs must use a new SiteInstance and BrowsingInstance. 698 // View-source URLs must use a new SiteInstance and BrowsingInstance.
698 // TODO(creis): Refactor this method so this duplicated code isn't needed. 699 // TODO(creis): Refactor this method so this duplicated code isn't needed.
699 // See http://crbug.com/123007. 700 // See http://crbug.com/123007.
700 if (curr_entry && 701 if (current_entry &&
701 curr_entry->IsViewSourceMode() != entry.IsViewSourceMode()) { 702 current_entry->IsViewSourceMode() != entry.IsViewSourceMode()) {
702 return SiteInstance::CreateForURL(browser_context, dest_url); 703 return SiteInstance::CreateForURL(browser_context, dest_url);
703 } 704 }
704 705
705 // Use the current SiteInstance for same site navigations, as long as the 706 // Use the current SiteInstance for same site navigations, as long as the
706 // process type is correct. (The URL may have been installed as an app since 707 // process type is correct. (The URL may have been installed as an app since
707 // the last time we visited it.) 708 // the last time we visited it.)
708 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && 709 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) &&
709 !static_cast<SiteInstanceImpl*>(curr_instance)->HasWrongProcessForURL( 710 !current_site_instance->HasWrongProcessForURL(dest_url)) {
710 dest_url)) { 711 return current_instance;
711 return curr_instance;
712 } 712 }
713 713
714 // Start the new renderer in a new SiteInstance, but in the current 714 // Start the new renderer in a new SiteInstance, but in the current
715 // BrowsingInstance. It is important to immediately give this new 715 // BrowsingInstance. It is important to immediately give this new
716 // SiteInstance to a RenderViewHost (if it is different than our current 716 // SiteInstance to a RenderViewHost (if it is different than our current
717 // SiteInstance), so that it is ref counted. This will happen in 717 // SiteInstance), so that it is ref counted. This will happen in
718 // CreateRenderView. 718 // CreateRenderView.
719 return curr_instance->GetRelatedSiteInstance(dest_url); 719 return current_instance->GetRelatedSiteInstance(dest_url);
720 } 720 }
721 721
722 int RenderViewHostManager::CreateRenderView( 722 int RenderViewHostManager::CreateRenderView(
723 SiteInstance* instance, 723 SiteInstance* instance,
724 int opener_route_id, 724 int opener_route_id,
725 bool swapped_out, 725 bool swapped_out,
726 bool hidden) { 726 bool hidden) {
727 CHECK(instance); 727 CHECK(instance);
728 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden. 728 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden.
729 729
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 if (!swapped_out) 772 if (!swapped_out)
773 pending_render_view_host_ = new_render_view_host; 773 pending_render_view_host_ = new_render_view_host;
774 774
775 return new_render_view_host->GetRoutingID(); 775 return new_render_view_host->GetRoutingID();
776 } 776 }
777 777
778 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, 778 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host,
779 int opener_route_id) { 779 int opener_route_id) {
780 // If the pending navigation is to a WebUI and the RenderView is not in a 780 // If the pending navigation is to a WebUI and the RenderView is not in a
781 // guest process, tell the RenderView about any bindings it will need enabled. 781 // guest process, tell the RenderView about any bindings it will need enabled.
782 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) 782 if (pending_web_ui() && !render_view_host->GetProcess()->IsGuest()) {
783 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 783 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
784 } else {
785 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
786 // process.
787 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
788 render_view_host->GetProcess()->GetID()));
789 }
784 790
785 return delegate_->CreateRenderViewForRenderManager(render_view_host, 791 return delegate_->CreateRenderViewForRenderManager(render_view_host,
786 opener_route_id); 792 opener_route_id);
787 } 793 }
788 794
789 void RenderViewHostManager::CommitPending() { 795 void RenderViewHostManager::CommitPending() {
790 // First check whether we're going to want to focus the location bar after 796 // First check whether we're going to want to focus the location bar after
791 // this commit. We do this now because the navigation hasn't formally 797 // this commit. We do this now because the navigation hasn't formally
792 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 798 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
793 // this triggers won't be able to figure out what's going on. 799 // this triggers won't be able to figure out what's going on.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 continue; 910 continue;
905 RenderViewHostImpl* rvh = 911 RenderViewHostImpl* rvh =
906 static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget)); 912 static_cast<RenderViewHostImpl*>(RenderViewHost::From(widget));
907 if (site_instance_id == rvh->GetSiteInstance()->GetId()) 913 if (site_instance_id == rvh->GetSiteInstance()->GetId())
908 rvh->Shutdown(); 914 rvh->Shutdown();
909 } 915 }
910 } 916 }
911 917
912 RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate( 918 RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
913 const NavigationEntryImpl& entry) { 919 const NavigationEntryImpl& entry) {
914 // If we are cross-navigating, then we want to get back to normal and navigate 920 // If we are currently navigating cross-process, we want to get back to normal
915 // as usual. 921 // and then navigate as usual.
916 if (cross_navigation_pending_) { 922 if (cross_navigation_pending_) {
917 if (pending_render_view_host_) 923 if (pending_render_view_host_)
918 CancelPending(); 924 CancelPending();
919 cross_navigation_pending_ = false; 925 cross_navigation_pending_ = false;
920 } 926 }
921 927
922 // render_view_host_ will not be deleted before the end of this method, so we 928 // render_view_host_'s SiteInstance and new_instance will not be deleted
923 // don't have to worry about this SiteInstance's ref count dropping to zero. 929 // before the end of this method, so we don't have to worry about their ref
924 SiteInstance* curr_instance = render_view_host_->GetSiteInstance(); 930 // counts dropping to zero.
931 SiteInstance* current_instance = render_view_host_->GetSiteInstance();
932 SiteInstance* new_instance = current_instance;
925 933
926 // Determine if we need a new SiteInstance for this entry. 934 // We do not currently swap processes for navigations in webview tag guests.
927 // Again, new_instance won't be deleted before the end of this method, so it 935 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme);
928 // is safe to use a normal pointer here. 936
929 SiteInstance* new_instance = curr_instance; 937 // Determine if we need a new BrowsingInstance for this entry. If true, this
930 const NavigationEntry* curr_entry = 938 // implies that it will get a new SiteInstance (and likely process), and that
939 // other tabs in the current BrosingInstance will be unalbe to script it.
940 // This is used for cases that require a process swap even in the
941 // process-per-tab model, such as WebUI pages.
942 const NavigationEntry* current_entry =
931 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 943 delegate_->GetLastCommittedNavigationEntryForRenderManager();
932 bool is_guest_scheme = curr_instance->GetSiteURL().SchemeIs(kGuestScheme);
933 bool force_swap = !is_guest_scheme && 944 bool force_swap = !is_guest_scheme &&
934 ShouldSwapProcessesForNavigation(curr_entry, &entry); 945 ShouldSwapBrowsingInstancesForNavigation(current_entry, &entry);
935 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) 946 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap))
936 new_instance = GetSiteInstanceForEntry(entry, curr_instance, force_swap); 947 new_instance = GetSiteInstanceForEntry(entry, current_instance, force_swap);
937 948
938 // If force_swap is true, we must use a different SiteInstance. If we didn't, 949 // If force_swap is true, we must use a different SiteInstance. If we didn't,
939 // we would have two RenderViewHosts in the same SiteInstance and the same 950 // we would have two RenderViewHosts in the same SiteInstance and the same
940 // tab, resulting in page_id conflicts for their NavigationEntries. 951 // tab, resulting in page_id conflicts for their NavigationEntries.
941 if (force_swap) 952 if (force_swap)
942 CHECK_NE(new_instance, curr_instance); 953 CHECK_NE(new_instance, current_instance);
943 954
944 if (new_instance != curr_instance) { 955 if (new_instance != current_instance) {
945 // New SiteInstance. 956 // New SiteInstance: create a pending RVH to navigate.
946 DCHECK(!cross_navigation_pending_); 957 DCHECK(!cross_navigation_pending_);
947 958
948 // This will possibly create (set to NULL) a Web UI object for the pending 959 // This will possibly create (set to NULL) a Web UI object for the pending
949 // page. We'll use this later to give the page special access. This must 960 // page. We'll use this later to give the page special access. This must
950 // happen before the new renderer is created below so it will get bindings. 961 // happen before the new renderer is created below so it will get bindings.
951 // It must also happen after the above conditional call to CancelPending(), 962 // It must also happen after the above conditional call to CancelPending(),
952 // otherwise CancelPending may clear the pending_web_ui_ and the page will 963 // otherwise CancelPending may clear the pending_web_ui_ and the page will
953 // not have its bindings set appropriately. 964 // not have its bindings set appropriately.
954 SetPendingWebUI(entry); 965 SetPendingWebUI(entry);
955 966
956 // Ensure that we have created RVHs for the new RVH's opener chain if 967 // Ensure that we have created RVHs for the new RVH's opener chain if
957 // we are staying in the same BrowsingInstance. This allows the pending RVH 968 // we are staying in the same BrowsingInstance. This allows the pending RVH
958 // to send cross-process script calls to its opener(s). 969 // to send cross-process script calls to its opener(s).
959 int opener_route_id = MSG_ROUTING_NONE; 970 int opener_route_id = MSG_ROUTING_NONE;
960 if (new_instance->IsRelatedSiteInstance(curr_instance)) { 971 if (new_instance->IsRelatedSiteInstance(current_instance)) {
961 opener_route_id = 972 opener_route_id =
962 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); 973 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
963 } 974 }
964 975
965 // Create a non-swapped-out pending RVH with the given opener and navigate 976 // Create a non-swapped-out pending RVH with the given opener and navigate
966 // it. 977 // it.
967 int route_id = CreateRenderView(new_instance, opener_route_id, false, 978 int route_id = CreateRenderView(new_instance, opener_route_id, false,
968 delegate_->IsHidden()); 979 delegate_->IsHidden());
969 if (route_id == MSG_ROUTING_NONE) 980 if (route_id == MSG_ROUTING_NONE)
970 return NULL; 981 return NULL;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 cross_navigation_pending_ = true; 1032 cross_navigation_pending_ = true;
1022 1033
1023 // Unless we are transferring an existing request, we should now 1034 // Unless we are transferring an existing request, we should now
1024 // tell the old render view to run its beforeunload handler, since it 1035 // tell the old render view to run its beforeunload handler, since it
1025 // doesn't otherwise know that the cross-site request is happening. This 1036 // doesn't otherwise know that the cross-site request is happening. This
1026 // will trigger a call to ShouldClosePage with the reply. 1037 // will trigger a call to ShouldClosePage with the reply.
1027 if (!is_transfer) 1038 if (!is_transfer)
1028 render_view_host_->FirePageBeforeUnload(true); 1039 render_view_host_->FirePageBeforeUnload(true);
1029 1040
1030 return pending_render_view_host_; 1041 return pending_render_view_host_;
1031 } else {
1032 if (ShouldReuseWebUI(curr_entry, &entry)) {
1033 pending_web_ui_.reset();
1034 pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
1035 } else {
1036 SetPendingWebUI(entry);
1037
1038 // Make sure the new RenderViewHost has the right bindings.
1039 if (pending_web_ui() && !render_view_host_->GetProcess()->IsGuest())
1040 render_view_host_->AllowBindings(pending_web_ui()->GetBindings());
1041 }
1042
1043 if (pending_web_ui() && render_view_host_->IsRenderViewLive())
1044 pending_web_ui()->GetController()->RenderViewReused(render_view_host_);
1045
1046 // The renderer can exit view source mode when any error or cancellation
1047 // happen. We must overwrite to recover the mode.
1048 if (entry.IsViewSourceMode()) {
1049 render_view_host_->Send(
1050 new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID()));
1051 }
1052 } 1042 }
1053 1043
1054 // Same SiteInstance can be used. Navigate render_view_host_ if we are not 1044 // Otherwise the same SiteInstance can be used. Navigate render_view_host_.
1055 // cross navigating.
1056 DCHECK(!cross_navigation_pending_); 1045 DCHECK(!cross_navigation_pending_);
1046 if (ShouldReuseWebUI(current_entry, &entry)) {
1047 pending_web_ui_.reset();
1048 pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
1049 } else {
1050 SetPendingWebUI(entry);
1051
1052 // Make sure the new RenderViewHost has the right bindings.
1053 if (pending_web_ui() && !render_view_host_->GetProcess()->IsGuest())
1054 render_view_host_->AllowBindings(pending_web_ui()->GetBindings());
1055 }
1056
1057 if (pending_web_ui() && render_view_host_->IsRenderViewLive())
1058 pending_web_ui()->GetController()->RenderViewReused(render_view_host_);
1059
1060 // The renderer can exit view source mode when any error or cancellation
1061 // happen. We must overwrite to recover the mode.
1062 if (entry.IsViewSourceMode()) {
1063 render_view_host_->Send(
1064 new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID()));
1065 }
1066
1057 return render_view_host_; 1067 return render_view_host_;
1058 } 1068 }
1059 1069
1060 void RenderViewHostManager::CancelPending() { 1070 void RenderViewHostManager::CancelPending() {
1061 RenderViewHostImpl* pending_render_view_host = pending_render_view_host_; 1071 RenderViewHostImpl* pending_render_view_host = pending_render_view_host_;
1062 pending_render_view_host_ = NULL; 1072 pending_render_view_host_ = NULL;
1063 1073
1064 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( 1074 RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
1065 pending_render_view_host, 1075 pending_render_view_host,
1066 render_view_host_); 1076 render_view_host_);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 RenderViewHostImpl* RenderViewHostManager::GetSwappedOutRenderViewHost( 1139 RenderViewHostImpl* RenderViewHostManager::GetSwappedOutRenderViewHost(
1130 SiteInstance* instance) { 1140 SiteInstance* instance) {
1131 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId()); 1141 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId());
1132 if (iter != swapped_out_hosts_.end()) 1142 if (iter != swapped_out_hosts_.end())
1133 return iter->second; 1143 return iter->second;
1134 1144
1135 return NULL; 1145 return NULL;
1136 } 1146 }
1137 1147
1138 } // namespace content 1148 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_view_host_manager.h ('k') | content/browser/frame_host/render_view_host_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698