diff options
author | gavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-11 23:58:40 +0000 |
---|---|---|
committer | gavinp@chromium.org <gavinp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-11 23:58:40 +0000 |
commit | 1ee57dd7a917d447692f9c69f570811d01400176 (patch) | |
tree | ecf68326f905e07dbd54d86a5d1231a029965406 | |
parent | 2421f95d69bae09623de1febafb834712de99347 (diff) | |
download | chromium_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.cc | 37 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_link_manager.h | 4 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_message_filter.cc | 5 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_message_filter.h | 3 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_unittest.cc | 56 | ||||
-rw-r--r-- | chrome/chrome_common.gypi | 1 | ||||
-rw-r--r-- | chrome/common/prerender_messages.h | 7 | ||||
-rw-r--r-- | chrome/common/prerender_types.h | 19 | ||||
-rw-r--r-- | chrome/renderer/prerender/prerender_dispatcher.cc | 7 |
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())); |