OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |