summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-30 00:41:44 +0000
committermmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-30 00:41:44 +0000
commit16e923d415597f97b567c5d3870ad4d489c3e31b (patch)
tree4daa203932464fb01cf4bdb116d6fd596eacdd96
parentbcf09fc7ff33c6bd4058f515baa5ab3133f355ec (diff)
downloadchromium_src-16e923d415597f97b567c5d3870ad4d489c3e31b.zip
chromium_src-16e923d415597f97b567c5d3870ad4d489c3e31b.tar.gz
chromium_src-16e923d415597f97b567c5d3870ad4d489c3e31b.tar.bz2
Remove most prerendering code/references from content.
The only place where prerendering code remains in content is in ResourceDispatcherHost. As NavigationState can no longer be used to track prerendering histogram information, the prerendering renderer-side histograms have been reworked (And renamed) as well. The histogram intended to track use of prerendering RenderViews has been removed, as histograms are not recorded when a RenderView is destroyed. BUG=77090 TEST=Compiles, existing PrerenderBrowserTests, grep Review URL: http://codereview.chromium.org/6900026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83642 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/prerender/prerender_contents.cc6
-rw-r--r--chrome/browser/prerender/prerender_manager.cc16
-rw-r--r--chrome/chrome_renderer.gypi2
-rw-r--r--chrome/common/render_messages.h11
-rw-r--r--chrome/renderer/blocked_plugin.cc22
-rw-r--r--chrome/renderer/blocked_plugin.h3
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc3
-rw-r--r--chrome/renderer/chrome_render_view_observer.cc11
-rw-r--r--chrome/renderer/chrome_render_view_observer.h1
-rw-r--r--chrome/renderer/page_load_histograms.cc72
-rw-r--r--chrome/renderer/page_load_histograms.h2
-rw-r--r--chrome/renderer/prerender/prerender_helper.cc164
-rw-r--r--chrome/renderer/prerender/prerender_helper.h70
-rw-r--r--content/browser/tab_contents/tab_contents.h7
-rw-r--r--content/common/view_messages.h11
-rw-r--r--content/renderer/navigation_state.cc40
-rw-r--r--content/renderer/navigation_state.h27
-rw-r--r--content/renderer/render_view.cc58
-rw-r--r--content/renderer/render_view.h5
-rw-r--r--content/renderer/render_view_observer.h4
20 files changed, 313 insertions, 222 deletions
diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc
index 1b092e0..c2dbe9e 100644
--- a/chrome/browser/prerender/prerender_contents.cc
+++ b/chrome/browser/prerender/prerender_contents.cc
@@ -171,6 +171,9 @@ void PrerenderContents::StartPrerendering(
DCHECK(load_start_time_.is_null());
load_start_time_ = base::TimeTicks::Now();
+ render_view_host_->Send(
+ new ViewMsg_SetIsPrerendering(render_view_host_->routing_id(), true));
+
ViewMsg_Navigate_Params params;
params.page_id = -1;
params.pending_history_list_offset = -1;
@@ -178,8 +181,9 @@ void PrerenderContents::StartPrerendering(
params.current_history_list_length = 0;
params.url = prerender_url_;
params.transition = PageTransition::LINK;
- params.navigation_type = ViewMsg_Navigate_Type::PRERENDER;
+ params.navigation_type = ViewMsg_Navigate_Type::NORMAL;
params.referrer = referrer_;
+ params.request_time = base::Time::Now();
render_view_host_->Navigate(params);
}
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index 2b80186..ec6ed62 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -12,6 +12,7 @@
#include "chrome/browser/prerender/prerender_contents.h"
#include "chrome/browser/prerender/prerender_final_status.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/render_messages.h"
#include "content/browser/browser_thread.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_process_host.h"
@@ -19,7 +20,6 @@
#include "content/browser/tab_contents/render_view_host_manager.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_service.h"
-#include "content/common/view_messages.h"
#include "googleurl/src/url_parse.h"
#include "googleurl/src/url_canon.h"
#include "googleurl/src/url_util.h"
@@ -370,7 +370,7 @@ bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tab_contents,
render_view_host->WasRestored();
prerender_contents->set_render_view_host(NULL);
render_view_host->Send(
- new ViewMsg_DisplayPrerenderedPage(render_view_host->routing_id()));
+ new ViewMsg_SetIsPrerendering(render_view_host->routing_id(), false));
tab_contents->SwapInRenderViewHost(render_view_host);
MarkTabContentsAsPrerendered(tab_contents);
@@ -393,16 +393,18 @@ bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tab_contents,
Source<std::pair<int, int> >(&child_route_pair),
NotificationService::NoDetails());
+ RenderViewHostDelegate* render_view_host_delegate =
+ static_cast<RenderViewHostDelegate*>(tab_contents);
ViewHostMsg_FrameNavigate_Params* params =
prerender_contents->navigate_params();
if (params != NULL)
- tab_contents->DidNavigate(render_view_host, *params);
+ render_view_host_delegate->DidNavigate(render_view_host, *params);
string16 title = prerender_contents->title();
if (!title.empty()) {
- tab_contents->UpdateTitle(render_view_host,
- prerender_contents->page_id(),
- UTF16ToWideHack(title));
+ render_view_host_delegate->UpdateTitle(render_view_host,
+ prerender_contents->page_id(),
+ UTF16ToWideHack(title));
}
GURL icon_url = prerender_contents->icon_url();
@@ -415,7 +417,7 @@ bool PrerenderManager::MaybeUsePreloadedPage(TabContents* tab_contents,
}
if (prerender_contents->has_stopped_loading())
- tab_contents->DidStopLoading();
+ render_view_host_delegate->DidStopLoading();
return true;
}
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index 42696c0..043e487 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -120,6 +120,8 @@
'renderer/page_click_tracker.h',
'renderer/page_load_histograms.cc',
'renderer/page_load_histograms.h',
+ 'renderer/prerender/prerender_helper.cc',
+ 'renderer/prerender/prerender_helper.h',
'renderer/print_web_view_helper.cc',
'renderer/print_web_view_helper.h',
'renderer/print_web_view_helper_linux.cc',
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index f046876..68c547c 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -261,6 +261,12 @@ IPC_MESSAGE_ROUTED4(ViewMsg_TranslatePage,
IPC_MESSAGE_ROUTED1(ViewMsg_RevertTranslation,
int /* page id */)
+// Tells a renderer if it's currently being prerendered. Must only be set
+// to true before any navigation occurs, and only set to false at most once
+// after that.
+IPC_MESSAGE_ROUTED1(ViewMsg_SetIsPrerendering,
+ bool /* whether the RenderView is prerendering */)
+
// Sent on process startup to indicate whether this process is running in
// incognito mode.
IPC_MESSAGE_CONTROL1(ViewMsg_SetIsIncognitoProcess,
@@ -420,6 +426,11 @@ IPC_MESSAGE_ROUTED4(ViewHostMsg_PageTranslated,
std::string /* the translated language */,
TranslateErrors::Type /* the error type if available */)
+// Message sent from the renderer to the browser to notify it of events which
+// may lead to the cancellation of a prerender. The message is sent only when
+// the renderer is prerendering.
+IPC_MESSAGE_ROUTED0(ViewHostMsg_MaybeCancelPrerenderForHTML5Media)
+
// Suggest results -----------------------------------------------------------
IPC_MESSAGE_ROUTED3(ViewHostMsg_SetSuggestions,
diff --git a/chrome/renderer/blocked_plugin.cc b/chrome/renderer/blocked_plugin.cc
index 6917f21..a1a1897 100644
--- a/chrome/renderer/blocked_plugin.cc
+++ b/chrome/renderer/blocked_plugin.cc
@@ -150,11 +150,11 @@ bool BlockedPlugin::OnMessageReceived(const IPC::Message& message) {
gLastActiveMenu == this) {
ViewMsg_CustomContextMenuAction::Dispatch(
&message, this, this, &BlockedPlugin::OnMenuItemSelected);
- } else if (message.type() == ViewMsg_LoadBlockedPlugins::ID) {
- LoadPlugin();
- } else if (message.type() == ViewMsg_DisplayPrerenderedPage::ID) {
- if (is_blocked_for_prerendering_)
- LoadPlugin();
+ } else {
+ IPC_BEGIN_MESSAGE_MAP(BlockedPlugin, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_LoadBlockedPlugins, OnLoadBlockedPlugins)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetIsPrerendering, OnSetIsPrerendering)
+ IPC_END_MESSAGE_MAP()
}
return false;
@@ -170,6 +170,18 @@ void BlockedPlugin::OnMenuItemSelected(
}
}
+void BlockedPlugin::OnLoadBlockedPlugins() {
+ LoadPlugin();
+}
+
+void BlockedPlugin::OnSetIsPrerendering(bool is_prerendering) {
+ // Prerendering can only be enabled prior to a RenderView's first navigation,
+ // so no BlockedPlugin should see the notification that enables prerendering.
+ DCHECK(!is_prerendering);
+ if (!is_prerendering)
+ LoadPlugin();
+}
+
void BlockedPlugin::LoadPlugin() {
CHECK(plugin_);
// This is not strictly necessary but is an important defense in case the
diff --git a/chrome/renderer/blocked_plugin.h b/chrome/renderer/blocked_plugin.h
index 93bf00a..bfd62ac 100644
--- a/chrome/renderer/blocked_plugin.h
+++ b/chrome/renderer/blocked_plugin.h
@@ -54,6 +54,9 @@ class BlockedPlugin : public RenderViewObserver,
const webkit_glue::CustomContextMenuContext& /* ignored */,
unsigned id);
+ void OnLoadBlockedPlugins();
+ void OnSetIsPrerendering(bool is_prerendering);
+
// Load the blocked plugin.
void LoadPlugin();
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 4b4f974..3a7d5ae 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -45,6 +45,7 @@
#include "chrome/renderer/net/renderer_net_predictor.h"
#include "chrome/renderer/page_click_tracker.h"
#include "chrome/renderer/page_load_histograms.h"
+#include "chrome/renderer/prerender/prerender_helper.h"
#include "chrome/renderer/print_web_view_helper.h"
#include "chrome/renderer/renderer_histogram_snapshots.h"
#include "chrome/renderer/safe_browsing/malware_dom_details.h"
@@ -306,7 +307,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin(
plugin_setting == CONTENT_SETTING_ALLOW ||
host_setting == CONTENT_SETTING_ALLOW) {
// Delay loading plugins if prerendering.
- if (render_view->is_prerendering()) {
+ if (prerender::PrerenderHelper::IsPrerendering(render_view)) {
return CreatePluginPlaceholder(
render_view, frame, params, *group, IDR_CLICK_TO_PLAY_PLUGIN_HTML,
IDS_PLUGIN_LOAD, true, true);
diff --git a/chrome/renderer/chrome_render_view_observer.cc b/chrome/renderer/chrome_render_view_observer.cc
index 12b9a60..58951fd 100644
--- a/chrome/renderer/chrome_render_view_observer.cc
+++ b/chrome/renderer/chrome_render_view_observer.cc
@@ -15,6 +15,7 @@
#include "chrome/renderer/about_handler.h"
#include "chrome/renderer/automation/dom_automation_controller.h"
#include "chrome/renderer/external_host_bindings.h"
+#include "chrome/renderer/prerender/prerender_helper.h"
#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
#include "chrome/renderer/translate_helper.h"
#include "content/common/bindings_policy.h"
@@ -150,6 +151,7 @@ bool ChromeRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
// Filter only.
IPC_BEGIN_MESSAGE_MAP(ChromeRenderViewObserver, message)
IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetIsPrerendering, OnSetIsPrerendering);
IPC_END_MESSAGE_MAP()
return handled;
@@ -287,6 +289,15 @@ void ChromeRenderViewObserver::OnNavigate(
AboutHandler::MaybeHandle(params.url);
}
+void ChromeRenderViewObserver::OnSetIsPrerendering(bool is_prerendering) {
+ if (is_prerendering) {
+ DCHECK(!prerender::PrerenderHelper::Get(render_view()));
+ // The PrerenderHelper will destroy itself either after recording histograms
+ // or on destruction of the RenderView.
+ new prerender::PrerenderHelper(render_view());
+ }
+}
+
void ChromeRenderViewObserver::DidStopLoading() {
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
diff --git a/chrome/renderer/chrome_render_view_observer.h b/chrome/renderer/chrome_render_view_observer.h
index 11ddff7..35ca8e9 100644
--- a/chrome/renderer/chrome_render_view_observer.h
+++ b/chrome/renderer/chrome_render_view_observer.h
@@ -74,6 +74,7 @@ class ChromeRenderViewObserver : public RenderViewObserver,
void OnDownloadFavicon(int id, const GURL& image_url, int image_size);
void OnEnableViewSourceMode();
void OnNavigate(const ViewMsg_Navigate_Params& params);
+ void OnSetIsPrerendering(bool is_prerendering);
// Captures the thumbnail and text contents for indexing for the given load
// ID. If the view's load ID is different than the parameter, this call is
diff --git a/chrome/renderer/page_load_histograms.cc b/chrome/renderer/page_load_histograms.cc
index 32a75e2..3ae1498 100644
--- a/chrome/renderer/page_load_histograms.cc
+++ b/chrome/renderer/page_load_histograms.cc
@@ -10,6 +10,7 @@
#include "base/time.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/extensions/url_pattern.h"
+#include "chrome/renderer/prerender/prerender_helper.h"
#include "chrome/renderer/renderer_histogram_snapshots.h"
#include "content/common/view_messages.h"
#include "content/renderer/navigation_state.h"
@@ -33,60 +34,6 @@ static const size_t kPLTCount(100);
#define PLT_HISTOGRAM(name, sample) \
UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, kPLTMin, kPLTMax, kPLTCount);
-namespace {
-
-// Histograms to determine prerendering's impact on perceived PLT.
-void UpdatePrerenderHistograms(NavigationState* navigation_state,
- const Time& finish_all_loads,
- const TimeDelta& begin_to_finish_all_loads) {
- // Load time for non-prerendered pages.
- static bool use_prerender_histogram =
- base::FieldTrialList::Find("Prefetch") &&
- !base::FieldTrialList::Find("Prefetch")->group_name().empty();
- if (!navigation_state->was_started_as_prerender()) {
- if (use_prerender_histogram) {
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.PerceivedLoadTime", "Prefetch"),
- begin_to_finish_all_loads);
- }
- return;
- }
-
- // Do not record stats for redirected prerendered pages.
- if (navigation_state->was_prerender_redirected())
- return;
-
- // Histogram for usage rate of prerendered pages.
- Time prerendered_page_display =
- navigation_state->prerendered_page_display_time();
- UMA_HISTOGRAM_ENUMERATION("PLT.PageUsed_PrerenderLoad",
- prerendered_page_display.is_null() ? 0 : 1, 2);
- if (prerendered_page_display.is_null())
- return;
-
- // Histograms for perceived load time of prerendered pages.
- Time prerendered_page_start =
- navigation_state->prerendered_page_start_time();
- PLT_HISTOGRAM("PLT.TimeUntilDisplay_PrerenderLoad",
- prerendered_page_display - prerendered_page_start);
- TimeDelta perceived_load_time = finish_all_loads - prerendered_page_display;
- if (perceived_load_time < TimeDelta::FromSeconds(0)) {
- PLT_HISTOGRAM("PLT.PrerenderIdleTime_PrerenderLoad", -perceived_load_time);
- perceived_load_time = TimeDelta::FromSeconds(0);
- }
- PLT_HISTOGRAM("PLT.PerceivedLoadTime_PrerenderLoad", perceived_load_time);
- if (use_prerender_histogram) {
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.PerceivedLoadTime_PrerenderLoad", "Prefetch"),
- perceived_load_time);
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.PerceivedLoadTime", "Prefetch"),
- perceived_load_time);
- }
-}
-
-} // namespace
-
// Returns the scheme type of the given URL if its type is one for which we
// dump page load histograms. Otherwise returns NULL.
static URLPattern::SchemeMasks GetSupportedSchemeType(const GURL& url) {
@@ -134,7 +81,8 @@ enum AbandonType {
};
PageLoadHistograms::PageLoadHistograms(
- RenderView* render_view, RendererHistogramSnapshots* histogram_snapshots)
+ RenderView* render_view,
+ RendererHistogramSnapshots* histogram_snapshots)
: RenderViewObserver(render_view),
cross_origin_access_count_(0),
same_origin_access_count_(0),
@@ -317,19 +265,10 @@ void PageLoadHistograms::Dump(WebFrame* frame) {
PLT_HISTOGRAM("PLT.BeginToFinish_LinkLoadCacheOnly",
begin_to_finish_all_loads);
break;
- case NavigationState::PRERENDER_LOAD:
- PLT_HISTOGRAM("PLT.BeginToFinishDoc_PrerenderLoad",
- begin_to_finish_doc);
- PLT_HISTOGRAM("PLT.BeginToFinish_PrerenderLoad",
- begin_to_finish_all_loads);
- break;
default:
break;
}
- UpdatePrerenderHistograms(navigation_state, finish_all_loads,
- begin_to_finish_all_loads);
-
// Histograms to determine if DNS prefetching has an impact on PLT.
static bool use_dns_histogram(base::FieldTrialList::Find("DnsImpact") &&
!base::FieldTrialList::Find("DnsImpact")->group_name().empty());
@@ -840,6 +779,11 @@ void PageLoadHistograms::Dump(WebFrame* frame) {
// Log the PLT to the info log.
LogPageLoadTime(navigation_state, frame->dataSource());
+ // Record prerendering histograms.
+ prerender::PrerenderHelper::RecordHistograms(render_view(),
+ finish_all_loads,
+ begin_to_finish_all_loads);
+
// Since there are currently no guarantees that renderer histograms will be
// sent to the browser, we initiate a PostTask here to be sure that we send
// the histograms we generated. Without this call, pages that don't have an
diff --git a/chrome/renderer/page_load_histograms.h b/chrome/renderer/page_load_histograms.h
index 35cf1df..e28a068 100644
--- a/chrome/renderer/page_load_histograms.h
+++ b/chrome/renderer/page_load_histograms.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
diff --git a/chrome/renderer/prerender/prerender_helper.cc b/chrome/renderer/prerender/prerender_helper.cc
new file mode 100644
index 0000000..98457bb
--- /dev/null
+++ b/chrome/renderer/prerender/prerender_helper.cc
@@ -0,0 +1,164 @@
+// Copyright (c) 2011 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/prerender/prerender_helper.h"
+
+#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram.h"
+#include "chrome/common/render_messages.h"
+#include "content/renderer/navigation_state.h"
+#include "content/renderer/render_view.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+
+// Helper macro for histograms.
+#define RECORD_PLT(tag, perceived_page_load_time) { \
+ UMA_HISTOGRAM_CUSTOM_TIMES( \
+ base::FieldTrial::MakeName(std::string("Prerender.") + tag, \
+ "Prefetch"), \
+ perceived_page_load_time, \
+ base::TimeDelta::FromMilliseconds(10), \
+ base::TimeDelta::FromSeconds(60), \
+ 100); \
+ }
+
+namespace prerender {
+
+PrerenderHelper::PrerenderHelper(RenderView* render_view)
+ : RenderViewObserver(render_view),
+ RenderViewObserverTracker<PrerenderHelper>(render_view),
+ is_prerendering_(true) {
+}
+
+PrerenderHelper::~PrerenderHelper() {
+}
+
+// static.
+bool PrerenderHelper::IsPrerendering(RenderView* render_view) {
+ PrerenderHelper* prerender_helper = PrerenderHelper::Get(render_view);
+ return (prerender_helper && prerender_helper->is_prerendering_);
+}
+
+// static.
+void PrerenderHelper::RecordHistograms(
+ RenderView* render_view,
+ const base::Time& finish_all_loads,
+ const base::TimeDelta& begin_to_finish_all_loads) {
+ static bool use_prerender_histogram =
+ base::FieldTrialList::Find("Prefetch") &&
+ !base::FieldTrialList::Find("Prefetch")->group_name().empty();
+ if (!use_prerender_histogram)
+ return;
+
+ PrerenderHelper* prerender_helper = PrerenderHelper::Get(render_view);
+
+ // Load time for non-prerendered pages.
+ if (!prerender_helper) {
+ RECORD_PLT("PerceivedLoadTime", begin_to_finish_all_loads);
+ return;
+ }
+
+ if (!prerender_helper->is_prerendering_ &&
+ !prerender_helper->HasUnrecordedData()) {
+ // If the RenderView has a PrerenderHelper and a histogram is being
+ // recorded, it should either be prerendering or have histogram data that
+ // has yet to be recorded.
+ NOTREACHED();
+ delete prerender_helper;
+ return;
+ }
+
+ // There should be a start time, since the first provisional load should have
+ // occured before recording any histograms.
+ DCHECK(!prerender_helper->prerender_start_time_.is_null());
+
+ // The only case where this should happen is if a page is being redirected
+ // prior to display. No histograms are currently recorded when the renderer
+ // is shutting down, so this point will never be reached in that case.
+ if (prerender_helper->is_prerendering_) {
+ DCHECK(!prerender_helper->HasUnrecordedData());
+ return;
+ }
+
+ // There should be a display time, since HasUnrecordedData() returned true.
+ DCHECK(!prerender_helper->prerender_display_time_.is_null());
+
+ // The RenderView still has a PrerenderHelper and is not currently being
+ // prerendered, so the page was prerendered and then displayed. Record
+ // histograms for the prerender, before deleting the PrerenderHelper.
+ base::Time prerender_display_time =
+ prerender_helper->prerender_display_time_;
+ base::Time prerender_start_time = prerender_helper->prerender_start_time_;
+
+ RECORD_PLT("TimeUntilDisplayed",
+ prerender_display_time - prerender_start_time);
+ base::TimeDelta perceived_load_time = finish_all_loads -
+ prerender_display_time;
+ if (perceived_load_time < base::TimeDelta::FromSeconds(0)) {
+ RECORD_PLT("IdleTime", -perceived_load_time);
+ perceived_load_time = base::TimeDelta::FromSeconds(0);
+ }
+ RECORD_PLT("PerceivedPrerenderLoadTime", perceived_load_time);
+ RECORD_PLT("PerceivedLoadTime", perceived_load_time);
+
+ // Once a prerendered page is displayed and its histograms recorded, it no
+ // longer needs a PrerenderHelper.
+ delete prerender_helper;
+}
+
+void PrerenderHelper::WillCreateMediaPlayer(
+ WebKit::WebFrame* frame,
+ WebKit::WebMediaPlayerClient* client) {
+ if (is_prerendering_) {
+ // Cancel prerendering in the case of HTML5 media, to avoid playing sounds
+ // in the background.
+ Send(new ViewHostMsg_MaybeCancelPrerenderForHTML5Media(
+ render_view()->routing_id()));
+ }
+}
+
+void PrerenderHelper::DidStartProvisionalLoad(WebKit::WebFrame* frame) {
+ // If this is the first provisional load since prerendering started, get its
+ // request time.
+ if (is_prerendering_ && prerender_start_time_.is_null()) {
+ WebKit::WebDataSource* data_source = frame->provisionalDataSource();
+ if (!data_source) {
+ NOTREACHED();
+ return;
+ }
+ NavigationState* navigation_state =
+ NavigationState::FromDataSource(data_source);
+ prerender_start_time_ = navigation_state->request_time();
+ // The first navigation for prerendering RenderViews can only be triggered
+ // from PrerenderContents, so there should be a request_time.
+ DCHECK(!prerender_start_time_.is_null());
+ }
+}
+
+bool PrerenderHelper::OnMessageReceived(
+ const IPC::Message& message) {
+ IPC_BEGIN_MESSAGE_MAP(PrerenderHelper, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetIsPrerendering, OnSetIsPrerendering)
+ IPC_END_MESSAGE_MAP()
+ // Return false on ViewMsg_SetIsPrerendering so other observers can see the
+ // message.
+ return false;
+}
+
+void PrerenderHelper::OnSetIsPrerendering(bool is_prerendering) {
+ // Immediately after construction, |this| may receive the message that
+ // triggered its creation. If so, ignore it.
+ if (is_prerendering)
+ return;
+ DCHECK(!is_prerendering);
+ DCHECK(!HasUnrecordedData());
+
+ is_prerendering_ = false;
+ prerender_display_time_ = base::Time::Now();
+}
+
+bool PrerenderHelper::HasUnrecordedData() const {
+ return !prerender_display_time_.is_null();
+}
+
+} // namespace prerender
diff --git a/chrome/renderer/prerender/prerender_helper.h b/chrome/renderer/prerender/prerender_helper.h
new file mode 100644
index 0000000..0060287
--- /dev/null
+++ b/chrome/renderer/prerender/prerender_helper.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2011 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_PRERENDER_PRERENDER_HELPER_H_
+#define CHROME_RENDERER_PRERENDER_PRERENDER_HELPER_H_
+#pragma once
+
+#include "base/compiler_specific.h"
+#include "base/time.h"
+#include "content/renderer/render_view_observer.h"
+#include "content/renderer/render_view_observer_tracker.h"
+
+namespace prerender {
+
+// Helper class to track whether its RenderView is currently being prerendered.
+// Also records prerendering-related histograms information and cancels
+// prerendering when necessary, based on observed events. Created when
+// prerendering starts and deleted as soon as just after the prerendering
+// histograms have been recorded for a displayed prerendered page. For
+// non-displayed pages, deleted on destruction of the RenderView.
+class PrerenderHelper : public RenderViewObserver,
+ public RenderViewObserverTracker<PrerenderHelper> {
+ public:
+ explicit PrerenderHelper(RenderView* render_view);
+ virtual ~PrerenderHelper();
+
+ // Returns true if |render_view| is currently prerendering.
+ static bool IsPrerendering(RenderView* render_view);
+
+ // Records prerender histograms. These are recorded even for pages that are
+ // not prerendered, for comparison to pages that are.
+ static void RecordHistograms(
+ RenderView* render_view,
+ const base::Time& finish_all_loads,
+ const base::TimeDelta& begin_to_finish_all_loads);
+
+ private:
+ // RenderViewObserver implementation
+ virtual void DidStartProvisionalLoad(WebKit::WebFrame* frame) OVERRIDE;
+ virtual void WillCreateMediaPlayer(
+ WebKit::WebFrame* frame,
+ WebKit::WebMediaPlayerClient* client) OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+ void OnSetIsPrerendering(bool is_prerendering);
+
+ // Returns true if the page is no longer being prerendered, but no histograms
+ // for the prerender have been recorded.
+ bool HasUnrecordedData() const;
+
+ // Tracks whether or not observed RenderView is currently prerendering.
+ bool is_prerendering_;
+
+ // Time when the prerender started.
+ base::Time prerender_start_time_;
+ // Time when the prerendered page was displayed.
+ base::Time prerender_display_time_;
+
+ // Set to true when a prerendered page is displayed to prevent deletion from
+ // when a prerendered page is displayed until after the histograms for the
+ // page load have been recorded.
+ bool has_unrecorded_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrerenderHelper);
+};
+
+} // namespace prerender
+
+#endif // CHROME_RENDERER_PRERENDER_PRERENDER_HELPER_H_
diff --git a/content/browser/tab_contents/tab_contents.h b/content/browser/tab_contents/tab_contents.h
index 3eb3012..3ef1372 100644
--- a/content/browser/tab_contents/tab_contents.h
+++ b/content/browser/tab_contents/tab_contents.h
@@ -47,10 +47,6 @@ namespace history {
class HistoryAddPageArgs;
}
-namespace prerender {
-class PrerenderManager;
-}
-
namespace safe_browsing {
class ClientSideDetectionHost;
}
@@ -637,9 +633,6 @@ class TabContents : public PageNavigator,
// Used to access the CreateHistoryAddPageArgs member function.
friend class ExternalTabContainer;
- // Used to access RVH Delegates.
- friend class prerender::PrerenderManager;
-
// Add all the TabContentObservers.
void AddObservers();
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index f8be887..55a118c 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -127,9 +127,6 @@ struct ViewMsg_Navigate_Type {
// the page's cache policy is ignored and we load from the cache.
RESTORE,
- // Speculatively prerendering the page.
- PRERENDER,
-
// Navigation type not categorized by the other types.
NORMAL
};
@@ -1183,9 +1180,6 @@ IPC_MESSAGE_ROUTED0(ViewMsg_InstallMissingPlugin)
// into a full window).
IPC_MESSAGE_ROUTED0(ViewMsg_DisassociateFromPopupCount)
-// Tells the render view a prerendered page is about to be displayed.
-IPC_MESSAGE_ROUTED0(ViewMsg_DisplayPrerenderedPage)
-
// Messages sent from the renderer to the browser.
@@ -1964,11 +1958,6 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_UpdateInspectorSetting,
std::string, /* key */
std::string /* value */)
-// Message sent from the renderer to the browser to notify it of events which
-// may lead to the cancellation of a prerender. The message is sent only when
-// the renderer is in prerender mode.
-IPC_MESSAGE_ROUTED0(ViewHostMsg_MaybeCancelPrerenderForHTML5Media)
-
// Send back a string to be recorded by UserMetrics.
IPC_MESSAGE_CONTROL1(ViewHostMsg_UserMetricsRecordAction,
std::string /* action */)
diff --git a/content/renderer/navigation_state.cc b/content/renderer/navigation_state.cc
index 9019759..386cf24 100644
--- a/content/renderer/navigation_state.cc
+++ b/content/renderer/navigation_state.cc
@@ -9,25 +9,6 @@
NavigationState::~NavigationState() {}
-const base::Time& NavigationState::prerendered_page_start_time() const {
- return prerendered_page_start_time_;
-}
-
-void NavigationState::set_prerendered_page_start_time(const base::Time& value) {
- DCHECK(prerendered_page_start_time_.is_null());
- start_load_time_ = value;
-}
-
-const base::Time& NavigationState::prerendered_page_display_time() const {
- return prerendered_page_display_time_;
-}
-
-void NavigationState::set_prerendered_page_display_time(
- const base::Time& value) {
- DCHECK(prerendered_page_display_time_.is_null());
- prerendered_page_display_time_ = value;
-}
-
void NavigationState::set_password_form_data(webkit_glue::PasswordForm* data) {
password_form_data_.reset(data);
}
@@ -37,25 +18,6 @@ void NavigationState::set_alt_error_page_fetcher(
alt_error_page_fetcher_.reset(f);
}
-bool NavigationState::was_started_as_prerender() const {
- return was_started_as_prerender_;
-}
-
-void NavigationState::set_was_started_as_prerender(
- bool was_started_as_prerender) {
- DCHECK(!was_started_as_prerender_);
- was_started_as_prerender_ = was_started_as_prerender;
-}
-
-bool NavigationState::was_prerender_redirected() const {
- return was_prerender_redirected_;
-}
-
-void NavigationState::set_was_prerender_redirected(
- bool was_prerender_redirected) {
- was_prerender_redirected_ = was_prerender_redirected;
-}
-
NavigationState::NavigationState(PageTransition::Type transition_type,
const base::Time& request_time,
bool is_content_initiated,
@@ -71,8 +33,6 @@ NavigationState::NavigationState(PageTransition::Type transition_type,
pending_page_id_(pending_page_id),
pending_history_list_offset_(pending_history_list_offset),
use_error_page_(false),
- was_started_as_prerender_(false),
- was_prerender_redirected_(false),
cache_policy_override_set_(false),
cache_policy_override_(WebKit::WebURLRequest::UseProtocolCachePolicy),
http_status_code_(0),
diff --git a/content/renderer/navigation_state.h b/content/renderer/navigation_state.h
index 0656a5e..84e4f7e 100644
--- a/content/renderer/navigation_state.h
+++ b/content/renderer/navigation_state.h
@@ -36,8 +36,6 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
LINK_LOAD_RELOAD, // JS/link directed reload.
LINK_LOAD_CACHE_STALE_OK, // back/forward or encoding change.
LINK_LOAD_CACHE_ONLY, // Allow stale data (avoid doing a re-post)
- PRERENDER_LOAD, // Navigation started as the speculative
- // prendering of a linked page.
kLoadTypeMax // Bounding value for this enum.
};
@@ -150,17 +148,6 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
first_paint_after_load_time_ = value;
}
- // The time that prerendering started. Note that this is preserved against
- // HTML/Javascript redirects, until the page is displayed.
- const base::Time& prerendered_page_start_time() const;
- void set_prerendered_page_start_time(const base::Time& value);
-
- // The time that a prerendered page was displayed. Invalid for
- // non-prerendered pages. Can be either before or after
- // |finish_document_load_time_|.
- const base::Time& prerendered_page_display_time() const;
- void set_prerendered_page_display_time(const base::Time& value);
-
// True iff the histograms for the associated frame have been dumped.
bool load_histograms_recorded() const { return load_histograms_recorded_; }
void set_load_histograms_recorded(bool value) {
@@ -213,15 +200,6 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
use_error_page_ = use_error_page;
}
- // True if a page load started as a prerender. Preserved across redirects.
- bool was_started_as_prerender() const;
- void set_was_started_as_prerender(bool was_started_as_prerender);
-
- // True if there was an HTML/Javascript redirect while a page was still being
- // prerendered.
- bool was_prerender_redirected() const;
- void set_was_prerender_redirected(bool was_prerender_redirected);
-
int http_status_code() const { return http_status_code_; }
void set_http_status_code(int http_status_code) {
http_status_code_ = http_status_code;
@@ -299,8 +277,6 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
base::Time finish_load_time_;
base::Time first_paint_time_;
base::Time first_paint_after_load_time_;
- base::Time prerendered_page_start_time_;
- base::Time prerendered_page_display_time_;
bool load_histograms_recorded_;
bool web_timing_histograms_recorded_;
bool request_committed_;
@@ -315,9 +291,6 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
bool use_error_page_;
- bool was_started_as_prerender_;
- bool was_prerender_redirected_;
-
bool cache_policy_override_set_;
WebKit::WebURLRequest::CachePolicy cache_policy_override_;
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc
index 489ad2b..4dbc188 100644
--- a/content/renderer/render_view.cc
+++ b/content/renderer/render_view.cc
@@ -332,7 +332,6 @@ RenderView::RenderView(RenderThreadBase* render_thread,
navigation_gesture_(NavigationGestureUnknown),
opened_by_user_gesture_(true),
opener_suppressed_(false),
- is_prerendering_(false),
page_id_(-1),
last_page_id_sent_to_browser_(-1),
history_list_offset_(-1),
@@ -629,8 +628,6 @@ bool RenderView::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_UpdateWebPreferences, OnUpdateWebPreferences)
IPC_MESSAGE_HANDLER(ViewMsg_SetAltErrorPageURL, OnSetAltErrorPageURL)
IPC_MESSAGE_HANDLER(ViewMsg_InstallMissingPlugin, OnInstallMissingPlugin)
- IPC_MESSAGE_HANDLER(ViewMsg_DisplayPrerenderedPage,
- OnDisplayPrerenderedPage)
IPC_MESSAGE_HANDLER(ViewMsg_EnumerateDirectoryResponse,
OnEnumerateDirectoryResponse)
IPC_MESSAGE_HANDLER(ViewMsg_RunFileChooserResponse, OnFileChooserResponse)
@@ -780,14 +777,8 @@ void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) {
}
}
- if (navigation_state) {
- if (params.navigation_type != ViewMsg_Navigate_Type::PRERENDER) {
- navigation_state->set_load_type(NavigationState::NORMAL_LOAD);
- } else {
- navigation_state->set_load_type(NavigationState::PRERENDER_LOAD);
- is_prerendering_ = true;
- }
- }
+ if (navigation_state)
+ navigation_state->set_load_type(NavigationState::NORMAL_LOAD);
main_frame->loadRequest(request);
}
@@ -1849,10 +1840,8 @@ WebSharedWorker* RenderView::createSharedWorker(
WebMediaPlayer* RenderView::createMediaPlayer(
WebFrame* frame, WebMediaPlayerClient* client) {
- // If this is a prerendering page, start the cancel of the prerender.
- if (is_prerendering_) {
- Send(new ViewHostMsg_MaybeCancelPrerenderForHTML5Media(routing_id_));
- }
+ FOR_EACH_OBSERVER(
+ RenderViewObserver, observers_, WillCreateMediaPlayer(frame, client));
scoped_ptr<media::MessageLoopFactory> message_loop_factory(
new media::MessageLoopFactoryImpl());
@@ -2219,25 +2208,10 @@ void RenderView::didCreateDataSource(WebFrame* frame, WebDataSource* ds) {
}
}
- state->set_was_started_as_prerender(is_prerendering_);
- if (is_prerendering_ && !frame->parent()) {
- if (content_initiated) {
- NavigationState* old_state =
- NavigationState::FromDataSource(webview()->mainFrame()->dataSource());
- state->set_prerendered_page_start_time(
- old_state->prerendered_page_start_time());
- old_state->set_was_prerender_redirected(true);
- } else if (!state->request_time().is_null()) {
- state->set_prerendered_page_start_time(state->request_time());
- } else {
- state->set_prerendered_page_start_time(state->start_load_time());
- }
- }
+ ds->setExtraData(state);
FOR_EACH_OBSERVER(
RenderViewObserver, observers_, DidCreateDataSource(frame, ds));
-
- ds->setExtraData(state);
}
void RenderView::didStartProvisionalLoad(WebFrame* frame) {
@@ -3463,28 +3437,6 @@ void RenderView::OnInstallMissingPlugin() {
first_default_plugin_->InstallMissingPlugin();
}
-void RenderView::OnDisplayPrerenderedPage() {
- DCHECK(is_prerendering_);
- is_prerendering_ = false;
-
- // Update NavigationState for histograms.
- WebDataSource* ds = webview()->mainFrame()->dataSource();
- NavigationState* navigation_state = NavigationState::FromDataSource(ds);
- navigation_state->set_prerendered_page_display_time(Time::Now());
-
- // If there is a provisional data source, update its NavigationState, too.
- WebDataSource* provisional_ds =
- webview()->mainFrame()->provisionalDataSource();
- if (provisional_ds) {
- NavigationState* provisional_navigation_state =
- NavigationState::FromDataSource(provisional_ds);
- if (provisional_navigation_state) {
- provisional_navigation_state->set_prerendered_page_display_time(
- Time::Now());
- }
- }
-}
-
void RenderView::OnEnumerateDirectoryResponse(
int id,
const std::vector<FilePath>& paths) {
diff --git a/content/renderer/render_view.h b/content/renderer/render_view.h
index 059e681..b99329c 100644
--- a/content/renderer/render_view.h
+++ b/content/renderer/render_view.h
@@ -198,7 +198,6 @@ class RenderView : public RenderWidget,
// May return NULL when the view is closing.
WebKit::WebView* webview() const;
- bool is_prerendering() const { return is_prerendering_; }
int page_id() const { return page_id_; }
PepperPluginDelegateImpl* pepper_delegate() { return &pepper_delegate_; }
@@ -773,7 +772,6 @@ class RenderView : public RenderWidget,
void OnFindReplyAck();
void OnEnableAccessibility();
void OnInstallMissingPlugin();
- void OnDisplayPrerenderedPage();
void OnMediaPlayerActionAt(const gfx::Point& location,
const WebKit::WebMediaPlayerAction& action);
void OnMoveOrResizeStarted();
@@ -964,9 +962,6 @@ class RenderView : public RenderWidget,
// Timer used to delay the updating of nav state (see SyncNavigationState).
base::OneShotTimer<RenderView> nav_state_sync_timer_;
- // True if the RenderView is currently prerendering a page.
- bool is_prerendering_;
-
// Page IDs ------------------------------------------------------------------
//
// Page IDs allow the browser to identify pages in each renderer process for
diff --git a/content/renderer/render_view_observer.h b/content/renderer/render_view_observer.h
index a5c0130..864c4fd 100644
--- a/content/renderer/render_view_observer.h
+++ b/content/renderer/render_view_observer.h
@@ -15,6 +15,7 @@ namespace WebKit {
class WebDataSource;
class WebFrame;
class WebFormElement;
+class WebMediaPlayerClient;
class WebMouseEvent;
class WebNode;
class WebString;
@@ -76,6 +77,9 @@ class RenderViewObserver : public IPC::Channel::Listener,
// These match the RenderView methods.
virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {}
+ virtual void WillCreateMediaPlayer(WebKit::WebFrame* frame,
+ WebKit::WebMediaPlayerClient* client) {}
+
protected:
explicit RenderViewObserver(RenderView* render_view);
virtual ~RenderViewObserver();