OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/web_contents/render_view_host_manager.h" | 5 #include "content/browser/web_contents/render_view_host_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "content/browser/child_process_security_policy_impl.h" |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |