summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-11 23:58:40 +0000
committergavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-11 23:58:40 +0000
commit1ee57dd7a917d447692f9c69f570811d01400176 (patch)
treeecf68326f905e07dbd54d86a5d1231a029965406
parent2421f95d69bae09623de1febafb834712de99347 (diff)
downloadchromium_src-1ee57dd7a917d447692f9c69f570811d01400176.zip
chromium_src-1ee57dd7a917d447692f9c69f570811d01400176.tar.gz
chromium_src-1ee57dd7a917d447692f9c69f570811d01400176.tar.bz2
Add <link rel=next> support to prerender.
IEs prerender implementation supports rel=next link elements. Let's also parse them, and based on a field trial launch these as prerenders. R=davidben,tburkard,jochen,jschuh@chromium.org BUG=329963 Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=250280 Review URL: https://codereview.chromium.org/113803003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@250558 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/prerender/prerender_link_manager.cc37
-rw-r--r--chrome/browser/prerender/prerender_link_manager.h4
-rw-r--r--chrome/browser/prerender/prerender_message_filter.cc5
-rw-r--r--chrome/browser/prerender/prerender_message_filter.h3
-rw-r--r--chrome/browser/prerender/prerender_unittest.cc56
-rw-r--r--chrome/chrome_common.gypi1
-rw-r--r--chrome/common/prerender_messages.h7
-rw-r--r--chrome/common/prerender_types.h19
-rw-r--r--chrome/renderer/prerender/prerender_dispatcher.cc7
9 files changed, 117 insertions, 22 deletions
diff --git a/chrome/browser/prerender/prerender_link_manager.cc b/chrome/browser/prerender/prerender_link_manager.cc
index 8213ded..30846b4 100644
--- a/chrome/browser/prerender/prerender_link_manager.cc
+++ b/chrome/browser/prerender/prerender_link_manager.cc
@@ -7,15 +7,18 @@
#include <functional>
#include <limits>
#include <set>
+#include <string>
#include <utility>
#include "base/memory/scoped_ptr.h"
+#include "base/metrics/field_trial.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_handle.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/prerender_messages.h"
+#include "chrome/common/prerender_types.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/session_storage_namespace.h"
@@ -28,8 +31,30 @@ using base::TimeTicks;
using content::RenderViewHost;
using content::SessionStorageNamespace;
+namespace prerender {
+
namespace {
+bool ShouldStartRelNextPrerenders() {
+ const std::string experiment_name =
+ base::FieldTrialList::FindFullName("PrerenderRelNextTrial");
+
+ return experiment_name.find("Yes") != std::string::npos;
+}
+
+bool ShouldStartPrerender(uint32 rel_types) {
+ const bool should_start_rel_next_prerenders =
+ ShouldStartRelNextPrerenders();
+
+ if (rel_types & PrerenderRelTypePrerender) {
+ return true;
+ } else if (should_start_rel_next_prerenders &&
+ (rel_types & PrerenderRelTypeNext) == PrerenderRelTypeNext) {
+ return true;
+ }
+ return false;
+}
+
void Send(int child_id, IPC::Message* raw_message) {
using content::RenderProcessHost;
scoped_ptr<IPC::Message> own_message(raw_message);
@@ -42,8 +67,6 @@ void Send(int child_id, IPC::Message* raw_message) {
} // namespace
-namespace prerender {
-
// Helper class to implement PrerenderContents::Observer and watch prerenders
// which launch other prerenders.
class PrerenderLinkManager::PendingPrerenderManager
@@ -109,6 +132,7 @@ PrerenderLinkManager::~PrerenderLinkManager() {
void PrerenderLinkManager::OnAddPrerender(int launcher_child_id,
int prerender_id,
const GURL& url,
+ uint32 rel_types,
const content::Referrer& referrer,
const gfx::Size& size,
int render_view_route_id) {
@@ -135,7 +159,7 @@ void PrerenderLinkManager::OnAddPrerender(int launcher_child_id,
}
LinkPrerender
- prerender(launcher_child_id, prerender_id, url, referrer, size,
+ prerender(launcher_child_id, prerender_id, url, rel_types, referrer, size,
render_view_route_id, manager_->GetCurrentTimeTicks(),
prerender_contents);
prerenders_.push_back(prerender);
@@ -196,6 +220,7 @@ PrerenderLinkManager::LinkPrerender::LinkPrerender(
int launcher_child_id,
int prerender_id,
const GURL& url,
+ uint32 rel_types,
const content::Referrer& referrer,
const gfx::Size& size,
int render_view_route_id,
@@ -204,6 +229,7 @@ PrerenderLinkManager::LinkPrerender::LinkPrerender(
: launcher_child_id(launcher_child_id),
prerender_id(prerender_id),
url(url),
+ rel_types(rel_types),
referrer(referrer),
size(size),
render_view_route_id(render_view_route_id),
@@ -314,6 +340,11 @@ void PrerenderLinkManager::StartPrerenders() {
}
}
+ if (!ShouldStartPrerender((*i)->rel_types)) {
+ prerenders_.erase(*i);
+ continue;
+ }
+
PrerenderHandle* handle = manager_->AddPrerenderFromLinkRelPrerender(
(*i)->launcher_child_id, (*i)->render_view_route_id,
(*i)->url, (*i)->referrer, (*i)->size);
diff --git a/chrome/browser/prerender/prerender_link_manager.h b/chrome/browser/prerender/prerender_link_manager.h
index ec8dbf6..743765d 100644
--- a/chrome/browser/prerender/prerender_link_manager.h
+++ b/chrome/browser/prerender/prerender_link_manager.h
@@ -47,6 +47,7 @@ class PrerenderLinkManager : public BrowserContextKeyedService,
void OnAddPrerender(int child_id,
int prerender_id,
const GURL& url,
+ uint32 rel_types,
const content::Referrer& referrer,
const gfx::Size& size,
int render_view_route_id);
@@ -75,6 +76,7 @@ class PrerenderLinkManager : public BrowserContextKeyedService,
LinkPrerender(int launcher_child_id,
int prerender_id,
const GURL& url,
+ uint32 rel_types,
const content::Referrer& referrer,
const gfx::Size& size,
int render_view_route_id,
@@ -86,6 +88,7 @@ class PrerenderLinkManager : public BrowserContextKeyedService,
int launcher_child_id;
int prerender_id;
GURL url;
+ uint32 rel_types;
content::Referrer referrer;
gfx::Size size;
int render_view_route_id;
@@ -170,4 +173,3 @@ class PrerenderLinkManager : public BrowserContextKeyedService,
} // namespace prerender
#endif // CHROME_BROWSER_PRERENDER_PRERENDER_LINK_MANAGER_H_
-
diff --git a/chrome/browser/prerender/prerender_message_filter.cc b/chrome/browser/prerender/prerender_message_filter.cc
index 2379b55..4f203bd 100644
--- a/chrome/browser/prerender/prerender_message_filter.cc
+++ b/chrome/browser/prerender/prerender_message_filter.cc
@@ -72,7 +72,7 @@ void PrerenderMessageFilter::OnChannelClosing() {
void PrerenderMessageFilter::OnAddPrerender(
int prerender_id,
- const GURL& url,
+ const PrerenderAttributes& attributes,
const content::Referrer& referrer,
const gfx::Size& size,
int render_view_route_id) {
@@ -83,7 +83,8 @@ void PrerenderMessageFilter::OnAddPrerender(
return;
prerender_link_manager->OnAddPrerender(
render_process_id_, prerender_id,
- url, referrer, size, render_view_route_id);
+ attributes.url, attributes.rel_types, referrer,
+ size, render_view_route_id);
}
void PrerenderMessageFilter::OnCancelPrerender(
diff --git a/chrome/browser/prerender/prerender_message_filter.h b/chrome/browser/prerender/prerender_message_filter.h
index 0d5eb06..a5a7ac6 100644
--- a/chrome/browser/prerender/prerender_message_filter.h
+++ b/chrome/browser/prerender/prerender_message_filter.h
@@ -10,6 +10,7 @@
#include "url/gurl.h"
class Profile;
+struct PrerenderAttributes;
namespace content {
struct Referrer;
@@ -41,7 +42,7 @@ class PrerenderMessageFilter : public content::BrowserMessageFilter {
virtual void OnChannelClosing() OVERRIDE;
void OnAddPrerender(int prerender_id,
- const GURL& url,
+ const PrerenderAttributes& attributes,
const content::Referrer& referrer,
const gfx::Size& size,
int render_view_route_id);
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc
index 8ffb439..055be35 100644
--- a/chrome/browser/prerender/prerender_unittest.cc
+++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_origin.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/prerender_types.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/render_view_host.h"
@@ -84,6 +85,8 @@ int DummyPrerenderContents::g_next_route_id_ = 0;
const gfx::Size kSize(640, 480);
+const uint32 kDefaultRelTypes = PrerenderRelTypePrerender;
+
} // namespace
class UnitTestPrerenderManager : public PrerenderManager {
@@ -376,10 +379,9 @@ class PrerenderTest : public testing::Test {
// true iff the prerender has been added to the PrerenderManager by the
// PrerenderLinkManager and the PrerenderManager returned a handle.
bool AddSimplePrerender(const GURL& url) {
- prerender_link_manager()->OnAddPrerender(kDefaultChildId,
- GetNextPrerenderID(),
- url, content::Referrer(),
- kSize, kDefaultRenderViewRouteId);
+ prerender_link_manager()->OnAddPrerender(
+ kDefaultChildId, GetNextPrerenderID(), url, kDefaultRelTypes,
+ content::Referrer(), kSize, kDefaultRenderViewRouteId);
return LauncherHasRunningPrerender(kDefaultChildId, last_prerender_id());
}
@@ -719,7 +721,7 @@ TEST_F(PrerenderTest, PendingPrerenderTest) {
ORIGIN_GWS_PRERENDER,
FINAL_STATUS_USED);
prerender_link_manager()->OnAddPrerender(
- child_id, GetNextPrerenderID(), pending_url,
+ child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
Referrer(url, blink::WebReferrerPolicyDefault),
kSize, route_id);
EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
@@ -760,7 +762,7 @@ TEST_F(PrerenderTest, InvalidPendingPrerenderTest) {
ORIGIN_GWS_PRERENDER,
FINAL_STATUS_UNSUPPORTED_SCHEME);
prerender_link_manager()->OnAddPrerender(
- child_id, GetNextPrerenderID(), pending_url,
+ child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
Referrer(url, blink::WebReferrerPolicyDefault),
kSize, route_id);
EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
@@ -792,7 +794,7 @@ TEST_F(PrerenderTest, CancelPendingPrerenderTest) {
// Schedule a pending prerender launched from the prerender.
prerender_link_manager()->OnAddPrerender(
- child_id, GetNextPrerenderID(), pending_url,
+ child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
Referrer(url, blink::WebReferrerPolicyDefault),
kSize, route_id);
EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
@@ -831,11 +833,40 @@ TEST_F(PrerenderTest, SourceRenderViewClosed) {
prerender_manager()->CreateNextPrerenderContents(
url,
FINAL_STATUS_MANAGER_SHUTDOWN);
- prerender_link_manager()->OnAddPrerender(100, GetNextPrerenderID(), url,
- Referrer(), kSize, 200);
+ prerender_link_manager()->OnAddPrerender(
+ 100, GetNextPrerenderID(), url, kDefaultRelTypes, Referrer(), kSize, 200);
EXPECT_FALSE(LauncherHasRunningPrerender(100, last_prerender_id()));
}
+// Tests that prerendering doesn't launch rel=next prerenders without the field
+// trial.
+TEST_F(PrerenderTest, NoRelNextByDefault) {
+ GURL url("http://www.google.com/");
+ prerender_manager()->CreateNextPrerenderContents(
+ url, FINAL_STATUS_MANAGER_SHUTDOWN);
+ DummyPrerenderContents* null = NULL;
+
+ prerender_link_manager()->OnAddPrerender(
+ kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
+ Referrer(), kSize, kDefaultRenderViewRouteId);
+ EXPECT_EQ(null, prerender_manager()->FindEntry(url));
+}
+
+// Tests that prerendering does launch rel=next prerenders with the field trial.
+TEST_F(PrerenderTest, RelNextByFieldTrial) {
+ ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("PrerenderRelNextTrial",
+ "Yes"));
+ GURL url("http://www.google.com/");
+ DummyPrerenderContents* prerender_contents =
+ prerender_manager()->CreateNextPrerenderContents(
+ url, FINAL_STATUS_USED);
+
+ prerender_link_manager()->OnAddPrerender(
+ kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
+ Referrer(), kSize, kDefaultRenderViewRouteId);
+ EXPECT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+}
+
// Tests that prerendering is cancelled when we launch a second prerender of
// the same target within a short time interval.
TEST_F(PrerenderTest, RecentlyVisited) {
@@ -1391,10 +1422,9 @@ TEST_F(PrerenderTest, LinkManagerClearOnPendingAbandon) {
ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
GURL pending_url("http://www.neverlaunched.com");
- prerender_link_manager()->OnAddPrerender(child_id,
- GetNextPrerenderID(),
- pending_url, content::Referrer(),
- kSize, route_id);
+ prerender_link_manager()->OnAddPrerender(
+ child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
+ content::Referrer(), kSize, route_id);
const int second_prerender_id = last_prerender_id();
EXPECT_FALSE(IsEmptyPrerenderLinkManager());
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index e6ce973..1f0d3f1 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -327,6 +327,7 @@
'common/pepper_permission_util.h',
'common/pref_names_util.cc',
'common/pref_names_util.h',
+ 'common/prerender_types.h',
'common/print_messages.cc',
'common/print_messages.h',
'common/profiling.cc',
diff --git a/chrome/common/prerender_messages.h b/chrome/common/prerender_messages.h
index 2b0310c..21ce045 100644
--- a/chrome/common/prerender_messages.h
+++ b/chrome/common/prerender_messages.h
@@ -18,11 +18,16 @@
// These are messages sent from the renderer to the browser in
// relation to <link rel=prerender> elements.
+IPC_STRUCT_BEGIN(PrerenderAttributes)
+ IPC_STRUCT_MEMBER(GURL, url)
+ IPC_STRUCT_MEMBER(uint32, rel_types)
+IPC_STRUCT_END()
+
// Notifies of the insertion of a <link rel=prerender> element in the
// document.
IPC_MESSAGE_CONTROL5(PrerenderHostMsg_AddLinkRelPrerender,
int /* prerender_id, assigned by WebPrerendererClient */,
- GURL /* url */,
+ PrerenderAttributes,
content::Referrer,
gfx::Size,
int /* render_view_route_id of launcher */)
diff --git a/chrome/common/prerender_types.h b/chrome/common/prerender_types.h
new file mode 100644
index 0000000..3ed3dd0
--- /dev/null
+++ b/chrome/common/prerender_types.h
@@ -0,0 +1,19 @@
+// Copyright 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_COMMON_PRERENDER_TYPES_H_
+#define CHROME_COMMON_PRERENDER_TYPES_H_
+
+namespace prerender {
+
+// PrerenderRelType is a bitfield since multiple rel attributes can be set
+// on the same link. Must be the same as blink::WebPrerenderRelType.
+enum PrerenderRelType {
+ PrerenderRelTypePrerender = 0x1,
+ PrerenderRelTypeNext = 0x2,
+};
+
+} // namespace prerender
+
+#endif // CHROME_COMMON_PRERENDER_TYPES_H_
diff --git a/chrome/renderer/prerender/prerender_dispatcher.cc b/chrome/renderer/prerender/prerender_dispatcher.cc
index a787a70..31e23cf 100644
--- a/chrome/renderer/prerender/prerender_dispatcher.cc
+++ b/chrome/renderer/prerender/prerender_dispatcher.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "chrome/common/prerender_messages.h"
+#include "chrome/common/prerender_types.h"
#include "chrome/renderer/prerender/prerender_extra_data.h"
#include "content/public/common/referrer.h"
#include "content/public/renderer/render_thread.h"
@@ -117,8 +118,12 @@ void PrerenderDispatcher::add(const WebPrerender& prerender) {
prerenders_[extra_data.prerender_id()] = prerender;
+ PrerenderAttributes attributes;
+ attributes.url = GURL(prerender.url());
+ attributes.rel_types = prerender.relTypes();
+
content::RenderThread::Get()->Send(new PrerenderHostMsg_AddLinkRelPrerender(
- extra_data.prerender_id(), GURL(prerender.url()),
+ extra_data.prerender_id(), attributes,
content::Referrer(GURL(prerender.referrer()),
prerender.referrerPolicy()),
extra_data.size(), extra_data.render_view_route_id()));