Chromium Code Reviews| 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 |
| 77 void RenderViewHostManager::Observe(NotificationType type, | |
| 78 const NotificationSource& source, | |
| 79 const NotificationDetails& details) { | |
| 80 switch (type.value) { | |
| 81 case NotificationType::RENDERER_PROCESS_CLOSING: | |
| 82 RendererProcessClosing(Source<RenderProcessHost>(source).ptr()); | |
| 83 break; | |
| 84 | |
| 85 default: | |
| 86 NOTREACHED(); | |
| 87 } | |
| 88 } | |
| 89 | |
| 73 RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) { | 90 RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) { |
| 74 // Create a pending RenderViewHost. It will give us the one we should use | 91 // Create a pending RenderViewHost. It will give us the one we should use |
| 75 RenderViewHost* dest_render_view_host = UpdateRendererStateForNavigate(entry); | 92 RenderViewHost* dest_render_view_host = UpdateRendererStateForNavigate(entry); |
| 76 if (!dest_render_view_host) | 93 if (!dest_render_view_host) |
| 77 return NULL; // We weren't able to create a pending render view host. | 94 return NULL; // We weren't able to create a pending render view host. |
| 78 | 95 |
| 79 // If the current render_view_host_ isn't live, we should create it so | 96 // If the current render_view_host_ isn't live, we should create it so |
| 80 // that we don't show a sad tab while the dest_render_view_host fetches | 97 // that we don't show a sad tab while the dest_render_view_host fetches |
| 81 // its first page. (Bug 1145340) | 98 // its first page. (Bug 1145340) |
| 82 if (dest_render_view_host != render_view_host_ && | 99 if (dest_render_view_host != render_view_host_ && |
| (...skipping 125 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 | 225 // looks for this TabContents based on a render view ID. Instead, we just |
| 209 // leave the pending renderer around until the next navigation event | 226 // leave the pending renderer around until the next navigation event |
| 210 // (Navigate, DidNavigate, etc), which will clean it up properly. | 227 // (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 | 228 // 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 | 229 // to ResourceDispatcherHost, so that we intercept responses rather than |
| 213 // navigation events. (That's necessary to support onunload anyway.) Once | 230 // 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 | 231 // we've made that change, we won't create a pending renderer until we know |
| 215 // the response is not a download. | 232 // the response is not a download. |
| 216 } | 233 } |
| 217 | 234 |
| 235 void RenderViewHostManager::RendererProcessClosing( | |
| 236 RenderProcessHost* render_process_host) { | |
| 237 // TODO(creis): Don't schedule new navigations in RenderViewHosts of this | |
| 238 // process. (Part of http://crbug.com/65953.) | |
| 239 } | |
| 240 | |
| 218 void RenderViewHostManager::ShouldClosePage(bool for_cross_site_transition, | 241 void RenderViewHostManager::ShouldClosePage(bool for_cross_site_transition, |
| 219 bool proceed) { | 242 bool proceed) { |
| 220 if (for_cross_site_transition) { | 243 if (for_cross_site_transition) { |
| 221 // Ignore if we're not in a cross-site navigation. | 244 // Ignore if we're not in a cross-site navigation. |
| 222 if (!cross_navigation_pending_) | 245 if (!cross_navigation_pending_) |
| 223 return; | 246 return; |
| 224 | 247 |
| 225 if (proceed) { | 248 if (proceed) { |
| 226 // Ok to unload the current page, so proceed with the cross-site | 249 // Ok to unload the current page, so proceed with the cross-site |
| 227 // navigation. Note that if navigations are not currently suspended, it | 250 // navigation. Note that if navigations are not currently suspended, it |
| (...skipping 228 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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_; |
| 663 pending_render_view_host_ = NULL; | 692 pending_render_view_host_ = NULL; |
| 664 pending_render_view_host->Shutdown(); | 693 pending_render_view_host->Shutdown(); |
| 665 | 694 |
| 695 // We no longer need to prevent the process from exiting. | |
| 696 pending_render_view_host->process()->RemovePendingView(); | |
|
Matt Perry
2011/05/10 01:14:02
does it matter if this comes before or after Shutd
Charlie Reis
2011/05/10 01:33:09
That's a good question-- Shutdown doesn't null out
| |
| 697 | |
| 666 pending_web_ui_.reset(); | 698 pending_web_ui_.reset(); |
| 667 } | 699 } |
| 668 | 700 |
| 669 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) { | 701 void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) { |
| 670 // We are doing this in order to work around and to track a crasher | 702 // 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 | 703 // (http://crbug.com/23411) where it seems that pending_render_view_host_ is |
| 672 // deleted (not sure from where) but not NULLed. | 704 // deleted (not sure from where) but not NULLed. |
| 673 if (rvh == pending_render_view_host_) { | 705 if (rvh == pending_render_view_host_) { |
| 674 // If you hit this NOTREACHED, please report it in the following bug | 706 // If you hit this NOTREACHED, please report it in the following bug |
| 675 // http://crbug.com/23411 Make sure to include what you were doing when it | 707 // http://crbug.com/23411 Make sure to include what you were doing when it |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 720 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), | 752 Source<NavigationController>(&delegate_->GetControllerForRenderManager()), |
| 721 Details<RenderViewHostSwitchedDetails>(&details)); | 753 Details<RenderViewHostSwitchedDetails>(&details)); |
| 722 | 754 |
| 723 // This will cause the old RenderViewHost to delete itself. | 755 // This will cause the old RenderViewHost to delete itself. |
| 724 old_render_view_host->Shutdown(); | 756 old_render_view_host->Shutdown(); |
| 725 | 757 |
| 726 // Let the task manager know that we've swapped RenderViewHosts, since it | 758 // Let the task manager know that we've swapped RenderViewHosts, since it |
| 727 // might need to update its process groupings. | 759 // might need to update its process groupings. |
| 728 delegate_->NotifySwappedFromRenderManager(); | 760 delegate_->NotifySwappedFromRenderManager(); |
| 729 } | 761 } |
| OLD | NEW |