diff options
author | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-30 00:41:44 +0000 |
---|---|---|
committer | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-30 00:41:44 +0000 |
commit | 16e923d415597f97b567c5d3870ad4d489c3e31b (patch) | |
tree | 4daa203932464fb01cf4bdb116d6fd596eacdd96 | |
parent | bcf09fc7ff33c6bd4058f515baa5ab3133f355ec (diff) | |
download | chromium_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
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(); |