Commit 70ea134b authored by japhet's avatar japhet Committed by Commit bot

If a RemoteFrame asks to navigate, send an OpenURL IPC

This is the first step toward making remote frames able to be navigated by their parent correctly, and to enable them to transition back into the same process as the parent.

This, combined with https://codereview.chromium.org/573353002/, "just work" to route a navigation request from a RemoteFrame back to its LocalFrame. However, we incorrectly commit the load into the existing LocalFrame (rather than transitioning processes again) and we assert during that commit.

BUG=

Review URL: https://codereview.chromium.org/574403002

Cr-Commit-Position: refs/heads/master@{#297513}
parent c619607d
...@@ -1282,6 +1282,10 @@ void RenderFrameHostImpl::NavigateToURL(const GURL& url) { ...@@ -1282,6 +1282,10 @@ void RenderFrameHostImpl::NavigateToURL(const GURL& url) {
Navigate(params); Navigate(params);
} }
void RenderFrameHostImpl::OpenURL(const FrameHostMsg_OpenURL_Params& params) {
OnOpenURL(params);
}
void RenderFrameHostImpl::Stop() { void RenderFrameHostImpl::Stop() {
Send(new FrameMsg_Stop(routing_id_)); Send(new FrameMsg_Stop(routing_id_));
} }
......
...@@ -255,6 +255,11 @@ class CONTENT_EXPORT RenderFrameHostImpl ...@@ -255,6 +255,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
// Load the specified URL; this is a shortcut for Navigate(). // Load the specified URL; this is a shortcut for Navigate().
void NavigateToURL(const GURL& url); void NavigateToURL(const GURL& url);
// Treat this prospective navigation as thought it originated from the
// frame. Used, e.g., for a navigation request that originated from
// a RemoteFrame.
void OpenURL(const FrameHostMsg_OpenURL_Params& params);
// Stop the load in progress. // Stop the load in progress.
void Stop(); void Stop();
......
...@@ -115,7 +115,12 @@ bool RenderFrameProxyHost::OnMessageReceived(const IPC::Message& msg) { ...@@ -115,7 +115,12 @@ bool RenderFrameProxyHost::OnMessageReceived(const IPC::Message& msg) {
if (render_frame_host_.get()) if (render_frame_host_.get())
return render_frame_host_->OnMessageReceived(msg); return render_frame_host_->OnMessageReceived(msg);
return false; bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderFrameProxyHost, msg)
IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
} }
bool RenderFrameProxyHost::InitRenderFrameProxy() { bool RenderFrameProxyHost::InitRenderFrameProxy() {
...@@ -149,4 +154,9 @@ void RenderFrameProxyHost::DisownOpener() { ...@@ -149,4 +154,9 @@ void RenderFrameProxyHost::DisownOpener() {
Send(new FrameMsg_DisownOpener(GetRoutingID())); Send(new FrameMsg_DisownOpener(GetRoutingID()));
} }
void RenderFrameProxyHost::OnOpenURL(
const FrameHostMsg_OpenURL_Params& params) {
frame_tree_node_->current_frame_host()->OpenURL(params);
}
} // namespace content } // namespace content
...@@ -107,6 +107,9 @@ class RenderFrameProxyHost ...@@ -107,6 +107,9 @@ class RenderFrameProxyHost
void DisownOpener(); void DisownOpener();
private: private:
// IPC Message handlers.
void OnOpenURL(const FrameHostMsg_OpenURL_Params& params);
// This RenderFrameProxyHost's routing id. // This RenderFrameProxyHost's routing id.
int routing_id_; int routing_id_;
......
...@@ -299,6 +299,78 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_CrossSiteIframe) { ...@@ -299,6 +299,78 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_CrossSiteIframe) {
proxy_to_parent->cross_process_frame_connector()->get_view_for_testing()); proxy_to_parent->cross_process_frame_connector()->get_view_for_testing());
} }
// It fails on ChromeOS and Android, so disabled while investigating.
// http://crbug.com/399775
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
#define MAYBE_NavigateRemoteFrame DISABLED_NavigateRemoteFrame
#else
#define MAYBE_NavigateRemoteFrame NavigateRemoteFrame
#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, MAYBE_NavigateRemoteFrame) {
host_resolver()->AddRule("*", "127.0.0.1");
ASSERT_TRUE(test_server()->Start());
GURL main_url(test_server()->GetURL("files/site_per_process_main.html"));
NavigateToURL(shell(), main_url);
// It is safe to obtain the root frame tree node here, as it doesn't change.
FrameTreeNode* root =
static_cast<WebContentsImpl*>(shell()->web_contents())->
GetFrameTree()->root();
SitePerProcessWebContentsObserver observer(shell()->web_contents());
// Load same-site page into iframe.
FrameTreeNode* child = root->child_at(0);
GURL http_url(test_server()->GetURL("files/title1.html"));
NavigateFrameToURL(child, http_url);
EXPECT_EQ(http_url, observer.navigation_url());
EXPECT_TRUE(observer.navigation_succeeded());
// These must stay in scope with replace_host.
GURL::Replacements replace_host;
std::string foo_com("foo.com");
// Load cross-site page into iframe.
GURL cross_site_url(test_server()->GetURL("files/title2.html"));
replace_host.SetHostStr(foo_com);
cross_site_url = cross_site_url.ReplaceComponents(replace_host);
NavigateFrameToURL(root->child_at(0), cross_site_url);
EXPECT_EQ(cross_site_url, observer.navigation_url());
EXPECT_TRUE(observer.navigation_succeeded());
// Ensure that we have created a new process for the subframe.
ASSERT_EQ(1U, root->child_count());
SiteInstance* site_instance = child->current_frame_host()->GetSiteInstance();
EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site_instance);
// Emulate the main frame changing the src of the iframe such that it
// navigates cross-site.
cross_site_url = test_server()->GetURL("files/title3.html");
std::string bar_com("bar.com");
replace_host.SetHostStr(bar_com);
cross_site_url = cross_site_url.ReplaceComponents(replace_host);
NavigateIframeToURL(shell(), cross_site_url, "test");
EXPECT_EQ(cross_site_url, observer.navigation_url());
EXPECT_TRUE(observer.navigation_succeeded());
// Check again that a new process is created and is different from the
// top level one and the previous one.
ASSERT_EQ(1U, root->child_count());
child = root->child_at(0);
EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
child->current_frame_host()->GetSiteInstance());
EXPECT_NE(site_instance,
child->current_frame_host()->GetSiteInstance());
// TODO(japhet): This currently causes an assertion in the renderer process.
// Enable when the assertion is fixed.
//NavigateFrameToURL(child, http_url);
//EXPECT_EQ(http_url, observer.navigation_url());
//EXPECT_TRUE(observer.navigation_succeeded());
//EXPECT_EQ(shell()->web_contents()->GetSiteInstance(),
// child->current_frame_host()->GetSiteInstance());
}
// Crash a subframe and ensures its children are cleared from the FrameTree. // Crash a subframe and ensures its children are cleared from the FrameTree.
// See http://crbug.com/338508. // See http://crbug.com/338508.
// TODO(creis): Disabled for flakiness; see http://crbug.com/405582. // TODO(creis): Disabled for flakiness; see http://crbug.com/405582.
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h" #include "content/renderer/render_view_impl.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "third_party/WebKit/public/web/WebView.h" #include "third_party/WebKit/public/web/WebView.h"
namespace content { namespace content {
...@@ -278,4 +279,19 @@ void RenderFrameProxy::initializeChildFrame( ...@@ -278,4 +279,19 @@ void RenderFrameProxy::initializeChildFrame(
routing_id_, frame_rect, scale_factor)); routing_id_, frame_rect, scale_factor));
} }
void RenderFrameProxy::navigate(const blink::WebURLRequest& request,
bool should_replace_current_entry) {
FrameHostMsg_OpenURL_Params params;
params.url = request.url();
params.referrer = Referrer(
GURL(request.httpHeaderField(blink::WebString::fromUTF8("Referer"))),
request.referrerPolicy());
params.disposition = CURRENT_TAB;
params.should_replace_current_entry = should_replace_current_entry;
params.user_gesture =
blink::WebUserGestureIndicator::isProcessingUserGesture();
blink::WebUserGestureIndicator::consumeUserGesture();
Send(new FrameHostMsg_OpenURL(routing_id_, params));
}
} // namespace } // namespace
...@@ -102,6 +102,8 @@ class CONTENT_EXPORT RenderFrameProxy ...@@ -102,6 +102,8 @@ class CONTENT_EXPORT RenderFrameProxy
virtual void initializeChildFrame( virtual void initializeChildFrame(
const blink::WebRect& frame_rect, const blink::WebRect& frame_rect,
float scale_factor); float scale_factor);
virtual void navigate(const blink::WebURLRequest& request,
bool should_replace_current_entry);
private: private:
RenderFrameProxy(int routing_id, int frame_routing_id); RenderFrameProxy(int routing_id, int frame_routing_id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment