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

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

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

Powered by Google App Engine
This is Rietveld 408576698