summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorcreis@chromium.org <creis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 20:51:32 +0000
committercreis@chromium.org <creis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 20:51:32 +0000
commite1c3a5536d62aa836a5c1e2e8eccdf4eed175a14 (patch)
treeeb6faa304469ae3dcadc058deeb88226fb97f928 /content
parent8734f0a862d4fddb4d63e3544c78d70d9539bd9d (diff)
downloadchromium_src-e1c3a5536d62aa836a5c1e2e8eccdf4eed175a14.zip
chromium_src-e1c3a5536d62aa836a5c1e2e8eccdf4eed175a14.tar.gz
chromium_src-e1c3a5536d62aa836a5c1e2e8eccdf4eed175a14.tar.bz2
Support cross-process window.close() messages.
BUG=99202 TEST=Call w.close() on a window that has opened but navigated cross-process. Review URL: https://chromiumcodereview.appspot.com/10344028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135416 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/render_view_host_impl.cc7
-rw-r--r--content/browser/renderer_host/render_view_host_impl.h1
-rw-r--r--content/browser/renderer_host/render_view_host_manager_browsertest.cc18
-rw-r--r--content/browser/web_contents/web_contents_impl.cc10
-rw-r--r--content/browser/web_contents/web_contents_impl.h1
-rw-r--r--content/common/swapped_out_messages.cc2
-rw-r--r--content/common/view_messages.h4
-rw-r--r--content/public/browser/render_view_host_delegate.h3
-rw-r--r--content/renderer/render_widget.cc8
9 files changed, 53 insertions, 1 deletions
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 4cd062f..860398a 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -938,6 +938,8 @@ bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
OnMsgDidChangeScrollOffsetPinningForMainFrame)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeNumWheelEvents,
OnMsgDidChangeNumWheelEvents)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_RouteCloseEvent,
+ OnMsgRouteCloseEvent)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunJavaScriptMessage,
OnMsgRunJavaScriptMessage)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_RunBeforeUnloadConfirm,
@@ -1299,6 +1301,11 @@ void RenderViewHostImpl::OnMsgSelectionBoundsChanged(
view_->SelectionBoundsChanged(start_rect, end_rect);
}
+void RenderViewHostImpl::OnMsgRouteCloseEvent() {
+ // Have the delegate route this to the active RenderViewHost.
+ delegate_->RouteCloseEvent(this);
+}
+
void RenderViewHostImpl::OnMsgRunJavaScriptMessage(
const string16& message,
const string16& default_prompt,
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index 903027d..6f3ccf0 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -474,6 +474,7 @@ class CONTENT_EXPORT RenderViewHostImpl
void OnMsgSelectionBoundsChanged(const gfx::Rect& start_rect,
const gfx::Rect& end_rect);
void OnMsgPasteFromSelectionClipboard();
+ void OnMsgRouteCloseEvent();
void OnMsgRunJavaScriptMessage(const string16& message,
const string16& default_prompt,
const GURL& frame_url,
diff --git a/content/browser/renderer_host/render_view_host_manager_browsertest.cc b/content/browser/renderer_host/render_view_host_manager_browsertest.cc
index e392536..917947b 100644
--- a/content/browser/renderer_host/render_view_host_manager_browsertest.cc
+++ b/content/browser/renderer_host/render_view_host_manager_browsertest.cc
@@ -389,7 +389,6 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
EXPECT_EQ(orig_site_instance, blank_site_instance);
// Now navigate the new tab to a different site.
- //browser()->ActivateTabAt(1, true);
content::WebContents* new_contents = browser()->GetSelectedWebContents();
ui_test_utils::NavigateToURL(browser(),
https_server.GetURL("files/title1.html"));
@@ -415,6 +414,23 @@ IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
scoped_refptr<SiteInstance> revisit_site_instance(
browser()->GetSelectedWebContents()->GetSiteInstance());
EXPECT_EQ(orig_site_instance, revisit_site_instance);
+
+ // If it navigates away to another process, the original window should
+ // still be able to close it (using a cross-process close message).
+ ui_test_utils::NavigateToURL(browser(),
+ https_server.GetURL("files/title1.html"));
+ EXPECT_EQ(new_site_instance,
+ browser()->GetSelectedWebContents()->GetSiteInstance());
+ browser()->ActivateTabAt(0, true);
+ ui_test_utils::WindowedNotificationObserver close_observer(
+ content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
+ content::Source<content::WebContents>(new_contents));
+ EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ browser()->GetSelectedWebContents()->GetRenderViewHost(), L"",
+ L"window.domAutomationController.send(testCloseWindow());",
+ &success));
+ EXPECT_TRUE(success);
+ close_observer.Wait();
}
// Test for crbug.com/116192. Navigations to a window's opener should
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index a8abbc6f1..2bdb987 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2398,6 +2398,16 @@ void WebContentsImpl::RequestTransferURL(
}
}
+void WebContentsImpl::RouteCloseEvent(RenderViewHost* rvh) {
+ // Tell the active RenderViewHost to run unload handlers and close, as long
+ // as the request came from a RenderViewHost in the same BrowsingInstance.
+ // In most cases, we receive this from a swapped out RenderViewHost.
+ // It is possible to receive it from one that has just been swapped in,
+ // in which case we might as well deliver the message anyway.
+ if (rvh->GetSiteInstance()->IsRelatedSiteInstance(GetSiteInstance()))
+ GetRenderViewHost()->ClosePage();
+}
+
void WebContentsImpl::RunJavaScriptMessage(
RenderViewHost* rvh,
const string16& message,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 594a05c..07d0dcd 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -293,6 +293,7 @@ class CONTENT_EXPORT WebContentsImpl
WindowOpenDisposition disposition,
int64 source_frame_id,
const content::GlobalRequestID& transferred_global_request_id) OVERRIDE;
+ virtual void RouteCloseEvent(content::RenderViewHost* rvh) OVERRIDE;
virtual void RunJavaScriptMessage(content::RenderViewHost* rvh,
const string16& message,
const string16& default_prompt,
diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc
index f94e0c0..1e0b667 100644
--- a/content/common/swapped_out_messages.cc
+++ b/content/common/swapped_out_messages.cc
@@ -28,6 +28,8 @@ bool SwappedOutMessages::CanSendWhileSwappedOut(const IPC::Message* msg) {
case ViewHostMsg_SwapOut_ACK::ID:
case ViewHostMsg_ClosePage_ACK::ID:
case ViewHostMsg_DomOperationResponse::ID:
+ // Allow cross-process JavaScript calls.
+ case ViewHostMsg_RouteCloseEvent::ID:
return true;
default:
break;
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index e02874a..502360f 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -1611,6 +1611,10 @@ IPC_MESSAGE_ROUTED3(ViewHostMsg_DownloadUrl,
IPC_MESSAGE_ROUTED1(ViewHostMsg_GoToEntryAtOffset,
int /* offset (from current) of history item to get */)
+// Sent from an inactive renderer for the browser to route to the active
+// renderer, instructing it to close.
+IPC_MESSAGE_ROUTED0(ViewHostMsg_RouteCloseEvent)
+
IPC_SYNC_MESSAGE_ROUTED4_2(ViewHostMsg_RunJavaScriptMessage,
string16 /* in - alert message */,
string16 /* in - default prompt */,
diff --git a/content/public/browser/render_view_host_delegate.h b/content/public/browser/render_view_host_delegate.h
index b56d828..3750266 100644
--- a/content/public/browser/render_view_host_delegate.h
+++ b/content/public/browser/render_view_host_delegate.h
@@ -298,6 +298,9 @@ class CONTENT_EXPORT RenderViewHostDelegate : public IPC::Channel::Listener {
int64 source_frame_id,
const content::GlobalRequestID& old_request_id) {}
+ // The page wants to close the active view in this tab.
+ virtual void RouteCloseEvent(RenderViewHost* rvh) {}
+
// A javascript message, confirmation or prompt should be shown.
virtual void RunJavaScriptMessage(RenderViewHost* rvh,
const string16& message,
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index ed8eb0c..1462582 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -1255,6 +1255,14 @@ void RenderWidget::DoDeferredClose() {
}
void RenderWidget::closeWidgetSoon() {
+ if (is_swapped_out_) {
+ // This widget is currently swapped out, and the active widget is in a
+ // different process. Have the browser route the close request to the
+ // active widget instead, so that the correct unload handlers are run.
+ Send(new ViewHostMsg_RouteCloseEvent(routing_id_));
+ return;
+ }
+
// If a page calls window.close() twice, we'll end up here twice, but that's
// OK. It is safe to send multiple Close messages.