Commit 798da054 authored by tburkard@chromium.org's avatar tburkard@chromium.org

Enable resource prefetch from the browser process.

R=jam@chromium.org, jochen@chromium.org, jschuh@chromium.org

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277761 0039d316-1c4b-4281-b951-d872f2087c98
parent 0299de34
...@@ -4,15 +4,23 @@ ...@@ -4,15 +4,23 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/common/prefetch_messages.h"
#include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h" #include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_job.h"
using content::BrowserThread;
namespace { namespace {
...@@ -27,13 +35,11 @@ class PrefetchBrowserTestBase : public InProcessBrowserTest { ...@@ -27,13 +35,11 @@ class PrefetchBrowserTestBase : public InProcessBrowserTest {
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
if (do_prefetch_field_trial_) { if (do_prefetch_field_trial_) {
command_line->AppendSwitchASCII( command_line->AppendSwitchASCII(switches::kForceFieldTrials,
switches::kForceFieldTrials, "Prefetch/ExperimentYes/");
"Prefetch/ExperimentYes/");
} else { } else {
command_line->AppendSwitchASCII( command_line->AppendSwitchASCII(switches::kForceFieldTrials,
switches::kForceFieldTrials, "Prefetch/ExperimentNo/");
"Prefetch/ExperimentNo/");
} }
} }
...@@ -84,6 +90,50 @@ class PrefetchBrowserTestPredictionOffExpOff : public PrefetchBrowserTestBase { ...@@ -84,6 +90,50 @@ class PrefetchBrowserTestPredictionOffExpOff : public PrefetchBrowserTestBase {
: PrefetchBrowserTestBase(false, false) {} : PrefetchBrowserTestBase(false, false) {}
}; };
// URLRequestJob (and associated handler) which hangs.
class HangingURLRequestJob : public net::URLRequestJob {
public:
HangingURLRequestJob(net::URLRequest* request,
net::NetworkDelegate* network_delegate)
: net::URLRequestJob(request, network_delegate) {}
// net::URLRequestJob implementation
virtual void Start() OVERRIDE {}
private:
virtual ~HangingURLRequestJob() {}
DISALLOW_COPY_AND_ASSIGN(HangingURLRequestJob);
};
class HangingRequestInterceptor : public net::URLRequestInterceptor {
public:
explicit HangingRequestInterceptor(const base::Closure& callback)
: callback_(callback) {}
virtual ~HangingRequestInterceptor() {}
virtual net::URLRequestJob* MaybeInterceptRequest(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const OVERRIDE {
if (!callback_.is_null())
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback_);
return new HangingURLRequestJob(request, network_delegate);
}
private:
base::Closure callback_;
};
void CreateHangingRequestInterceptorOnIO(const GURL& url,
base::Closure callback) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
scoped_ptr<net::URLRequestInterceptor> never_respond_handler(
new HangingRequestInterceptor(callback));
net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
url, never_respond_handler.Pass());
}
// Privacy option is on, experiment is on. Prefetch should succeed. // Privacy option is on, experiment is on. Prefetch should succeed.
IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, PredOnExpOn) { IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, PredOnExpOn) {
EXPECT_TRUE(RunPrefetchExperiment(true, browser())); EXPECT_TRUE(RunPrefetchExperiment(true, browser()));
...@@ -118,5 +168,25 @@ IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, IncognitoTest) { ...@@ -118,5 +168,25 @@ IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, IncognitoTest) {
EXPECT_TRUE(RunPrefetchExperiment(true, incognito_browser)); EXPECT_TRUE(RunPrefetchExperiment(true, incognito_browser));
} }
} // namespace // This test will verify the following:
// - that prefetches from the browser are actually launched
// - if a prefetch is in progress, but the originating renderer is destroyed,
// that the pending prefetch request is cleaned up cleanly and does not
// result in a crash.
IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn,
PrefetchFromBrowser) {
const GURL kHangingUrl("http://hanging-url.com");
base::RunLoop loop_;
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&CreateHangingRequestInterceptorOnIO,
kHangingUrl,
loop_.QuitClosure()));
ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
content::RenderFrameHost* rfh =
browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
rfh->Send(new PrefetchMsg_Prefetch(rfh->GetRoutingID(), kHangingUrl));
loop_.Run();
}
} // namespace
...@@ -212,6 +212,8 @@ ...@@ -212,6 +212,8 @@
'renderer/plugins/chrome_plugin_placeholder.h', 'renderer/plugins/chrome_plugin_placeholder.h',
'renderer/plugins/plugin_uma.cc', 'renderer/plugins/plugin_uma.cc',
'renderer/plugins/plugin_uma.h', 'renderer/plugins/plugin_uma.h',
'renderer/prefetch_helper.cc',
'renderer/prefetch_helper.h',
'renderer/prerender/prerender_dispatcher.cc', 'renderer/prerender/prerender_dispatcher.cc',
'renderer/prerender/prerender_dispatcher.h', 'renderer/prerender/prerender_dispatcher.h',
'renderer/prerender/prerender_extra_data.cc', 'renderer/prerender/prerender_extra_data.cc',
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/common/cast_messages.h" #include "chrome/common/cast_messages.h"
#include "chrome/common/chrome_utility_messages.h" #include "chrome/common/chrome_utility_messages.h"
#include "chrome/common/extensions/chrome_extension_messages.h" #include "chrome/common/extensions/chrome_extension_messages.h"
#include "chrome/common/prefetch_messages.h"
#include "chrome/common/prerender_messages.h" #include "chrome/common/prerender_messages.h"
#include "chrome/common/render_messages.h" #include "chrome/common/render_messages.h"
#include "chrome/common/safe_browsing/safebrowsing_messages.h" #include "chrome/common/safe_browsing/safebrowsing_messages.h"
......
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Multiply-included message file, no traditional include guard.
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
#include "url/gurl.h"
#define IPC_MESSAGE_START PrefetchMsgStart
// Prefetch Messages
// These are messages sent from the browser to the renderer related to
// prefetching.
// Instructs the renderer to launch a prefetch within its context.
IPC_MESSAGE_ROUTED1(PrefetchMsg_Prefetch,
GURL /* url */)
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "chrome/renderer/playback_extension.h" #include "chrome/renderer/playback_extension.h"
#include "chrome/renderer/plugins/chrome_plugin_placeholder.h" #include "chrome/renderer/plugins/chrome_plugin_placeholder.h"
#include "chrome/renderer/plugins/plugin_uma.h" #include "chrome/renderer/plugins/plugin_uma.h"
#include "chrome/renderer/prefetch_helper.h"
#include "chrome/renderer/prerender/prerender_dispatcher.h" #include "chrome/renderer/prerender/prerender_dispatcher.h"
#include "chrome/renderer/prerender/prerender_helper.h" #include "chrome/renderer/prerender/prerender_helper.h"
#include "chrome/renderer/prerender/prerender_media_load_deferrer.h" #include "chrome/renderer/prerender/prerender_media_load_deferrer.h"
...@@ -423,7 +424,9 @@ void ChromeContentRendererClient::RenderFrameCreated( ...@@ -423,7 +424,9 @@ void ChromeContentRendererClient::RenderFrameCreated(
if (render_frame->GetRenderView()->GetMainRenderFrame() == render_frame) { if (render_frame->GetRenderView()->GetMainRenderFrame() == render_frame) {
// Only attach NetErrorHelper to the main frame, since only the main frame // Only attach NetErrorHelper to the main frame, since only the main frame
// should get error pages. // should get error pages.
// PrefetchHelper is also needed only for main frames.
new NetErrorHelper(render_frame); new NetErrorHelper(render_frame);
new prefetch::PrefetchHelper(render_frame);
} }
} }
......
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/renderer/prefetch_helper.h"
#include "chrome/common/prefetch_messages.h"
#include "content/public/renderer/render_frame.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebURLLoaderOptions.h"
namespace prefetch {
PrefetchHelper::PrefetchHelper(content::RenderFrame* render_frame)
: content::RenderFrameObserver(render_frame) {
}
PrefetchHelper::~PrefetchHelper() {
STLDeleteElements(&loader_set_);
}
bool PrefetchHelper::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PrefetchHelper, message)
IPC_MESSAGE_HANDLER(PrefetchMsg_Prefetch, OnPrefetch)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void PrefetchHelper::OnPrefetch(const GURL& url) {
blink::WebFrame* frame = render_frame()->GetWebFrame();
blink::WebURLRequest request(url);
request.setTargetType(blink::WebURLRequest::TargetIsPrefetch);
request.setPriority(blink::WebURLRequest::PriorityVeryLow);
blink::WebURLLoaderOptions options;
options.allowCredentials = true;
options.crossOriginRequestPolicy =
blink::WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
blink::WebURLLoader* loader = frame->createAssociatedURLLoader(options);
loader->loadAsynchronously(request, this);
loader_set_.insert(loader);
}
void PrefetchHelper::didFinishLoading(blink::WebURLLoader* loader,
double finishTime,
int64_t totalEncodedDataLength) {
loader_set_.erase(loader);
}
void PrefetchHelper::didFail(blink::WebURLLoader* loader,
const blink::WebURLError& error) {
loader_set_.erase(loader);
}
} // namespace prefetch
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_RENDERER_PREFETCH_HELPER_H_
#define CHROME_RENDERER_PREFETCH_HELPER_H_
#include <set>
#include "content/public/renderer/render_frame_observer.h"
#include "third_party/WebKit/public/platform/WebURLLoader.h"
#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
#include "url/gurl.h"
namespace prefetch {
// Helper class initiating prefetches on behalf of a RenderFrame.
class PrefetchHelper : public content::RenderFrameObserver,
public blink::WebURLLoaderClient {
public:
explicit PrefetchHelper(content::RenderFrame* render_frame);
virtual ~PrefetchHelper();
// blink::WebURLLoaderClient implementation
virtual void didFinishLoading(blink::WebURLLoader* loader,
double finishTime,
int64_t totalEncodedDataLength) OVERRIDE;
virtual void didFail(blink::WebURLLoader* loader,
const blink::WebURLError& error) OVERRIDE;
private:
// RenderViewObserver implementation
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
void OnPrefetch(const GURL& url);
std::set<blink::WebURLLoader*> loader_set_;
DISALLOW_COPY_AND_ASSIGN(PrefetchHelper);
};
} // namespace prefetch
#endif // CHROME_RENDERER_PREFETCH_HELPER_H_
...@@ -66,6 +66,7 @@ enum IPCMessageStart { ...@@ -66,6 +66,7 @@ enum IPCMessageStart {
GamepadMsgStart, GamepadMsgStart,
ShellMsgStart, ShellMsgStart,
AccessibilityMsgStart, AccessibilityMsgStart,
PrefetchMsgStart,
PrerenderMsgStart, PrerenderMsgStart,
ChromotingMsgStart, ChromotingMsgStart,
OldBrowserPluginMsgStart, OldBrowserPluginMsgStart,
......
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