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_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 Loading... |
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::ShouldSwapBrowsingInstanceForNavigation( |
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 (enabled_bindings & content::BINDINGS_POLICY_WEB_UI || |
| 392 web_ui_factory->UseWebUIForURL(browser_context, current_url)) { |
| 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 ShouldSwapBrowsingInstanceForNavigation(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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 = ShouldSwapBrowsingInstanceForNavigation(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 Loading... |
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 Loading... |
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 } |
OLD | NEW |