Index: content/browser/tab_contents/tab_contents.cc |
diff --git a/content/browser/tab_contents/tab_contents.cc b/content/browser/tab_contents/tab_contents.cc |
index 7c113a3dc38f4d4badf33291c9ce7a5acf1ef569..c39ff9cb94f5a1de4a7bef0aface524435c4f078 100644 |
--- a/content/browser/tab_contents/tab_contents.cc |
+++ b/content/browser/tab_contents/tab_contents.cc |
@@ -122,14 +122,17 @@ |
// - After RDH receives a response and determines that it is safe and not a |
// download, it pauses the response to first run the old page's onunload |
// handler. It does this by asynchronously calling the OnCrossSiteResponse |
-// method of TabContents on the UI thread, which sends a ClosePage message |
+// method of TabContents on the UI thread, which sends a SwapOut message |
// to the current RVH. |
-// - Once the onunload handler is finished, a ClosePage_ACK message is sent to |
+// - Once the onunload handler is finished, a SwapOut_ACK message is sent to |
// the ResourceDispatcherHost, who unpauses the response. Data is then sent |
// to the pending RVH. |
// - The pending renderer sends a FrameNavigate message that invokes the |
// DidNavigate method. This replaces the current RVH with the |
// pending RVH and goes back to the NORMAL RendererState. |
+// - The previous renderer is kept swapped out in RenderViewHostManager in case |
+// the user goes back. The process only stays live if another tab is using |
+// it, but if so, the existing frame relationships will be maintained. |
namespace { |
@@ -384,23 +387,6 @@ bool TabContents::OnMessageReceived(const IPC::Message& message) { |
bool handled = true; |
bool message_is_ok = true; |
IPC_BEGIN_MESSAGE_MAP_EX(TabContents, message, message_is_ok) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_DidStartProvisionalLoadForFrame, |
- OnDidStartProvisionalLoadForFrame) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_DidRedirectProvisionalLoad, |
- OnDidRedirectProvisionalLoad) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_DidFailProvisionalLoadWithError, |
- OnDidFailProvisionalLoadWithError) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_DidLoadResourceFromMemoryCache, |
- OnDidLoadResourceFromMemoryCache) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_DidDisplayInsecureContent, |
- OnDidDisplayInsecureContent) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_DidRunInsecureContent, |
- OnDidRunInsecureContent) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentLoadedInFrame, |
- OnDocumentLoadedInFrame) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_DidFinishLoad, OnDidFinishLoad) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateContentRestrictions, |
- OnUpdateContentRestrictions) |
IPC_MESSAGE_HANDLER(ViewHostMsg_PDFHasUnsupportedFeature, |
OnPDFHasUnsupportedFeature) |
IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, OnGoToEntryAtOffset) |
@@ -1141,9 +1127,9 @@ void TabContents::SetContentRestrictions(int restrictions) { |
delegate()->ContentRestrictionsChanged(this); |
} |
-void TabContents::OnDidStartProvisionalLoadForFrame(int64 frame_id, |
- bool is_main_frame, |
- const GURL& url) { |
+void TabContents::DidStartProvisionalLoadForFrame(int64 frame_id, |
+ bool is_main_frame, |
+ const GURL& url) { |
bool is_error_page = (url.spec() == chrome::kUnreachableWebDataURL); |
GURL validated_url(url); |
render_view_host()->FilterURL(ChildProcessSecurityPolicy::GetInstance(), |
@@ -1168,9 +1154,9 @@ void TabContents::OnDidStartProvisionalLoadForFrame(int64 frame_id, |
} |
} |
-void TabContents::OnDidRedirectProvisionalLoad(int32 page_id, |
- const GURL& source_url, |
- const GURL& target_url) { |
+void TabContents::DidRedirectProvisionalLoad(int32 page_id, |
+ const GURL& source_url, |
+ const GURL& target_url) { |
// TODO(creis): Remove this method and have the pre-rendering code listen to |
// the ResourceDispatcherHost's RESOURCE_RECEIVED_REDIRECT notification |
// instead. See http://crbug.com/78512. |
@@ -1187,7 +1173,7 @@ void TabContents::OnDidRedirectProvisionalLoad(int32 page_id, |
ProvisionalChangeToMainFrameUrl(target_url)); |
} |
-void TabContents::OnDidFailProvisionalLoadWithError( |
+void TabContents::DidFailProvisionalLoadWithError( |
int64 frame_id, |
bool is_main_frame, |
int error_code, |
@@ -1256,7 +1242,7 @@ void TabContents::OnDidFailProvisionalLoadWithError( |
validated_url, error_code)); |
} |
-void TabContents::OnDidLoadResourceFromMemoryCache( |
+void TabContents::DidLoadResourceFromMemoryCache( |
const GURL& url, |
const std::string& security_info) { |
base::StatsCounter cache("WebKit.CacheHit"); |
@@ -1277,30 +1263,30 @@ void TabContents::OnDidLoadResourceFromMemoryCache( |
Details<LoadFromMemoryCacheDetails>(&details)); |
} |
-void TabContents::OnDidDisplayInsecureContent() { |
+void TabContents::DidDisplayInsecureContent() { |
displayed_insecure_content_ = true; |
SSLManager::NotifySSLInternalStateChanged(); |
} |
-void TabContents::OnDidRunInsecureContent( |
+void TabContents::DidRunInsecureContent( |
const std::string& security_origin, const GURL& target_url) { |
LOG(INFO) << security_origin << " ran insecure content from " |
<< target_url.possibly_invalid_spec(); |
controller_.ssl_manager()->DidRunInsecureContent(security_origin); |
} |
-void TabContents::OnDocumentLoadedInFrame(int64 frame_id) { |
+void TabContents::DocumentLoadedInFrame(int64 frame_id) { |
controller_.DocumentLoadedInFrame(); |
FOR_EACH_OBSERVER(TabContentsObserver, observers_, |
DocumentLoadedInFrame(frame_id)); |
} |
-void TabContents::OnDidFinishLoad(int64 frame_id) { |
+void TabContents::DidFinishLoad(int64 frame_id) { |
FOR_EACH_OBSERVER(TabContentsObserver, observers_, |
DidFinishLoad(frame_id)); |
} |
-void TabContents::OnUpdateContentRestrictions(int restrictions) { |
+void TabContents::UpdateContentRestrictions(int restrictions) { |
SetContentRestrictions(restrictions); |
} |
@@ -1856,7 +1842,9 @@ void TabContents::DidNavigate(RenderViewHost* rvh, |
void TabContents::UpdateState(RenderViewHost* rvh, |
int32 page_id, |
const std::string& state) { |
- DCHECK(rvh == render_view_host()); |
+ // Ensure that this state update comes from either the active RVH or one of |
+ // the swapped out RVHs. We don't expect to hear from any other RVHs. |
+ DCHECK(rvh == render_view_host() || render_manager_.IsSwappedOut(rvh)); |
// We must be prepared to handle state updates for any page, these occur |
// when the user is scrolling and entering form data, as well as when we're |
@@ -1865,7 +1853,7 @@ void TabContents::UpdateState(RenderViewHost* rvh, |
// NavigationEntry and update it when it is notified via the delegate. |
int entry_index = controller_.GetEntryIndexWithPageID( |
- GetSiteInstance(), page_id); |
+ rvh->site_instance(), page_id); |
if (entry_index < 0) |
return; |
NavigationEntry* entry = controller_.GetEntryAtIndex(entry_index); |
@@ -2037,6 +2025,7 @@ void TabContents::ProcessExternalHostMessage(const std::string& message, |
} |
void TabContents::RunJavaScriptMessage( |
+ const RenderViewHost* rvh, |
const std::wstring& message, |
const std::wstring& default_prompt, |
const GURL& frame_url, |
@@ -2050,6 +2039,7 @@ void TabContents::RunJavaScriptMessage( |
// shown over the previous page, we don't want the hidden page dialogs to |
// interfere with the interstitial. |
bool suppress_this_message = |
+ rvh->is_swapped_out() || |
suppress_javascript_messages_ || |
showing_interstitial_page() || |
(delegate() && delegate()->ShouldSuppressDialogs()); |
@@ -2079,11 +2069,14 @@ void TabContents::RunJavaScriptMessage( |
} |
} |
-void TabContents::RunBeforeUnloadConfirm(const std::wstring& message, |
+void TabContents::RunBeforeUnloadConfirm(const RenderViewHost* rvh, |
+ const std::wstring& message, |
IPC::Message* reply_msg) { |
if (delegate()) |
delegate()->WillRunBeforeUnloadConfirm(); |
- if (delegate() && delegate()->ShouldSuppressDialogs()) { |
+ bool suppress_this_message = rvh->is_swapped_out() || |
+ (delegate() && delegate()->ShouldSuppressDialogs()); |
+ if (suppress_this_message) { |
render_view_host()->JavaScriptMessageBoxClosed(reply_msg, true, |
std::wstring()); |
return; |
@@ -2159,6 +2152,10 @@ void TabContents::OnCrossSiteResponse(int new_render_process_host_id, |
void TabContents::RendererUnresponsive(RenderViewHost* rvh, |
bool is_during_unload) { |
+ // Don't show hung renderer dialog for a swapped out RVH. |
+ if (rvh != render_view_host()) |
+ return; |
+ |
if (is_during_unload) { |
// Hang occurred while firing the beforeunload/unload handler. |
// Pretend the handler fired so tab closing continues as if it had. |