| 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 |