OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 bool PrerenderLocalPredictor::ApplyParsedPrerenderServiceResponse( |
| 698 DictionaryValue* dict, |
| 699 CandidatePrerenderInfo* info, |
| 700 bool* hinting_timed_out, |
| 701 bool* hinting_url_lookup_timed_out, |
| 702 bool* candidate_url_lookup_timed_out) { |
| 703 /* |
| 704 Process the response to the request. |
| 705 Here is a sample response to illustrate the format. |
| 706 { |
| 707 "prerender_response": { |
| 708 "behavior_id": 6, |
| 709 "hint_response": { |
| 710 "hinting_timed_out": 0, |
| 711 "candidates": [ |
| 712 { "url": "http://www.cnn.com/story-1", |
| 713 "in_index": 1, |
| 714 "likelihood": 0.60, |
| 715 "in_index_timed_out": 0 |
| 716 }, |
| 717 { "url": "http://www.cnn.com/story-2", |
| 718 "in_index": 1, |
| 719 "likelihood": 0.30, |
| 720 "in_index_timed_out": 0 |
| 721 } |
| 722 ] |
| 723 }, |
| 724 "candidate_check_response": { |
| 725 "candidates": [ |
| 726 { "url": "http://www.cnn.com/sports/", |
| 727 "in_index": 1, |
| 728 "in_index_timed_out": 0 |
| 729 }, |
| 730 { "url": "http://www.cnn.com/politics/", |
| 731 "in_index": 0, |
| 732 "in_index_timed_out": "1" |
| 733 } |
| 734 ] |
| 735 } |
| 736 } |
| 737 } |
| 738 */ |
| 739 ListValue* list = NULL; |
| 740 int int_value; |
| 741 if (!dict->GetInteger("prerender_response.behavior_id", &int_value) || |
| 742 int_value != GetPrerenderServiceBehaviorID()) { |
| 743 return false; |
| 744 } |
| 745 if (!dict->GetList("prerender_response.candidate_check_response.candidates", |
| 746 &list)) { |
| 747 if (info->candidate_urls_.size() > 0) |
| 748 return false; |
| 749 } else { |
| 750 for (size_t i = 0; i < list->GetSize(); i++) { |
| 751 DictionaryValue* d; |
| 752 if (!list->GetDictionary(i, &d)) |
| 753 return false; |
| 754 string url_string; |
| 755 if (!d->GetString("url", &url_string) || !GURL(url_string).is_valid()) |
| 756 return false; |
| 757 GURL url(url_string); |
| 758 int in_index_timed_out = 0; |
| 759 int in_index = 0; |
| 760 if ((!d->GetInteger("in_index_timed_out", &in_index_timed_out) || |
| 761 in_index_timed_out != 1) && |
| 762 !d->GetInteger("in_index", &in_index)) { |
| 763 return false; |
| 764 } |
| 765 if (in_index < 0 || in_index > 1 || |
| 766 in_index_timed_out < 0 || in_index_timed_out > 1) { |
| 767 return false; |
| 768 } |
| 769 if (in_index_timed_out == 1) |
| 770 *candidate_url_lookup_timed_out = true; |
| 771 for (size_t j = 0; j < info->candidate_urls_.size(); j++) { |
| 772 if (info->candidate_urls_[j].url == url) { |
| 773 info->candidate_urls_[j].service_whitelist_reported = true; |
| 774 info->candidate_urls_[j].service_whitelist = (in_index == 1); |
| 775 info->candidate_urls_[j].service_whitelist_lookup_ok = |
| 776 ((1 - in_index_timed_out) == 1); |
| 777 } |
| 778 } |
| 779 } |
| 780 for (size_t i = 0; i < info->candidate_urls_.size(); i++) { |
| 781 if (!info->candidate_urls_[i].service_whitelist_reported) |
| 782 return false; |
| 783 } |
| 784 } |
| 785 |
| 786 list = NULL; |
| 787 if (dict->GetInteger("prerender_response.hint_response.hinting_timed_out", |
| 788 &int_value) && |
| 789 int_value == 1) { |
| 790 *hinting_timed_out = true; |
| 791 } else if (!dict->GetList("prerender_response.hint_response.candidates", |
| 792 &list)) { |
| 793 return false; |
| 794 } else { |
| 795 for (int i = 0; i < static_cast<int>(list->GetSize()); i++) { |
| 796 DictionaryValue* d; |
| 797 if (!list->GetDictionary(i, &d)) |
| 798 return false; |
| 799 string url; |
| 800 double priority; |
| 801 if (!d->GetString("url", &url) || !d->GetDouble("likelihood", &priority) |
| 802 || !GURL(url).is_valid()) { |
| 803 return false; |
| 804 } |
| 805 int in_index_timed_out = 0; |
| 806 int in_index = 0; |
| 807 if ((!d->GetInteger("in_index_timed_out", &in_index_timed_out) || |
| 808 in_index_timed_out != 1) && |
| 809 !d->GetInteger("in_index", &in_index)) { |
| 810 return false; |
| 811 } |
| 812 if (priority < 0.0 || priority > 1.0 || in_index < 0 || in_index > 1 || |
| 813 in_index_timed_out < 0 || in_index_timed_out > 1) { |
| 814 return false; |
| 815 } |
| 816 if (in_index_timed_out == 1) |
| 817 *hinting_url_lookup_timed_out = true; |
| 818 info->MaybeAddCandidateURLFromService(GURL(url), |
| 819 priority, |
| 820 in_index == 1, |
| 821 (1 - in_index_timed_out) == 1); |
| 822 } |
| 823 } |
| 824 |
| 825 return true; |
| 826 } |
| 827 |
| 828 void PrerenderLocalPredictor::OnURLFetchComplete( |
| 829 const net::URLFetcher* source) { |
| 830 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 831 RecordEvent(EVENT_PRERENDER_SERVICE_RECEIVED_RESULT); |
| 832 net::URLFetcher* fetcher = const_cast<net::URLFetcher*>(source); |
| 833 OutstandingFetchers::iterator it = |
| 834 outstanding_prerender_service_requests_.find(fetcher); |
| 835 if (it == outstanding_prerender_service_requests_.end()) { |
| 836 RecordEvent(EVENT_PRERENDER_SERVICE_NO_RECORD_FOR_RESULT); |
| 837 return; |
| 838 } |
| 839 scoped_ptr<CandidatePrerenderInfo> info(it->second); |
| 840 outstanding_prerender_service_requests_.erase(it); |
| 841 TIMING_HISTOGRAM("Prerender.LocalPredictorServiceLookupTime", |
| 842 base::Time::Now() - info->start_time_); |
| 843 string result; |
| 844 fetcher->GetResponseAsString(&result); |
| 845 scoped_ptr<Value> root; |
| 846 root.reset(base::JSONReader::Read(result)); |
| 847 bool hinting_timed_out = false; |
| 848 bool hinting_url_lookup_timed_out = false; |
| 849 bool candidate_url_lookup_timed_out = false; |
| 850 if (!root.get() || !root->IsType(Value::TYPE_DICTIONARY)) { |
| 851 RecordEvent(EVENT_PRERENDER_SERVICE_PARSE_ERROR_INCORRECT_JSON); |
| 852 } else { |
| 853 if (ApplyParsedPrerenderServiceResponse( |
| 854 static_cast<DictionaryValue*>(root.get()), |
| 855 info.get(), |
| 856 &hinting_timed_out, |
| 857 &hinting_url_lookup_timed_out, |
| 858 &candidate_url_lookup_timed_out)) { |
| 859 // We finished parsing the result, and found no errors. |
| 860 RecordEvent(EVENT_PRERENDER_SERVICE_PARSED_CORRECTLY); |
| 861 if (hinting_timed_out) |
| 862 RecordEvent(EVENT_PRERENDER_SERVICE_HINTING_TIMED_OUT); |
| 863 if (hinting_url_lookup_timed_out) |
| 864 RecordEvent(EVENT_PRERENDER_SERVICE_HINTING_URL_LOOKUP_TIMED_OUT); |
| 865 if (candidate_url_lookup_timed_out) |
| 866 RecordEvent(EVENT_PRERENDER_SERVICE_CANDIDATE_URL_LOOKUP_TIMED_OUT); |
| 867 DoLoggedInLookup(info.Pass()); |
| 868 return; |
| 869 } |
| 870 } |
| 871 |
| 872 // If we did not return earlier, an error happened during parsing. |
| 873 // Record this, and proceed. |
| 874 RecordEvent(EVENT_PRERENDER_SERVICE_PARSE_ERROR); |
| 875 DoLoggedInLookup(info.Pass()); |
| 876 } |
| 877 |
| 878 void PrerenderLocalPredictor:: DoLoggedInLookup( |
| 879 scoped_ptr<CandidatePrerenderInfo> info) { |
| 880 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
551 scoped_refptr<LoggedInPredictorTable> logged_in_table = | 881 scoped_refptr<LoggedInPredictorTable> logged_in_table = |
552 prerender_manager_->logged_in_predictor_table(); | 882 prerender_manager_->logged_in_predictor_table(); |
553 | 883 |
554 if (!logged_in_table.get()) { | 884 if (!logged_in_table.get()) { |
555 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_LOGGED_IN_TABLE_FOUND); | 885 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_NO_LOGGED_IN_TABLE_FOUND); |
556 return; | 886 return; |
557 } | 887 } |
558 | 888 |
559 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_ISSUING_LOGGED_IN_LOOKUP); | 889 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_ISSUING_LOGGED_IN_LOOKUP); |
560 | 890 |
561 LocalPredictorURLLookupInfo* info_ptr = info.get(); | 891 info->start_time_ = base::Time::Now(); |
| 892 |
| 893 CandidatePrerenderInfo* info_ptr = info.get(); |
562 BrowserThread::PostTaskAndReply( | 894 BrowserThread::PostTaskAndReply( |
563 BrowserThread::DB, FROM_HERE, | 895 BrowserThread::DB, FROM_HERE, |
564 base::Bind(&LookupLoggedInStatesOnDBThread, | 896 base::Bind(&LookupLoggedInStatesOnDBThread, |
565 logged_in_table, | 897 logged_in_table, |
566 info_ptr), | 898 info_ptr), |
567 base::Bind(&PrerenderLocalPredictor::ContinuePrerenderCheck, | 899 base::Bind(&PrerenderLocalPredictor::ContinuePrerenderCheck, |
568 weak_factory_.GetWeakPtr(), | 900 weak_factory_.GetWeakPtr(), |
569 session_storage_namespace, | |
570 base::Passed(&size), | |
571 base::Passed(&info))); | 901 base::Passed(&info))); |
572 } | 902 } |
573 | 903 |
574 void PrerenderLocalPredictor::LogCandidateURLStats(const GURL& url) const { | 904 void PrerenderLocalPredictor::LogCandidateURLStats(const GURL& url) const { |
575 if (url_whitelist_.count(GetInt64URLHashForURL(url)) > 0) { | 905 if (url_whitelist_.count(GetInt64URLHashForURL(url)) > 0) { |
576 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST); | 906 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST); |
577 if (IsRootPageURL(url)) | 907 if (IsRootPageURL(url)) |
578 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST_ROOT_PAGE); | 908 RecordEvent(EVENT_PRERENDER_URL_LOOKUP_RESULT_ON_WHITELIST_ROOT_PAGE); |
579 } | 909 } |
580 if (IsRootPageURL(url)) | 910 if (IsRootPageURL(url)) |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 if (lowest_priority_prerender == NULL || | 1034 if (lowest_priority_prerender == NULL || |
705 lowest_priority_prerender->GetCurrentDecayedPriority() > | 1035 lowest_priority_prerender->GetCurrentDecayedPriority() > |
706 decayed_priority) { | 1036 decayed_priority) { |
707 lowest_priority_prerender = p; | 1037 lowest_priority_prerender = p; |
708 } | 1038 } |
709 } | 1039 } |
710 return lowest_priority_prerender; | 1040 return lowest_priority_prerender; |
711 } | 1041 } |
712 | 1042 |
713 void PrerenderLocalPredictor::ContinuePrerenderCheck( | 1043 void PrerenderLocalPredictor::ContinuePrerenderCheck( |
714 scoped_refptr<SessionStorageNamespace> session_storage_namespace, | 1044 scoped_ptr<CandidatePrerenderInfo> info) { |
715 scoped_ptr<gfx::Size> size, | 1045 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
716 scoped_ptr<LocalPredictorURLLookupInfo> info) { | 1046 TIMING_HISTOGRAM("Prerender.LocalPredictorLoggedInLookupTime", |
| 1047 base::Time::Now() - info->start_time_); |
717 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_STARTED); | 1048 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_STARTED); |
| 1049 if (info->candidate_urls_.size() == 0) { |
| 1050 RecordEvent(EVENT_NO_PRERENDER_CANDIDATES); |
| 1051 return; |
| 1052 } |
718 scoped_ptr<LocalPredictorURLInfo> url_info; | 1053 scoped_ptr<LocalPredictorURLInfo> url_info; |
719 scoped_refptr<SafeBrowsingDatabaseManager> sb_db_manager = | 1054 scoped_refptr<SafeBrowsingDatabaseManager> sb_db_manager = |
720 g_browser_process->safe_browsing_service()->database_manager(); | 1055 g_browser_process->safe_browsing_service()->database_manager(); |
721 PrerenderProperties* prerender_properties = NULL; | 1056 PrerenderProperties* prerender_properties = NULL; |
722 | 1057 |
723 for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) { | 1058 for (int i = 0; i < static_cast<int>(info->candidate_urls_.size()); i++) { |
724 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_EXAMINE_NEXT_URL); | 1059 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_EXAMINE_NEXT_URL); |
725 url_info.reset(new LocalPredictorURLInfo(info->candidate_urls_[i])); | 1060 url_info.reset(new LocalPredictorURLInfo(info->candidate_urls_[i])); |
726 | 1061 |
727 // We need to check whether we can issue a prerender for this URL. | 1062 // 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 Loading... |
772 url_info.reset(NULL); | 1107 url_info.reset(NULL); |
773 continue; | 1108 continue; |
774 } | 1109 } |
775 if (!SkipLocalPredictorWhitelist() && | 1110 if (!SkipLocalPredictorWhitelist() && |
776 sb_db_manager->CheckSideEffectFreeWhitelistUrl(url_info->url)) { | 1111 sb_db_manager->CheckSideEffectFreeWhitelistUrl(url_info->url)) { |
777 // If a page is on the side-effect free whitelist, we will just prerender | 1112 // If a page is on the side-effect free whitelist, we will just prerender |
778 // it without any additional checks. | 1113 // it without any additional checks. |
779 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ON_SIDE_EFFECT_FREE_WHITELIST); | 1114 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ON_SIDE_EFFECT_FREE_WHITELIST); |
780 break; | 1115 break; |
781 } | 1116 } |
| 1117 if (!SkipLocalPredictorServiceWhitelist() && |
| 1118 url_info->service_whitelist && url_info->service_whitelist_lookup_ok) { |
| 1119 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ON_SERVICE_WHITELIST); |
| 1120 break; |
| 1121 } |
782 if (!SkipLocalPredictorLoggedIn() && | 1122 if (!SkipLocalPredictorLoggedIn() && |
783 !url_info->logged_in && url_info->logged_in_lookup_ok) { | 1123 !url_info->logged_in && url_info->logged_in_lookup_ok) { |
784 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_NOT_LOGGED_IN); | 1124 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_NOT_LOGGED_IN); |
785 break; | 1125 break; |
786 } | 1126 } |
787 if (!SkipLocalPredictorDefaultNoPrerender()) { | 1127 if (!SkipLocalPredictorDefaultNoPrerender()) { |
788 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_NOT_PRERENDERING); | 1128 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_NOT_PRERENDERING); |
789 url_info.reset(NULL); | 1129 url_info.reset(NULL); |
790 } else { | 1130 } else { |
791 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_PRERENDERING); | 1131 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_FALLTHROUGH_PRERENDERING); |
792 } | 1132 } |
793 } | 1133 } |
794 if (!url_info.get()) | 1134 if (!url_info.get()) |
795 return; | 1135 return; |
796 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER); | 1136 RecordEvent(EVENT_CONTINUE_PRERENDER_CHECK_ISSUING_PRERENDER); |
797 DCHECK(prerender_properties != NULL); | 1137 DCHECK(prerender_properties != NULL); |
798 if (IsLocalPredictorPrerenderLaunchEnabled()) { | 1138 if (IsLocalPredictorPrerenderLaunchEnabled()) { |
799 IssuePrerender(session_storage_namespace, size.Pass(), | 1139 IssuePrerender(info.Pass(), url_info.Pass(), prerender_properties); |
800 url_info.Pass(), prerender_properties); | |
801 } | 1140 } |
802 } | 1141 } |
803 | 1142 |
804 void PrerenderLocalPredictor::IssuePrerender( | 1143 void PrerenderLocalPredictor::IssuePrerender( |
805 scoped_refptr<SessionStorageNamespace> session_storage_namespace, | 1144 scoped_ptr<CandidatePrerenderInfo> info, |
806 scoped_ptr<gfx::Size> size, | 1145 scoped_ptr<LocalPredictorURLInfo> url_info, |
807 scoped_ptr<LocalPredictorURLInfo> info, | |
808 PrerenderProperties* prerender_properties) { | 1146 PrerenderProperties* prerender_properties) { |
809 URLID url_id = info->id; | 1147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
810 const GURL& url = info->url; | 1148 URLID url_id = url_info->id; |
811 double priority = info->priority; | 1149 const GURL& url = url_info->url; |
| 1150 double priority = url_info->priority; |
812 base::Time current_time = GetCurrentTime(); | 1151 base::Time current_time = GetCurrentTime(); |
813 RecordEvent(EVENT_ISSUING_PRERENDER); | 1152 RecordEvent(EVENT_ISSUING_PRERENDER); |
814 | 1153 |
815 // Issue the prerender and obtain a new handle. | 1154 // Issue the prerender and obtain a new handle. |
816 scoped_ptr<prerender::PrerenderHandle> new_prerender_handle( | 1155 scoped_ptr<prerender::PrerenderHandle> new_prerender_handle( |
817 prerender_manager_->AddPrerenderFromLocalPredictor( | 1156 prerender_manager_->AddPrerenderFromLocalPredictor( |
818 url, session_storage_namespace.get(), *size)); | 1157 url, info->session_storage_namespace_.get(), *(info->size_))); |
819 | 1158 |
820 // Check if this is a duplicate of an existing prerender. If yes, clean up | 1159 // Check if this is a duplicate of an existing prerender. If yes, clean up |
821 // the new handle. | 1160 // the new handle. |
822 for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) { | 1161 for (int i = 0; i < static_cast<int>(issued_prerenders_.size()); i++) { |
823 PrerenderProperties* p = issued_prerenders_[i]; | 1162 PrerenderProperties* p = issued_prerenders_[i]; |
824 DCHECK(p != NULL); | 1163 DCHECK(p != NULL); |
825 if (new_prerender_handle && | 1164 if (new_prerender_handle && |
826 new_prerender_handle->RepresentingSamePrerenderAs( | 1165 new_prerender_handle->RepresentingSamePrerenderAs( |
827 p->prerender_handle.get())) { | 1166 p->prerender_handle.get())) { |
828 new_prerender_handle->OnCancel(); | 1167 new_prerender_handle->OnCancel(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 } | 1245 } |
907 if (best_matched_prerender) { | 1246 if (best_matched_prerender) { |
908 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_MATCH); | 1247 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_MATCH); |
909 best_matched_prerender->would_have_matched = true; | 1248 best_matched_prerender->would_have_matched = true; |
910 if (session_storage_namespace_matches) | 1249 if (session_storage_namespace_matches) |
911 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MATCH); | 1250 RecordEvent(EVENT_TAB_HELPER_URL_SEEN_NAMESPACE_MATCH); |
912 } | 1251 } |
913 } | 1252 } |
914 | 1253 |
915 } // namespace prerender | 1254 } // namespace prerender |
OLD | NEW |