OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/suggestions/suggestions_service.h" | 5 #include "components/suggestions/suggestions_service.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
12 #include "base/metrics/sparse_histogram.h" | 12 #include "base/metrics/sparse_histogram.h" |
13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "base/strings/stringprintf.h" |
16 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
17 #include "base/time/time.h" | 18 #include "base/time/time.h" |
18 #include "components/pref_registry/pref_registry_syncable.h" | 19 #include "components/pref_registry/pref_registry_syncable.h" |
19 #include "components/suggestions/blacklist_store.h" | 20 #include "components/suggestions/blacklist_store.h" |
20 #include "components/suggestions/suggestions_store.h" | 21 #include "components/suggestions/suggestions_store.h" |
21 #include "components/variations/net/variations_http_header_provider.h" | 22 #include "components/variations/net/variations_http_header_provider.h" |
22 #include "net/base/escape.h" | 23 #include "net/base/escape.h" |
23 #include "net/base/load_flags.h" | 24 #include "net/base/load_flags.h" |
24 #include "net/base/net_errors.h" | 25 #include "net/base/net_errors.h" |
25 #include "net/base/url_util.h" | 26 #include "net/base/url_util.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 // Default delay used when scheduling a request. | 75 // Default delay used when scheduling a request. |
75 const int kDefaultSchedulingDelaySec = 1; | 76 const int kDefaultSchedulingDelaySec = 1; |
76 | 77 |
77 // Multiplier on the delay used when re-scheduling a failed request. | 78 // Multiplier on the delay used when re-scheduling a failed request. |
78 const int kSchedulingBackoffMultiplier = 2; | 79 const int kSchedulingBackoffMultiplier = 2; |
79 | 80 |
80 // Maximum valid delay for scheduling a request. Candidate delays larger than | 81 // Maximum valid delay for scheduling a request. Candidate delays larger than |
81 // this are rejected. This means the maximum backoff is at least 5 / 2 minutes. | 82 // this are rejected. This means the maximum backoff is at least 5 / 2 minutes. |
82 const int kSchedulingMaxDelaySec = 5 * 60; | 83 const int kSchedulingMaxDelaySec = 5 * 60; |
83 | 84 |
| 85 const char kFaviconURL[] = |
| 86 "https://s2.googleusercontent.com/s2/favicons?domain_url=%s&alt=s&sz=32"; |
| 87 |
84 } // namespace | 88 } // namespace |
85 | 89 |
86 // TODO(mathp): Put this in TemplateURL. | 90 // TODO(mathp): Put this in TemplateURL. |
| 91 // TODO(fserb): Add logic to decide the device type of the request. |
| 92 #if defined(OS_ANDROID) || defined(OS_IOS) |
87 const char kSuggestionsURL[] = "https://www.google.com/chromesuggestions?t=2"; | 93 const char kSuggestionsURL[] = "https://www.google.com/chromesuggestions?t=2"; |
88 const char kSuggestionsBlacklistURLPrefix[] = | 94 const char kSuggestionsBlacklistURLPrefix[] = |
89 "https://www.google.com/chromesuggestions/blacklist?t=2&url="; | 95 "https://www.google.com/chromesuggestions/blacklist?t=2&url="; |
| 96 const char kSuggestionsBlacklistClearURL[] = |
| 97 "https://www.google.com/chromesuggestions/blacklist/clear?t=2"; |
| 98 #else |
| 99 const char kSuggestionsURL[] = "https://www.google.com/chromesuggestions?t=1"; |
| 100 const char kSuggestionsBlacklistURLPrefix[] = |
| 101 "https://www.google.com/chromesuggestions/blacklist?t=1&url="; |
| 102 const char kSuggestionsBlacklistClearURL[] = |
| 103 "https://www.google.com/chromesuggestions/blacklist/clear?t=1"; |
| 104 #endif |
90 const char kSuggestionsBlacklistURLParam[] = "url"; | 105 const char kSuggestionsBlacklistURLParam[] = "url"; |
91 | 106 |
92 // The default expiry timeout is 72 hours. | 107 // The default expiry timeout is 168 hours. |
93 const int64 kDefaultExpiryUsec = 72 * base::Time::kMicrosecondsPerHour; | 108 const int64 kDefaultExpiryUsec = 168 * base::Time::kMicrosecondsPerHour; |
94 | 109 |
95 SuggestionsService::SuggestionsService( | 110 SuggestionsService::SuggestionsService( |
96 net::URLRequestContextGetter* url_request_context, | 111 net::URLRequestContextGetter* url_request_context, |
97 scoped_ptr<SuggestionsStore> suggestions_store, | 112 scoped_ptr<SuggestionsStore> suggestions_store, |
98 scoped_ptr<ImageManager> thumbnail_manager, | 113 scoped_ptr<ImageManager> thumbnail_manager, |
99 scoped_ptr<BlacklistStore> blacklist_store) | 114 scoped_ptr<BlacklistStore> blacklist_store) |
100 : url_request_context_(url_request_context), | 115 : url_request_context_(url_request_context), |
101 suggestions_store_(suggestions_store.Pass()), | 116 suggestions_store_(suggestions_store.Pass()), |
102 thumbnail_manager_(thumbnail_manager.Pass()), | 117 thumbnail_manager_(thumbnail_manager.Pass()), |
103 blacklist_store_(blacklist_store.Pass()), | 118 blacklist_store_(blacklist_store.Pass()), |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 blacklist_store_->RemoveUrl(url)) { | 183 blacklist_store_->RemoveUrl(url)) { |
169 // The URL was not yet candidate for upload to the server and could be | 184 // The URL was not yet candidate for upload to the server and could be |
170 // removed from the blacklist. | 185 // removed from the blacklist. |
171 waiting_requestors_.push_back(callback); | 186 waiting_requestors_.push_back(callback); |
172 ServeFromCache(); | 187 ServeFromCache(); |
173 return; | 188 return; |
174 } | 189 } |
175 fail_callback.Run(); | 190 fail_callback.Run(); |
176 } | 191 } |
177 | 192 |
| 193 void SuggestionsService::ClearBlacklist(const ResponseCallback& callback) { |
| 194 DCHECK(thread_checker_.CalledOnValidThread()); |
| 195 blacklist_store_->ClearBlacklist(); |
| 196 IssueRequestIfNoneOngoing(GURL(kSuggestionsBlacklistClearURL)); |
| 197 waiting_requestors_.push_back(callback); |
| 198 ServeFromCache(); |
| 199 } |
| 200 |
178 // static | 201 // static |
179 bool SuggestionsService::GetBlacklistedUrl(const net::URLFetcher& request, | 202 bool SuggestionsService::GetBlacklistedUrl(const net::URLFetcher& request, |
180 GURL* url) { | 203 GURL* url) { |
181 bool is_blacklist_request = base::StartsWith( | 204 bool is_blacklist_request = base::StartsWith( |
182 request.GetOriginalURL().spec(), kSuggestionsBlacklistURLPrefix, | 205 request.GetOriginalURL().spec(), kSuggestionsBlacklistURLPrefix, |
183 base::CompareCase::SENSITIVE); | 206 base::CompareCase::SENSITIVE); |
184 if (!is_blacklist_request) return false; | 207 if (!is_blacklist_request) return false; |
185 | 208 |
186 // Extract the blacklisted URL from the blacklist request. | 209 // Extract the blacklisted URL from the blacklist request. |
187 std::string blacklisted; | 210 std::string blacklisted; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 // in the case of invalid response. | 312 // in the case of invalid response. |
290 SuggestionsProfile suggestions; | 313 SuggestionsProfile suggestions; |
291 if (suggestions_data.empty()) { | 314 if (suggestions_data.empty()) { |
292 LogResponseState(RESPONSE_EMPTY); | 315 LogResponseState(RESPONSE_EMPTY); |
293 suggestions_store_->ClearSuggestions(); | 316 suggestions_store_->ClearSuggestions(); |
294 } else if (suggestions.ParseFromString(suggestions_data)) { | 317 } else if (suggestions.ParseFromString(suggestions_data)) { |
295 LogResponseState(RESPONSE_VALID); | 318 LogResponseState(RESPONSE_VALID); |
296 int64 now_usec = (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()) | 319 int64 now_usec = (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()) |
297 .ToInternalValue(); | 320 .ToInternalValue(); |
298 SetDefaultExpiryTimestamp(&suggestions, now_usec + kDefaultExpiryUsec); | 321 SetDefaultExpiryTimestamp(&suggestions, now_usec + kDefaultExpiryUsec); |
| 322 PopulateFaviconUrls(&suggestions); |
299 suggestions_store_->StoreSuggestions(suggestions); | 323 suggestions_store_->StoreSuggestions(suggestions); |
300 } else { | 324 } else { |
301 LogResponseState(RESPONSE_INVALID); | 325 LogResponseState(RESPONSE_INVALID); |
302 } | 326 } |
303 | 327 |
304 UpdateBlacklistDelay(true); | 328 UpdateBlacklistDelay(true); |
305 ScheduleBlacklistUpload(); | 329 ScheduleBlacklistUpload(); |
306 } | 330 } |
307 | 331 |
| 332 void SuggestionsService::PopulateFaviconUrls(SuggestionsProfile* suggestions) { |
| 333 for (int i = 0; i < suggestions->suggestions_size(); ++i) { |
| 334 suggestions::ChromeSuggestion* s = suggestions->mutable_suggestions(i); |
| 335 if (!s->has_favicon_url() || s->favicon_url().empty()) { |
| 336 s->set_favicon_url(base::StringPrintf(kFaviconURL, s->url().c_str())); |
| 337 } |
| 338 } |
| 339 } |
| 340 |
308 void SuggestionsService::Shutdown() { | 341 void SuggestionsService::Shutdown() { |
309 // Cancel pending request, then serve existing requestors from cache. | 342 // Cancel pending request, then serve existing requestors from cache. |
310 pending_request_.reset(NULL); | 343 pending_request_.reset(NULL); |
311 ServeFromCache(); | 344 ServeFromCache(); |
312 } | 345 } |
313 | 346 |
314 void SuggestionsService::ServeFromCache() { | 347 void SuggestionsService::ServeFromCache() { |
315 SuggestionsProfile suggestions; | 348 SuggestionsProfile suggestions; |
316 // In case of empty cache or error, |suggestions| stays empty. | 349 // In case of empty cache or error, |suggestions| stays empty. |
317 suggestions_store_->LoadSuggestions(&suggestions); | 350 suggestions_store_->LoadSuggestions(&suggestions); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 scheduling_delay_ = TimeDelta::FromSeconds(kDefaultSchedulingDelaySec); | 394 scheduling_delay_ = TimeDelta::FromSeconds(kDefaultSchedulingDelaySec); |
362 } else { | 395 } else { |
363 TimeDelta candidate_delay = | 396 TimeDelta candidate_delay = |
364 scheduling_delay_ * kSchedulingBackoffMultiplier; | 397 scheduling_delay_ * kSchedulingBackoffMultiplier; |
365 if (candidate_delay < TimeDelta::FromSeconds(kSchedulingMaxDelaySec)) | 398 if (candidate_delay < TimeDelta::FromSeconds(kSchedulingMaxDelaySec)) |
366 scheduling_delay_ = candidate_delay; | 399 scheduling_delay_ = candidate_delay; |
367 } | 400 } |
368 } | 401 } |
369 | 402 |
370 } // namespace suggestions | 403 } // namespace suggestions |
OLD | NEW |