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 "chrome/browser/profiles/profile.h" | 9 #include "chrome/browser/profiles/profile.h" |
10 #include "chrome/common/chrome_switches.h" | 10 #include "chrome/common/chrome_switches.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 SiteInstance* site_instance, | 55 SiteInstance* site_instance, |
56 int routing_id) { | 56 int routing_id) { |
57 // Create a RenderViewHost, once we have an instance. It is important to | 57 // Create a RenderViewHost, once we have an instance. It is important to |
58 // immediately give this SiteInstance to a RenderViewHost so that it is | 58 // immediately give this SiteInstance to a RenderViewHost so that it is |
59 // ref counted. | 59 // ref counted. |
60 if (!site_instance) | 60 if (!site_instance) |
61 site_instance = SiteInstance::CreateSiteInstance(profile); | 61 site_instance = SiteInstance::CreateSiteInstance(profile); |
62 render_view_host_ = RenderViewHostFactory::Create( | 62 render_view_host_ = RenderViewHostFactory::Create( |
63 site_instance, render_view_delegate_, routing_id, delegate_-> | 63 site_instance, render_view_delegate_, routing_id, delegate_-> |
64 GetControllerForRenderManager().session_storage_namespace()); | 64 GetControllerForRenderManager().session_storage_namespace()); |
| 65 |
| 66 // Keep track of renderer processes as they start to shut down. |
| 67 registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSING, |
| 68 NotificationService::AllSources()); |
65 } | 69 } |
66 | 70 |
67 RenderWidgetHostView* RenderViewHostManager::GetRenderWidgetHostView() const { | 71 RenderWidgetHostView* RenderViewHostManager::GetRenderWidgetHostView() const { |
68 if (!render_view_host_) | 72 if (!render_view_host_) |
69 return NULL; | 73 return NULL; |
70 return render_view_host_->view(); | 74 return render_view_host_->view(); |
71 } | 75 } |
72 | 76 |
73 RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) { | 77 RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) { |
74 // Create a pending RenderViewHost. It will give us the one we should use | 78 // Create a pending RenderViewHost. It will give us the one we should use |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 // looks for this TabContents based on a render view ID. Instead, we just | 212 // looks for this TabContents based on a render view ID. Instead, we just |
209 // leave the pending renderer around until the next navigation event | 213 // leave the pending renderer around until the next navigation event |
210 // (Navigate, DidNavigate, etc), which will clean it up properly. | 214 // (Navigate, DidNavigate, etc), which will clean it up properly. |
211 // TODO(creis): All of this will go away when we move the cross-site logic | 215 // TODO(creis): All of this will go away when we move the cross-site logic |
212 // to ResourceDispatcherHost, so that we intercept responses rather than | 216 // to ResourceDispatcherHost, so that we intercept responses rather than |
213 // navigation events. (That's necessary to support onunload anyway.) Once | 217 // navigation events. (That's necessary to support onunload anyway.) Once |
214 // we've made that change, we won't create a pending renderer until we know | 218 // we've made that change, we won't create a pending renderer until we know |
215 // the response is not a download. | 219 // the response is not a download. |
216 } | 220 } |
217 | 221 |
| 222 void RenderViewHostManager::RendererProcessClosing( |
| 223 RenderProcessHost* render_process_host) { |
| 224 // TODO(creis): Don't schedule new navigations in RenderViewHosts of this |
| 225 // process. (Part of http://crbug.com/65953.) |
| 226 } |
| 227 |
218 void RenderViewHostManager::ShouldClosePage(bool for_cross_site_transition, | 228 void RenderViewHostManager::ShouldClosePage(bool for_cross_site_transition, |
219 bool proceed) { | 229 bool proceed) { |
220 if (for_cross_site_transition) { | 230 if (for_cross_site_transition) { |
221 // Ignore if we're not in a cross-site navigation. | 231 // Ignore if we're not in a cross-site navigation. |
222 if (!cross_navigation_pending_) | 232 if (!cross_navigation_pending_) |
223 return; | 233 return; |
224 | 234 |
225 if (proceed) { | 235 if (proceed) { |
226 // Ok to unload the current page, so proceed with the cross-site | 236 // Ok to unload the current page, so proceed with the cross-site |
227 // navigation. Note that if navigations are not currently suspended, it | 237 // navigation. Note that if navigations are not currently suspended, it |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 new_request_id); | 281 new_request_id); |
272 } | 282 } |
273 | 283 |
274 void RenderViewHostManager::OnCrossSiteNavigationCanceled() { | 284 void RenderViewHostManager::OnCrossSiteNavigationCanceled() { |
275 DCHECK(cross_navigation_pending_); | 285 DCHECK(cross_navigation_pending_); |
276 cross_navigation_pending_ = false; | 286 cross_navigation_pending_ = false; |
277 if (pending_render_view_host_) | 287 if (pending_render_view_host_) |
278 CancelPending(); | 288 CancelPending(); |
279 } | 289 } |
280 | 290 |
| 291 void RenderViewHostManager::Observe(NotificationType type, |
| 292 const NotificationSource& source, |
| 293 const NotificationDetails& details) { |
| 294 switch (type.value) { |
| 295 case NotificationType::RENDERER_PROCESS_CLOSING: |
| 296 RendererProcessClosing(Source<RenderProcessHost>(source).ptr()); |
| 297 break; |
| 298 |
| 299 default: |
| 300 NOTREACHED(); |
| 301 } |
| 302 } |
| 303 |
281 bool RenderViewHostManager::ShouldTransitionCrossSite() { | 304 bool RenderViewHostManager::ShouldTransitionCrossSite() { |
282 // True if we are using process-per-site-instance (default) or | 305 // True if we are using process-per-site-instance (default) or |
283 // process-per-site (kProcessPerSite). | 306 // process-per-site (kProcessPerSite). |
284 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); | 307 return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab); |
285 } | 308 } |
286 | 309 |
287 bool RenderViewHostManager::ShouldSwapProcessesForNavigation( | 310 bool RenderViewHostManager::ShouldSwapProcessesForNavigation( |
288 const NavigationEntry* cur_entry, | 311 const NavigationEntry* cur_entry, |
289 const NavigationEntry* new_entry) const { | 312 const NavigationEntry* new_entry) const { |
290 DCHECK(new_entry); | 313 DCHECK(new_entry); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 if (curr_entry) { | 479 if (curr_entry) { |
457 DCHECK(!curr_entry->content_state().empty()); | 480 DCHECK(!curr_entry->content_state().empty()); |
458 // TODO(creis): Should send a message to the RenderView to let it know | 481 // TODO(creis): Should send a message to the RenderView to let it know |
459 // we're about to switch away, so that it sends an UpdateState message. | 482 // we're about to switch away, so that it sends an UpdateState message. |
460 } | 483 } |
461 | 484 |
462 pending_render_view_host_ = RenderViewHostFactory::Create( | 485 pending_render_view_host_ = RenderViewHostFactory::Create( |
463 instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_-> | 486 instance, render_view_delegate_, MSG_ROUTING_NONE, delegate_-> |
464 GetControllerForRenderManager().session_storage_namespace()); | 487 GetControllerForRenderManager().session_storage_namespace()); |
465 | 488 |
| 489 // Prevent the process from exiting while we're trying to use it. |
| 490 pending_render_view_host_->process()->AddPendingView(); |
| 491 |
466 bool success = InitRenderView(pending_render_view_host_, entry); | 492 bool success = InitRenderView(pending_render_view_host_, entry); |
467 if (success) { | 493 if (success) { |
468 // Don't show the view until we get a DidNavigate from it. | 494 // Don't show the view until we get a DidNavigate from it. |
469 pending_render_view_host_->view()->Hide(); | 495 pending_render_view_host_->view()->Hide(); |
470 } else { | 496 } else { |
471 CancelPending(); | 497 CancelPending(); |
472 } | 498 } |
473 return success; | 499 return success; |
474 } | 500 } |
475 | 501 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 // TODO(creis): Get the old RenderViewHost to send us an UpdateState message | 545 // TODO(creis): Get the old RenderViewHost to send us an UpdateState message |
520 // before we destroy it. | 546 // before we destroy it. |
521 if (render_view_host_->view()) | 547 if (render_view_host_->view()) |
522 render_view_host_->view()->Hide(); | 548 render_view_host_->view()->Hide(); |
523 RenderViewHost* old_render_view_host = render_view_host_; | 549 RenderViewHost* old_render_view_host = render_view_host_; |
524 | 550 |
525 // Swap in the pending view and make it active. | 551 // Swap in the pending view and make it active. |
526 render_view_host_ = pending_render_view_host_; | 552 render_view_host_ = pending_render_view_host_; |
527 pending_render_view_host_ = NULL; | 553 pending_render_view_host_ = NULL; |
528 | 554 |
| 555 // The process will no longer try to exit, so we can decrement the count. |
| 556 render_view_host_->process()->RemovePendingView(); |
| 557 |
529 // If the view is gone, then this RenderViewHost died while it was hidden. | 558 // If the view is gone, then this RenderViewHost died while it was hidden. |
530 // We ignored the RenderViewGone call at the time, so we should send it now | 559 // We ignored the RenderViewGone call at the time, so we should send it now |
531 // to make sure the sad tab shows up, etc. | 560 // to make sure the sad tab shows up, etc. |
532 if (render_view_host_->view()) | 561 if (render_view_host_->view()) |
533 render_view_host_->view()->Show(); | 562 render_view_host_->view()->Show(); |
534 else | 563 else |
535 delegate_->RenderViewGoneFromRenderManager(render_view_host_); | 564 delegate_->RenderViewGoneFromRenderManager(render_view_host_); |
536 | 565 |
537 // Make sure the size is up to date. (Fix for bug 1079768.) | 566 // Make sure the size is up to date. (Fix for bug 1079768.) |
538 delegate_->UpdateRenderViewSizeForRenderManager(); | 567 delegate_->UpdateRenderViewSizeForRenderManager(); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 } | 682 } |
654 | 683 |
655 // Same SiteInstance can be used. Navigate render_view_host_ if we are not | 684 // Same SiteInstance can be used. Navigate render_view_host_ if we are not |
656 // cross navigating. | 685 // cross navigating. |
657 DCHECK(!cross_navigation_pending_); | 686 DCHECK(!cross_navigation_pending_); |
658 return render_view_host_; | 687 return render_view_host_; |
659 } | 688 } |
660 | 689 |
661 void RenderViewHostManager::CancelPending() { | 690 void RenderViewHostManager::CancelPending() { |
662 RenderViewHost* pending_render_view_host = pending_render_view_host_; | 691 RenderViewHost* pending_render_view_host = pending_render_view_host_; |
| 692 |
| 693 // We no longer need to prevent the process from exiting. |
| 694 pending_render_view_host->process()->RemovePendingView(); |
| 695 |
663 pending_render_view_host_ = NULL; | 696 pending_render_view_host_ = NULL; |
664 pending_render_view_host->Shutdown(); | 697 pending_render_view_host->Shutdown(); |
665 | 698 |
666 pending_web_ui_.reset(); | 699 pending_web_ui_.reset(); |
667 } | 700 } |
668 | 701 |
669 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) { | 702 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) { |
670 // We are doing this in order to work around and to track a crasher | 703 // We are doing this in order to work around and to track a crasher |
671 // (http://crbug.com/23411) where it seems that pending_render_view_host_ is | 704 // (http://crbug.com/23411) where it seems that pending_render_view_host_ is |
672 // deleted (not sure from where) but not NULLed. | 705 // deleted (not sure from where) but not NULLed. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), | 753 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), |
721 Details<RenderViewHostSwitchedDetails>(&details)); | 754 Details<RenderViewHostSwitchedDetails>(&details)); |
722 | 755 |
723 // This will cause the old RenderViewHost to delete itself. | 756 // This will cause the old RenderViewHost to delete itself. |
724 old_render_view_host->Shutdown(); | 757 old_render_view_host->Shutdown(); |
725 | 758 |
726 // Let the task manager know that we've swapped RenderViewHosts, since it | 759 // Let the task manager know that we've swapped RenderViewHosts, since it |
727 // might need to update its process groupings. | 760 // might need to update its process groupings. |
728 delegate_->NotifySwappedFromRenderManager(); | 761 delegate_->NotifySwappedFromRenderManager(); |
729 } | 762 } |
OLD | NEW |