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

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

Issue 10690048: Clean up RenderViewHostManager swapping logic. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix merge conflict Created 8 years, 1 month 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 (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"
11 #include "content/browser/debugger/devtools_manager_impl.h" 12 #include "content/browser/debugger/devtools_manager_impl.h"
12 #include "content/browser/renderer_host/render_process_host_impl.h" 13 #include "content/browser/renderer_host/render_process_host_impl.h"
13 #include "content/browser/renderer_host/render_view_host_factory.h" 14 #include "content/browser/renderer_host/render_view_host_factory.h"
14 #include "content/browser/renderer_host/render_view_host_impl.h" 15 #include "content/browser/renderer_host/render_view_host_impl.h"
15 #include "content/browser/site_instance_impl.h" 16 #include "content/browser/site_instance_impl.h"
16 #include "content/browser/web_contents/navigation_controller_impl.h" 17 #include "content/browser/web_contents/navigation_controller_impl.h"
17 #include "content/browser/web_contents/navigation_entry_impl.h" 18 #include "content/browser/web_contents/navigation_entry_impl.h"
18 #include "content/browser/webui/web_ui_impl.h" 19 #include "content/browser/webui/web_ui_impl.h"
19 #include "content/common/view_messages.h" 20 #include "content/common/view_messages.h"
20 #include "content/port/browser/render_widget_host_view_port.h" 21 #include "content/port/browser/render_widget_host_view_port.h"
21 #include "content/public/browser/content_browser_client.h" 22 #include "content/public/browser/content_browser_client.h"
22 #include "content/public/browser/notification_service.h" 23 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/notification_types.h" 24 #include "content/public/browser/notification_types.h"
24 #include "content/public/browser/web_contents_view.h" 25 #include "content/public/browser/web_contents_view.h"
25 #include "content/public/browser/web_ui_controller.h" 26 #include "content/public/browser/web_ui_controller.h"
26 #include "content/public/browser/web_ui_controller_factory.h" 27 #include "content/public/browser/web_ui_controller_factory.h"
28 #include "content/public/common/bindings_policy.h"
27 #include "content/public/common/content_switches.h" 29 #include "content/public/common/content_switches.h"
28 #include "content/public/common/url_constants.h" 30 #include "content/public/common/url_constants.h"
29 31
30 namespace content { 32 namespace content {
31 33
32 RenderViewHostManager::RenderViewHostManager( 34 RenderViewHostManager::RenderViewHostManager(
33 RenderViewHostDelegate* render_view_delegate, 35 RenderViewHostDelegate* render_view_delegate,
34 RenderWidgetHostDelegate* render_widget_delegate, 36 RenderWidgetHostDelegate* render_widget_delegate,
35 Delegate* delegate) 37 Delegate* delegate)
36 : delegate_(delegate), 38 : delegate_(delegate),
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 NOTREACHED(); 381 NOTREACHED();
380 } 382 }
381 } 383 }
382 384
383 bool RenderViewHostManager::ShouldTransitionCrossSite() { 385 bool RenderViewHostManager::ShouldTransitionCrossSite() {
384 // True if we are using process-per-site-instance (default) or 386 // True if we are using process-per-site-instance (default) or
385 // process-per-site (kProcessPerSite). 387 // process-per-site (kProcessPerSite).
386 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); 388 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab);
387 } 389 }
388 390
389 bool RenderViewHostManager::ShouldSwapProcessesForNavigation( 391 bool RenderViewHostManager::ShouldSwapBrowsingInstanceForNavigation(
390 const NavigationEntry* curr_entry, 392 const NavigationEntry* current_entry,
391 const NavigationEntryImpl* new_entry) const { 393 const NavigationEntryImpl* new_entry) const {
392 DCHECK(new_entry); 394 DCHECK(new_entry);
393 395
396 // If new_entry already has a SiteInstance, assume it is correct and use it.
397 if (new_entry->site_instance())
398 return false;
399
394 // Check for reasons to swap processes even if we are in a process model that 400 // Check for reasons to swap processes even if we are in a process model that
395 // doesn't usually swap (e.g., process-per-tab). 401 // doesn't usually swap (e.g., process-per-tab). Any time we return true,
402 // the new_entry will be rendered in a new SiteInstance AND BrowsingInstance.
396 403
397 // For security, we should transition between processes when one is a Web UI 404 // For security, we should transition between processes when one is a Web UI
398 // page and one isn't. If there's no curr_entry, check the current RVH's 405 // page and one isn't. If there's no current_entry, check the current RVH's
399 // site, which might already be committed to a Web UI URL (such as the NTP). 406 // site, which might already be committed to a Web UI URL (such as the NTP).
400 const GURL& current_url = (curr_entry) ? curr_entry->GetURL() : 407 const GURL& current_url = current_entry ? current_entry->GetURL() :
401 render_view_host_->GetSiteInstance()->GetSiteURL(); 408 render_view_host_->GetSiteInstance()->GetSiteURL();
409 const GURL& new_url = new_entry->GetURL();
402 BrowserContext* browser_context = 410 BrowserContext* browser_context =
403 delegate_->GetControllerForRenderManager().GetBrowserContext(); 411 delegate_->GetControllerForRenderManager().GetBrowserContext();
404 const WebUIControllerFactory* web_ui_factory = 412 const WebUIControllerFactory* web_ui_factory =
405 GetContentClient()->browser()->GetWebUIControllerFactory(); 413 GetContentClient()->browser()->GetWebUIControllerFactory();
406 if (web_ui_factory) { 414 if (web_ui_factory) {
407 if (web_ui_factory->UseWebUIForURL(browser_context, current_url)) { 415 int enabled_bindings = render_view_host_->GetEnabledBindings();
408 // Force swap if it's not an acceptable URL for Web UI. 416
417 // Check if we're currently in a WebUI RenderViewHost, based on either URL
418 // or bindings.
419 if (enabled_bindings & BINDINGS_POLICY_WEB_UI ||
420 web_ui_factory->UseWebUIForURL(browser_context, current_url)) {
421 // If so, force a swap if destination not an acceptable URL for Web UI.
409 // Here, data URLs are never allowed. 422 // Here, data URLs are never allowed.
410 if (!web_ui_factory->IsURLAcceptableForWebUI(browser_context, 423 if (!web_ui_factory->IsURLAcceptableForWebUI(browser_context, new_url,
411 new_entry->GetURL(), false)) 424 false))
412 return true; 425 return true;
413 } else { 426 } else {
414 // Force swap if it's a Web UI URL. 427 // Force a swap if it's a Web UI URL.
415 if (web_ui_factory->UseWebUIForURL(browser_context, new_entry->GetURL())) 428 if (web_ui_factory->UseWebUIForURL(browser_context, new_url))
416 return true; 429 return true;
417 } 430 }
418 } 431 }
419 432
420 if (GetContentClient()->browser()->ShouldSwapProcessesForNavigation( 433 // Also let the embedder decide if a BrowsingInstance swap is required.
421 curr_entry ? curr_entry->GetURL() : GURL(), new_entry->GetURL())) { 434 if (GetContentClient()->browser()->
435 ShouldSwapBrowsingInstanceForNavigation(browser_context,
436 current_url, new_url)) {
422 return true; 437 return true;
423 } 438 }
424 439
425 if (!curr_entry)
426 return false;
427
428 // We can't switch a RenderView between view source and non-view source mode 440 // We can't switch a RenderView between view source and non-view source mode
429 // without screwing up the session history sometimes (when navigating between 441 // without screwing up the session history sometimes (when navigating between
430 // "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat 442 // "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat
431 // it as a new navigation). So require a view switch. 443 // it as a new navigation). So require a BrowsingInstance switch.
432 if (curr_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) 444 if (current_entry &&
445 current_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) {
433 return true; 446 return true;
447 }
434 448
435 return false; 449 return false;
436 } 450 }
437 451
438 bool RenderViewHostManager::ShouldReuseWebUI( 452 bool RenderViewHostManager::ShouldReuseWebUI(
439 const NavigationEntry* curr_entry, 453 const NavigationEntry* curr_entry,
440 const NavigationEntryImpl* new_entry) const { 454 const NavigationEntryImpl* new_entry) const {
441 NavigationControllerImpl& controller = 455 NavigationControllerImpl& controller =
442 delegate_->GetControllerForRenderManager(); 456 delegate_->GetControllerForRenderManager();
443 WebUIControllerFactory* factory = 457 WebUIControllerFactory* factory =
444 GetContentClient()->browser()->GetWebUIControllerFactory(); 458 GetContentClient()->browser()->GetWebUIControllerFactory();
445 return curr_entry && web_ui_.get() && 459 return curr_entry && web_ui_.get() &&
446 (factory->GetWebUIType(controller.GetBrowserContext(), 460 (factory->GetWebUIType(controller.GetBrowserContext(),
447 curr_entry->GetURL()) == 461 curr_entry->GetURL()) ==
448 factory->GetWebUIType(controller.GetBrowserContext(), 462 factory->GetWebUIType(controller.GetBrowserContext(),
449 new_entry->GetURL())); 463 new_entry->GetURL()));
450 } 464 }
451 465
452 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( 466 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
453 const NavigationEntryImpl& entry, 467 const NavigationEntryImpl& entry,
454 SiteInstance* curr_instance) { 468 SiteInstance* curr_instance,
455 // NOTE: This is only called when ShouldTransitionCrossSite is true. 469 bool force_swap) {
456 470 // Determine which SiteInstance to use for navigating to |entry|.
457 const GURL& dest_url = entry.GetURL(); 471 const GURL& dest_url = entry.GetURL();
458 NavigationControllerImpl& controller = 472 NavigationControllerImpl& controller =
459 delegate_->GetControllerForRenderManager(); 473 delegate_->GetControllerForRenderManager();
460 BrowserContext* browser_context = controller.GetBrowserContext(); 474 BrowserContext* browser_context = controller.GetBrowserContext();
461 475
476 // If a swap is required, we need to force the SiteInstance AND
477 // BrowsingInstance to be different ones, using CreateForURL.
478 if (force_swap) {
479 // We shouldn't be forcing a swap if an entry already has a SiteInstance.
480 DCHECK(!entry.site_instance());
481 return SiteInstance::CreateForURL(browser_context, dest_url);
482 }
483
462 // If the entry has an instance already we should use it. 484 // If the entry has an instance already we should use it.
463 if (entry.site_instance()) 485 if (entry.site_instance())
464 return entry.site_instance(); 486 return entry.site_instance();
465 487
466 // (UGLY) HEURISTIC, process-per-site only: 488 // (UGLY) HEURISTIC, process-per-site only:
467 //
468 // If this navigation is generated, then it probably corresponds to a search 489 // If this navigation is generated, then it probably corresponds to a search
469 // query. Given that search results typically lead to users navigating to 490 // query. Given that search results typically lead to users navigating to
470 // other sites, we don't really want to use the search engine hostname to 491 // other sites, we don't really want to use the search engine hostname to
471 // determine the site instance for this navigation. 492 // determine the site instance for this navigation.
472 //
473 // NOTE: This can be removed once we have a way to transition between 493 // NOTE: This can be removed once we have a way to transition between
474 // RenderViews in response to a link click. 494 // RenderViews in response to a link click.
475 //
476 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && 495 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) &&
477 entry.GetTransitionType() == PAGE_TRANSITION_GENERATED) 496 entry.GetTransitionType() == PAGE_TRANSITION_GENERATED)
478 return curr_instance; 497 return curr_instance;
479 498
480 SiteInstanceImpl* curr_site_instance = 499 SiteInstanceImpl* curr_site_instance =
481 static_cast<SiteInstanceImpl*>(curr_instance); 500 static_cast<SiteInstanceImpl*>(curr_instance);
482 501
483 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it 502 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it
484 // for this entry. We won't commit the SiteInstance to this site until the 503 // for this entry. We won't commit the SiteInstance to this site until the
485 // navigation commits (in DidNavigate), unless the navigation entry was 504 // navigation commits (in DidNavigate), unless the navigation entry was
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 // 554 //
536 // In the case of session restore, as it loads all the pages immediately 555 // In the case of session restore, as it loads all the pages immediately
537 // we need to set the site first, otherwise after a restore none of the 556 // we need to set the site first, otherwise after a restore none of the
538 // pages would share renderers in process-per-site. 557 // pages would share renderers in process-per-site.
539 if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE) 558 if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE)
540 curr_site_instance->SetSite(dest_url); 559 curr_site_instance->SetSite(dest_url);
541 560
542 return curr_site_instance; 561 return curr_site_instance;
543 } 562 }
544 563
545 // Otherwise, only create a new SiteInstance for cross-site navigation. 564 // Otherwise, only create a new SiteInstance for a cross-site navigation.
546 565
547 // TODO(creis): Once we intercept links and script-based navigations, we 566 // TODO(creis): Once we intercept links and script-based navigations, we
548 // will be able to enforce that all entries in a SiteInstance actually have 567 // will be able to enforce that all entries in a SiteInstance actually have
549 // the same site, and it will be safe to compare the URL against the 568 // the same site, and it will be safe to compare the URL against the
550 // SiteInstance's site, as follows: 569 // SiteInstance's site, as follows:
551 // const GURL& current_url = curr_instance->site(); 570 // const GURL& current_url = curr_instance->site();
552 // For now, though, we're in a hybrid model where you only switch 571 // For now, though, we're in a hybrid model where you only switch
553 // SiteInstances if you type in a cross-site URL. This means we have to 572 // SiteInstances if you type in a cross-site URL. This means we have to
554 // compare the entry's URL to the last committed entry's URL. 573 // compare the entry's URL to the last committed entry's URL.
555 NavigationEntry* curr_entry = controller.GetLastCommittedEntry(); 574 NavigationEntry* curr_entry = controller.GetLastCommittedEntry();
(...skipping 20 matching lines...) Expand all
576 // See http://crbug.com/123007. 595 // See http://crbug.com/123007.
577 if (curr_entry && 596 if (curr_entry &&
578 curr_entry->IsViewSourceMode() != entry.IsViewSourceMode()) { 597 curr_entry->IsViewSourceMode() != entry.IsViewSourceMode()) {
579 return SiteInstance::CreateForURL(browser_context, dest_url); 598 return SiteInstance::CreateForURL(browser_context, dest_url);
580 } 599 }
581 600
582 // Use the current SiteInstance for same site navigations, as long as the 601 // Use the current SiteInstance for same site navigations, as long as the
583 // process type is correct. (The URL may have been installed as an app since 602 // process type is correct. (The URL may have been installed as an app since
584 // the last time we visited it.) 603 // the last time we visited it.)
585 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && 604 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) &&
586 !static_cast<SiteInstanceImpl*>(curr_instance)->HasWrongProcessForURL( 605 !curr_site_instance->HasWrongProcessForURL(dest_url)) {
587 dest_url)) {
588 return curr_instance; 606 return curr_instance;
589 } else if (ShouldSwapProcessesForNavigation(curr_entry, &entry)) {
590 // When we're swapping, we need to force the site instance AND browsing
591 // instance to be different ones. This addresses special cases where we use
592 // a single BrowsingInstance for all pages of a certain type (e.g., New Tab
593 // Pages), keeping them in the same process. When you navigate away from
594 // that page, we want to explicity ignore that BrowsingInstance and group
595 // this page into the appropriate SiteInstance for its URL.
596 return SiteInstance::CreateForURL(browser_context, dest_url);
597 } else {
598 // Start the new renderer in a new SiteInstance, but in the current
599 // BrowsingInstance. It is important to immediately give this new
600 // SiteInstance to a RenderViewHost (if it is different than our current
601 // SiteInstance), so that it is ref counted. This will happen in
602 // CreateRenderView.
603 return curr_instance->GetRelatedSiteInstance(dest_url);
604 } 607 }
608
609 // Otherwise start the new renderer in a new SiteInstance, but in the current
610 // BrowsingInstance. It is important to immediately give this new
611 // SiteInstance to a RenderViewHost (if it is different than our current
612 // SiteInstance), so that it is ref counted. This will happen in
613 // CreateRenderView.
614 return curr_instance->GetRelatedSiteInstance(dest_url);
605 } 615 }
606 616
607 int RenderViewHostManager::CreateRenderView( 617 int RenderViewHostManager::CreateRenderView(
608 SiteInstance* instance, 618 SiteInstance* instance,
609 int opener_route_id, 619 int opener_route_id,
610 bool swapped_out) { 620 bool swapped_out) {
611 CHECK(instance); 621 CHECK(instance);
612 622
613 // Check if we've already created an RVH for this SiteInstance. If so, try 623 // Check if we've already created an RVH for this SiteInstance. If so, try
614 // to re-use the existing one, which has already been initialized. We'll 624 // to re-use the existing one, which has already been initialized. We'll
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 if (!swapped_out) 662 if (!swapped_out)
653 pending_render_view_host_ = new_render_view_host; 663 pending_render_view_host_ = new_render_view_host;
654 664
655 return new_render_view_host->GetRoutingID(); 665 return new_render_view_host->GetRoutingID();
656 } 666 }
657 667
658 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, 668 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host,
659 int opener_route_id) { 669 int opener_route_id) {
660 // If the pending navigation is to a WebUI, tell the RenderView about any 670 // If the pending navigation is to a WebUI, tell the RenderView about any
661 // bindings it will need enabled. 671 // bindings it will need enabled.
662 if (pending_web_ui()) 672 if (pending_web_ui()) {
663 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 673 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
674 } else {
675 // Ensure that we don't create an unprivileged view in a WebUI-enabled
676 // process.
677 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
678 render_view_host->GetProcess()->GetID()));
679 }
664 680
665 return delegate_->CreateRenderViewForRenderManager(render_view_host, 681 return delegate_->CreateRenderViewForRenderManager(render_view_host,
666 opener_route_id); 682 opener_route_id);
667 } 683 }
668 684
669 void RenderViewHostManager::CommitPending() { 685 void RenderViewHostManager::CommitPending() {
670 // First check whether we're going to want to focus the location bar after 686 // First check whether we're going to want to focus the location bar after
671 // this commit. We do this now because the navigation hasn't formally 687 // this commit. We do this now because the navigation hasn't formally
672 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 688 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
673 // this triggers won't be able to figure out what's going on. 689 // 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
759 old_render_view_host->Shutdown(); 775 old_render_view_host->Shutdown();
760 } 776 }
761 777
762 // Let the task manager know that we've swapped RenderViewHosts, since it 778 // Let the task manager know that we've swapped RenderViewHosts, since it
763 // might need to update its process groupings. 779 // might need to update its process groupings.
764 delegate_->NotifySwappedFromRenderManager(); 780 delegate_->NotifySwappedFromRenderManager();
765 } 781 }
766 782
767 RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate( 783 RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
768 const NavigationEntryImpl& entry) { 784 const NavigationEntryImpl& entry) {
769 // If we are cross-navigating, then we want to get back to normal and navigate 785 // If we are currently navigating cross-process, we want to get back to normal
770 // as usual. 786 // and then navigate as usual.
771 if (cross_navigation_pending_) { 787 if (cross_navigation_pending_) {
772 if (pending_render_view_host_) 788 if (pending_render_view_host_)
773 CancelPending(); 789 CancelPending();
774 cross_navigation_pending_ = false; 790 cross_navigation_pending_ = false;
775 } 791 }
776 792
777 // render_view_host_ will not be deleted before the end of this method, so we 793 // render_view_host_'s SiteInstance and new_instance will not be deleted
778 // don't have to worry about this SiteInstance's ref count dropping to zero. 794 // before the end of this method, so we don't have to worry about their ref
795 // counts dropping to zero.
779 SiteInstance* curr_instance = render_view_host_->GetSiteInstance(); 796 SiteInstance* curr_instance = render_view_host_->GetSiteInstance();
797 SiteInstance* new_instance = curr_instance;
780 798
781 // Determine if we need a new SiteInstance for this entry. 799 // We do not currently swap processes for navigations in webview tag guests.
782 // Again, new_instance won't be deleted before the end of this method, so it 800 bool is_guest_scheme = curr_instance->GetSiteURL().SchemeIs(
783 // is safe to use a normal pointer here. 801 chrome::kGuestScheme);
784 SiteInstance* new_instance = curr_instance; 802
803 // Determine if we need a new BrowsingInstance for this entry. If true,
804 // this implies it will get a new SiteInstance (and likely process), and
805 // that other tabs in the current BrowsingInstance will be unable to script
806 // it. This is used for cases that require a process swap even in the
807 // process-per-tab model, such as WebUI pages.
785 const NavigationEntry* curr_entry = 808 const NavigationEntry* curr_entry =
786 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 809 delegate_->GetLastCommittedNavigationEntryForRenderManager();
787 bool is_guest_scheme = curr_instance->GetSiteURL().SchemeIs( 810 bool force_swap = !is_guest_scheme &&
788 chrome::kGuestScheme); 811 ShouldSwapBrowsingInstanceForNavigation(curr_entry, &entry);
789 bool force_swap = ShouldSwapProcessesForNavigation(curr_entry, &entry);
790 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap)) 812 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap))
791 new_instance = GetSiteInstanceForEntry(entry, curr_instance); 813 new_instance = GetSiteInstanceForEntry(entry, curr_instance, force_swap);
792 814
793 if (!is_guest_scheme && (new_instance != curr_instance || force_swap)) { 815 // If force_swap is true, we must use a different SiteInstance. If we didn't,
794 // New SiteInstance. 816 // we would have two RenderViewHosts in the same SiteInstance and the same
817 // tab, resulting in page_id conflicts for their NavigationEntries.
818 if (force_swap)
819 CHECK_NE(new_instance, curr_instance);
820
821 if (new_instance != curr_instance) {
822 // New SiteInstance: create a pending RVH to navigate.
795 DCHECK(!cross_navigation_pending_); 823 DCHECK(!cross_navigation_pending_);
796 824
797 // This will possibly create (set to NULL) a Web UI object for the pending 825 // This will possibly create (set to NULL) a Web UI object for the pending
798 // page. We'll use this later to give the page special access. This must 826 // page. We'll use this later to give the page special access. This must
799 // happen before the new renderer is created below so it will get bindings. 827 // happen before the new renderer is created below so it will get bindings.
800 // It must also happen after the above conditional call to CancelPending(), 828 // It must also happen after the above conditional call to CancelPending(),
801 // otherwise CancelPending may clear the pending_web_ui_ and the page will 829 // otherwise CancelPending may clear the pending_web_ui_ and the page will
802 // not have its bindings set appropriately. 830 // not have its bindings set appropriately.
803 pending_web_ui_.reset( 831 pending_web_ui_.reset(
804 delegate_->CreateWebUIForRenderManager(entry.GetURL())); 832 delegate_->CreateWebUIForRenderManager(entry.GetURL()));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 // We now have a pending RVH. 883 // We now have a pending RVH.
856 DCHECK(!cross_navigation_pending_); 884 DCHECK(!cross_navigation_pending_);
857 cross_navigation_pending_ = true; 885 cross_navigation_pending_ = true;
858 886
859 // Tell the old render view to run its onbeforeunload handler, since it 887 // Tell the old render view to run its onbeforeunload handler, since it
860 // doesn't otherwise know that the cross-site request is happening. This 888 // doesn't otherwise know that the cross-site request is happening. This
861 // will trigger a call to ShouldClosePage with the reply. 889 // will trigger a call to ShouldClosePage with the reply.
862 render_view_host_->FirePageBeforeUnload(true); 890 render_view_host_->FirePageBeforeUnload(true);
863 891
864 return pending_render_view_host_; 892 return pending_render_view_host_;
865 } else {
866 if (ShouldReuseWebUI(curr_entry, &entry)) {
867 pending_web_ui_.reset();
868 pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
869 } else {
870 pending_and_current_web_ui_.reset();
871 pending_web_ui_.reset(
872 delegate_->CreateWebUIForRenderManager(entry.GetURL()));
873 }
874
875 if (pending_web_ui() && render_view_host_->IsRenderViewLive())
876 pending_web_ui()->GetController()->RenderViewReused(render_view_host_);
877
878 // The renderer can exit view source mode when any error or cancellation
879 // happen. We must overwrite to recover the mode.
880 if (entry.IsViewSourceMode()) {
881 render_view_host_->Send(
882 new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID()));
883 }
884 } 893 }
885 894
886 // Same SiteInstance can be used. Navigate render_view_host_ if we are not 895 // Otherwise the same SiteInstance can be used. Navigate render_view_host_.
887 // cross navigating.
888 DCHECK(!cross_navigation_pending_); 896 DCHECK(!cross_navigation_pending_);
897 if (ShouldReuseWebUI(curr_entry, &entry)) {
898 pending_web_ui_.reset();
899 pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
900 } else {
901 pending_and_current_web_ui_.reset();
902 pending_web_ui_.reset(
903 delegate_->CreateWebUIForRenderManager(entry.GetURL()));
904 }
905
906 if (pending_web_ui() && render_view_host_->IsRenderViewLive())
907 pending_web_ui()->GetController()->RenderViewReused(render_view_host_);
908
909 // The renderer can exit view source mode when any error or cancellation
910 // happen. We must overwrite to recover the mode.
911 if (entry.IsViewSourceMode()) {
912 render_view_host_->Send(
913 new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID()));
914 }
915
889 return render_view_host_; 916 return render_view_host_;
890 } 917 }
891 918
892 void RenderViewHostManager::CancelPending() { 919 void RenderViewHostManager::CancelPending() {
893 RenderViewHostImpl* pending_render_view_host = pending_render_view_host_; 920 RenderViewHostImpl* pending_render_view_host = pending_render_view_host_;
894 pending_render_view_host_ = NULL; 921 pending_render_view_host_ = NULL;
895 922
896 DevToolsManagerImpl::GetInstance()->OnCancelPendingNavigation( 923 DevToolsManagerImpl::GetInstance()->OnCancelPendingNavigation(
897 pending_render_view_host, 924 pending_render_view_host,
898 render_view_host_); 925 render_view_host_);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 RenderViewHostImpl* RenderViewHostManager::GetSwappedOutRenderViewHost( 986 RenderViewHostImpl* RenderViewHostManager::GetSwappedOutRenderViewHost(
960 SiteInstance* instance) { 987 SiteInstance* instance) {
961 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId()); 988 RenderViewHostMap::iterator iter = swapped_out_hosts_.find(instance->GetId());
962 if (iter != swapped_out_hosts_.end()) 989 if (iter != swapped_out_hosts_.end())
963 return iter->second; 990 return iter->second;
964 991
965 return NULL; 992 return NULL;
966 } 993 }
967 994
968 } // namespace content 995 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698