OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/tab_contents/render_view_host_manager.h" | 5 #include "content/browser/tab_contents/render_view_host_manager.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "content/browser/debugger/devtools_manager_impl.h" | 9 #include "content/browser/debugger/devtools_manager_impl.h" |
10 #include "content/browser/renderer_host/render_view_host.h" | 10 #include "content/browser/renderer_host/render_view_host.h" |
11 #include "content/browser/renderer_host/render_view_host_delegate.h" | 11 #include "content/browser/renderer_host/render_view_host_delegate.h" |
12 #include "content/browser/renderer_host/render_view_host_factory.h" | 12 #include "content/browser/renderer_host/render_view_host_factory.h" |
13 #include "content/browser/renderer_host/render_widget_host_view.h" | 13 #include "content/browser/renderer_host/render_widget_host_view.h" |
14 #include "content/browser/site_instance.h" | 14 #include "content/browser/site_instance.h" |
15 #include "content/browser/tab_contents/navigation_controller.h" | 15 #include "content/browser/tab_contents/navigation_controller.h" |
16 #include "content/browser/tab_contents/navigation_entry.h" | 16 #include "content/browser/tab_contents/navigation_entry_impl.h" |
17 #include "content/browser/tab_contents/tab_contents_view.h" | 17 #include "content/browser/tab_contents/tab_contents_view.h" |
18 #include "content/browser/webui/web_ui.h" | 18 #include "content/browser/webui/web_ui.h" |
19 #include "content/browser/webui/web_ui_factory.h" | 19 #include "content/browser/webui/web_ui_factory.h" |
20 #include "content/public/browser/notification_service.h" | 20 #include "content/public/browser/notification_service.h" |
21 #include "content/common/view_messages.h" | 21 #include "content/common/view_messages.h" |
22 #include "content/public/browser/content_browser_client.h" | 22 #include "content/public/browser/content_browser_client.h" |
23 #include "content/public/browser/notification_types.h" | 23 #include "content/public/browser/notification_types.h" |
24 #include "content/public/common/content_switches.h" | 24 #include "content/public/common/content_switches.h" |
25 #include "content/public/common/url_constants.h" | 25 #include "content/public/common/url_constants.h" |
26 | 26 |
27 namespace base { | 27 using content::NavigationEntry; |
28 class WaitableEvent; | 28 using content::NavigationEntryImpl; |
29 } | |
30 | 29 |
31 RenderViewHostManager::RenderViewHostManager( | 30 RenderViewHostManager::RenderViewHostManager( |
32 RenderViewHostDelegate* render_view_delegate, | 31 RenderViewHostDelegate* render_view_delegate, |
33 Delegate* delegate) | 32 Delegate* delegate) |
34 : delegate_(delegate), | 33 : delegate_(delegate), |
35 cross_navigation_pending_(false), | 34 cross_navigation_pending_(false), |
36 render_view_delegate_(render_view_delegate), | 35 render_view_delegate_(render_view_delegate), |
37 render_view_host_(NULL), | 36 render_view_host_(NULL), |
38 pending_render_view_host_(NULL), | 37 pending_render_view_host_(NULL), |
39 interstitial_page_(NULL) { | 38 interstitial_page_(NULL) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSING, | 71 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSING, |
73 content::NotificationService::AllSources()); | 72 content::NotificationService::AllSources()); |
74 } | 73 } |
75 | 74 |
76 RenderWidgetHostView* RenderViewHostManager::GetRenderWidgetHostView() const { | 75 RenderWidgetHostView* RenderViewHostManager::GetRenderWidgetHostView() const { |
77 if (!render_view_host_) | 76 if (!render_view_host_) |
78 return NULL; | 77 return NULL; |
79 return render_view_host_->view(); | 78 return render_view_host_->view(); |
80 } | 79 } |
81 | 80 |
82 RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) { | 81 RenderViewHost* RenderViewHostManager::Navigate( |
| 82 const NavigationEntryImpl& entry) { |
83 // Create a pending RenderViewHost. It will give us the one we should use | 83 // Create a pending RenderViewHost. It will give us the one we should use |
84 RenderViewHost* dest_render_view_host = UpdateRendererStateForNavigate(entry); | 84 RenderViewHost* dest_render_view_host = UpdateRendererStateForNavigate(entry); |
85 if (!dest_render_view_host) | 85 if (!dest_render_view_host) |
86 return NULL; // We weren't able to create a pending render view host. | 86 return NULL; // We weren't able to create a pending render view host. |
87 | 87 |
88 // If the current render_view_host_ isn't live, we should create it so | 88 // If the current render_view_host_ isn't live, we should create it so |
89 // that we don't show a sad tab while the dest_render_view_host fetches | 89 // that we don't show a sad tab while the dest_render_view_host fetches |
90 // its first page. (Bug 1145340) | 90 // its first page. (Bug 1145340) |
91 if (dest_render_view_host != render_view_host_ && | 91 if (dest_render_view_host != render_view_host_ && |
92 !render_view_host_->IsRenderViewLive()) { | 92 !render_view_host_->IsRenderViewLive()) { |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 } | 322 } |
323 } | 323 } |
324 | 324 |
325 bool RenderViewHostManager::ShouldTransitionCrossSite() { | 325 bool RenderViewHostManager::ShouldTransitionCrossSite() { |
326 // True if we are using process-per-site-instance (default) or | 326 // True if we are using process-per-site-instance (default) or |
327 // process-per-site (kProcessPerSite). | 327 // process-per-site (kProcessPerSite). |
328 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); | 328 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); |
329 } | 329 } |
330 | 330 |
331 bool RenderViewHostManager::ShouldSwapProcessesForNavigation( | 331 bool RenderViewHostManager::ShouldSwapProcessesForNavigation( |
332 const content::NavigationEntry* cur_entry, | 332 const NavigationEntry* cur_entry, |
333 const NavigationEntry* new_entry) const { | 333 const NavigationEntryImpl* new_entry) const { |
334 DCHECK(new_entry); | 334 DCHECK(new_entry); |
335 | 335 |
336 // Check for reasons to swap processes even if we are in a process model that | 336 // Check for reasons to swap processes even if we are in a process model that |
337 // doesn't usually swap (e.g., process-per-tab). | 337 // doesn't usually swap (e.g., process-per-tab). |
338 | 338 |
339 // For security, we should transition between processes when one is a Web UI | 339 // For security, we should transition between processes when one is a Web UI |
340 // page and one isn't. If there's no cur_entry, check the current RVH's | 340 // page and one isn't. If there's no cur_entry, check the current RVH's |
341 // site, which might already be committed to a Web UI URL (such as the NTP). | 341 // site, which might already be committed to a Web UI URL (such as the NTP). |
342 const GURL& current_url = (cur_entry) ? cur_entry->GetURL() : | 342 const GURL& current_url = (cur_entry) ? cur_entry->GetURL() : |
343 render_view_host_->site_instance()->site(); | 343 render_view_host_->site_instance()->site(); |
(...skipping 23 matching lines...) Expand all Loading... |
367 // without screwing up the session history sometimes (when navigating between | 367 // without screwing up the session history sometimes (when navigating between |
368 // "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat | 368 // "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat |
369 // it as a new navigation). So require a view switch. | 369 // it as a new navigation). So require a view switch. |
370 if (cur_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) | 370 if (cur_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) |
371 return true; | 371 return true; |
372 | 372 |
373 return false; | 373 return false; |
374 } | 374 } |
375 | 375 |
376 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( | 376 SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( |
377 const NavigationEntry& entry, | 377 const NavigationEntryImpl& entry, |
378 SiteInstance* curr_instance) { | 378 SiteInstance* curr_instance) { |
379 // NOTE: This is only called when ShouldTransitionCrossSite is true. | 379 // NOTE: This is only called when ShouldTransitionCrossSite is true. |
380 | 380 |
381 const GURL& dest_url = entry.GetURL(); | 381 const GURL& dest_url = entry.GetURL(); |
382 NavigationController& controller = delegate_->GetControllerForRenderManager(); | 382 NavigationController& controller = delegate_->GetControllerForRenderManager(); |
383 content::BrowserContext* browser_context = controller.browser_context(); | 383 content::BrowserContext* browser_context = controller.browser_context(); |
384 | 384 |
385 // If the entry has an instance already we should use it. | 385 // If the entry has an instance already we should use it. |
386 if (entry.site_instance()) | 386 if (entry.site_instance()) |
387 return entry.site_instance(); | 387 return entry.site_instance(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 return curr_instance->GetRelatedSiteInstance(dest_url); | 422 return curr_instance->GetRelatedSiteInstance(dest_url); |
423 | 423 |
424 // Normally the "site" on the SiteInstance is set lazily when the load | 424 // Normally the "site" on the SiteInstance is set lazily when the load |
425 // actually commits. This is to support better process sharing in case | 425 // actually commits. This is to support better process sharing in case |
426 // the site redirects to some other site: we want to use the destination | 426 // the site redirects to some other site: we want to use the destination |
427 // site in the site instance. | 427 // site in the site instance. |
428 // | 428 // |
429 // In the case of session restore, as it loads all the pages immediately | 429 // In the case of session restore, as it loads all the pages immediately |
430 // we need to set the site first, otherwise after a restore none of the | 430 // we need to set the site first, otherwise after a restore none of the |
431 // pages would share renderers in process-per-site. | 431 // pages would share renderers in process-per-site. |
432 if (entry.restore_type() != NavigationEntry::RESTORE_NONE) | 432 if (entry.restore_type() != NavigationEntryImpl::RESTORE_NONE) |
433 curr_instance->SetSite(dest_url); | 433 curr_instance->SetSite(dest_url); |
434 | 434 |
435 return curr_instance; | 435 return curr_instance; |
436 } | 436 } |
437 | 437 |
438 // Otherwise, only create a new SiteInstance for cross-site navigation. | 438 // Otherwise, only create a new SiteInstance for cross-site navigation. |
439 | 439 |
440 // TODO(creis): Once we intercept links and script-based navigations, we | 440 // TODO(creis): Once we intercept links and script-based navigations, we |
441 // will be able to enforce that all entries in a SiteInstance actually have | 441 // will be able to enforce that all entries in a SiteInstance actually have |
442 // the same site, and it will be safe to compare the URL against the | 442 // the same site, and it will be safe to compare the URL against the |
443 // SiteInstance's site, as follows: | 443 // SiteInstance's site, as follows: |
444 // const GURL& current_url = curr_instance->site(); | 444 // const GURL& current_url = curr_instance->site(); |
445 // For now, though, we're in a hybrid model where you only switch | 445 // For now, though, we're in a hybrid model where you only switch |
446 // SiteInstances if you type in a cross-site URL. This means we have to | 446 // SiteInstances if you type in a cross-site URL. This means we have to |
447 // compare the entry's URL to the last committed entry's URL. | 447 // compare the entry's URL to the last committed entry's URL. |
448 content::NavigationEntry* curr_entry = controller.GetLastCommittedEntry(); | 448 NavigationEntry* curr_entry = controller.GetLastCommittedEntry(); |
449 if (interstitial_page_) { | 449 if (interstitial_page_) { |
450 // The interstitial is currently the last committed entry, but we want to | 450 // The interstitial is currently the last committed entry, but we want to |
451 // compare against the last non-interstitial entry. | 451 // compare against the last non-interstitial entry. |
452 curr_entry = controller.GetEntryAtOffset(-1); | 452 curr_entry = controller.GetEntryAtOffset(-1); |
453 } | 453 } |
454 // If there is no last non-interstitial entry (and curr_instance already | 454 // If there is no last non-interstitial entry (and curr_instance already |
455 // has a site), then we must have been opened from another tab. We want | 455 // has a site), then we must have been opened from another tab. We want |
456 // to compare against the URL of the page that opened us, but we can't | 456 // to compare against the URL of the page that opened us, but we can't |
457 // get to it directly. The best we can do is check against the site of | 457 // get to it directly. The best we can do is check against the site of |
458 // the SiteInstance. This will be correct when we intercept links and | 458 // the SiteInstance. This will be correct when we intercept links and |
(...skipping 23 matching lines...) Expand all Loading... |
482 // Start the new renderer in a new SiteInstance, but in the current | 482 // Start the new renderer in a new SiteInstance, but in the current |
483 // BrowsingInstance. It is important to immediately give this new | 483 // BrowsingInstance. It is important to immediately give this new |
484 // SiteInstance to a RenderViewHost (if it is different than our current | 484 // SiteInstance to a RenderViewHost (if it is different than our current |
485 // SiteInstance), so that it is ref counted. This will happen in | 485 // SiteInstance), so that it is ref counted. This will happen in |
486 // CreatePendingRenderView. | 486 // CreatePendingRenderView. |
487 return curr_instance->GetRelatedSiteInstance(dest_url); | 487 return curr_instance->GetRelatedSiteInstance(dest_url); |
488 } | 488 } |
489 } | 489 } |
490 | 490 |
491 bool RenderViewHostManager::CreatePendingRenderView( | 491 bool RenderViewHostManager::CreatePendingRenderView( |
492 const NavigationEntry& entry, SiteInstance* instance) { | 492 const NavigationEntryImpl& entry, SiteInstance* instance) { |
493 content::NavigationEntry* curr_entry = | 493 NavigationEntry* curr_entry = |
494 delegate_->GetControllerForRenderManager().GetLastCommittedEntry(); | 494 delegate_->GetControllerForRenderManager().GetLastCommittedEntry(); |
495 if (curr_entry) { | 495 if (curr_entry) { |
496 DCHECK(!curr_entry->GetContentState().empty()); | 496 DCHECK(!curr_entry->GetContentState().empty()); |
497 // TODO(creis): Should send a message to the RenderView to let it know | 497 // TODO(creis): Should send a message to the RenderView to let it know |
498 // we're about to switch away, so that it sends an UpdateState message. | 498 // we're about to switch away, so that it sends an UpdateState message. |
499 } | 499 } |
500 | 500 |
501 // Check if we've already created an RVH for this SiteInstance. | 501 // Check if we've already created an RVH for this SiteInstance. |
502 CHECK(instance); | 502 CHECK(instance); |
503 RenderViewHostMap::iterator iter = | 503 RenderViewHostMap::iterator iter = |
(...skipping 20 matching lines...) Expand all Loading... |
524 if (success) { | 524 if (success) { |
525 // Don't show the view until we get a DidNavigate from it. | 525 // Don't show the view until we get a DidNavigate from it. |
526 pending_render_view_host_->view()->Hide(); | 526 pending_render_view_host_->view()->Hide(); |
527 } else { | 527 } else { |
528 CancelPending(); | 528 CancelPending(); |
529 } | 529 } |
530 return success; | 530 return success; |
531 } | 531 } |
532 | 532 |
533 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, | 533 bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host, |
534 const NavigationEntry& entry) { | 534 const NavigationEntryImpl& entry) { |
535 // If the pending navigation is to a WebUI, tell the RenderView about any | 535 // If the pending navigation is to a WebUI, tell the RenderView about any |
536 // bindings it will need enabled. | 536 // bindings it will need enabled. |
537 if (pending_web_ui_.get()) | 537 if (pending_web_ui_.get()) |
538 render_view_host->AllowBindings(pending_web_ui_->bindings()); | 538 render_view_host->AllowBindings(pending_web_ui_->bindings()); |
539 | 539 |
540 return delegate_->CreateRenderViewForRenderManager(render_view_host); | 540 return delegate_->CreateRenderViewForRenderManager(render_view_host); |
541 } | 541 } |
542 | 542 |
543 void RenderViewHostManager::CommitPending() { | 543 void RenderViewHostManager::CommitPending() { |
544 // First check whether we're going to want to focus the location bar after | 544 // First check whether we're going to want to focus the location bar after |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 } else { | 629 } else { |
630 old_render_view_host->Shutdown(); | 630 old_render_view_host->Shutdown(); |
631 } | 631 } |
632 | 632 |
633 // Let the task manager know that we've swapped RenderViewHosts, since it | 633 // Let the task manager know that we've swapped RenderViewHosts, since it |
634 // might need to update its process groupings. | 634 // might need to update its process groupings. |
635 delegate_->NotifySwappedFromRenderManager(); | 635 delegate_->NotifySwappedFromRenderManager(); |
636 } | 636 } |
637 | 637 |
638 RenderViewHost* RenderViewHostManager::UpdateRendererStateForNavigate( | 638 RenderViewHost* RenderViewHostManager::UpdateRendererStateForNavigate( |
639 const NavigationEntry& entry) { | 639 const NavigationEntryImpl& entry) { |
640 // If we are cross-navigating, then we want to get back to normal and navigate | 640 // If we are cross-navigating, then we want to get back to normal and navigate |
641 // as usual. | 641 // as usual. |
642 if (cross_navigation_pending_) { | 642 if (cross_navigation_pending_) { |
643 if (pending_render_view_host_) | 643 if (pending_render_view_host_) |
644 CancelPending(); | 644 CancelPending(); |
645 cross_navigation_pending_ = false; | 645 cross_navigation_pending_ = false; |
646 } | 646 } |
647 | 647 |
648 // This will possibly create (set to NULL) a Web UI object for the pending | 648 // This will possibly create (set to NULL) a Web UI object for the pending |
649 // page. We'll use this later to give the page special access. This must | 649 // page. We'll use this later to give the page special access. This must |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 } | 805 } |
806 } | 806 } |
807 | 807 |
808 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) { | 808 bool RenderViewHostManager::IsSwappedOut(RenderViewHost* rvh) { |
809 if (!rvh->site_instance()) | 809 if (!rvh->site_instance()) |
810 return false; | 810 return false; |
811 | 811 |
812 return swapped_out_hosts_.find(rvh->site_instance()->id()) != | 812 return swapped_out_hosts_.find(rvh->site_instance()->id()) != |
813 swapped_out_hosts_.end(); | 813 swapped_out_hosts_.end(); |
814 } | 814 } |
OLD | NEW |