15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_local_predictor.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/json/json_reader.h" 1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/json/json_writer.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/field_trial.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/stl_util.h" 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/browser_process.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_database.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_db_task.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service_factory.h" 267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/prerender/prerender_field_trial.h" 27b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/prerender/prerender_handle.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_histograms.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prerender/prerender_manager.h" 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/prerender/prerender_util.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/safe_browsing/database_manager.h" 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/safe_browsing/safe_browsing_service.h" 34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "chrome/common/prefetch_messages.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "content/public/browser/navigation_controller.h" 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "content/public/browser/render_frame_host.h" 406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "content/public/browser/web_contents.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/secure_hash.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h" 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/escape.h" 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "net/base/load_flags.h" 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/url_request/url_fetcher.h" 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/base/page_transition_types.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/url_canon.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using base::DictionaryValue; 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using base::ListValue; 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using base::Value; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing ui::PageTransition; 566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)using content::RenderFrameHost; 57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using content::SessionStorageNamespace; 58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using content::WebContents; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using history::URLID; 6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using net::URLFetcher; 61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using predictors::LoggedInPredictorTable; 62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using std::string; 63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using std::vector; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace prerender { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kURLHashSize = 5; 70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)static const int kNumPrerenderCandidates = 5; 716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)static const int kInvalidProcessId = -1; 726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)static const int kInvalidFrameId = -1; 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static const int kMaxPrefetchItems = 100; 74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 75b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} // namespace 76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 77b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// When considering a candidate URL to be prerendered, we need to collect the 78b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// data in this struct to make the determination whether we should issue the 79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// prerender or not. 80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)struct PrerenderLocalPredictor::LocalPredictorURLInfo { 81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) URLID id; 82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GURL url; 83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool url_lookup_success; 84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool logged_in; 85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool logged_in_lookup_ok; 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool local_history_based; 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool service_whitelist; 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool service_whitelist_lookup_ok; 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool service_whitelist_reported; 90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) double priority; 91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}; 92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// A struct consisting of everything needed for launching a potential prerender 94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// on a navigation: The navigation URL (source) triggering potential prerenders, 95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// and a set of candidate URLs. 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct PrerenderLocalPredictor::CandidatePrerenderInfo { 97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LocalPredictorURLInfo source_url_; 98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) vector<LocalPredictorURLInfo> candidate_urls_; 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<SessionStorageNamespace> session_storage_namespace_; 1006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Render Process ID and Route ID of the page causing the prerender to be 1016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // issued. Needed so that we can cause its renderer to issue prefetches within 1026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // its context. 1036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) int render_process_id_; 1046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) int render_frame_id_; 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<gfx::Size> size_; 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Time start_time_; // used for various time measurements 1076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) explicit CandidatePrerenderInfo(URLID source_id) 1086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) : render_process_id_(kInvalidProcessId), 1096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) render_frame_id_(kInvalidFrameId) { 110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) source_url_.id = source_id; 111b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void MaybeAddCandidateURLFromLocalData(URLID id, double priority) { 113b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LocalPredictorURLInfo info; 114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) info.id = id; 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.local_history_based = true; 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.service_whitelist = false; 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.service_whitelist_lookup_ok = false; 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.service_whitelist_reported = false; 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.priority = priority; 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) MaybeAddCandidateURLInternal(info); 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void MaybeAddCandidateURLFromService(GURL url, double priority, 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool whitelist, 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool whitelist_lookup_ok) { 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LocalPredictorURLInfo info; 12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.id = kint64max; 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.url = url; 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.url_lookup_success = true; 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.local_history_based = false; 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.service_whitelist = whitelist; 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.service_whitelist_lookup_ok = whitelist_lookup_ok; 13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.service_whitelist_reported = true; 133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) info.priority = priority; 13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) MaybeAddCandidateURLInternal(info); 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void MaybeAddCandidateURLInternal(const LocalPredictorURLInfo& info) { 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // TODO(tburkard): clean up this code, potentially using a list or a heap 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int max_candidates = kNumPrerenderCandidates; 13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // We first insert local candidates, then service candidates. 14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Since we want to keep kNumPrerenderCandidates for both local & service 14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // candidates, we need to double the maximum number of candidates once 14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // we start seeing service candidates. 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!info.local_history_based) 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) max_candidates *= 2; 145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) int insert_pos = candidate_urls_.size(); 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (insert_pos < max_candidates) 147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) candidate_urls_.push_back(info); 148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) while (insert_pos > 0 && 149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) candidate_urls_[insert_pos - 1].priority < info.priority) { 15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (insert_pos < max_candidates) 151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) candidate_urls_[insert_pos] = candidate_urls_[insert_pos - 1]; 152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) insert_pos--; 153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (insert_pos < max_candidates) 155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) candidate_urls_[insert_pos] = info; 156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}; 158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define TIMING_HISTOGRAM(name, value) \ 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES(name, value, \ 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeDelta::FromMilliseconds(10), \ 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeDelta::FromSeconds(10), \ 16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 50); 16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task to lookup the URL for a given URLID. 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GetURLForURLIDTask : public history::HistoryDBTask { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 170b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GetURLForURLIDTask( 17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PrerenderLocalPredictor::CandidatePrerenderInfo* request, 172b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const base::Closure& callback) 173b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) : request_(request), 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_(callback), 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_time_(base::Time::Now()) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool RunOnDBThread(history::HistoryBackend* backend, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::HistoryDatabase* db) OVERRIDE { 180b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DoURLLookup(db, &request_->source_url_); 181b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (int i = 0; i < static_cast<int>(request_->candidate_urls_.size()); i++) 182b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DoURLLookup(db, &request_->candidate_urls_[i]); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DoneRunOnMainThread() OVERRIDE { 187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) callback_.Run(); 18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TIMING_HISTOGRAM("Prerender.LocalPredictorURLLookupTime", 18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Time::Now() - start_time_); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~GetURLForURLIDTask() {} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void DoURLLookup(history::HistoryDatabase* db, 196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PrerenderLocalPredictor::LocalPredictorURLInfo* request) { 197b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) history::URLRow url_row; 198b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) request->url_lookup_success = db->GetURLRow(request->id, &url_row); 199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (request->url_lookup_success) 200b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) request->url = url_row.url(); 201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 202b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PrerenderLocalPredictor::CandidatePrerenderInfo* request_; 204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Closure callback_; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time start_time_; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GetURLForURLIDTask); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Task to load history from the visit database on startup. 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GetVisitHistoryTask : public history::HistoryDBTask { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetVisitHistoryTask(PrerenderLocalPredictor* local_predictor, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_visits) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : local_predictor_(local_predictor), 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_visits_(max_visits), 216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) visit_history_(new vector<history::BriefVisitInfo>) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool RunOnDBThread(history::HistoryBackend* backend, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::HistoryDatabase* db) OVERRIDE { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db->GetBriefVisitInfoOfMostRecentVisits(max_visits_, visit_history_.get()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DoneRunOnMainThread() OVERRIDE { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_predictor_->OnGetInitialVisitHistory(visit_history_.Pass()); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~GetVisitHistoryTask() {} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrerenderLocalPredictor* local_predictor_; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_visits_; 234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<vector<history::BriefVisitInfo> > visit_history_; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GetVisitHistoryTask); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum visit history to retrieve from the visit database. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxVisitHistory = 100 * 1000; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Visit history size at which to trigger pruning, and number of items to prune. 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kVisitHistoryPruneThreshold = 120 * 1000; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kVisitHistoryPruneAmount = 20 * 1000; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinLocalPredictionTimeMs = 500; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int GetMaxLocalPredictionTimeMs() { 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return GetLocalPredictorTTLSeconds() * 1000; 2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsBackForward(PageTransition transition) { 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (transition & ui::PAGE_TRANSITION_FORWARD_BACK) != 0; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsHomePage(PageTransition transition) { 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (transition & ui::PAGE_TRANSITION_HOME_PAGE) != 0; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsIntermediateRedirect(PageTransition transition) { 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (transition & ui::PAGE_TRANSITION_CHAIN_END) == 0; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochbool IsFormSubmit(PageTransition transition) { 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ui::PageTransitionCoreTypeIs(transition, 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_FORM_SUBMIT); 26658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch} 26758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShouldExcludeTransitionForPrediction(PageTransition transition) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsBackForward(transition) || IsHomePage(transition) || 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsIntermediateRedirect(transition); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Time GetCurrentTime() { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Time::Now(); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool StringContainsIgnoringCase(string haystack, string needle) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::transform(haystack.begin(), haystack.end(), haystack.begin(), ::tolower); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::transform(needle.begin(), needle.end(), needle.begin(), ::tolower); 280b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return haystack.find(needle) != string::npos; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsExtendedRootURL(const GURL& url) { 284b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const string& path = url.path(); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return path == "/index.html" || path == "/home.html" || 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path == "/main.html" || 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path == "/index.htm" || path == "/home.htm" || path == "/main.htm" || 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path == "/index.php" || path == "/home.php" || path == "/main.php" || 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path == "/index.asp" || path == "/home.asp" || path == "/main.asp" || 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path == "/index.py" || path == "/home.py" || path == "/main.py" || 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path == "/index.pl" || path == "/home.pl" || path == "/main.pl"; 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsRootPageURL(const GURL& url) { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (url.path() == "/" || url.path() == "" || IsExtendedRootURL(url)) && 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!url.has_query()) && (!url.has_ref()); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool IsLogInURL(const GURL& url) { 300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return StringContainsIgnoringCase(url.spec().c_str(), "login") || 301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StringContainsIgnoringCase(url.spec().c_str(), "signin"); 302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool IsLogOutURL(const GURL& url) { 305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return StringContainsIgnoringCase(url.spec().c_str(), "logout") || 306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StringContainsIgnoringCase(url.spec().c_str(), "signout"); 307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 URLHashToInt64(const unsigned char* data) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(kURLHashSize < sizeof(int64), url_hash_must_fit_in_int64); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 value = 0; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&value, data, kURLHashSize); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 GetInt64URLHashForURL(const GURL& url) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(kURLHashSize < sizeof(int64), url_hash_must_fit_in_int64); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<crypto::SecureHash> hash( 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crypto::SecureHash::Create(crypto::SecureHash::SHA256)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 hash_value = 0; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* url_string = url.spec().c_str(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash->Update(url_string, strlen(url_string)); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash->Finish(&hash_value, kURLHashSize); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hash_value; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 327b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool URLsIdenticalIgnoringFragments(const GURL& url1, const GURL& url2) { 3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url::Replacements<char> replacement; 329b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) replacement.ClearRef(); 330b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GURL u1 = url1.ReplaceComponents(replacement); 331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GURL u2 = url2.ReplaceComponents(replacement); 332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return (u1 == u2); 333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void LookupLoggedInStatesOnDBThread( 336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_refptr<LoggedInPredictorTable> logged_in_predictor_table, 33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PrerenderLocalPredictor::CandidatePrerenderInfo* request) { 338b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (int i = 0; i < static_cast<int>(request->candidate_urls_.size()); i++) { 340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PrerenderLocalPredictor::LocalPredictorURLInfo* info = 34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &request->candidate_urls_[i]; 342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (info->url_lookup_success) { 343b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) logged_in_predictor_table->HasUserLoggedIn( 344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) info->url, &info->logged_in, &info->logged_in_lookup_ok); 345b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } else { 346b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) info->logged_in_lookup_ok = false; 347b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 349b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 353b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)struct PrerenderLocalPredictor::PrerenderProperties { 354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PrerenderProperties(URLID url_id, const GURL& url, double priority, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time start_time) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : url_id(url_id), 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url(url), 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority(priority), 359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) start_time(start_time), 360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) would_have_matched(false) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Default constructor for dummy element 3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PrerenderProperties() 365424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : priority(0.0), would_have_matched(false) { 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) double GetCurrentDecayedPriority() { 3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // If we are no longer prerendering, the priority is 0. 3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!prerender_handle || !prerender_handle->IsPrerendering()) 3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return 0.0; 3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int half_life_time_seconds = 3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GetLocalPredictorPrerenderPriorityHalfLifeTimeSeconds(); 3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (half_life_time_seconds < 1) 3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return priority; 3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) double multiple_elapsed = 3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (GetCurrentTime() - actual_start_time).InMillisecondsF() / 3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::TimeDelta::FromSeconds(half_life_time_seconds).InMillisecondsF(); 3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Decay factor: 2 ^ (-multiple_elapsed) 3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) double decay_factor = exp(- multiple_elapsed * log(2.0)); 3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return priority * decay_factor; 3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLID url_id; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double priority; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For expiration purposes, this is a synthetic start time consisting either 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the actual start time, or of the last time the page was re-requested 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for prerendering - 10 seconds (unless the original request came after 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that). This is to emulate the effect of re-prerendering a page that is 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // about to expire, because it was re-requested for prerendering a second 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // time after the actual prerender being kept around. 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time start_time; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The actual time this page was last requested for prerendering. 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time actual_start_time; 3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<PrerenderHandle> prerender_handle; 3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Indicates whether this prerender would have matched a URL navigated to, 3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // but was not swapped in for some reason. 3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool would_have_matched; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A class simulating a set of URLs prefetched, for statistical purposes. 4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class PrerenderLocalPredictor::PrefetchList { 4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) enum SeenType { 4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SEEN_TABCONTENTS_OBSERVER, 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SEEN_HISTORY, 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SEEN_MAX_VALUE 4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }; 4105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PrefetchList() {} 4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ~PrefetchList() { 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) STLDeleteValues(&entries_); 4145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Adds a new URL being prefetched. If the URL is already in the list, 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // nothing will happen. Returns whether a new prefetch was added. 4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool AddURL(const GURL& url) { 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExpireOldItems(); 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) string url_string = url.spec().c_str(); 4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::hash_map<string, ListEntry*>::iterator it = entries_.find(url_string); 4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (it != entries_.end()) { 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If a prefetch previously existed, and has not been seen yet in either 4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // a tab contents or a history, we will not re-issue it. Otherwise, if it 4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // may have been consumed by either tab contents or history, we will 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // permit re-issuing another one. 4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!it->second->seen_history_ && 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !it->second->seen_tabcontents_) { 4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ListEntry* entry = new ListEntry(url_string); 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entries_[entry->url_] = entry; 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry_list_.push_back(entry); 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExpireOldItems(); 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Marks the URL provided as seen in the context specified. Returns true 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // iff the item is currently in the list and had not been seen before in 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the context specified, i.e. the marking was successful. 4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool MarkURLSeen(const GURL& url, SeenType type) { 4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExpireOldItems(); 4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool return_value = false; 4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::hash_map<string, ListEntry*>::iterator it = 4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entries_.find(url.spec().c_str()); 4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (it == entries_.end()) 4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return return_value; 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (type == SEEN_TABCONTENTS_OBSERVER && !it->second->seen_tabcontents_) { 4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) it->second->seen_tabcontents_ = true; 4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return_value = true; 4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (type == SEEN_HISTORY && !it->second->seen_history_) { 4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) it->second->seen_history_ = true; 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return_value = true; 4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the item has been seen in both the history and in tab contents, 45803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // and the page load time has been recorded, erase it from the map to 45903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // make room for new prefetches. 46003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (it->second->seen_tabcontents_ && it->second->seen_history_ && 46103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) it->second->seen_plt_) { 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entries_.erase(url.spec().c_str()); 46303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return return_value; 4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 46703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Marks the PLT for the provided UR as seen. Returns true 46803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // iff the item is currently in the list and the PLT had not been seen 46903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // before, i.e. the sighting was successful. 47003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool MarkPLTSeen(const GURL& url, base::TimeDelta plt) { 47103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ExpireOldItems(); 47203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::hash_map<string, ListEntry*>::iterator it = 47303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) entries_.find(url.spec().c_str()); 47403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (it == entries_.end() || it->second->seen_plt_ || 47503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) it->second->add_time_ > GetCurrentTime() - plt) { 47603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 47703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 47803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) it->second->seen_plt_ = true; 47903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If the item has been seen in both the history and in tab contents, 48003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // and the page load time has been recorded, erase it from the map to 48103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // make room for new prefetches. 48203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (it->second->seen_tabcontents_ && it->second->seen_history_ && 48303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) it->second->seen_plt_) { 48403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) entries_.erase(url.spec().c_str()); 48503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 48603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return true; 48703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 48803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct ListEntry { 4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) explicit ListEntry(const string& url) 4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : url_(url), 4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) add_time_(GetCurrentTime()), 4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) seen_tabcontents_(false), 49503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) seen_history_(false), 49603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) seen_plt_(false) { 4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string url_; 4995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Time add_time_; 5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool seen_tabcontents_; 5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool seen_history_; 50203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool seen_plt_; 5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) }; 5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void ExpireOldItems() { 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Time expiry_cutoff = GetCurrentTime() - 5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeDelta::FromSeconds(GetPrerenderPrefetchListTimeoutSeconds()); 5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while (!entry_list_.empty() && 5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (entry_list_.front()->add_time_ < expiry_cutoff || 5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entries_.size() > kMaxPrefetchItems)) { 5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ListEntry* entry = entry_list_.front(); 5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry_list_.pop_front(); 5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If the entry to be deleted is still the one active in entries_, 5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // we must erase it from entries_. 5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::hash_map<string, ListEntry*>::iterator it = 5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entries_.find(entry->url_); 5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (it != entries_.end() && it->second == entry) 5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entries_.erase(entry->url_); 5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delete entry; 5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::hash_map<string, ListEntry*> entries_; 5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::list<ListEntry*> entry_list_; 5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PrefetchList); 5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrerenderLocalPredictor::PrerenderLocalPredictor( 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrerenderManager* prerender_manager) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : prerender_manager_(prerender_manager), 531b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) is_visit_database_observer_(false), 5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_factory_(this), 5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) prefetch_list_(new PrefetchList()) { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_CONSTRUCTED); 53590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (base::MessageLoop::current()) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Start(FROM_HERE, 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kInitDelayMs), 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &PrerenderLocalPredictor::Init); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_INIT_SCHEDULED); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kChecksumHashSize = 32; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RefCountedStaticMemory* url_whitelist_data = 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceBundle::GetSharedInstance().LoadDataResourceBytes( 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDR_PRERENDER_URL_WHITELIST); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size = url_whitelist_data->size(); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char* front = url_whitelist_data->front(); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size < kChecksumHashSize || 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (size - kChecksumHashSize) % kURLHashSize != 0) { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_URL_WHITELIST_ERROR); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<crypto::SecureHash> hash( 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crypto::SecureHash::Create(crypto::SecureHash::SHA256)); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash->Update(front + kChecksumHashSize, size - kChecksumHashSize); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char hash_value[kChecksumHashSize]; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash->Finish(hash_value, kChecksumHashSize); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (memcmp(hash_value, front, kChecksumHashSize)) { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_URL_WHITELIST_ERROR); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const unsigned char* p = front + kChecksumHashSize; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p < front + size; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += kURLHashSize) { 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_whitelist_.insert(URLHashToInt64(p)); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_URL_WHITELIST_OK); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrerenderLocalPredictor::~PrerenderLocalPredictor() { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shutdown(); 5737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) { 5747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PrerenderProperties* p = issued_prerenders_[i]; 5757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(p != NULL); 5767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (p->prerender_handle) 5777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) p->prerender_handle->OnCancel(); 5787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 57958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) STLDeleteContainerPairPointers( 58058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) outstanding_prerender_service_requests_.begin(), 58158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) outstanding_prerender_service_requests_.end()); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderLocalPredictor::Shutdown() { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Stop(); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_visit_database_observer_) { 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryService* history = GetHistoryIfExists(); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(history); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history->RemoveVisitDatabaseObserver(this); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_visit_database_observer_ = false; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderLocalPredictor::OnAddVisit(const history::BriefVisitInfo& info) { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_ADD_VISIT); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!visit_history_.get()) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_history_->push_back(info); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (static_cast<int>(visit_history_->size()) > kVisitHistoryPruneThreshold) { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_history_->erase(visit_history_->begin(), 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_history_->begin() + kVisitHistoryPruneAmount); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_ADD_VISIT_INITIALIZED); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_prerender_.get() && 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_prerender_->url_id == info.url_id && 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsPrerenderStillValid(current_prerender_.get())) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Prerender.LocalPredictorTimeUntilUsed", 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetCurrentTime() - current_prerender_->actual_start_time, 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 6127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::TimeDelta::FromMilliseconds(GetMaxLocalPredictionTimeMs()), 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_swapped_in_prerender_.reset(current_prerender_.release()); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_ADD_VISIT_PRERENDER_IDENTIFIED); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldExcludeTransitionForPrediction(info.transition)) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Profile* profile = prerender_manager_->profile(); 6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!profile || 6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ShouldDisableLocalPredictorDueToPreferencesAndNetwork(profile)) { 6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_ADD_VISIT_RELEVANT_TRANSITION); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta max_age = 6267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::TimeDelta::FromMilliseconds(GetMaxLocalPredictionTimeMs()); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta min_age = 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kMinLocalPredictionTimeMs); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<URLID> next_urls_currently_found; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<URLID, int> next_urls_num_found; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_occurrences_of_current_visit = 0; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time last_visited; 63358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<CandidatePrerenderInfo> lookup_info( 63458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) new CandidatePrerenderInfo(info.url_id)); 635b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const vector<history::BriefVisitInfo>& visits = *(visit_history_.get()); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < static_cast<int>(visits.size()); i++) { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ShouldExcludeTransitionForPrediction(visits[i].transition)) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visits[i].url_id == info.url_id) { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_visited = visits[i].time; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_occurrences_of_current_visit++; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_urls_currently_found.clear(); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!last_visited.is_null() && 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_visited > visits[i].time - max_age && 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_visited < visits[i].time - min_age) { 64758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch if (!IsFormSubmit(visits[i].transition)) 64858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch next_urls_currently_found.insert(visits[i].url_id); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == static_cast<int>(visits.size()) - 1 || 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visits[i+1].url_id == info.url_id) { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<URLID>::iterator it = next_urls_currently_found.begin(); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != next_urls_currently_found.end(); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::pair<std::map<URLID, int>::iterator, bool> insert_ret = 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_urls_num_found.insert(std::pair<URLID, int>(*it, 0)); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<URLID, int>::iterator num_found_it = insert_ret.first; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_found_it->second++; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (num_occurrences_of_current_visit > 1) { 66558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_ADD_VISIT_RELEVANT_TRANSITION_REPEAT_URL); 66658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 66758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_ADD_VISIT_RELEVANT_TRANSITION_NEW_URL); 66858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 66958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 670b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (std::map<URLID, int>::const_iterator it = next_urls_num_found.begin(); 671b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) it != next_urls_num_found.end(); 672b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ++it) { 673b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Only consider a candidate next page for prerendering if it was viewed 674b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // at least twice, and at least 10% of the time. 675b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (num_occurrences_of_current_visit > 0 && 676b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) it->second > 1 && 677b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) it->second * 10 >= num_occurrences_of_current_visit) { 678b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_ADD_VISIT_IDENTIFIED_PRERENDER_CANDIDATE); 679b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) double priority = static_cast<double>(it->second) / 680b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) static_cast<double>(num_occurrences_of_current_visit); 68158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) lookup_info->MaybeAddCandidateURLFromLocalData(it->first, priority); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 684b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 685b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_START_URL_LOOKUP); 686b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) HistoryService* history = GetHistoryIfExists(); 687b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (history) { 688b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_GOT_HISTORY_ISSUING_LOOKUP); 68958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CandidatePrerenderInfo* lookup_info_ptr = lookup_info.get(); 690b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) history->ScheduleDBTask( 6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<history::HistoryDBTask>( 6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new GetURLForURLIDTask( 6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) lookup_info_ptr, 6945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&PrerenderLocalPredictor::OnLookupURL, 6955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Unretained(this), 6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Passed(&lookup_info)))), 697116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &history_db_tracker_); 698b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 701b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void PrerenderLocalPredictor::OnLookupURL( 70258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<CandidatePrerenderInfo> info) { 70358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 70558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT); 706b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 707b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!info->source_url_.url_lookup_success) { 708b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_FAILED); 709b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return; 710b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 711b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (prefetch_list_->MarkURLSeen(info->source_url_.url, 7135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PrefetchList::SEEN_HISTORY)) { 7145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RecordEvent(EVENT_PREFETCH_LIST_SEEN_HISTORY); 7155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 7165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 71758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (info->candidate_urls_.size() > 0 && 71858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->candidate_urls_[0].url_lookup_success) { 71958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LogCandidateURLStats(info->candidate_urls_[0].url); 72058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 721b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 722b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) WebContents* source_web_contents = NULL; 723a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) bool multiple_source_web_contents_candidates = false; 724b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 725b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#if !defined(OS_ANDROID) 726b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // We need to figure out what tab launched the prerender. We do this by 727b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // comparing URLs. This may not always work: the URL may occur in two 728b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // tabs, and we pick the wrong one, or the tab we should have picked 729b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // may have navigated elsewhere. Hopefully, this doesn't happen too often, 730b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // so we ignore these cases for now. 731b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // TODO(tburkard): Reconsider this, potentially measure it, and fix this 732b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // in the future. 733b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (TabContentsIterator it; !it.done(); it.Next()) { 734b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (it->GetURL() == info->source_url_.url) { 735a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!source_web_contents) 736a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) source_web_contents = *it; 737a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) else 738a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) multiple_source_web_contents_candidates = true; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 741b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif 742b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 743b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!source_web_contents) { 744b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_SOURCE_WEBCONTENTS_FOUND); 745b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return; 746b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 747b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 748a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (multiple_source_web_contents_candidates) 749a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_MULTIPLE_SOURCE_WEBCONTENTS_FOUND); 750a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 75158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->session_storage_namespace_ = 752ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch source_web_contents->GetController().GetDefaultSessionStorageNamespace(); 7536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) RenderFrameHost* rfh = source_web_contents->GetMainFrame(); 7546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) info->render_process_id_ = rfh->GetProcess()->GetID(); 7556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) info->render_frame_id_ = rfh->GetRoutingID(); 756b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 757010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect container_bounds = source_web_contents->GetContainerBounds(); 75858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->size_.reset(new gfx::Size(container_bounds.size())); 75958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 76058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_SUCCESS); 76158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 76258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DoPrerenderServiceCheck(info.Pass()); 76358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 76458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 76558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PrerenderLocalPredictor::DoPrerenderServiceCheck( 76658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<CandidatePrerenderInfo> info) { 76758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 76858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!ShouldQueryPrerenderService(prerender_manager_->profile())) { 76958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_DISABLED); 77058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DoLoggedInLookup(info.Pass()); 77158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 77258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 77358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /* 77458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Create a JSON request. 77558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Here is a sample request: 77658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { "prerender_request": { 77758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "version": 1, 77858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "behavior_id": 6, 77958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "hint_request": { 78058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "browse_history": [ 78158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { "url": "http://www.cnn.com/" 78258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 78358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ] 78458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }, 78558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "candidate_check_request": { 78658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "candidates": [ 78758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { "url": "http://www.cnn.com/sports/" 78858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }, 78958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { "url": "http://www.cnn.com/politics/" 79058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 79158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ] 79258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 79358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 79458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 79558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */ 7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue json_data; 7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* req = new base::DictionaryValue(); 79858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) req->SetInteger("version", 1); 79958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) req->SetInteger("behavior_id", GetPrerenderServiceBehaviorID()); 80058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (ShouldQueryPrerenderServiceForCurrentURL() && 80158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->source_url_.url_lookup_success) { 8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* browse_history = new base::ListValue(); 8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* browse_item = new base::DictionaryValue(); 80458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browse_item->SetString("url", info->source_url_.url.spec()); 80558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) browse_history->Append(browse_item); 8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* hint_request = new base::DictionaryValue(); 80758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) hint_request->Set("browse_history", browse_history); 80858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) req->Set("hint_request", hint_request); 80958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 81058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int num_candidate_urls = 0; 81158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) { 81258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (info->candidate_urls_[i].url_lookup_success) 81358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) num_candidate_urls++; 81458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 81558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (ShouldQueryPrerenderServiceForCandidateURLs() && 81658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) num_candidate_urls > 0) { 8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* candidates = new base::ListValue(); 8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* candidate; 81958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) { 82058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (info->candidate_urls_[i].url_lookup_success) { 8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) candidate = new base::DictionaryValue(); 82258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) candidate->SetString("url", info->candidate_urls_[i].url.spec()); 82358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) candidates->Append(candidate); 82458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 82558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* candidate_check_request = 8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new base::DictionaryValue(); 82858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) candidate_check_request->Set("candidates", candidates); 82958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) req->Set("candidate_check_request", candidate_check_request); 83058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 83158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) json_data.Set("prerender_request", req); 83258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) string request_string; 83358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::JSONWriter::Write(&json_data, &request_string); 83458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GURL fetch_url(GetPrerenderServiceURLPrefix() + 83558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) net::EscapeQueryParamValue(request_string, false)); 83658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) net::URLFetcher* fetcher = net::URLFetcher::Create( 83758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0, 83858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fetch_url, 83958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) URLFetcher::GET, this); 84058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fetcher->SetRequestContext( 84158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) prerender_manager_->profile()->GetRequestContext()); 842d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE | 843d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) net::LOAD_DO_NOT_SAVE_COOKIES | 844d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) net::LOAD_DO_NOT_SEND_COOKIES); 84558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fetcher->AddExtraRequestHeader("Pragma: no-cache"); 84658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->start_time_ = base::Time::Now(); 84758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) outstanding_prerender_service_requests_.insert( 84858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::make_pair(fetcher, info.release())); 84958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 85058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FROM_HERE, 85158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&PrerenderLocalPredictor::MaybeCancelURLFetcher, 85258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_.GetWeakPtr(), fetcher), 85358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeDelta::FromMilliseconds(GetPrerenderServiceFetchTimeoutMs())); 85458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_ISSUED_LOOKUP); 85558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fetcher->Start(); 85658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 85758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 85858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PrerenderLocalPredictor::MaybeCancelURLFetcher(net::URLFetcher* fetcher) { 85958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 86058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) OutstandingFetchers::iterator it = 86158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) outstanding_prerender_service_requests_.find(fetcher); 86258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (it == outstanding_prerender_service_requests_.end()) 86358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 86458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) delete it->first; 86558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<CandidatePrerenderInfo> info(it->second); 86658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) outstanding_prerender_service_requests_.erase(it); 86758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_LOOKUP_TIMED_OUT); 86858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DoLoggedInLookup(info.Pass()); 86958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 87058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 87158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool PrerenderLocalPredictor::ApplyParsedPrerenderServiceResponse( 8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict, 87358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CandidatePrerenderInfo* info, 87458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool* hinting_timed_out, 87558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool* hinting_url_lookup_timed_out, 87658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool* candidate_url_lookup_timed_out) { 87758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) /* 87858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Process the response to the request. 87958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Here is a sample response to illustrate the format. 88058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 88158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "prerender_response": { 88258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "behavior_id": 6, 88358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "hint_response": { 88458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "hinting_timed_out": 0, 88558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "candidates": [ 88658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { "url": "http://www.cnn.com/story-1", 88758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "in_index": 1, 88858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "likelihood": 0.60, 88958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "in_index_timed_out": 0 89058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }, 89158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { "url": "http://www.cnn.com/story-2", 89258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "in_index": 1, 89358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "likelihood": 0.30, 89458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "in_index_timed_out": 0 89558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 89658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ] 89758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }, 89858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "candidate_check_response": { 89958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "candidates": [ 90058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { "url": "http://www.cnn.com/sports/", 90158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "in_index": 1, 90258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "in_index_timed_out": 0 90358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }, 90458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { "url": "http://www.cnn.com/politics/", 90558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "in_index": 0, 90658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "in_index_timed_out": "1" 90758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 90858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ] 90958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 91058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 91158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 91258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */ 9135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ListValue* list = NULL; 91458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int int_value; 91558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!dict->GetInteger("prerender_response.behavior_id", &int_value) || 91658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int_value != GetPrerenderServiceBehaviorID()) { 91758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 91858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 91958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!dict->GetList("prerender_response.candidate_check_response.candidates", 92058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &list)) { 92158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (ShouldQueryPrerenderServiceForCandidateURLs()) { 92258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) { 92358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (info->candidate_urls_[i].url_lookup_success) 92458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 92558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 92658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 92758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 92858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < list->GetSize(); i++) { 9295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* d; 93058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!list->GetDictionary(i, &d)) 93158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 93258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) string url_string; 93358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!d->GetString("url", &url_string) || !GURL(url_string).is_valid()) 93458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 93558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GURL url(url_string); 93658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int in_index_timed_out = 0; 93758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int in_index = 0; 93858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if ((!d->GetInteger("in_index_timed_out", &in_index_timed_out) || 93958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) in_index_timed_out != 1) && 94058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !d->GetInteger("in_index", &in_index)) { 94158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 94258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 94358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (in_index < 0 || in_index > 1 || 94458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) in_index_timed_out < 0 || in_index_timed_out > 1) { 94558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 94658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 94758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (in_index_timed_out == 1) 94858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *candidate_url_lookup_timed_out = true; 94958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t j = 0; j < info->candidate_urls_.size(); j++) { 95058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (info->candidate_urls_[j].url == url) { 95158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->candidate_urls_[j].service_whitelist_reported = true; 95258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->candidate_urls_[j].service_whitelist = (in_index == 1); 95358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->candidate_urls_[j].service_whitelist_lookup_ok = 95458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ((1 - in_index_timed_out) == 1); 95558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 95658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 95758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 95858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (size_t i = 0; i < info->candidate_urls_.size(); i++) { 95958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (info->candidate_urls_[i].url_lookup_success && 96058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !info->candidate_urls_[i].service_whitelist_reported) { 96158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 96258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 96358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 96458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 96558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 96658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (ShouldQueryPrerenderServiceForCurrentURL() && 96758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->source_url_.url_lookup_success) { 96858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) list = NULL; 96958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (dict->GetInteger("prerender_response.hint_response.hinting_timed_out", 97058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &int_value) && 97158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int_value == 1) { 97258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *hinting_timed_out = true; 97358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (!dict->GetList("prerender_response.hint_response.candidates", 97458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &list)) { 97558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 97658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 97758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (int i = 0; i < static_cast<int>(list->GetSize()); i++) { 9785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* d; 97958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!list->GetDictionary(i, &d)) 98058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 98158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) string url; 982116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!d->GetString("url", &url) || !GURL(url).is_valid()) 983116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 98458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) double priority; 985116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!d->GetDouble("likelihood", &priority) || priority < 0.0 || 986116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch priority > 1.0) { 98758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 98858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 98958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int in_index_timed_out = 0; 99058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int in_index = 0; 99158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if ((!d->GetInteger("in_index_timed_out", &in_index_timed_out) || 99258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) in_index_timed_out != 1) && 99358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !d->GetInteger("in_index", &in_index)) { 99458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 99558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 996116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (in_index < 0 || in_index > 1 || in_index_timed_out < 0 || 997116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch in_index_timed_out > 1) { 99858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 99958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 100058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (in_index_timed_out == 1) 100158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *hinting_url_lookup_timed_out = true; 100258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->MaybeAddCandidateURLFromService(GURL(url), 100358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) priority, 100458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) in_index == 1, 1005116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !in_index_timed_out); 100658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 10078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (list->GetSize() > 0) 100803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_RETURNED_HINTING_CANDIDATES); 100958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 101058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1011b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 101258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 101358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 101458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 101558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PrerenderLocalPredictor::OnURLFetchComplete( 101658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const net::URLFetcher* source) { 101758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 101858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_RECEIVED_RESULT); 101958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) net::URLFetcher* fetcher = const_cast<net::URLFetcher*>(source); 102058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) OutstandingFetchers::iterator it = 102158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) outstanding_prerender_service_requests_.find(fetcher); 102258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (it == outstanding_prerender_service_requests_.end()) { 102358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_NO_RECORD_FOR_RESULT); 102458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 102558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 102658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<CandidatePrerenderInfo> info(it->second); 102758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) outstanding_prerender_service_requests_.erase(it); 102858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TIMING_HISTOGRAM("Prerender.LocalPredictorServiceLookupTime", 102958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Time::Now() - info->start_time_); 103058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) string result; 103158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fetcher->GetResponseAsString(&result); 10325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Value> root; 103358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) root.reset(base::JSONReader::Read(result)); 103458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool hinting_timed_out = false; 103558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool hinting_url_lookup_timed_out = false; 103658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool candidate_url_lookup_timed_out = false; 10375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!root.get() || !root->IsType(base::Value::TYPE_DICTIONARY)) { 103858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_PARSE_ERROR_INCORRECT_JSON); 103958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 104058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (ApplyParsedPrerenderServiceResponse( 10415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<base::DictionaryValue*>(root.get()), 104258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info.get(), 104358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &hinting_timed_out, 104458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &hinting_url_lookup_timed_out, 104558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &candidate_url_lookup_timed_out)) { 104658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // We finished parsing the result, and found no errors. 104758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_PARSED_CORRECTLY); 104858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (hinting_timed_out) 104958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_HINTING_TIMED_OUT); 105058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (hinting_url_lookup_timed_out) 105158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_HINTING_URL_LOOKUP_TIMED_OUT); 105258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (candidate_url_lookup_timed_out) 105358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_CANDIDATE_URL_LOOKUP_TIMED_OUT); 105458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DoLoggedInLookup(info.Pass()); 105558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 105658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 105758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 105858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 105958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // If we did not return earlier, an error happened during parsing. 106058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Record this, and proceed. 106158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_SERVICE_PARSE_ERROR); 106258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DoLoggedInLookup(info.Pass()); 106358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 106458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 106558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void PrerenderLocalPredictor:: DoLoggedInLookup( 106658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<CandidatePrerenderInfo> info) { 106758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1068b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_refptr<LoggedInPredictorTable> logged_in_table = 1069b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) prerender_manager_->logged_in_predictor_table(); 1070b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1071b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!logged_in_table.get()) { 1072b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_LOGGED_IN_TABLE_FOUND); 1073b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return; 1074b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 1075b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1076b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_ISSUING_LOGGED_IN_LOOKUP); 1077b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 107858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) info->start_time_ = base::Time::Now(); 107958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 108058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CandidatePrerenderInfo* info_ptr = info.get(); 1081b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) BrowserThread::PostTaskAndReply( 1082b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) BrowserThread::DB, FROM_HERE, 1083b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&LookupLoggedInStatesOnDBThread, 1084b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) logged_in_table, 1085b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) info_ptr), 1086b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Bind(&PrerenderLocalPredictor::ContinuePrerenderCheck, 1087b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) weak_factory_.GetWeakPtr(), 1088b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Passed(&info))); 1089b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1091b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void PrerenderLocalPredictor::LogCandidateURLStats(const GURL& url) const { 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_whitelist_.count(GetInt64URLHashForURL(url)) > 0) { 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsRootPageURL(url)) 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST_ROOT_PAGE); 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsRootPageURL(url)) 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ROOT_PAGE); 10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsExtendedRootURL(url)) 11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_EXTENDED_ROOT_PAGE); 11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsRootPageURL(url) && url.SchemeIs("http")) 11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ROOT_PAGE_HTTP); 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.SchemeIs("http")) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_IS_HTTP); 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.has_query()) 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_HAS_QUERY_STRING); 1107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (IsLogOutURL(url)) 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_CONTAINS_LOGOUT); 1109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (IsLogInURL(url)) 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_CONTAINS_LOGIN); 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderLocalPredictor::OnGetInitialVisitHistory( 1114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<vector<history::BriefVisitInfo> > visit_history) { 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!visit_history_.get()); 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_INIT_SUCCEEDED); 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since the visit history has descending timestamps, we must reverse it. 1119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) visit_history_.reset(new vector<history::BriefVisitInfo>( 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visit_history->rbegin(), visit_history->rend())); 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryService* PrerenderLocalPredictor::GetHistoryIfExists() const { 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = prerender_manager_->profile(); 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HistoryServiceFactory::GetForProfileWithoutCreating(profile); 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderLocalPredictor::Init() { 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_INIT_STARTED); 11338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Profile* profile = prerender_manager_->profile(); 11341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!profile || 11351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ShouldDisableLocalPredictorBasedOnSyncAndConfiguration(profile)) { 11368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) RecordEvent(EVENT_INIT_FAILED_UNENCRYPTED_SYNC_NOT_ENABLED); 11378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 11388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryService* history = GetHistoryIfExists(); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (history) { 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!is_visit_database_observer_); 11425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) history->ScheduleDBTask( 11435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<history::HistoryDBTask>( 11445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new GetVisitHistoryTask(this, kMaxVisitHistory)), 11455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &history_db_tracker_); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history->AddVisitDatabaseObserver(this); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_visit_database_observer_ = true; 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_INIT_FAILED_NO_HISTORY); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderLocalPredictor::OnPLTEventForURL(const GURL& url, 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta page_load_time) { 115503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (prefetch_list_->MarkPLTSeen(url, page_load_time)) { 115603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES("Prerender.LocalPredictorPrefetchMatchPLT", 115703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) page_load_time, 115803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 115903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::TimeDelta::FromSeconds(60), 116003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 100); 116103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 116203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<PrerenderProperties> prerender; 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DoesPrerenderMatchPLTRecord(last_swapped_in_prerender_.get(), 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, page_load_time)) { 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender.reset(last_swapped_in_prerender_.release()); 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DoesPrerenderMatchPLTRecord(current_prerender_.get(), 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, page_load_time)) { 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prerender.reset(current_prerender_.release()); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!prerender.get()) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsPrerenderStillValid(prerender.get())) { 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES("Prerender.SimulatedLocalBrowsingBaselinePLT", 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) page_load_time, 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(60), 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta prerender_age = GetCurrentTime() - prerender->start_time; 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prerender_age > page_load_time) { 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta new_plt; 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prerender_age < 2 * page_load_time) 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_plt = 2 * page_load_time - prerender_age; 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES("Prerender.SimulatedLocalBrowsingPLT", 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_plt, 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(60), 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrerenderLocalPredictor::IsPrerenderStillValid( 1196b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PrerenderLocalPredictor::PrerenderProperties* prerender) const { 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (prerender && 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (prerender->start_time + 11997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::TimeDelta::FromMilliseconds(GetMaxLocalPredictionTimeMs())) 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) > GetCurrentTime()); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrerenderLocalPredictor::RecordEvent( 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrerenderLocalPredictor::Event event) const { 1205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Prerender.LocalPredictorEvent", 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event, PrerenderLocalPredictor::EVENT_MAX_VALUE); 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PrerenderLocalPredictor::DoesPrerenderMatchPLTRecord( 1210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PrerenderProperties* prerender, 1211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const GURL& url, 1212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::TimeDelta plt) const { 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prerender && prerender->start_time < GetCurrentTime() - plt) { 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prerender->url.is_empty()) 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordEvent(EVENT_ERROR_NO_PRERENDER_URL_FOR_PLT); 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (prerender->url == url); 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PrerenderLocalPredictor::PrerenderProperties* 12236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)PrerenderLocalPredictor::GetIssuedPrerenderSlotForPriority(const GURL& url, 12246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) double priority) { 12257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int num_prerenders = GetLocalPredictorMaxConcurrentPrerenders(); 12267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) while (static_cast<int>(issued_prerenders_.size()) < num_prerenders) 12277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) issued_prerenders_.push_back(new PrerenderProperties()); 12286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // First, check if we already have a prerender for the same URL issued. 12296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // If yes, we don't want to prerender this URL again, so we return NULL 12306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // (on matching slot found). 12316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) { 12326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) PrerenderProperties* p = issued_prerenders_[i]; 12336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(p != NULL); 12346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (p->prerender_handle && p->prerender_handle->IsPrerendering() && 12356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) p->prerender_handle->Matches(url, NULL)) { 12366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return NULL; 12376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 12386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 12396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Otherwise, let's see if there are any empty slots. If yes, return the first 12406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // one we find. Otherwise, if the lowest priority prerender has a lower 12416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // priority than the page we want to prerender, use its slot. 12427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PrerenderProperties* lowest_priority_prerender = NULL; 12437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) { 12447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PrerenderProperties* p = issued_prerenders_[i]; 12457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(p != NULL); 12467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!p->prerender_handle || !p->prerender_handle->IsPrerendering()) 12477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return p; 12487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) double decayed_priority = p->GetCurrentDecayedPriority(); 12497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (decayed_priority > priority) 12507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) continue; 12517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (lowest_priority_prerender == NULL || 12527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) lowest_priority_prerender->GetCurrentDecayedPriority() > 12537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) decayed_priority) { 12547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) lowest_priority_prerender = p; 12557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 12567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 12577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return lowest_priority_prerender; 1258b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 1259b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1260b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void PrerenderLocalPredictor::ContinuePrerenderCheck( 126158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<CandidatePrerenderInfo> info) { 126258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 126358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TIMING_HISTOGRAM("Prerender.LocalPredictorLoggedInLookupTime", 126458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Time::Now() - info->start_time_); 1265b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_STARTED); 126658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (info->candidate_urls_.size() == 0) { 126758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_NO_PRERENDER_CANDIDATES); 126858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 126958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) scoped_ptr<LocalPredictorURLInfo> url_info; 1271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING) 127290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<SafeBrowsingDatabaseManager> sb_db_manager = 127390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) g_browser_process->safe_browsing_service()->database_manager(); 1274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 12756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) int num_issued = 0; 1276b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) { 12775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (num_issued >= GetLocalPredictorMaxLaunchPrerenders()) 12786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 127958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_EXAMINE_NEXT_URL); 1280b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) url_info.reset(new LocalPredictorURLInfo(info->candidate_urls_[i])); 128158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (url_info->local_history_based) { 128258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (SkipLocalPredictorLocalCandidates()) { 128358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) url_info.reset(NULL); 128458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) continue; 128558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 128658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_EXAMINE_NEXT_URL_LOCAL); 128758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 128858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!url_info->local_history_based) { 128958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (SkipLocalPredictorServiceCandidates()) { 129058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) url_info.reset(NULL); 129158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) continue; 129258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 129358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_EXAMINE_NEXT_URL_SERVICE); 129458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 12968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_EXAMINE_NEXT_URL_NOT_SKIPPED); 12978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1298b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // We need to check whether we can issue a prerender for this URL. 1299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // We test a set of conditions. Each condition can either rule out 1300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // a prerender (in which case we reset url_info, so that it will not 1301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // be prerendered, and we continue, which means try the next candidate 1302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // URL), or it can be sufficient to issue the prerender without any 1303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // further checks (in which case we just break). 1304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // The order of the checks is critical, because it prescribes the logic 1305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // we use here to decide what to prerender. 1306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!url_info->url_lookup_success) { 1307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_NO_URL); 1308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) url_info.reset(NULL); 1309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) continue; 1310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 13112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (!SkipLocalPredictorFragment() && 13122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch URLsIdenticalIgnoringFragments(info->source_url_.url, 1313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) url_info->url)) { 1314b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_URLS_IDENTICAL_BUT_FRAGMENT); 1315b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) url_info.reset(NULL); 1316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) continue; 1317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 13182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (!SkipLocalPredictorHTTPS() && url_info->url.SchemeIs("https")) { 1319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_HTTPS); 1320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) url_info.reset(NULL); 1321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) continue; 1322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 1323b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (IsRootPageURL(url_info->url)) { 1324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // For root pages, we assume that they are reasonably safe, and we 1325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // will just prerender them without any additional checks. 1326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ROOT_PAGE); 13275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IssuePrerender(info.get(), url_info.get()); 13286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) num_issued++; 13296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) continue; 1330b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 1331b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (IsLogOutURL(url_info->url)) { 1332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_LOGOUT_URL); 1333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) url_info.reset(NULL); 1334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) continue; 1335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 1336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (IsLogInURL(url_info->url)) { 1337b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_LOGIN_URL); 1338b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) url_info.reset(NULL); 1339b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) continue; 1340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 1341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(FULL_SAFE_BROWSING) 13421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!SkipLocalPredictorWhitelist() && sb_db_manager.get() && 13432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch sb_db_manager->CheckSideEffectFreeWhitelistUrl(url_info->url)) { 134490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If a page is on the side-effect free whitelist, we will just prerender 134590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // it without any additional checks. 134690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ON_SIDE_EFFECT_FREE_WHITELIST); 13475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IssuePrerender(info.get(), url_info.get()); 13486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) num_issued++; 13496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) continue; 135090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 1351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 135258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!SkipLocalPredictorServiceWhitelist() && 135358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) url_info->service_whitelist && url_info->service_whitelist_lookup_ok) { 135458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ON_SERVICE_WHITELIST); 13555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IssuePrerender(info.get(), url_info.get()); 13566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) num_issued++; 13576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) continue; 135858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 13592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (!SkipLocalPredictorLoggedIn() && 13602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch !url_info->logged_in && url_info->logged_in_lookup_ok) { 1361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_NOT_LOGGED_IN); 13625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IssuePrerender(info.get(), url_info.get()); 13636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) num_issued++; 13646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) continue; 1365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 13662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if (!SkipLocalPredictorDefaultNoPrerender()) { 13672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_NOT_PRERENDERING); 13682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch url_info.reset(NULL); 13692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } else { 13702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_PRERENDERING); 13715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IssuePrerender(info.get(), url_info.get()); 13726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) num_issued++; 13736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) continue; 13742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch } 1375b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 1376b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 1377b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void PrerenderLocalPredictor::IssuePrerender( 13796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) CandidatePrerenderInfo* info, 13805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LocalPredictorURLInfo* url_info) { 138158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 13821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RecordEvent(EVENT_ISSUE_PRERENDER_CALLED); 138303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (prefetch_list_->AddURL(url_info->url)) { 13845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RecordEvent(EVENT_PREFETCH_LIST_ADDED); 138503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If we are prefetching rather than prerendering, now is the time to launch 138603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // the prefetch. 138703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsLocalPredictorPrerenderPrefetchEnabled()) { 13881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RecordEvent(EVENT_ISSUE_PRERENDER_PREFETCH_ENABLED); 138903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Obtain the render frame host that caused this prefetch. 139003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RenderFrameHost* rfh = RenderFrameHost::FromID(info->render_process_id_, 139103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) info->render_frame_id_); 139203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If it is still alive, launch the prefresh. 13931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (rfh) { 139403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) rfh->Send(new PrefetchMsg_Prefetch(rfh->GetRoutingID(), url_info->url)); 13951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RecordEvent(EVENT_ISSUE_PRERENDER_PREFETCH_ISSUED); 13961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 139703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 139803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 13995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PrerenderProperties* prerender_properties = 14005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetIssuedPrerenderSlotForPriority(url_info->url, url_info->priority); 14015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!prerender_properties) { 14025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_PRIORITY_TOO_LOW); 14035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 14045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 14056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER); 14066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(prerender_properties != NULL); 14076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(info != NULL); 14086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(url_info != NULL); 14096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (!IsLocalPredictorPrerenderLaunchEnabled()) 14106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 141158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) URLID url_id = url_info->id; 141258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const GURL& url = url_info->url; 141358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) double priority = url_info->priority; 1414b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Time current_time = GetCurrentTime(); 1415b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_ISSUING_PRERENDER); 1416b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 14177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Issue the prerender and obtain a new handle. 14187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<prerender::PrerenderHandle> new_prerender_handle( 14197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) prerender_manager_->AddPrerenderFromLocalPredictor( 142058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) url, info->session_storage_namespace_.get(), *(info->size_))); 14217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 14227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Check if this is a duplicate of an existing prerender. If yes, clean up 14237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // the new handle. 14247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) { 14257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PrerenderProperties* p = issued_prerenders_[i]; 14267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(p != NULL); 14277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (new_prerender_handle && 14287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new_prerender_handle->RepresentingSamePrerenderAs( 14297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) p->prerender_handle.get())) { 14307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new_prerender_handle->OnCancel(); 14317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new_prerender_handle.reset(NULL); 143258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch RecordEvent(EVENT_ISSUE_PRERENDER_ALREADY_PRERENDERING); 14337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 14347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 14357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 14367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 14377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (new_prerender_handle.get()) { 143858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch RecordEvent(EVENT_ISSUE_PRERENDER_NEW_PRERENDER); 14397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // The new prerender does not match any existing prerenders. Update 14407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // prerender_properties so that it reflects the new entry. 14417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) prerender_properties->url_id = url_id; 14427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) prerender_properties->url = url; 14437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) prerender_properties->priority = priority; 14447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) prerender_properties->start_time = current_time; 14457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) prerender_properties->actual_start_time = current_time; 14467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) prerender_properties->would_have_matched = false; 14477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) prerender_properties->prerender_handle.swap(new_prerender_handle); 14487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // new_prerender_handle now represents the old previou prerender that we 14497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // are replacing. So we need to cancel it. 145058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch if (new_prerender_handle) { 14517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new_prerender_handle->OnCancel(); 145258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch RecordEvent(EVENT_ISSUE_PRERENDER_CANCELLED_OLD_PRERENDER); 145358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch } 14547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1455b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1456b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_ADD_VISIT_PRERENDERING); 1457b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (current_prerender_.get() && current_prerender_->url_id == url_id) { 1458b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RecordEvent(EVENT_ADD_VISIT_PRERENDERING_EXTENDED); 1459b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (priority > current_prerender_->priority) 1460b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) current_prerender_->priority = priority; 1461b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // If the prerender already existed, we want to extend it. However, 1462b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // we do not want to set its start_time to the current time to 1463b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // disadvantage PLT computations when the prerender is swapped in. 1464b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // So we set the new start time to current_time - 10s (since the vast 1465b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // majority of PLTs are < 10s), provided that is not before the actual 1466b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // time the prerender was started (so as to not artificially advantage 1467b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // the PLT computation). 1468b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::Time simulated_new_start_time = 1469b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) current_time - base::TimeDelta::FromSeconds(10); 1470b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (simulated_new_start_time > current_prerender_->start_time) 1471b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) current_prerender_->start_time = simulated_new_start_time; 1472b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } else { 1473b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) current_prerender_.reset( 1474b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) new PrerenderProperties(url_id, url, priority, current_time)); 1475b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 1476b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) current_prerender_->actual_start_time = current_time; 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1479a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void PrerenderLocalPredictor::OnTabHelperURLSeen( 1480a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const GURL& url, WebContents* web_contents) { 1481a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) RecordEvent(EVENT_TAB_HELPER_URL_SEEN); 14827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 14835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (prefetch_list_->MarkURLSeen(url, PrefetchList::SEEN_TABCONTENTS_OBSERVER)) 14845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RecordEvent(EVENT_PREFETCH_LIST_SEEN_TABCONTENTS); 1485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool browser_navigate_initiated = false; 1486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const content::NavigationEntry* entry = 1487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) web_contents->GetController().GetPendingEntry(); 1488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (entry) { 1489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 result; 1490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) browser_navigate_initiated = 1491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) entry->GetExtraData(kChromeNavigateExtraDataKey, &result); 1492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1494a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // If the namespace matches and the URL matches, we might be able to swap 1495a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // in. However, the actual code initating the swapin is in the renderer 1496a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // and is checking for other criteria (such as POSTs). There may 1497a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // also be conditions when a swapin should happen but does not. By recording 1498a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // the two previous events, we can keep an eye on the magnitude of the 1499a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // discrepancy. 15007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 15017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PrerenderProperties* best_matched_prerender = NULL; 15027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool session_storage_namespace_matches = false; 15034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionStorageNamespace* tab_session_storage_namespace = 15044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) web_contents->GetController().GetDefaultSessionStorageNamespace(); 15057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) { 15067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PrerenderProperties* p = issued_prerenders_[i]; 15077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(p != NULL); 15087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!p->prerender_handle.get() || 15097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) !p->prerender_handle->Matches(url, NULL) || 15107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) p->would_have_matched) { 15117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) continue; 15127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 15137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!best_matched_prerender || !session_storage_namespace_matches) { 15147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) best_matched_prerender = p; 15157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) session_storage_namespace_matches = 15164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) p->prerender_handle->Matches(url, tab_session_storage_namespace); 15177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 15187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 15197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (best_matched_prerender) { 15207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RecordEvent(EVENT_TAB_HELPER_URL_SEEN_MATCH); 1521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (entry) 1522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RecordEvent(EVENT_TAB_HELPER_URL_SEEN_MATCH_ENTRY); 1523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (browser_navigate_initiated) 1524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RecordEvent(EVENT_TAB_HELPER_URL_SEEN_MATCH_BROWSER_NAVIGATE); 15257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) best_matched_prerender->would_have_matched = true; 15264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (session_storage_namespace_matches) { 15277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MATCH); 1528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (entry) 1529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MATCH_ENTRY); 1530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (browser_navigate_initiated) 1531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MATCH_BROWSER_NAVIGATE); 15324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 15334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SessionStorageNamespace* prerender_session_storage_namespace = 15344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) best_matched_prerender->prerender_handle-> 15354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetSessionStorageNamespace(); 15364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!prerender_session_storage_namespace) { 15374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MISMATCH_NO_NAMESPACE); 15384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 15394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MISMATCH_MERGE_ISSUED); 1540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prerender_session_storage_namespace->Merge( 1541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) false, 15424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) best_matched_prerender->prerender_handle->GetChildId(), 15434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_session_storage_namespace, 15444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&PrerenderLocalPredictor::ProcessNamespaceMergeResult, 15454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_.GetWeakPtr())); 15464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 15474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 15484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 15494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 15504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 15514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void PrerenderLocalPredictor::ProcessNamespaceMergeResult( 15524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content::SessionStorageNamespace::MergeResult result) { 15534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_RECEIVED); 15544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (result) { 15554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case content::SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_FOUND: 15564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_NAMESPACE_NOT_FOUND); 15574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 1558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case content::SessionStorageNamespace::MERGE_RESULT_NAMESPACE_NOT_ALIAS: 1559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_NAMESPACE_NOT_ALIAS); 1560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 15614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case content::SessionStorageNamespace::MERGE_RESULT_NOT_LOGGING: 15624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_NOT_LOGGING); 15634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 15644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case content::SessionStorageNamespace::MERGE_RESULT_NO_TRANSACTIONS: 15654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_NO_TRANSACTIONS); 15664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 15674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case content::SessionStorageNamespace::MERGE_RESULT_TOO_MANY_TRANSACTIONS: 15684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_TOO_MANY_TRANSACTIONS); 15694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 15704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case content::SessionStorageNamespace::MERGE_RESULT_NOT_MERGEABLE: 15714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_NOT_MERGEABLE); 15724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 15734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case content::SessionStorageNamespace::MERGE_RESULT_MERGEABLE: 15744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RecordEvent(EVENT_NAMESPACE_MISMATCH_MERGE_RESULT_MERGEABLE); 15754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 15764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) default: 15774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOTREACHED(); 15787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1579a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 1580a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace prerender 1582