diff options
-rw-r--r-- | chrome/browser/prerender/prerender_browsertest.cc | 22 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_contents.cc | 21 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_contents.h | 2 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_final_status.cc | 1 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_final_status.h | 1 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_histograms.cc | 9 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_histograms.h | 4 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_manager.cc | 68 | ||||
-rw-r--r-- | chrome/browser/prerender/prerender_manager.h | 4 |
9 files changed, 103 insertions, 29 deletions
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 62035ec..be115b1 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc @@ -127,7 +127,8 @@ class TestPrerenderContents : public PrerenderContents { should_be_shown_(expected_final_status == FINAL_STATUS_USED), quit_message_loop_on_destruction_( expected_final_status != FINAL_STATUS_EVICTED && - expected_final_status != FINAL_STATUS_APP_TERMINATING), + expected_final_status != FINAL_STATUS_APP_TERMINATING && + expected_final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY), expected_pending_prerenders_(0) { if (expected_number_of_loads == 0) MessageLoopForUI::current()->Quit(); @@ -303,11 +304,11 @@ class WaitForLoadPrerenderContentsFactory : public PrerenderContents::Factory { const GURL& referrer, Origin origin, uint8 experiment_id) OVERRIDE { - CHECK(!expected_final_status_queue_.empty()) << - "Creating prerender contents for " << url.path() << - " with no expected final status"; - FinalStatus expected_final_status = expected_final_status_queue_.front(); - expected_final_status_queue_.pop_front(); + FinalStatus expected_final_status = FINAL_STATUS_MATCH_COMPLETE_DUMMY; + if (!expected_final_status_queue_.empty()) { + expected_final_status = expected_final_status_queue_.front(); + expected_final_status_queue_.pop_front(); + } VLOG(1) << "Creating prerender contents for " << url.path() << " with expected final status " << expected_final_status; VLOG(1) << expected_final_status_queue_.size() << " left in the queue."; @@ -723,8 +724,10 @@ class PrerenderBrowserTest : public InProcessBrowserTest { } } else { // In the failure case, we should have removed |dest_url_| from the - // prerender_manager. - EXPECT_TRUE(prerender_contents == NULL); + // prerender_manager. We ignore dummy PrerenderContents (as indicated + // by not having started). + EXPECT_TRUE(prerender_contents == NULL || + !prerender_contents->prerendering_has_started()); } } @@ -1837,7 +1840,8 @@ IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, // Validate that the sessionStorage namespace remains the same when swapping // in a prerendered page. -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorage) { +// http://crbug.com/103563 +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DISABLED_PrerenderSessionStorage) { set_loader_path("files/prerender/prerender_loader_with_session_storage.html"); PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"), FINAL_STATUS_USED, diff --git a/chrome/browser/prerender/prerender_contents.cc b/chrome/browser/prerender/prerender_contents.cc index 44efdc7..c4b67322 100644 --- a/chrome/browser/prerender/prerender_contents.cc +++ b/chrome/browser/prerender/prerender_contents.cc @@ -349,11 +349,14 @@ bool PrerenderContents::GetRouteId(int* route_id) const { void PrerenderContents::set_final_status(FinalStatus final_status) { DCHECK(final_status >= FINAL_STATUS_USED && final_status < FINAL_STATUS_MAX); DCHECK(final_status_ == FINAL_STATUS_MAX || - final_status_ == FINAL_STATUS_CONTROL_GROUP); - - // Don't override final_status_ if it's FINAL_STATUS_CONTROL_GROUP, - // otherwise data will be collected in the Prerender.FinalStatus histogram. - if (final_status_ == FINAL_STATUS_CONTROL_GROUP) + final_status_ == FINAL_STATUS_CONTROL_GROUP || + final_status_ == FINAL_STATUS_MATCH_COMPLETE_DUMMY); + + // Don't override final_status_ if it's FINAL_STATUS_CONTROL_GROUP or + // FINAL_STATUS_MATCH_COMPLETE_DUMMY, otherwise data will be collected + // in the Prerender.FinalStatus histogram. + if (final_status_ == FINAL_STATUS_CONTROL_GROUP || + final_status_ == FINAL_STATUS_MATCH_COMPLETE_DUMMY) return; final_status_ = final_status; @@ -363,11 +366,13 @@ PrerenderContents::~PrerenderContents() { DCHECK(final_status_ != FINAL_STATUS_MAX); DCHECK(prerendering_has_been_cancelled_ || final_status_ == FINAL_STATUS_USED || - final_status_ == FINAL_STATUS_CONTROL_GROUP); + final_status_ == FINAL_STATUS_CONTROL_GROUP || + final_status_ == FINAL_STATUS_MATCH_COMPLETE_DUMMY); DCHECK(origin_ != ORIGIN_MAX); // If we haven't even started prerendering, we were just in the control - // group, which means we do not want to record the status. + // group (or a match complete dummy), which means we do not want to record + // the status. if (prerendering_has_started()) prerender_manager_->RecordFinalStatus(origin_, experiment_id_, final_status_); @@ -579,7 +584,7 @@ void PrerenderContents::Destroy(FinalStatus final_status) { prerendering_has_been_cancelled_ = true; // This has to be done after setting the final status, as it adds the // prerender to the history. - prerender_manager_->MoveEntryToPendingDelete(this); + prerender_manager_->MoveEntryToPendingDelete(this, final_status); // We may destroy the PrerenderContents before we have initialized the // RenderViewHost. Otherwise set the Observer's PrerenderContents to NULL to diff --git a/chrome/browser/prerender/prerender_contents.h b/chrome/browser/prerender/prerender_contents.h index 10cb239..3c26e30 100644 --- a/chrome/browser/prerender/prerender_contents.h +++ b/chrome/browser/prerender/prerender_contents.h @@ -106,6 +106,7 @@ class PrerenderContents : public content::NotificationObserver, int32 page_id() const { return page_id_; } GURL icon_url() const { return icon_url_; } const GURL& prerender_url() const { return prerender_url_; } + const GURL& referrer() const { return referrer_; } bool has_stopped_loading() const { return has_stopped_loading_; } bool prerendering_has_started() const { return prerendering_has_started_; } @@ -124,6 +125,7 @@ class PrerenderContents : public content::NotificationObserver, FinalStatus final_status() const { return final_status_; } Origin origin() const { return origin_; } + uint8 experiment_id() const { return experiment_id_; } base::TimeTicks load_start_time() const { return load_start_time_; } diff --git a/chrome/browser/prerender/prerender_final_status.cc b/chrome/browser/prerender/prerender_final_status.cc index ba8892e..9e2e6da 100644 --- a/chrome/browser/prerender/prerender_final_status.cc +++ b/chrome/browser/prerender/prerender_final_status.cc @@ -49,6 +49,7 @@ const char* kFinalStatusNames[] = { "DevTools Attached To The Tab", "Session Storage Namespace Mismatch", "No Use Group", + "Match Complete Dummy", "Max", }; COMPILE_ASSERT(arraysize(kFinalStatusNames) == FINAL_STATUS_MAX + 1, diff --git a/chrome/browser/prerender/prerender_final_status.h b/chrome/browser/prerender/prerender_final_status.h index 1b3abe2..769e274 100644 --- a/chrome/browser/prerender/prerender_final_status.h +++ b/chrome/browser/prerender/prerender_final_status.h @@ -50,6 +50,7 @@ enum FinalStatus { FINAL_STATUS_DEVTOOLS_ATTACHED = 35, FINAL_STATUS_SESSION_STORAGE_NAMESPACE_MISMATCH = 36, FINAL_STATUS_NO_USE_GROUP = 37, + FINAL_STATUS_MATCH_COMPLETE_DUMMY = 38, FINAL_STATUS_MAX, }; diff --git a/chrome/browser/prerender/prerender_histograms.cc b/chrome/browser/prerender/prerender_histograms.cc index 09d08c3..dfbb583 100644 --- a/chrome/browser/prerender/prerender_histograms.cc +++ b/chrome/browser/prerender/prerender_histograms.cc @@ -165,7 +165,7 @@ base::TimeTicks PrerenderHistograms::GetCurrentTimeTicks() const { void PrerenderHistograms::RecordPerceivedPageLoadTime( base::TimeDelta perceived_page_load_time, bool was_prerender, - const GURL& url) { + bool was_complete_prerender, const GURL& url) { if (!IsWebURL(url)) return; bool within_window = WithinWindow(); @@ -173,8 +173,11 @@ void PrerenderHistograms::RecordPerceivedPageLoadTime( RECORD_PLT("PerceivedPLT", perceived_page_load_time); if (within_window) RECORD_PLT("PerceivedPLTWindowed", perceived_page_load_time); - if (was_prerender) { - RECORD_PLT("PerceivedPLTMatched", perceived_page_load_time); + if (was_prerender || was_complete_prerender) { + if (was_prerender) + RECORD_PLT("PerceivedPLTMatched", perceived_page_load_time); + if (was_complete_prerender) + RECORD_PLT("PerceivedPLTMatchedComplete", perceived_page_load_time); seen_any_pageload_ = true; seen_pageload_started_after_prerender_ = true; } else if (within_window) { diff --git a/chrome/browser/prerender/prerender_histograms.h b/chrome/browser/prerender/prerender_histograms.h index cca9692..53c9df1 100644 --- a/chrome/browser/prerender/prerender_histograms.h +++ b/chrome/browser/prerender/prerender_histograms.h @@ -31,7 +31,9 @@ class PrerenderHistograms { // when the user navigates to a page to when it finishes loading. The actual // load may have started prior to navigation due to prerender hints. void RecordPerceivedPageLoadTime(base::TimeDelta perceived_page_load_time, - bool was_prerender, const GURL& url); + bool was_prerender, + bool was_complete_prerender, + const GURL& url); // Records the time from when a page starts prerendering to when the user // navigates to it. This must be called on the UI thread. diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc index a2e07b41..a9e8777 100644 --- a/chrome/browser/prerender/prerender_manager.cc +++ b/chrome/browser/prerender/prerender_manager.cc @@ -77,6 +77,24 @@ const char* const kValidHttpMethods[] = { // Length of prerender history, for display in chrome://net-internals const int kHistoryLength = 100; +// Indicates whether a Prerender has been cancelled such that we need +// a dummy replacement for the purpose of recording the correct PPLT for +// the Match Complete case. + +bool NeedMatchCompleteDummyForFinalStatus(FinalStatus final_status) { + return final_status != FINAL_STATUS_USED && + final_status != FINAL_STATUS_TIMED_OUT && + final_status != FINAL_STATUS_EVICTED && + final_status != FINAL_STATUS_MANAGER_SHUTDOWN && + final_status != FINAL_STATUS_APP_TERMINATING && + final_status != FINAL_STATUS_RENDERER_CRASHED && + final_status != FINAL_STATUS_WINDOW_OPENER && + final_status != FINAL_STATUS_FRAGMENT_MISMATCH && + final_status != FINAL_STATUS_CACHE_OR_HISTORY_CLEARED && + final_status != FINAL_STATUS_CANCELLED && + final_status != FINAL_STATUS_MATCH_COMPLETE_DUMMY; +} + } // namespace class PrerenderManager::OnCloseTabContentsDeleter : public TabContentsDelegate { @@ -130,6 +148,11 @@ bool PrerenderManager::IsPrerenderingPossible() { } // static +bool PrerenderManager::ActuallyPrerendering() { + return IsPrerenderingPossible() && !IsControlGroup(); +} + +// static bool PrerenderManager::IsControlGroup() { return GetMode() == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP; } @@ -655,14 +678,46 @@ bool PrerenderManager::MaybeUsePrerenderedPage(TabContents* tab_contents, return true; } -void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry) { +void PrerenderManager::MoveEntryToPendingDelete(PrerenderContents* entry, + FinalStatus final_status) { DCHECK(CalledOnValidThread()); + DCHECK(entry); DCHECK(!IsPendingDelete(entry)); + for (std::list<PrerenderContentsData>::iterator it = prerender_list_.begin(); it != prerender_list_.end(); ++it) { if (it->contents_ == entry) { - prerender_list_.erase(it); + bool swapped_in_dummy_replacement = false; + + // If this PrerenderContents is being deleted due to a cancellation, + // we need to create a dummy replacement for PPLT accounting purposes + // for the Match Complete group. + // This is the case if the cancellation is for any reason that would not + // occur in the control group case. + if (NeedMatchCompleteDummyForFinalStatus(final_status)) { + // TODO(tburkard): I'd like to DCHECK that we are actually prerendering. + // However, what if new conditions are added and + // NeedMatchCompleteDummyForFinalStatus, is not being updated. Not sure + // what's the best thing to do here. For now, I will just check whether + // we are actually prerendering. + if (ActuallyPrerendering()) { + PrerenderContents* dummy_replacement_prerender_contents = + CreatePrerenderContents( + entry->prerender_url(), + entry->referrer(), + entry->origin(), + entry->experiment_id()); + if (dummy_replacement_prerender_contents && + dummy_replacement_prerender_contents->Init()) { + it->contents_ = dummy_replacement_prerender_contents; + it->contents_->set_final_status(FINAL_STATUS_MATCH_COMPLETE_DUMMY); + swapped_in_dummy_replacement = true; + } + } + } + if (!swapped_in_dummy_replacement) + prerender_list_.erase(it); break; } } @@ -734,12 +789,11 @@ void PrerenderManager::RecordPerceivedPageLoadTime( if (!prerender_manager->is_enabled()) return; bool was_prerender = - ((mode_ == PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP && - prerender_manager->WouldTabContentsBePrerendered(tab_contents)) || - (mode_ == PRERENDER_MODE_EXPERIMENT_PRERENDER_GROUP && - prerender_manager->IsTabContentsPrerendered(tab_contents))); + prerender_manager->IsTabContentsPrerendered(tab_contents); + bool was_complete_prerender = was_prerender || + prerender_manager->WouldTabContentsBePrerendered(tab_contents); prerender_manager->histograms_->RecordPerceivedPageLoadTime( - perceived_page_load_time, was_prerender, url); + perceived_page_load_time, was_prerender, was_complete_prerender, url); } bool PrerenderManager::is_enabled() const { diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h index 1343958..87adfe6 100644 --- a/chrome/browser/prerender/prerender_manager.h +++ b/chrome/browser/prerender/prerender_manager.h @@ -128,7 +128,8 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, // Moves a PrerenderContents to the pending delete list from the list of // active prerenders when prerendering should be cancelled. - void MoveEntryToPendingDelete(PrerenderContents* entry); + void MoveEntryToPendingDelete(PrerenderContents* entry, + FinalStatus final_status); // Records the perceived page load time for a page - effectively the time from // when the user navigates to a page to when it finishes loading. The actual @@ -152,6 +153,7 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>, static PrerenderManagerMode GetMode(); static void SetMode(PrerenderManagerMode mode); static bool IsPrerenderingPossible(); + static bool ActuallyPrerendering(); static bool IsControlGroup(); static bool IsNoUseGroup(); |