Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Side by Side Diff: chrome/browser/prerender/prerender_local_predictor.cc

Issue 23622012: Integrate the LocalPredictor with the Prerender Service. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/prerender/prerender_local_predictor.h" 5 #include "chrome/browser/prerender/prerender_local_predictor.h"
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <map> 10 #include <map>
11 #include <set> 11 #include <set>
12 #include <string> 12 #include <string>
13 #include <utility> 13 #include <utility>
14 14
15 #include "base/json/json_reader.h"
16 #include "base/json/json_writer.h"
15 #include "base/metrics/field_trial.h" 17 #include "base/metrics/field_trial.h"
16 #include "base/metrics/histogram.h" 18 #include "base/metrics/histogram.h"
19 #include "base/stl_util.h"
17 #include "base/timer/timer.h" 20 #include "base/timer/timer.h"
18 #include "chrome/browser/browser_process.h" 21 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/history/history_database.h" 22 #include "chrome/browser/history/history_database.h"
20 #include "chrome/browser/history/history_db_task.h" 23 #include "chrome/browser/history/history_db_task.h"
21 #include "chrome/browser/history/history_service.h" 24 #include "chrome/browser/history/history_service.h"
22 #include "chrome/browser/history/history_service_factory.h" 25 #include "chrome/browser/history/history_service_factory.h"
23 #include "chrome/browser/prerender/prerender_field_trial.h" 26 #include "chrome/browser/prerender/prerender_field_trial.h"
24 #include "chrome/browser/prerender/prerender_handle.h" 27 #include "chrome/browser/prerender/prerender_handle.h"
25 #include "chrome/browser/prerender/prerender_histograms.h" 28 #include "chrome/browser/prerender/prerender_histograms.h"
26 #include "chrome/browser/prerender/prerender_manager.h" 29 #include "chrome/browser/prerender/prerender_manager.h"
27 #include "chrome/browser/profiles/profile.h" 30 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/safe_browsing/database_manager.h" 31 #include "chrome/browser/safe_browsing/database_manager.h"
29 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 32 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
30 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 33 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
31 #include "content/public/browser/browser_thread.h" 34 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/navigation_controller.h" 35 #include "content/public/browser/navigation_controller.h"
33 #include "content/public/browser/session_storage_namespace.h" 36 #include "content/public/browser/session_storage_namespace.h"
34 #include "content/public/browser/web_contents.h" 37 #include "content/public/browser/web_contents.h"
35 #include "content/public/browser/web_contents_view.h" 38 #include "content/public/browser/web_contents_view.h"
36 #include "content/public/common/page_transition_types.h" 39 #include "content/public/common/page_transition_types.h"
37 #include "crypto/secure_hash.h" 40 #include "crypto/secure_hash.h"
38 #include "grit/browser_resources.h" 41 #include "grit/browser_resources.h"
42 #include "net/base/escape.h"
43 #include "net/url_request/url_fetcher.h"
39 #include "ui/base/resource/resource_bundle.h" 44 #include "ui/base/resource/resource_bundle.h"
40 #include "url/url_canon.h" 45 #include "url/url_canon.h"
41 46
47 using base::DictionaryValue;
48 using base::ListValue;
49 using base::Value;
42 using content::BrowserThread; 50 using content::BrowserThread;
43 using content::PageTransition; 51 using content::PageTransition;
44 using content::SessionStorageNamespace; 52 using content::SessionStorageNamespace;
45 using content::WebContents; 53 using content::WebContents;
46 using history::URLID; 54 using history::URLID;
55 using net::URLFetcher;
47 using predictors::LoggedInPredictorTable; 56 using predictors::LoggedInPredictorTable;
48 using std::string; 57 using std::string;
49 using std::vector; 58 using std::vector;
50 59
51 namespace prerender { 60 namespace prerender {
52 61
53 namespace { 62 namespace {
54 63
55 static const size_t kURLHashSize = 5; 64 static const size_t kURLHashSize = 5;
56 static const int kNumPrerenderCandidates = 5; 65 static const int kNumPrerenderCandidates = 5;
57 66
58 } // namespace 67 } // namespace
59 68
60 // When considering a candidate URL to be prerendered, we need to collect the 69 // When considering a candidate URL to be prerendered, we need to collect the
61 // data in this struct to make the determination whether we should issue the 70 // data in this struct to make the determination whether we should issue the
62 // prerender or not. 71 // prerender or not.
63 struct PrerenderLocalPredictor::LocalPredictorURLInfo { 72 struct PrerenderLocalPredictor::LocalPredictorURLInfo {
64 URLID id; 73 URLID id;
65 GURL url; 74 GURL url;
66 bool url_lookup_success; 75 bool url_lookup_success;
67 bool logged_in; 76 bool logged_in;
68 bool logged_in_lookup_ok; 77 bool logged_in_lookup_ok;
78 bool local_history_based;
79 bool service_whitelist;
80 bool service_whitelist_lookup_ok;
81 bool service_whitelist_reported;
69 double priority; 82 double priority;
70 }; 83 };
71 84
72 // A struct consisting of everything needed for launching a potential prerender 85 // A struct consisting of everything needed for launching a potential prerender
73 // on a navigation: The navigation URL (source) triggering potential prerenders, 86 // on a navigation: The navigation URL (source) triggering potential prerenders,
74 // and a set of candidate URLs. 87 // and a set of candidate URLs.
75 struct PrerenderLocalPredictor::LocalPredictorURLLookupInfo { 88 struct PrerenderLocalPredictor::CandidatePrerenderInfo {
76 LocalPredictorURLInfo source_url_; 89 LocalPredictorURLInfo source_url_;
77 vector<LocalPredictorURLInfo> candidate_urls_; 90 vector<LocalPredictorURLInfo> candidate_urls_;
78 explicit LocalPredictorURLLookupInfo(URLID source_id) { 91 scoped_refptr<SessionStorageNamespace> session_storage_namespace_;
92 scoped_ptr<gfx::Size> size_;
93 base::Time start_time_; // used for various time measurements
94 explicit CandidatePrerenderInfo(URLID source_id) {
79 source_url_.id = source_id; 95 source_url_.id = source_id;
80 } 96 }
81 void MaybeAddCandidateURL(URLID id, double priority) { 97 void MaybeAddCandidateURLFromLocalData(URLID id, double priority) {
82 // TODO(tburkard): clean up this code, potentially using a list or a heap
83 LocalPredictorURLInfo info; 98 LocalPredictorURLInfo info;
84 info.id = id; 99 info.id = id;
100 info.local_history_based = true;
101 info.service_whitelist = false;
102 info.service_whitelist_lookup_ok = false;
103 info.service_whitelist_reported = false;
85 info.priority = priority; 104 info.priority = priority;
105 MaybeAddCandidateURLInternal(info);
106 }
107 void MaybeAddCandidateURLFromService(GURL url, double priority,
108 bool whitelist,
109 bool whitelist_lookup_ok) {
110 LocalPredictorURLInfo info;
111 info.id = kint64max;
112 info.url = url;
113 info.url_lookup_success = true;
114 info.local_history_based = false;
115 info.service_whitelist = whitelist;
116 info.service_whitelist_lookup_ok = whitelist_lookup_ok;
117 info.service_whitelist_reported = true;
118 info.priority = priority;
119 MaybeAddCandidateURLInternal(info);
120 }
121 void MaybeAddCandidateURLInternal(const LocalPredictorURLInfo& info) {
122 // TODO(tburkard): clean up this code, potentially using a list or a heap
86 int insert_pos = candidate_urls_.size(); 123 int insert_pos = candidate_urls_.size();
87 if (insert_pos < kNumPrerenderCandidates) 124 if (insert_pos < kNumPrerenderCandidates)
88 candidate_urls_.push_back(info); 125 candidate_urls_.push_back(info);
89 while (insert_pos > 0 && 126 while (insert_pos > 0 &&
90 candidate_urls_[insert_pos - 1].priority < info.priority) { 127 candidate_urls_[insert_pos - 1].priority < info.priority) {
91 if (insert_pos < kNumPrerenderCandidates) 128 if (insert_pos < kNumPrerenderCandidates)
92 candidate_urls_[insert_pos] = candidate_urls_[insert_pos - 1]; 129 candidate_urls_[insert_pos] = candidate_urls_[insert_pos - 1];
93 insert_pos--; 130 insert_pos--;
94 } 131 }
95 if (insert_pos < kNumPrerenderCandidates) 132 if (insert_pos < kNumPrerenderCandidates)
96 candidate_urls_[insert_pos] = info; 133 candidate_urls_[insert_pos] = info;
97 } 134 }
98 }; 135 };
99 136
100 namespace { 137 namespace {
101 138
139 #define TIMING_HISTOGRAM(name, value) \
140 UMA_HISTOGRAM_CUSTOM_TIMES(name, value, \
141 base::TimeDelta::FromMilliseconds(10), \
142 base::TimeDelta::FromSeconds(10), \
143 50);
144
102 // Task to lookup the URL for a given URLID. 145 // Task to lookup the URL for a given URLID.
103 class GetURLForURLIDTask : public history::HistoryDBTask { 146 class GetURLForURLIDTask : public history::HistoryDBTask {
104 public: 147 public:
105 GetURLForURLIDTask( 148 GetURLForURLIDTask(
106 PrerenderLocalPredictor::LocalPredictorURLLookupInfo* request, 149 PrerenderLocalPredictor::CandidatePrerenderInfo* request,
107 const base::Closure& callback) 150 const base::Closure& callback)
108 : request_(request), 151 : request_(request),
109 callback_(callback), 152 callback_(callback),
110 start_time_(base::Time::Now()) { 153 start_time_(base::Time::Now()) {
111 } 154 }
112 155
113 virtual bool RunOnDBThread(history::HistoryBackend* backend, 156 virtual bool RunOnDBThread(history::HistoryBackend* backend,
114 history::HistoryDatabase* db) OVERRIDE { 157 history::HistoryDatabase* db) OVERRIDE {
115 DoURLLookup(db, &request_->source_url_); 158 DoURLLookup(db, &request_->source_url_);
116 for (int i = 0; i < static_cast<int>(request_->candidate_urls_.size()); i++) 159 for (int i = 0; i < static_cast<int>(request_->candidate_urls_.size()); i++)
117 DoURLLookup(db, &request_->candidate_urls_[i]); 160 DoURLLookup(db, &request_->candidate_urls_[i]);
118 return true; 161 return true;
119 } 162 }
120 163
121 virtual void DoneRunOnMainThread() OVERRIDE { 164 virtual void DoneRunOnMainThread() OVERRIDE {
122 callback_.Run(); 165 callback_.Run();
123 UMA_HISTOGRAM_CUSTOM_TIMES("Prerender.LocalPredictorURLLookupTime", 166 TIMING_HISTOGRAM("Prerender.LocalPredictorURLLookupTime",
124 base::Time::Now() - start_time_, 167 base::Time::Now() - start_time_);
125 base::TimeDelta::FromMilliseconds(10),
126 base::TimeDelta::FromSeconds(10),
127 50);
128 } 168 }
129 169
130 private: 170 private:
131 virtual ~GetURLForURLIDTask() {} 171 virtual ~GetURLForURLIDTask() {}
132 172
133 void DoURLLookup(history::HistoryDatabase* db, 173 void DoURLLookup(history::HistoryDatabase* db,
134 PrerenderLocalPredictor::LocalPredictorURLInfo* request) { 174 PrerenderLocalPredictor::LocalPredictorURLInfo* request) {
135 history::URLRow url_row; 175 history::URLRow url_row;
136 request->url_lookup_success = db->GetURLRow(request->id, &url_row); 176 request->url_lookup_success = db->GetURLRow(request->id, &url_row);
137 if (request->url_lookup_success) 177 if (request->url_lookup_success)
138 request->url = url_row.url(); 178 request->url = url_row.url();
139 } 179 }
140 180
141 PrerenderLocalPredictor::LocalPredictorURLLookupInfo* request_; 181 PrerenderLocalPredictor::CandidatePrerenderInfo* request_;
142 base::Closure callback_; 182 base::Closure callback_;
143 base::Time start_time_; 183 base::Time start_time_;
144 DISALLOW_COPY_AND_ASSIGN(GetURLForURLIDTask); 184 DISALLOW_COPY_AND_ASSIGN(GetURLForURLIDTask);
145 }; 185 };
146 186
147 // Task to load history from the visit database on startup. 187 // Task to load history from the visit database on startup.
148 class GetVisitHistoryTask : public history::HistoryDBTask { 188 class GetVisitHistoryTask : public history::HistoryDBTask {
149 public: 189 public:
150 GetVisitHistoryTask(PrerenderLocalPredictor* local_predictor, 190 GetVisitHistoryTask(PrerenderLocalPredictor* local_predictor,
151 int max_visits) 191 int max_visits)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 232
193 bool IsHomePage(PageTransition transition) { 233 bool IsHomePage(PageTransition transition) {
194 return (transition & content::PAGE_TRANSITION_HOME_PAGE) != 0; 234 return (transition & content::PAGE_TRANSITION_HOME_PAGE) != 0;
195 } 235 }
196 236
197 bool IsIntermediateRedirect(PageTransition transition) { 237 bool IsIntermediateRedirect(PageTransition transition) {
198 return (transition & content::PAGE_TRANSITION_CHAIN_END) == 0; 238 return (transition & content::PAGE_TRANSITION_CHAIN_END) == 0;
199 } 239 }
200 240
201 bool IsFormSubmit(PageTransition transition) { 241 bool IsFormSubmit(PageTransition transition) {
202 return (transition & content::PAGE_TRANSITION_FORM_SUBMIT) != 0; 242 return PageTransitionCoreTypeIs(transition,
243 content::PAGE_TRANSITION_FORM_SUBMIT);
203 } 244 }
204 245
205 bool ShouldExcludeTransitionForPrediction(PageTransition transition) { 246 bool ShouldExcludeTransitionForPrediction(PageTransition transition) {
206 return IsBackForward(transition) || IsHomePage(transition) || 247 return IsBackForward(transition) || IsHomePage(transition) ||
207 IsIntermediateRedirect(transition); 248 IsIntermediateRedirect(transition);
208 } 249 }
209 250
210 base::Time GetCurrentTime() { 251 base::Time GetCurrentTime() {
211 return base::Time::Now(); 252 return base::Time::Now();
212 } 253 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 bool URLsIdenticalIgnoringFragments(const GURL& url1, const GURL& url2) { 305 bool URLsIdenticalIgnoringFragments(const GURL& url1, const GURL& url2) {
265 url_canon::Replacements<char> replacement; 306 url_canon::Replacements<char> replacement;
266 replacement.ClearRef(); 307 replacement.ClearRef();
267 GURL u1 = url1.ReplaceComponents(replacement); 308 GURL u1 = url1.ReplaceComponents(replacement);
268 GURL u2 = url2.ReplaceComponents(replacement); 309 GURL u2 = url2.ReplaceComponents(replacement);
269 return (u1 == u2); 310 return (u1 == u2);
270 } 311 }
271 312
272 void LookupLoggedInStatesOnDBThread( 313 void LookupLoggedInStatesOnDBThread(
273 scoped_refptr<LoggedInPredictorTable> logged_in_predictor_table, 314 scoped_refptr<LoggedInPredictorTable> logged_in_predictor_table,
274 PrerenderLocalPredictor::LocalPredictorURLLookupInfo* request_) { 315 PrerenderLocalPredictor::CandidatePrerenderInfo* request) {
275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 316 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
276 for (int i = 0; i < static_cast<int>(request_->candidate_urls_.size()); i++) { 317 for (int i = 0; i < static_cast<int>(request->candidate_urls_.size()); i++) {
277 PrerenderLocalPredictor::LocalPredictorURLInfo* info = 318 PrerenderLocalPredictor::LocalPredictorURLInfo* info =
278 &request_->candidate_urls_[i]; 319 &request->candidate_urls_[i];
279 if (info->url_lookup_success) { 320 if (info->url_lookup_success) {
280 logged_in_predictor_table->HasUserLoggedIn( 321 logged_in_predictor_table->HasUserLoggedIn(
281 info->url, &info->logged_in, &info->logged_in_lookup_ok); 322 info->url, &info->logged_in, &info->logged_in_lookup_ok);
282 } else { 323 } else {
283 info->logged_in_lookup_ok = false; 324 info->logged_in_lookup_ok = false;
284 } 325 }
285 } 326 }
286 } 327 }
287 328
288 } // namespace 329 } // namespace
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 } 420 }
380 421
381 PrerenderLocalPredictor::~PrerenderLocalPredictor() { 422 PrerenderLocalPredictor::~PrerenderLocalPredictor() {
382 Shutdown(); 423 Shutdown();
383 for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) { 424 for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) {
384 PrerenderProperties* p = issued_prerenders_[i]; 425 PrerenderProperties* p = issued_prerenders_[i];
385 DCHECK(p != NULL); 426 DCHECK(p != NULL);
386 if (p->prerender_handle) 427 if (p->prerender_handle)
387 p->prerender_handle->OnCancel(); 428 p->prerender_handle->OnCancel();
388 } 429 }
430 STLDeleteContainerPairPointers(
431 outstanding_prerender_service_requests_.begin(),
432 outstanding_prerender_service_requests_.end());
389 } 433 }
390 434
391 void PrerenderLocalPredictor::Shutdown() { 435 void PrerenderLocalPredictor::Shutdown() {
392 timer_.Stop(); 436 timer_.Stop();
393 if (is_visit_database_observer_) { 437 if (is_visit_database_observer_) {
394 HistoryService* history = GetHistoryIfExists(); 438 HistoryService* history = GetHistoryIfExists();
395 CHECK(history); 439 CHECK(history);
396 history->RemoveVisitDatabaseObserver(this); 440 history->RemoveVisitDatabaseObserver(this);
397 is_visit_database_observer_ = false; 441 is_visit_database_observer_ = false;
398 } 442 }
(...skipping 26 matching lines...) Expand all
425 return; 469 return;
426 RecordEvent(EVENT_ADD_VISIT_RELEVANT_TRANSITION); 470 RecordEvent(EVENT_ADD_VISIT_RELEVANT_TRANSITION);
427 base::TimeDelta max_age = 471 base::TimeDelta max_age =
428 base::TimeDelta::FromMilliseconds(GetMaxLocalPredictionTimeMs()); 472 base::TimeDelta::FromMilliseconds(GetMaxLocalPredictionTimeMs());
429 base::TimeDelta min_age = 473 base::TimeDelta min_age =
430 base::TimeDelta::FromMilliseconds(kMinLocalPredictionTimeMs); 474 base::TimeDelta::FromMilliseconds(kMinLocalPredictionTimeMs);
431 std::set<URLID> next_urls_currently_found; 475 std::set<URLID> next_urls_currently_found;
432 std::map<URLID, int> next_urls_num_found; 476 std::map<URLID, int> next_urls_num_found;
433 int num_occurrences_of_current_visit = 0; 477 int num_occurrences_of_current_visit = 0;
434 base::Time last_visited; 478 base::Time last_visited;
435 scoped_ptr<LocalPredictorURLLookupInfo> lookup_info( 479 scoped_ptr<CandidatePrerenderInfo> lookup_info(
436 new LocalPredictorURLLookupInfo(info.url_id)); 480 new CandidatePrerenderInfo(info.url_id));
437 const vector<history::BriefVisitInfo>& visits = *(visit_history_.get()); 481 const vector<history::BriefVisitInfo>& visits = *(visit_history_.get());
438 for (int i = 0; i < static_cast<int>(visits.size()); i++) { 482 for (int i = 0; i < static_cast<int>(visits.size()); i++) {
439 if (!ShouldExcludeTransitionForPrediction(visits[i].transition)) { 483 if (!ShouldExcludeTransitionForPrediction(visits[i].transition)) {
440 if (visits[i].url_id == info.url_id) { 484 if (visits[i].url_id == info.url_id) {
441 last_visited = visits[i].time; 485 last_visited = visits[i].time;
442 num_occurrences_of_current_visit++; 486 num_occurrences_of_current_visit++;
443 next_urls_currently_found.clear(); 487 next_urls_currently_found.clear();
444 continue; 488 continue;
445 } 489 }
446 if (!last_visited.is_null() && 490 if (!last_visited.is_null() &&
(...skipping 20 matching lines...) Expand all
467 it != next_urls_num_found.end(); 511 it != next_urls_num_found.end();
468 ++it) { 512 ++it) {
469 // Only consider a candidate next page for prerendering if it was viewed 513 // Only consider a candidate next page for prerendering if it was viewed
470 // at least twice, and at least 10% of the time. 514 // at least twice, and at least 10% of the time.
471 if (num_occurrences_of_current_visit > 0 && 515 if (num_occurrences_of_current_visit > 0 &&
472 it->second > 1 && 516 it->second > 1 &&
473 it->second * 10 >= num_occurrences_of_current_visit) { 517 it->second * 10 >= num_occurrences_of_current_visit) {
474 RecordEvent(EVENT_ADD_VISIT_IDENTIFIED_PRERENDER_CANDIDATE); 518 RecordEvent(EVENT_ADD_VISIT_IDENTIFIED_PRERENDER_CANDIDATE);
475 double priority = static_cast<double>(it->second) / 519 double priority = static_cast<double>(it->second) /
476 static_cast<double>(num_occurrences_of_current_visit); 520 static_cast<double>(num_occurrences_of_current_visit);
477 lookup_info->MaybeAddCandidateURL(it->first, priority); 521 lookup_info->MaybeAddCandidateURLFromLocalData(it->first, priority);
478 } 522 }
479 } 523 }
480 524
481 if (lookup_info->candidate_urls_.size() == 0) {
482 RecordEvent(EVENT_NO_PRERENDER_CANDIDATES);
483 return;
484 }
485
486 RecordEvent(EVENT_START_URL_LOOKUP); 525 RecordEvent(EVENT_START_URL_LOOKUP);
487 HistoryService* history = GetHistoryIfExists(); 526 HistoryService* history = GetHistoryIfExists();
488 if (history) { 527 if (history) {
489 RecordEvent(EVENT_GOT_HISTORY_ISSUING_LOOKUP); 528 RecordEvent(EVENT_GOT_HISTORY_ISSUING_LOOKUP);
490 LocalPredictorURLLookupInfo* lookup_info_ptr = lookup_info.get(); 529 CandidatePrerenderInfo* lookup_info_ptr = lookup_info.get();
491 history->ScheduleDBTask( 530 history->ScheduleDBTask(
492 new GetURLForURLIDTask( 531 new GetURLForURLIDTask(
493 lookup_info_ptr, 532 lookup_info_ptr,
494 base::Bind(&PrerenderLocalPredictor::OnLookupURL, 533 base::Bind(&PrerenderLocalPredictor::OnLookupURL,
495 base::Unretained(this), 534 base::Unretained(this),
496 base::Passed(&lookup_info))), 535 base::Passed(&lookup_info))),
497 &history_db_consumer_); 536 &history_db_consumer_);
498 } 537 }
499 } 538 }
500 539
501 void PrerenderLocalPredictor::OnLookupURL( 540 void PrerenderLocalPredictor::OnLookupURL(
502 scoped_ptr<LocalPredictorURLLookupInfo> info) { 541 scoped_ptr<CandidatePrerenderInfo> info) {
542 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
543
503 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT); 544 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT);
504 545
505 DCHECK_GE(static_cast<int>(info->candidate_urls_.size()), 1);
506
507 if (!info->source_url_.url_lookup_success) { 546 if (!info->source_url_.url_lookup_success) {
508 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_FAILED); 547 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_FAILED);
509 return; 548 return;
510 } 549 }
511 550
512 LogCandidateURLStats(info->candidate_urls_[0].url); 551 if (info->candidate_urls_.size() > 0 &&
552 info->candidate_urls_[0].url_lookup_success) {
553 LogCandidateURLStats(info->candidate_urls_[0].url);
554 }
513 555
514 WebContents* source_web_contents = NULL; 556 WebContents* source_web_contents = NULL;
515 bool multiple_source_web_contents_candidates = false; 557 bool multiple_source_web_contents_candidates = false;
516 558
517 #if !defined(OS_ANDROID) 559 #if !defined(OS_ANDROID)
518 // We need to figure out what tab launched the prerender. We do this by 560 // We need to figure out what tab launched the prerender. We do this by
519 // comparing URLs. This may not always work: the URL may occur in two 561 // comparing URLs. This may not always work: the URL may occur in two
520 // tabs, and we pick the wrong one, or the tab we should have picked 562 // tabs, and we pick the wrong one, or the tab we should have picked
521 // may have navigated elsewhere. Hopefully, this doesn't happen too often, 563 // may have navigated elsewhere. Hopefully, this doesn't happen too often,
522 // so we ignore these cases for now. 564 // so we ignore these cases for now.
(...skipping 10 matching lines...) Expand all
533 #endif 575 #endif
534 576
535 if (!source_web_contents) { 577 if (!source_web_contents) {
536 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_SOURCE_WEBCONTENTS_FOUND); 578 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_SOURCE_WEBCONTENTS_FOUND);
537 return; 579 return;
538 } 580 }
539 581
540 if (multiple_source_web_contents_candidates) 582 if (multiple_source_web_contents_candidates)
541 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_MULTIPLE_SOURCE_WEBCONTENTS_FOUND); 583 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_MULTIPLE_SOURCE_WEBCONTENTS_FOUND);
542 584
543 585 info->session_storage_namespace_ =
544 scoped_refptr<SessionStorageNamespace> session_storage_namespace =
545 source_web_contents->GetController().GetDefaultSessionStorageNamespace(); 586 source_web_contents->GetController().GetDefaultSessionStorageNamespace();
546 587
547 gfx::Rect container_bounds; 588 gfx::Rect container_bounds;
548 source_web_contents->GetView()->GetContainerBounds(&container_bounds); 589 source_web_contents->GetView()->GetContainerBounds(&container_bounds);
549 scoped_ptr<gfx::Size> size(new gfx::Size(container_bounds.size())); 590 info->size_.reset(new gfx::Size(container_bounds.size()));
550 591
592 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_SUCCESS);
593
594 DoPrerenderServiceCheck(info.Pass());
595 }
596
597 void PrerenderLocalPredictor::DoPrerenderServiceCheck(
598 scoped_ptr<CandidatePrerenderInfo> info) {
599 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
600 if (!ShouldQueryPrerenderService(prerender_manager_->profile())) {
601 RecordEvent(EVENT_PRERENDER_SERVICE_DISABLED);
602 DoLoggedInLookup(info.Pass());
603 return;
604 }
605 /*
606 Create a JSON request.
607 Here is a sample request:
608 { "prerender_request": {
609 "version": 1,
610 "behavior_id": 6,
611 "hint_request": {
612 "browse_history": [
613 { "url": "http://www.cnn.com/"
614 }
615 ]
616 },
617 "candidate_check_request": {
618 "candidates": [
619 { "url": "http://www.cnn.com/sports/"
620 },
621 { "url": "http://www.cnn.com/politics/"
622 }
623 ]
624 }
625 }
626 }
627 */
628 DictionaryValue json_data;
629 DictionaryValue* req = new DictionaryValue();
630 req->SetInteger("version", 1);
631 req->SetInteger("behavior_id", GetPrerenderServiceBehaviorID());
632 if (info->source_url_.url_lookup_success) {
633 ListValue* browse_history = new ListValue();
634 DictionaryValue* browse_item = new DictionaryValue();
635 browse_item->SetString("url", info->source_url_.url.spec());
636 browse_history->Append(browse_item);
637 DictionaryValue* hint_request = new DictionaryValue();
638 hint_request->Set("browse_history", browse_history);
639 req->Set("hint_request", hint_request);
640 }
641 int num_candidate_urls = 0;
642 for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) {
643 if (info->candidate_urls_[i].url_lookup_success)
644 num_candidate_urls++;
645 }
646 if (num_candidate_urls > 0) {
647 ListValue* candidates = new ListValue();
648 DictionaryValue* candidate;
649 for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) {
650 if (info->candidate_urls_[i].url_lookup_success) {
651 candidate = new DictionaryValue();
652 candidate->SetString("url", info->candidate_urls_[i].url.spec());
653 candidates->Append(candidate);
654 }
655 }
656 DictionaryValue* candidate_check_request = new DictionaryValue();
657 candidate_check_request->Set("candidates", candidates);
658 req->Set("candidate_check_request", candidate_check_request);
659 }
660 json_data.Set("prerender_request", req);
661 string request_string;
662 base::JSONWriter::Write(&json_data, &request_string);
663 GURL fetch_url(GetPrerenderServiceURLPrefix() +
664 net::EscapeQueryParamValue(request_string, false));
665 net::URLFetcher* fetcher = net::URLFetcher::Create(
666 0,
667 fetch_url,
668 URLFetcher::GET, this);
669 fetcher->SetRequestContext(
670 prerender_manager_->profile()->GetRequestContext());
671 fetcher->AddExtraRequestHeader("Pragma: no-cache");
672 info->start_time_ = base::Time::Now();
673 outstanding_prerender_service_requests_.insert(
674 std::make_pair(fetcher, info.release()));
675 base::MessageLoop::current()->PostDelayedTask(
676 FROM_HERE,
677 base::Bind(&PrerenderLocalPredictor::MaybeCancelURLFetcher,
678 weak_factory_.GetWeakPtr(), fetcher),
679 base::TimeDelta::FromMilliseconds(GetPrerenderServiceFetchTimeoutMs()));
680 RecordEvent(EVENT_PRERENDER_SERVICE_ISSUED_LOOKUP);
681 fetcher->Start();
682 }
683
684 void PrerenderLocalPredictor::MaybeCancelURLFetcher(net::URLFetcher* fetcher) {
685 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
686 OutstandingFetchers::iterator it =
687 outstanding_prerender_service_requests_.find(fetcher);
688 if (it == outstanding_prerender_service_requests_.end())
689 return;
690 delete it->first;
691 scoped_ptr<CandidatePrerenderInfo> info(it->second);
692 outstanding_prerender_service_requests_.erase(it);
693 RecordEvent(EVENT_PRERENDER_SERVICE_LOOKUP_TIMED_OUT);
694 DoLoggedInLookup(info.Pass());
695 }
696
697 void PrerenderLocalPredictor::OnURLFetchComplete(
698 const net::URLFetcher* source) {
699 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
700 RecordEvent(EVENT_PRERENDER_SERVICE_RECEIVED_RESULT);
701 net::URLFetcher* fetcher = const_cast<net::URLFetcher*>(source);
702 OutstandingFetchers::iterator it =
703 outstanding_prerender_service_requests_.find(fetcher);
704 if (it == outstanding_prerender_service_requests_.end()) {
705 RecordEvent(EVENT_PRERENDER_SERVICE_NO_RECORD_FOR_RESULT);
706 return;
707 }
708 scoped_ptr<CandidatePrerenderInfo> info(it->second);
709 outstanding_prerender_service_requests_.erase(it);
710 TIMING_HISTOGRAM("Prerender.LocalPredictorServiceLookupTime",
711 base::Time::Now() - info->start_time_);
712 /*
713 Read and process the response to our request.
714 Here is a sample response to illustrate the format.
715 {
716 "prerender_response": {
717 "behavior_id": 6,
718 "hint_response": {
719 "hinting_timed_out": 0,
720 "candidates": [
721 { "url": "http://www.cnn.com/story-1",
722 "in_index": 1,
723 "likelihood": 0.60,
724 "in_index_timed_out": 0
725 },
726 { "url": "http://www.cnn.com/story-2",
727 "in_index": 1,
728 "likelihood": 0.30,
729 "in_index_timed_out": 0
730 }
731 ]
732 },
733 "candidate_check_response": {
734 "candidates": [
735 { "url": "http://www.cnn.com/sports/",
736 "in_index": 1,
737 "in_index_timed_out": 0
738 },
739 { "url": "http://www.cnn.com/politics/",
740 "in_index": 0,
741 "in_index_timed_out": "1"
742 }
743 ]
744 }
745 }
746 }
747 */
748 string result;
749 fetcher->GetResponseAsString(&result);
750 scoped_ptr<Value> root;
751 root.reset(base::JSONReader::Read(result));
752 DictionaryValue* dict = NULL;
753 ListValue* list = NULL;
754 bool hinting_timed_out = false;
755 bool hinting_url_lookup_timed_out = false;
756 bool candidate_url_lookup_timed_out = false;
757 if (!root.get() || !root->IsType(Value::TYPE_DICTIONARY)) {
758 RecordEvent(EVENT_PRERENDER_SERVICE_PARSE_ERROR_INCORRECT_JSON);
759 goto error;
760 }
761 dict = static_cast<DictionaryValue*>(root.get());
762 int int_value;
763 if (!dict->GetInteger("prerender_response.behavior_id", &int_value) ||
764 int_value != GetPrerenderServiceBehaviorID()) {
765 goto error;
766 }
767 if (!dict->GetList("prerender_response.candidate_check_response.candidates",
768 &list)) {
769 if (info->candidate_urls_.size() > 0)
770 goto error;
771 } else {
772 for (int i = 0; i < static_cast<int>(list->GetSize()); i++) {
jam 2013/08/30 20:34:30 nit: instead of casting, just use "size_t i", also
tburkard 2013/08/30 20:59:01 Done.
773 DictionaryValue* d;
774 if (!list->GetDictionary(i, &d))
775 goto error;
776 string url_string;
777 if (!d->GetString("url", &url_string) || !GURL(url_string).is_valid()) {
778 goto error;
779 }
780 GURL url(url_string);
781 int in_index_timed_out = 0;
782 int in_index = 0;
783 if ((!d->GetInteger("in_index_timed_out", &in_index_timed_out) ||
784 in_index_timed_out != 1) &&
785 !d->GetInteger("in_index", &in_index)) {
786 goto error;
787 }
788 if (in_index < 0 || in_index > 1 ||
789 in_index_timed_out < 0 || in_index_timed_out > 1) {
790 goto error;
791 }
792 for (int j = 0; j < static_cast<int>(info->candidate_urls_.size()); j++) {
793 if (info->candidate_urls_[j].url == url) {
794 info->candidate_urls_[j].service_whitelist_reported = true;
795 info->candidate_urls_[j].service_whitelist = (in_index == 1);
796 info->candidate_urls_[j].service_whitelist_lookup_ok =
797 ((1 - in_index_timed_out) == 1);
798 }
799 }
800 }
801 for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) {
802 if (!info->candidate_urls_[i].service_whitelist_reported)
803 goto error;
804 }
805 }
806
807 list = NULL;
808 if (dict->GetInteger("prerender_response.hint_response.hinting_timed_out",
809 &int_value) &&
810 int_value == 1) {
811 hinting_timed_out = true;
812 } else if (!dict->GetList("prerender_response.hint_response.candidates",
813 &list)) {
814 goto error;
815 } else {
816 for (int i = 0; i < static_cast<int>(list->GetSize()); i++) {
817 DictionaryValue* d;
818 if (!list->GetDictionary(i, &d))
819 goto error;
820 string url;
821 double priority;
822 if (!d->GetString("url", &url) || !d->GetDouble("likelihood", &priority)
823 || !GURL(url).is_valid()) {
824 goto error;
825 }
826 int in_index_timed_out = 0;
827 int in_index = 0;
828 if ((!d->GetInteger("in_index_timed_out", &in_index_timed_out) ||
829 in_index_timed_out != 1) &&
830 !d->GetInteger("in_index", &in_index)) {
831 goto error;
832 }
833 if (priority < 0.0 || priority > 1.0 || in_index < 0 || in_index > 1 ||
834 in_index_timed_out < 0 || in_index_timed_out > 1) {
835 goto error;
836 }
837 info->MaybeAddCandidateURLFromService(GURL(url),
838 priority,
839 in_index == 1,
840 (1 - in_index_timed_out) == 1);
841 }
842 }
843
844 // We finished parsing the result, and found no errors.
845 RecordEvent(EVENT_PRERENDER_SERVICE_PARSED_CORRECTLY);
846 if (hinting_timed_out)
847 RecordEvent(EVENT_PRERENDER_SERVICE_HINTING_TIMED_OUT);
848 if (hinting_url_lookup_timed_out)
849 RecordEvent(EVENT_PRERENDER_SERVICE_HINTING_URL_LOOKUP_TIMED_OUT);
850 if (candidate_url_lookup_timed_out)
851 RecordEvent(EVENT_PRERENDER_SERVICE_CANDIDATE_URL_LOOKUP_TIMED_OUT);
852 DoLoggedInLookup(info.Pass());
853 return;
854
855 error:
856 // Parser errors, record this, and continue with LoggedIn Lookup.
857 RecordEvent(EVENT_PRERENDER_SERVICE_PARSE_ERROR);
858 DoLoggedInLookup(info.Pass());
859 }
860
861 void PrerenderLocalPredictor:: DoLoggedInLookup(
862 scoped_ptr<CandidatePrerenderInfo> info) {
863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
551 scoped_refptr<LoggedInPredictorTable> logged_in_table = 864 scoped_refptr<LoggedInPredictorTable> logged_in_table =
552 prerender_manager_->logged_in_predictor_table(); 865 prerender_manager_->logged_in_predictor_table();
553 866
554 if (!logged_in_table.get()) { 867 if (!logged_in_table.get()) {
555 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_LOGGED_IN_TABLE_FOUND); 868 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_LOGGED_IN_TABLE_FOUND);
556 return; 869 return;
557 } 870 }
558 871
559 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_ISSUING_LOGGED_IN_LOOKUP); 872 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_ISSUING_LOGGED_IN_LOOKUP);
560 873
561 LocalPredictorURLLookupInfo* info_ptr = info.get(); 874 info->start_time_ = base::Time::Now();
875
876 CandidatePrerenderInfo* info_ptr = info.get();
562 BrowserThread::PostTaskAndReply( 877 BrowserThread::PostTaskAndReply(
563 BrowserThread::DB, FROM_HERE, 878 BrowserThread::DB, FROM_HERE,
564 base::Bind(&LookupLoggedInStatesOnDBThread, 879 base::Bind(&LookupLoggedInStatesOnDBThread,
565 logged_in_table, 880 logged_in_table,
566 info_ptr), 881 info_ptr),
567 base::Bind(&PrerenderLocalPredictor::ContinuePrerenderCheck, 882 base::Bind(&PrerenderLocalPredictor::ContinuePrerenderCheck,
568 weak_factory_.GetWeakPtr(), 883 weak_factory_.GetWeakPtr(),
569 session_storage_namespace,
570 base::Passed(&size),
571 base::Passed(&info))); 884 base::Passed(&info)));
572 } 885 }
573 886
574 void PrerenderLocalPredictor::LogCandidateURLStats(const GURL& url) const { 887 void PrerenderLocalPredictor::LogCandidateURLStats(const GURL& url) const {
575 if (url_whitelist_.count(GetInt64URLHashForURL(url)) > 0) { 888 if (url_whitelist_.count(GetInt64URLHashForURL(url)) > 0) {
576 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST); 889 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST);
577 if (IsRootPageURL(url)) 890 if (IsRootPageURL(url))
578 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST_ROOT_PAGE); 891 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST_ROOT_PAGE);
579 } 892 }
580 if (IsRootPageURL(url)) 893 if (IsRootPageURL(url))
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 if (lowest_priority_prerender == NULL || 1017 if (lowest_priority_prerender == NULL ||
705 lowest_priority_prerender->GetCurrentDecayedPriority() > 1018 lowest_priority_prerender->GetCurrentDecayedPriority() >
706 decayed_priority) { 1019 decayed_priority) {
707 lowest_priority_prerender = p; 1020 lowest_priority_prerender = p;
708 } 1021 }
709 } 1022 }
710 return lowest_priority_prerender; 1023 return lowest_priority_prerender;
711 } 1024 }
712 1025
713 void PrerenderLocalPredictor::ContinuePrerenderCheck( 1026 void PrerenderLocalPredictor::ContinuePrerenderCheck(
714 scoped_refptr<SessionStorageNamespace> session_storage_namespace, 1027 scoped_ptr<CandidatePrerenderInfo> info) {
715 scoped_ptr<gfx::Size> size, 1028 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
716 scoped_ptr<LocalPredictorURLLookupInfo> info) { 1029 TIMING_HISTOGRAM("Prerender.LocalPredictorLoggedInLookupTime",
1030 base::Time::Now() - info->start_time_);
717 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_STARTED); 1031 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_STARTED);
1032 if (info->candidate_urls_.size() == 0) {
1033 RecordEvent(EVENT_NO_PRERENDER_CANDIDATES);
1034 return;
1035 }
718 scoped_ptr<LocalPredictorURLInfo> url_info; 1036 scoped_ptr<LocalPredictorURLInfo> url_info;
719 scoped_refptr<SafeBrowsingDatabaseManager> sb_db_manager = 1037 scoped_refptr<SafeBrowsingDatabaseManager> sb_db_manager =
720 g_browser_process->safe_browsing_service()->database_manager(); 1038 g_browser_process->safe_browsing_service()->database_manager();
721 PrerenderProperties* prerender_properties = NULL; 1039 PrerenderProperties* prerender_properties = NULL;
722 1040
723 for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) { 1041 for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) {
724 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_EXAMINE_NEXT_URL); 1042 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_EXAMINE_NEXT_URL);
725 url_info.reset(new LocalPredictorURLInfo(info->candidate_urls_[i])); 1043 url_info.reset(new LocalPredictorURLInfo(info->candidate_urls_[i]));
726 1044
727 // We need to check whether we can issue a prerender for this URL. 1045 // We need to check whether we can issue a prerender for this URL.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 url_info.reset(NULL); 1090 url_info.reset(NULL);
773 continue; 1091 continue;
774 } 1092 }
775 if (!SkipLocalPredictorWhitelist() && 1093 if (!SkipLocalPredictorWhitelist() &&
776 sb_db_manager->CheckSideEffectFreeWhitelistUrl(url_info->url)) { 1094 sb_db_manager->CheckSideEffectFreeWhitelistUrl(url_info->url)) {
777 // If a page is on the side-effect free whitelist, we will just prerender 1095 // If a page is on the side-effect free whitelist, we will just prerender
778 // it without any additional checks. 1096 // it without any additional checks.
779 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ON_SIDE_EFFECT_FREE_WHITELIST); 1097 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ON_SIDE_EFFECT_FREE_WHITELIST);
780 break; 1098 break;
781 } 1099 }
1100 if (!SkipLocalPredictorServiceWhitelist() &&
1101 url_info->service_whitelist && url_info->service_whitelist_lookup_ok) {
1102 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ON_SERVICE_WHITELIST);
1103 break;
1104 }
782 if (!SkipLocalPredictorLoggedIn() && 1105 if (!SkipLocalPredictorLoggedIn() &&
783 !url_info->logged_in && url_info->logged_in_lookup_ok) { 1106 !url_info->logged_in && url_info->logged_in_lookup_ok) {
784 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_NOT_LOGGED_IN); 1107 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_NOT_LOGGED_IN);
785 break; 1108 break;
786 } 1109 }
787 if (!SkipLocalPredictorDefaultNoPrerender()) { 1110 if (!SkipLocalPredictorDefaultNoPrerender()) {
788 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_NOT_PRERENDERING); 1111 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_NOT_PRERENDERING);
789 url_info.reset(NULL); 1112 url_info.reset(NULL);
790 } else { 1113 } else {
791 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_PRERENDERING); 1114 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_PRERENDERING);
792 } 1115 }
793 } 1116 }
794 if (!url_info.get()) 1117 if (!url_info.get())
795 return; 1118 return;
796 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER); 1119 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER);
797 DCHECK(prerender_properties != NULL); 1120 DCHECK(prerender_properties != NULL);
798 if (IsLocalPredictorPrerenderLaunchEnabled()) { 1121 if (IsLocalPredictorPrerenderLaunchEnabled()) {
799 IssuePrerender(session_storage_namespace, size.Pass(), 1122 IssuePrerender(info.Pass(), url_info.Pass(), prerender_properties);
800 url_info.Pass(), prerender_properties);
801 } 1123 }
802 } 1124 }
803 1125
804 void PrerenderLocalPredictor::IssuePrerender( 1126 void PrerenderLocalPredictor::IssuePrerender(
805 scoped_refptr<SessionStorageNamespace> session_storage_namespace, 1127 scoped_ptr<CandidatePrerenderInfo> info,
806 scoped_ptr<gfx::Size> size, 1128 scoped_ptr<LocalPredictorURLInfo> url_info,
807 scoped_ptr<LocalPredictorURLInfo> info,
808 PrerenderProperties* prerender_properties) { 1129 PrerenderProperties* prerender_properties) {
809 URLID url_id = info->id; 1130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
810 const GURL& url = info->url; 1131 URLID url_id = url_info->id;
811 double priority = info->priority; 1132 const GURL& url = url_info->url;
1133 double priority = url_info->priority;
812 base::Time current_time = GetCurrentTime(); 1134 base::Time current_time = GetCurrentTime();
813 RecordEvent(EVENT_ISSUING_PRERENDER); 1135 RecordEvent(EVENT_ISSUING_PRERENDER);
814 1136
815 // Issue the prerender and obtain a new handle. 1137 // Issue the prerender and obtain a new handle.
816 scoped_ptr<prerender::PrerenderHandle> new_prerender_handle( 1138 scoped_ptr<prerender::PrerenderHandle> new_prerender_handle(
817 prerender_manager_->AddPrerenderFromLocalPredictor( 1139 prerender_manager_->AddPrerenderFromLocalPredictor(
818 url, session_storage_namespace.get(), *size)); 1140 url, info->session_storage_namespace_.get(), *(info->size_)));
819 1141
820 // Check if this is a duplicate of an existing prerender. If yes, clean up 1142 // Check if this is a duplicate of an existing prerender. If yes, clean up
821 // the new handle. 1143 // the new handle.
822 for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) { 1144 for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) {
823 PrerenderProperties* p = issued_prerenders_[i]; 1145 PrerenderProperties* p = issued_prerenders_[i];
824 DCHECK(p != NULL); 1146 DCHECK(p != NULL);
825 if (new_prerender_handle && 1147 if (new_prerender_handle &&
826 new_prerender_handle->RepresentingSamePrerenderAs( 1148 new_prerender_handle->RepresentingSamePrerenderAs(
827 p->prerender_handle.get())) { 1149 p->prerender_handle.get())) {
828 new_prerender_handle->OnCancel(); 1150 new_prerender_handle->OnCancel();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 } 1228 }
907 if (best_matched_prerender) { 1229 if (best_matched_prerender) {
908 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_MATCH); 1230 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_MATCH);
909 best_matched_prerender->would_have_matched = true; 1231 best_matched_prerender->would_have_matched = true;
910 if (session_storage_namespace_matches) 1232 if (session_storage_namespace_matches)
911 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MATCH); 1233 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MATCH);
912 } 1234 }
913 } 1235 }
914 1236
915 } // namespace prerender 1237 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698