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

Side by Side Diff: components/suggestions/suggestions_service.cc

Issue 410673002: [Suggestions] Moving suggestions code to a new component (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixes Created 6 years, 5 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 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 "chrome/browser/search/suggestions/suggestions_service.h" 5 #include "components/suggestions/suggestions_service.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 #include <string> 8 #include <string>
9 9
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.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/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
15 #include "base/time/time.h" 16 #include "base/time/time.h"
16 #include "chrome/browser/search/suggestions/blacklist_store.h"
17 #include "chrome/browser/search/suggestions/suggestions_store.h"
18 #include "components/pref_registry/pref_registry_syncable.h" 17 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "components/suggestions/blacklist_store.h"
19 #include "components/suggestions/suggestions_store.h"
19 #include "components/variations/variations_associated_data.h" 20 #include "components/variations/variations_associated_data.h"
20 #include "components/variations/variations_http_header_provider.h" 21 #include "components/variations/variations_http_header_provider.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "net/base/escape.h" 22 #include "net/base/escape.h"
23 #include "net/base/load_flags.h" 23 #include "net/base/load_flags.h"
24 #include "net/base/net_errors.h" 24 #include "net/base/net_errors.h"
25 #include "net/base/url_util.h" 25 #include "net/base/url_util.h"
26 #include "net/http/http_response_headers.h" 26 #include "net/http/http_response_headers.h"
27 #include "net/http/http_status_code.h" 27 #include "net/http/http_status_code.h"
28 #include "net/http/http_util.h" 28 #include "net/http/http_util.h"
29 #include "net/url_request/url_fetcher.h" 29 #include "net/url_request/url_fetcher.h"
30 #include "net/url_request/url_request_status.h" 30 #include "net/url_request/url_request_status.h"
31 #include "url/gurl.h" 31 #include "url/gurl.h"
32 32
33 using base::CancelableClosure; 33 using base::CancelableClosure;
34 using content::BrowserThread;
35 34
36 namespace suggestions { 35 namespace suggestions {
37 36
38 namespace { 37 namespace {
39 38
40 // Used to UMA log the state of the last response from the server. 39 // Used to UMA log the state of the last response from the server.
41 enum SuggestionsResponseState { 40 enum SuggestionsResponseState {
42 RESPONSE_EMPTY, 41 RESPONSE_EMPTY,
43 RESPONSE_INVALID, 42 RESPONSE_INVALID,
44 RESPONSE_VALID, 43 RESPONSE_VALID,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 << GetExperimentParam(kSuggestionsFieldTrialBlacklistUrlParam) << "="; 112 << GetExperimentParam(kSuggestionsFieldTrialBlacklistUrlParam) << "=";
114 return blacklist_url_prefix_stream.str(); 113 return blacklist_url_prefix_stream.str();
115 } 114 }
116 115
117 } // namespace 116 } // namespace
118 117
119 SuggestionsService::SuggestionsService( 118 SuggestionsService::SuggestionsService(
120 net::URLRequestContextGetter* url_request_context, 119 net::URLRequestContextGetter* url_request_context,
121 scoped_ptr<SuggestionsStore> suggestions_store, 120 scoped_ptr<SuggestionsStore> suggestions_store,
122 scoped_ptr<ImageManager> thumbnail_manager, 121 scoped_ptr<ImageManager> thumbnail_manager,
123 scoped_ptr<BlacklistStore> blacklist_store) 122 scoped_ptr<BlacklistStore> blacklist_store,
124 : suggestions_store_(suggestions_store.Pass()), 123 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
blundell 2014/07/24 08:31:45 It looks like this object is created and used enti
124 : ui_task_runner_(ui_task_runner),
125 suggestions_store_(suggestions_store.Pass()),
125 blacklist_store_(blacklist_store.Pass()), 126 blacklist_store_(blacklist_store.Pass()),
126 thumbnail_manager_(thumbnail_manager.Pass()), 127 thumbnail_manager_(thumbnail_manager.Pass()),
127 url_request_context_(url_request_context), 128 url_request_context_(url_request_context),
128 blacklist_delay_sec_(kBlacklistDefaultDelaySec), 129 blacklist_delay_sec_(kBlacklistDefaultDelaySec),
129 weak_ptr_factory_(this), 130 weak_ptr_factory_(this),
130 request_timeout_ms_(kDefaultRequestTimeoutMs) { 131 request_timeout_ms_(kDefaultRequestTimeoutMs) {
131 // Obtain various parameters from Variations. 132 // Obtain various parameters from Variations.
132 suggestions_url_ = 133 suggestions_url_ =
133 GURL(GetExperimentParam(kSuggestionsFieldTrialURLParam) + "?" + 134 GURL(GetExperimentParam(kSuggestionsFieldTrialURLParam) + "?" +
134 GetExperimentParam(kSuggestionsFieldTrialCommonParamsParam)); 135 GetExperimentParam(kSuggestionsFieldTrialCommonParamsParam));
(...skipping 14 matching lines...) Expand all
149 } 150 }
150 151
151 // static 152 // static
152 bool SuggestionsService::IsControlGroup() { 153 bool SuggestionsService::IsControlGroup() {
153 return GetExperimentParam(kSuggestionsFieldTrialControlParam) == 154 return GetExperimentParam(kSuggestionsFieldTrialControlParam) ==
154 kSuggestionsFieldTrialStateEnabled; 155 kSuggestionsFieldTrialStateEnabled;
155 } 156 }
156 157
157 void SuggestionsService::FetchSuggestionsData( 158 void SuggestionsService::FetchSuggestionsData(
158 SuggestionsService::ResponseCallback callback) { 159 SuggestionsService::ResponseCallback callback) {
159 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 160 DCHECK(thread_checker_.CalledOnValidThread());
160 161
161 FetchSuggestionsDataNoTimeout(callback); 162 FetchSuggestionsDataNoTimeout(callback);
162 163
163 // Post a task to serve the cached suggestions if the request hasn't completed 164 // Post a task to serve the cached suggestions if the request hasn't completed
164 // after some time. Cancels the previous such task, if one existed. 165 // after some time. Cancels the previous such task, if one existed.
165 pending_timeout_closure_.reset(new CancelableClosure(base::Bind( 166 pending_timeout_closure_.reset(new CancelableClosure(base::Bind(
166 &SuggestionsService::OnRequestTimeout, weak_ptr_factory_.GetWeakPtr()))); 167 &SuggestionsService::OnRequestTimeout, weak_ptr_factory_.GetWeakPtr())));
167 BrowserThread::PostDelayedTask( 168 ui_task_runner_->PostDelayedTask(
168 BrowserThread::UI, FROM_HERE, pending_timeout_closure_->callback(), 169 FROM_HERE, pending_timeout_closure_->callback(),
169 base::TimeDelta::FromMilliseconds(request_timeout_ms_)); 170 base::TimeDelta::FromMilliseconds(request_timeout_ms_));
170 } 171 }
171 172
172 void SuggestionsService::FetchSuggestionsDataNoTimeout( 173 void SuggestionsService::FetchSuggestionsDataNoTimeout(
173 SuggestionsService::ResponseCallback callback) { 174 SuggestionsService::ResponseCallback callback) {
174 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 175 DCHECK(thread_checker_.CalledOnValidThread());
175 if (pending_request_.get()) { 176 if (pending_request_.get()) {
176 // Request already exists, so just add requestor to queue. 177 // Request already exists, so just add requestor to queue.
177 waiting_requestors_.push_back(callback); 178 waiting_requestors_.push_back(callback);
178 return; 179 return;
179 } 180 }
180 181
181 // Form new request. 182 // Form new request.
182 DCHECK(waiting_requestors_.empty()); 183 DCHECK(waiting_requestors_.empty());
183 waiting_requestors_.push_back(callback); 184 waiting_requestors_.push_back(callback);
184 IssueRequest(suggestions_url_); 185 IssueRequest(suggestions_url_);
185 } 186 }
186 187
187 void SuggestionsService::GetPageThumbnail( 188 void SuggestionsService::GetPageThumbnail(
188 const GURL& url, 189 const GURL& url,
189 base::Callback<void(const GURL&, const SkBitmap*)> callback) { 190 base::Callback<void(const GURL&, const SkBitmap*)> callback) {
190 thumbnail_manager_->GetImageForURL(url, callback); 191 thumbnail_manager_->GetImageForURL(url, callback);
191 } 192 }
192 193
193 void SuggestionsService::BlacklistURL( 194 void SuggestionsService::BlacklistURL(
194 const GURL& candidate_url, 195 const GURL& candidate_url,
195 const SuggestionsService::ResponseCallback& callback) { 196 const SuggestionsService::ResponseCallback& callback) {
196 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 197 DCHECK(thread_checker_.CalledOnValidThread());
197 waiting_requestors_.push_back(callback); 198 waiting_requestors_.push_back(callback);
198 199
199 // Blacklist locally, for immediate effect. 200 // Blacklist locally, for immediate effect.
200 if (!blacklist_store_->BlacklistUrl(candidate_url)) { 201 if (!blacklist_store_->BlacklistUrl(candidate_url)) {
201 DVLOG(1) << "Failed blacklisting attempt."; 202 DVLOG(1) << "Failed blacklisting attempt.";
202 return; 203 return;
203 } 204 }
204 205
205 // If there's an ongoing request, let it complete. 206 // If there's an ongoing request, let it complete.
206 if (pending_request_.get()) return; 207 if (pending_request_.get()) return;
207
208 IssueRequest(BuildBlacklistRequestURL(blacklist_url_prefix_, candidate_url)); 208 IssueRequest(BuildBlacklistRequestURL(blacklist_url_prefix_, candidate_url));
209 } 209 }
210 210
211 // static 211 // static
212 bool SuggestionsService::GetBlacklistedUrl(const net::URLFetcher& request, 212 bool SuggestionsService::GetBlacklistedUrl(const net::URLFetcher& request,
213 GURL* url) { 213 GURL* url) {
214 bool is_blacklist_request = StartsWithASCII(request.GetOriginalURL().spec(), 214 bool is_blacklist_request = StartsWithASCII(request.GetOriginalURL().spec(),
215 GetBlacklistUrlPrefix(), true); 215 GetBlacklistUrlPrefix(), true);
216 if (!is_blacklist_request) return false; 216 if (!is_blacklist_request) return false;
217 217
(...skipping 30 matching lines...) Expand all
248 request->SetRequestContext(url_request_context_); 248 request->SetRequestContext(url_request_context_);
249 // Add Chrome experiment state to the request headers. 249 // Add Chrome experiment state to the request headers.
250 net::HttpRequestHeaders headers; 250 net::HttpRequestHeaders headers;
251 variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders( 251 variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders(
252 request->GetOriginalURL(), false, false, &headers); 252 request->GetOriginalURL(), false, false, &headers);
253 request->SetExtraRequestHeaders(headers.ToString()); 253 request->SetExtraRequestHeaders(headers.ToString());
254 return request; 254 return request;
255 } 255 }
256 256
257 void SuggestionsService::OnRequestTimeout() { 257 void SuggestionsService::OnRequestTimeout() {
258 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 258 DCHECK(thread_checker_.CalledOnValidThread());
259 ServeFromCache(); 259 ServeFromCache();
260 } 260 }
261 261
262 void SuggestionsService::OnURLFetchComplete(const net::URLFetcher* source) { 262 void SuggestionsService::OnURLFetchComplete(const net::URLFetcher* source) {
263 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 263 DCHECK(thread_checker_.CalledOnValidThread());
264 DCHECK_EQ(pending_request_.get(), source); 264 DCHECK_EQ(pending_request_.get(), source);
265
266 // We no longer need the timeout closure. Delete it whether or not it has run. 265 // We no longer need the timeout closure. Delete it whether or not it has run.
267 // If it hasn't, this cancels it. 266 // If it hasn't, this cancels it.
268 pending_timeout_closure_.reset(); 267 pending_timeout_closure_.reset();
269 268
270 // The fetcher will be deleted when the request is handled. 269 // The fetcher will be deleted when the request is handled.
271 scoped_ptr<const net::URLFetcher> request(pending_request_.release()); 270 scoped_ptr<const net::URLFetcher> request(pending_request_.release());
272 const net::URLRequestStatus& request_status = request->GetStatus(); 271 const net::URLRequestStatus& request_status = request->GetStatus();
273 if (request_status.status() != net::URLRequestStatus::SUCCESS) { 272 if (request_status.status() != net::URLRequestStatus::SUCCESS) {
274 UMA_HISTOGRAM_SPARSE_SLOWLY("Suggestions.FailedRequestErrorCode", 273 UMA_HISTOGRAM_SPARSE_SLOWLY("Suggestions.FailedRequestErrorCode",
275 -request_status.error()); 274 -request_status.error());
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 suggestions_store_->LoadSuggestions(&suggestions); 338 suggestions_store_->LoadSuggestions(&suggestions);
340 FilterAndServe(&suggestions); 339 FilterAndServe(&suggestions);
341 } 340 }
342 341
343 void SuggestionsService::FilterAndServe(SuggestionsProfile* suggestions) { 342 void SuggestionsService::FilterAndServe(SuggestionsProfile* suggestions) {
344 blacklist_store_->FilterSuggestions(suggestions); 343 blacklist_store_->FilterSuggestions(suggestions);
345 DispatchRequestsAndClear(*suggestions, &waiting_requestors_); 344 DispatchRequestsAndClear(*suggestions, &waiting_requestors_);
346 } 345 }
347 346
348 void SuggestionsService::ScheduleBlacklistUpload(bool last_request_successful) { 347 void SuggestionsService::ScheduleBlacklistUpload(bool last_request_successful) {
349 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 348 DCHECK(thread_checker_.CalledOnValidThread());
350 349
351 UpdateBlacklistDelay(last_request_successful); 350 UpdateBlacklistDelay(last_request_successful);
352 351
353 // Schedule a blacklist upload task. 352 // Schedule a blacklist upload task.
354 GURL blacklist_url; 353 GURL blacklist_url;
355 if (blacklist_store_->GetFirstUrlFromBlacklist(&blacklist_url)) { 354 if (blacklist_store_->GetFirstUrlFromBlacklist(&blacklist_url)) {
356 base::Closure blacklist_cb = 355 base::Closure blacklist_cb =
357 base::Bind(&SuggestionsService::UploadOneFromBlacklist, 356 base::Bind(&SuggestionsService::UploadOneFromBlacklist,
358 weak_ptr_factory_.GetWeakPtr()); 357 weak_ptr_factory_.GetWeakPtr());
359 BrowserThread::PostDelayedTask( 358 ui_task_runner_->PostDelayedTask(
360 BrowserThread::UI, FROM_HERE, blacklist_cb, 359 FROM_HERE, blacklist_cb,
361 base::TimeDelta::FromSeconds(blacklist_delay_sec_)); 360 base::TimeDelta::FromSeconds(blacklist_delay_sec_));
362 } 361 }
363 } 362 }
364 363
365 void SuggestionsService::UploadOneFromBlacklist() { 364 void SuggestionsService::UploadOneFromBlacklist() {
366 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 365 DCHECK(thread_checker_.CalledOnValidThread());
367 366
368 // If there's an ongoing request, let it complete. 367 // If there's an ongoing request, let it complete.
369 if (pending_request_.get()) return; 368 if (pending_request_.get()) return;
370 369
371 GURL blacklist_url; 370 GURL blacklist_url;
372 if (!blacklist_store_->GetFirstUrlFromBlacklist(&blacklist_url)) 371 if (!blacklist_store_->GetFirstUrlFromBlacklist(&blacklist_url))
373 return; // Local blacklist is empty. 372 return; // Local blacklist is empty.
374 373
375 // Send blacklisting request. 374 // Send blacklisting request.
376 IssueRequest(BuildBlacklistRequestURL(blacklist_url_prefix_, blacklist_url)); 375 IssueRequest(BuildBlacklistRequestURL(blacklist_url_prefix_, blacklist_url));
377 } 376 }
378 377
379 void SuggestionsService::UpdateBlacklistDelay(bool last_request_successful) { 378 void SuggestionsService::UpdateBlacklistDelay(bool last_request_successful) {
380 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 379 DCHECK(thread_checker_.CalledOnValidThread());
381 380
382 if (last_request_successful) { 381 if (last_request_successful) {
383 blacklist_delay_sec_ = kBlacklistDefaultDelaySec; 382 blacklist_delay_sec_ = kBlacklistDefaultDelaySec;
384 } else { 383 } else {
385 int candidate_delay = blacklist_delay_sec_ * kBlacklistBackoffMultiplier; 384 int candidate_delay = blacklist_delay_sec_ * kBlacklistBackoffMultiplier;
386 if (candidate_delay < kBlacklistMaxDelaySec) 385 if (candidate_delay < kBlacklistMaxDelaySec)
387 blacklist_delay_sec_ = candidate_delay; 386 blacklist_delay_sec_ = candidate_delay;
388 } 387 }
389 } 388 }
390 389
391 } // namespace suggestions 390 } // namespace suggestions
OLDNEW
« no previous file with comments | « components/suggestions/suggestions_service.h ('k') | components/suggestions/suggestions_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698