| 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 <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/feature_list.h" | 10 #include "base/feature_list.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 "https://s2.googleusercontent.com/s2/favicons?domain_url=%s&alt=s&sz=32"; | 133 "https://s2.googleusercontent.com/s2/favicons?domain_url=%s&alt=s&sz=32"; |
| 134 | 134 |
| 135 // The default expiry timeout is 168 hours. | 135 // The default expiry timeout is 168 hours. |
| 136 const int64_t kDefaultExpiryUsec = 168 * base::Time::kMicrosecondsPerHour; | 136 const int64_t kDefaultExpiryUsec = 168 * base::Time::kMicrosecondsPerHour; |
| 137 | 137 |
| 138 } // namespace | 138 } // namespace |
| 139 | 139 |
| 140 // Helper class for fetching OAuth2 access tokens. | 140 // Helper class for fetching OAuth2 access tokens. |
| 141 // To get a token, call |GetAccessToken|. Does not support multiple concurrent | 141 // To get a token, call |GetAccessToken|. Does not support multiple concurrent |
| 142 // token requests, i.e. check |HasPendingRequest| first. | 142 // token requests, i.e. check |HasPendingRequest| first. |
| 143 class SuggestionsService::AccessTokenFetcher | 143 class SuggestionsServiceImpl::AccessTokenFetcher |
| 144 : public OAuth2TokenService::Consumer { | 144 : public OAuth2TokenService::Consumer { |
| 145 public: | 145 public: |
| 146 using TokenCallback = base::Callback<void(const std::string&)>; | 146 using TokenCallback = base::Callback<void(const std::string&)>; |
| 147 | 147 |
| 148 AccessTokenFetcher(const SigninManagerBase* signin_manager, | 148 AccessTokenFetcher(const SigninManagerBase* signin_manager, |
| 149 OAuth2TokenService* token_service) | 149 OAuth2TokenService* token_service) |
| 150 : OAuth2TokenService::Consumer("suggestions_service"), | 150 : OAuth2TokenService::Consumer("suggestions_service"), |
| 151 signin_manager_(signin_manager), | 151 signin_manager_(signin_manager), |
| 152 token_service_(token_service) {} | 152 token_service_(token_service) {} |
| 153 | 153 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 183 token_request_.reset(nullptr); | 183 token_request_.reset(nullptr); |
| 184 } | 184 } |
| 185 | 185 |
| 186 const SigninManagerBase* signin_manager_; | 186 const SigninManagerBase* signin_manager_; |
| 187 OAuth2TokenService* token_service_; | 187 OAuth2TokenService* token_service_; |
| 188 | 188 |
| 189 TokenCallback callback_; | 189 TokenCallback callback_; |
| 190 std::unique_ptr<OAuth2TokenService::Request> token_request_; | 190 std::unique_ptr<OAuth2TokenService::Request> token_request_; |
| 191 }; | 191 }; |
| 192 | 192 |
| 193 SuggestionsService::SuggestionsService( | 193 SuggestionsServiceImpl::SuggestionsServiceImpl( |
| 194 const SigninManagerBase* signin_manager, | 194 const SigninManagerBase* signin_manager, |
| 195 OAuth2TokenService* token_service, | 195 OAuth2TokenService* token_service, |
| 196 syncer::SyncService* sync_service, | 196 syncer::SyncService* sync_service, |
| 197 net::URLRequestContextGetter* url_request_context, | 197 net::URLRequestContextGetter* url_request_context, |
| 198 std::unique_ptr<SuggestionsStore> suggestions_store, | 198 std::unique_ptr<SuggestionsStore> suggestions_store, |
| 199 std::unique_ptr<ImageManager> thumbnail_manager, | 199 std::unique_ptr<ImageManager> thumbnail_manager, |
| 200 std::unique_ptr<BlacklistStore> blacklist_store) | 200 std::unique_ptr<BlacklistStore> blacklist_store) |
| 201 : sync_service_(sync_service), | 201 : sync_service_(sync_service), |
| 202 sync_service_observer_(this), | 202 sync_service_observer_(this), |
| 203 url_request_context_(url_request_context), | 203 url_request_context_(url_request_context), |
| 204 suggestions_store_(std::move(suggestions_store)), | 204 suggestions_store_(std::move(suggestions_store)), |
| 205 thumbnail_manager_(std::move(thumbnail_manager)), | 205 thumbnail_manager_(std::move(thumbnail_manager)), |
| 206 blacklist_store_(std::move(blacklist_store)), | 206 blacklist_store_(std::move(blacklist_store)), |
| 207 scheduling_delay_(TimeDelta::FromSeconds(kDefaultSchedulingDelaySec)), | 207 scheduling_delay_(TimeDelta::FromSeconds(kDefaultSchedulingDelaySec)), |
| 208 token_fetcher_(new AccessTokenFetcher(signin_manager, token_service)), | 208 token_fetcher_(new AccessTokenFetcher(signin_manager, token_service)), |
| 209 weak_ptr_factory_(this) { | 209 weak_ptr_factory_(this) { |
| 210 // |sync_service_| is null if switches::kDisableSync is set (tests use that). | 210 // |sync_service_| is null if switches::kDisableSync is set (tests use that). |
| 211 if (sync_service_) | 211 if (sync_service_) |
| 212 sync_service_observer_.Add(sync_service_); | 212 sync_service_observer_.Add(sync_service_); |
| 213 // Immediately get the current sync state, so we'll flush the cache if | 213 // Immediately get the current sync state, so we'll flush the cache if |
| 214 // necessary. | 214 // necessary. |
| 215 OnStateChanged(); | 215 OnStateChanged(); |
| 216 } | 216 } |
| 217 | 217 |
| 218 SuggestionsService::~SuggestionsService() {} | 218 SuggestionsServiceImpl::~SuggestionsServiceImpl() {} |
| 219 | 219 |
| 220 bool SuggestionsService::FetchSuggestionsData() { | 220 bool SuggestionsServiceImpl::FetchSuggestionsData() { |
| 221 DCHECK(thread_checker_.CalledOnValidThread()); | 221 DCHECK(thread_checker_.CalledOnValidThread()); |
| 222 // If sync state allows, issue a network request to refresh the suggestions. | 222 // If sync state allows, issue a network request to refresh the suggestions. |
| 223 if (GetSyncState(sync_service_) != INITIALIZED_ENABLED_HISTORY) | 223 if (GetSyncState(sync_service_) != INITIALIZED_ENABLED_HISTORY) |
| 224 return false; | 224 return false; |
| 225 IssueRequestIfNoneOngoing(BuildSuggestionsURL()); | 225 IssueRequestIfNoneOngoing(BuildSuggestionsURL()); |
| 226 return true; | 226 return true; |
| 227 } | 227 } |
| 228 | 228 |
| 229 SuggestionsProfile SuggestionsService::GetSuggestionsDataFromCache() const { | 229 base::Optional<SuggestionsProfile> |
| 230 SuggestionsServiceImpl::GetSuggestionsDataFromCache() const { |
| 230 SuggestionsProfile suggestions; | 231 SuggestionsProfile suggestions; |
| 231 // In case of empty cache or error, |suggestions| stays empty. | 232 // In case of empty cache or error, return empty. |
| 232 suggestions_store_->LoadSuggestions(&suggestions); | 233 if (!suggestions_store_->LoadSuggestions(&suggestions)) { |
| 234 return base::Optional<SuggestionsProfile>(); |
| 235 } |
| 233 thumbnail_manager_->Initialize(suggestions); | 236 thumbnail_manager_->Initialize(suggestions); |
| 234 blacklist_store_->FilterSuggestions(&suggestions); | 237 blacklist_store_->FilterSuggestions(&suggestions); |
| 235 return suggestions; | 238 return base::Optional<SuggestionsProfile>(suggestions); |
| 236 } | 239 } |
| 237 | 240 |
| 238 std::unique_ptr<SuggestionsService::ResponseCallbackList::Subscription> | 241 std::unique_ptr<SuggestionsServiceImpl::ResponseCallbackList::Subscription> |
| 239 SuggestionsService::AddCallback(const ResponseCallback& callback) { | 242 SuggestionsServiceImpl::AddCallback(const ResponseCallback& callback) { |
| 240 return callback_list_.Add(callback); | 243 return callback_list_.Add(callback); |
| 241 } | 244 } |
| 242 | 245 |
| 243 void SuggestionsService::GetPageThumbnail(const GURL& url, | 246 void SuggestionsServiceImpl::GetPageThumbnail(const GURL& url, |
| 244 const BitmapCallback& callback) { | 247 const BitmapCallback& callback) { |
| 245 thumbnail_manager_->GetImageForURL(url, callback); | 248 thumbnail_manager_->GetImageForURL(url, callback); |
| 246 } | 249 } |
| 247 | 250 |
| 248 void SuggestionsService::GetPageThumbnailWithURL( | 251 void SuggestionsServiceImpl::GetPageThumbnailWithURL( |
| 249 const GURL& url, | 252 const GURL& url, |
| 250 const GURL& thumbnail_url, | 253 const GURL& thumbnail_url, |
| 251 const BitmapCallback& callback) { | 254 const BitmapCallback& callback) { |
| 252 thumbnail_manager_->AddImageURL(url, thumbnail_url); | 255 thumbnail_manager_->AddImageURL(url, thumbnail_url); |
| 253 GetPageThumbnail(url, callback); | 256 GetPageThumbnail(url, callback); |
| 254 } | 257 } |
| 255 | 258 |
| 256 bool SuggestionsService::BlacklistURL(const GURL& candidate_url) { | 259 bool SuggestionsServiceImpl::BlacklistURL(const GURL& candidate_url) { |
| 257 DCHECK(thread_checker_.CalledOnValidThread()); | 260 DCHECK(thread_checker_.CalledOnValidThread()); |
| 258 | 261 |
| 259 if (!blacklist_store_->BlacklistUrl(candidate_url)) | 262 if (!blacklist_store_->BlacklistUrl(candidate_url)) |
| 260 return false; | 263 return false; |
| 261 | 264 |
| 262 callback_list_.Notify(GetSuggestionsDataFromCache()); | 265 callback_list_.Notify( |
| 266 GetSuggestionsDataFromCache().value_or(SuggestionsProfile())); |
| 263 | 267 |
| 264 // Blacklist uploads are scheduled on any request completion, so only schedule | 268 // Blacklist uploads are scheduled on any request completion, so only schedule |
| 265 // an upload if there is no ongoing request. | 269 // an upload if there is no ongoing request. |
| 266 if (!pending_request_.get()) | 270 if (!pending_request_.get()) |
| 267 ScheduleBlacklistUpload(); | 271 ScheduleBlacklistUpload(); |
| 268 | 272 |
| 269 return true; | 273 return true; |
| 270 } | 274 } |
| 271 | 275 |
| 272 bool SuggestionsService::UndoBlacklistURL(const GURL& url) { | 276 bool SuggestionsServiceImpl::UndoBlacklistURL(const GURL& url) { |
| 273 DCHECK(thread_checker_.CalledOnValidThread()); | 277 DCHECK(thread_checker_.CalledOnValidThread()); |
| 274 TimeDelta time_delta; | 278 TimeDelta time_delta; |
| 275 if (blacklist_store_->GetTimeUntilURLReadyForUpload(url, &time_delta) && | 279 if (blacklist_store_->GetTimeUntilURLReadyForUpload(url, &time_delta) && |
| 276 time_delta > TimeDelta::FromSeconds(0) && | 280 time_delta > TimeDelta::FromSeconds(0) && |
| 277 blacklist_store_->RemoveUrl(url)) { | 281 blacklist_store_->RemoveUrl(url)) { |
| 278 // The URL was not yet candidate for upload to the server and could be | 282 // The URL was not yet candidate for upload to the server and could be |
| 279 // removed from the blacklist. | 283 // removed from the blacklist. |
| 280 callback_list_.Notify(GetSuggestionsDataFromCache()); | 284 callback_list_.Notify( |
| 285 GetSuggestionsDataFromCache().value_or(SuggestionsProfile())); |
| 281 return true; | 286 return true; |
| 282 } | 287 } |
| 283 return false; | 288 return false; |
| 284 } | 289 } |
| 285 | 290 |
| 286 void SuggestionsService::ClearBlacklist() { | 291 void SuggestionsServiceImpl::ClearBlacklist() { |
| 287 DCHECK(thread_checker_.CalledOnValidThread()); | 292 DCHECK(thread_checker_.CalledOnValidThread()); |
| 288 blacklist_store_->ClearBlacklist(); | 293 blacklist_store_->ClearBlacklist(); |
| 289 callback_list_.Notify(GetSuggestionsDataFromCache()); | 294 callback_list_.Notify( |
| 295 GetSuggestionsDataFromCache().value_or(SuggestionsProfile())); |
| 290 IssueRequestIfNoneOngoing(BuildSuggestionsBlacklistClearURL()); | 296 IssueRequestIfNoneOngoing(BuildSuggestionsBlacklistClearURL()); |
| 291 } | 297 } |
| 292 | 298 |
| 293 // static | 299 // static |
| 294 bool SuggestionsService::GetBlacklistedUrl(const net::URLFetcher& request, | 300 bool SuggestionsServiceImpl::GetBlacklistedUrl(const net::URLFetcher& request, |
| 295 GURL* url) { | 301 GURL* url) { |
| 296 bool is_blacklist_request = base::StartsWith( | 302 bool is_blacklist_request = base::StartsWith( |
| 297 request.GetOriginalURL().spec(), BuildSuggestionsBlacklistURLPrefix(), | 303 request.GetOriginalURL().spec(), BuildSuggestionsBlacklistURLPrefix(), |
| 298 base::CompareCase::SENSITIVE); | 304 base::CompareCase::SENSITIVE); |
| 299 if (!is_blacklist_request) return false; | 305 if (!is_blacklist_request) return false; |
| 300 | 306 |
| 301 // Extract the blacklisted URL from the blacklist request. | 307 // Extract the blacklisted URL from the blacklist request. |
| 302 std::string blacklisted; | 308 std::string blacklisted; |
| 303 if (!net::GetValueForKeyInQuery( | 309 if (!net::GetValueForKeyInQuery( |
| 304 request.GetOriginalURL(), | 310 request.GetOriginalURL(), |
| 305 kSuggestionsBlacklistURLParam, | 311 kSuggestionsBlacklistURLParam, |
| 306 &blacklisted)) { | 312 &blacklisted)) { |
| 307 return false; | 313 return false; |
| 308 } | 314 } |
| 309 | 315 |
| 310 GURL blacklisted_url(blacklisted); | 316 GURL blacklisted_url(blacklisted); |
| 311 blacklisted_url.Swap(url); | 317 blacklisted_url.Swap(url); |
| 312 return true; | 318 return true; |
| 313 } | 319 } |
| 314 | 320 |
| 315 // static | 321 // static |
| 316 void SuggestionsService::RegisterProfilePrefs( | 322 void SuggestionsServiceImpl::RegisterProfilePrefs( |
| 317 user_prefs::PrefRegistrySyncable* registry) { | 323 user_prefs::PrefRegistrySyncable* registry) { |
| 318 SuggestionsStore::RegisterProfilePrefs(registry); | 324 SuggestionsStore::RegisterProfilePrefs(registry); |
| 319 BlacklistStore::RegisterProfilePrefs(registry); | 325 BlacklistStore::RegisterProfilePrefs(registry); |
| 320 } | 326 } |
| 321 | 327 |
| 322 // static | 328 // static |
| 323 GURL SuggestionsService::BuildSuggestionsURL() { | 329 GURL SuggestionsServiceImpl::BuildSuggestionsURL() { |
| 324 return GURL(base::StringPrintf(kSuggestionsURLFormat, | 330 return GURL(base::StringPrintf(kSuggestionsURLFormat, |
| 325 GetGoogleBaseURL().spec().c_str(), | 331 GetGoogleBaseURL().spec().c_str(), |
| 326 kDeviceType)); | 332 kDeviceType)); |
| 327 } | 333 } |
| 328 | 334 |
| 329 // static | 335 // static |
| 330 std::string SuggestionsService::BuildSuggestionsBlacklistURLPrefix() { | 336 std::string SuggestionsServiceImpl::BuildSuggestionsBlacklistURLPrefix() { |
| 331 return base::StringPrintf(kSuggestionsBlacklistURLPrefixFormat, | 337 return base::StringPrintf(kSuggestionsBlacklistURLPrefixFormat, |
| 332 GetGoogleBaseURL().spec().c_str(), kDeviceType); | 338 GetGoogleBaseURL().spec().c_str(), kDeviceType); |
| 333 } | 339 } |
| 334 | 340 |
| 335 // static | 341 // static |
| 336 GURL SuggestionsService::BuildSuggestionsBlacklistURL( | 342 GURL SuggestionsServiceImpl::BuildSuggestionsBlacklistURL( |
| 337 const GURL& candidate_url) { | 343 const GURL& candidate_url) { |
| 338 return GURL(BuildSuggestionsBlacklistURLPrefix() + | 344 return GURL(BuildSuggestionsBlacklistURLPrefix() + |
| 339 net::EscapeQueryParamValue(candidate_url.spec(), true)); | 345 net::EscapeQueryParamValue(candidate_url.spec(), true)); |
| 340 } | 346 } |
| 341 | 347 |
| 342 // static | 348 // static |
| 343 GURL SuggestionsService::BuildSuggestionsBlacklistClearURL() { | 349 GURL SuggestionsServiceImpl::BuildSuggestionsBlacklistClearURL() { |
| 344 return GURL(base::StringPrintf(kSuggestionsBlacklistClearURLFormat, | 350 return GURL(base::StringPrintf(kSuggestionsBlacklistClearURLFormat, |
| 345 GetGoogleBaseURL().spec().c_str(), | 351 GetGoogleBaseURL().spec().c_str(), |
| 346 kDeviceType)); | 352 kDeviceType)); |
| 347 } | 353 } |
| 348 | 354 |
| 349 void SuggestionsService::OnStateChanged() { | 355 void SuggestionsServiceImpl::OnStateChanged() { |
| 350 switch (GetSyncState(sync_service_)) { | 356 switch (GetSyncState(sync_service_)) { |
| 351 case SYNC_OR_HISTORY_SYNC_DISABLED: | 357 case SYNC_OR_HISTORY_SYNC_DISABLED: |
| 352 // Cancel any ongoing request, to stop interacting with the server. | 358 // Cancel any ongoing request, to stop interacting with the server. |
| 353 pending_request_.reset(nullptr); | 359 pending_request_.reset(nullptr); |
| 354 suggestions_store_->ClearSuggestions(); | 360 suggestions_store_->ClearSuggestions(); |
| 355 callback_list_.Notify(SuggestionsProfile()); | 361 callback_list_.Notify(SuggestionsProfile()); |
| 356 break; | 362 break; |
| 357 case NOT_INITIALIZED_ENABLED: | 363 case NOT_INITIALIZED_ENABLED: |
| 358 // Keep the cache (if any), but don't refresh. | 364 // Keep the cache (if any), but don't refresh. |
| 359 break; | 365 break; |
| 360 case INITIALIZED_ENABLED_HISTORY: | 366 case INITIALIZED_ENABLED_HISTORY: |
| 361 // If we have any observers, issue a network request to refresh the | 367 // If we have any observers, issue a network request to refresh the |
| 362 // suggestions in the cache. | 368 // suggestions in the cache. |
| 363 if (!callback_list_.empty()) | 369 if (!callback_list_.empty()) |
| 364 IssueRequestIfNoneOngoing(BuildSuggestionsURL()); | 370 IssueRequestIfNoneOngoing(BuildSuggestionsURL()); |
| 365 break; | 371 break; |
| 366 } | 372 } |
| 367 } | 373 } |
| 368 | 374 |
| 369 void SuggestionsService::SetDefaultExpiryTimestamp( | 375 void SuggestionsServiceImpl::SetDefaultExpiryTimestamp( |
| 370 SuggestionsProfile* suggestions, | 376 SuggestionsProfile* suggestions, |
| 371 int64_t default_timestamp_usec) { | 377 int64_t default_timestamp_usec) { |
| 372 for (int i = 0; i < suggestions->suggestions_size(); ++i) { | 378 for (int i = 0; i < suggestions->suggestions_size(); ++i) { |
| 373 ChromeSuggestion* suggestion = suggestions->mutable_suggestions(i); | 379 ChromeSuggestion* suggestion = suggestions->mutable_suggestions(i); |
| 374 // Do not set expiry if the server has already provided a more specific | 380 // Do not set expiry if the server has already provided a more specific |
| 375 // expiry time for this suggestion. | 381 // expiry time for this suggestion. |
| 376 if (!suggestion->has_expiry_ts()) { | 382 if (!suggestion->has_expiry_ts()) { |
| 377 suggestion->set_expiry_ts(default_timestamp_usec); | 383 suggestion->set_expiry_ts(default_timestamp_usec); |
| 378 } | 384 } |
| 379 } | 385 } |
| 380 } | 386 } |
| 381 | 387 |
| 382 void SuggestionsService::IssueRequestIfNoneOngoing(const GURL& url) { | 388 void SuggestionsServiceImpl::IssueRequestIfNoneOngoing(const GURL& url) { |
| 383 // If there is an ongoing request, let it complete. | 389 // If there is an ongoing request, let it complete. |
| 384 if (pending_request_.get()) { | 390 if (pending_request_.get()) { |
| 385 return; | 391 return; |
| 386 } | 392 } |
| 387 // If there is an ongoing token request, also wait for that. | 393 // If there is an ongoing token request, also wait for that. |
| 388 if (token_fetcher_->HasPendingRequest()) { | 394 if (token_fetcher_->HasPendingRequest()) { |
| 389 return; | 395 return; |
| 390 } | 396 } |
| 391 token_fetcher_->GetAccessToken( | 397 token_fetcher_->GetAccessToken( |
| 392 base::Bind(&SuggestionsService::IssueSuggestionsRequest, | 398 base::Bind(&SuggestionsServiceImpl::IssueSuggestionsRequest, |
| 393 base::Unretained(this), url)); | 399 base::Unretained(this), url)); |
| 394 } | 400 } |
| 395 | 401 |
| 396 void SuggestionsService::IssueSuggestionsRequest( | 402 void SuggestionsServiceImpl::IssueSuggestionsRequest( |
| 397 const GURL& url, | 403 const GURL& url, |
| 398 const std::string& access_token) { | 404 const std::string& access_token) { |
| 399 if (access_token.empty()) { | 405 if (access_token.empty()) { |
| 400 UpdateBlacklistDelay(false); | 406 UpdateBlacklistDelay(false); |
| 401 ScheduleBlacklistUpload(); | 407 ScheduleBlacklistUpload(); |
| 402 return; | 408 return; |
| 403 } | 409 } |
| 404 pending_request_ = CreateSuggestionsRequest(url, access_token); | 410 pending_request_ = CreateSuggestionsRequest(url, access_token); |
| 405 pending_request_->Start(); | 411 pending_request_->Start(); |
| 406 last_request_started_time_ = TimeTicks::Now(); | 412 last_request_started_time_ = TimeTicks::Now(); |
| 407 } | 413 } |
| 408 | 414 |
| 409 std::unique_ptr<net::URLFetcher> SuggestionsService::CreateSuggestionsRequest( | 415 std::unique_ptr<net::URLFetcher> |
| 416 SuggestionsServiceImpl::CreateSuggestionsRequest( |
| 410 const GURL& url, | 417 const GURL& url, |
| 411 const std::string& access_token) { | 418 const std::string& access_token) { |
| 412 std::unique_ptr<net::URLFetcher> request = | 419 std::unique_ptr<net::URLFetcher> request = |
| 413 net::URLFetcher::Create(0, url, net::URLFetcher::GET, this); | 420 net::URLFetcher::Create(0, url, net::URLFetcher::GET, this); |
| 414 data_use_measurement::DataUseUserData::AttachToFetcher( | 421 data_use_measurement::DataUseUserData::AttachToFetcher( |
| 415 request.get(), data_use_measurement::DataUseUserData::SUGGESTIONS); | 422 request.get(), data_use_measurement::DataUseUserData::SUGGESTIONS); |
| 416 int load_flags = net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_COOKIES | | 423 int load_flags = net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_COOKIES | |
| 417 net::LOAD_DO_NOT_SAVE_COOKIES; | 424 net::LOAD_DO_NOT_SAVE_COOKIES; |
| 418 | 425 |
| 419 request->SetLoadFlags(load_flags); | 426 request->SetLoadFlags(load_flags); |
| 420 request->SetRequestContext(url_request_context_); | 427 request->SetRequestContext(url_request_context_); |
| 421 // Add Chrome experiment state to the request headers. | 428 // Add Chrome experiment state to the request headers. |
| 422 net::HttpRequestHeaders headers; | 429 net::HttpRequestHeaders headers; |
| 423 variations::AppendVariationHeaders(request->GetOriginalURL(), false, false, | 430 variations::AppendVariationHeaders(request->GetOriginalURL(), false, false, |
| 424 &headers); | 431 &headers); |
| 425 request->SetExtraRequestHeaders(headers.ToString()); | 432 request->SetExtraRequestHeaders(headers.ToString()); |
| 426 if (!access_token.empty()) { | 433 if (!access_token.empty()) { |
| 427 request->AddExtraRequestHeader( | 434 request->AddExtraRequestHeader( |
| 428 base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str())); | 435 base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str())); |
| 429 } | 436 } |
| 430 return request; | 437 return request; |
| 431 } | 438 } |
| 432 | 439 |
| 433 void SuggestionsService::OnURLFetchComplete(const net::URLFetcher* source) { | 440 void SuggestionsServiceImpl::OnURLFetchComplete(const net::URLFetcher* source) { |
| 434 DCHECK(thread_checker_.CalledOnValidThread()); | 441 DCHECK(thread_checker_.CalledOnValidThread()); |
| 435 DCHECK_EQ(pending_request_.get(), source); | 442 DCHECK_EQ(pending_request_.get(), source); |
| 436 | 443 |
| 437 // The fetcher will be deleted when the request is handled. | 444 // The fetcher will be deleted when the request is handled. |
| 438 std::unique_ptr<const net::URLFetcher> request(std::move(pending_request_)); | 445 std::unique_ptr<const net::URLFetcher> request(std::move(pending_request_)); |
| 439 | 446 |
| 440 const net::URLRequestStatus& request_status = request->GetStatus(); | 447 const net::URLRequestStatus& request_status = request->GetStatus(); |
| 441 if (request_status.status() != net::URLRequestStatus::SUCCESS) { | 448 if (request_status.status() != net::URLRequestStatus::SUCCESS) { |
| 442 // This represents network errors (i.e. the server did not provide a | 449 // This represents network errors (i.e. the server did not provide a |
| 443 // response). | 450 // response). |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 int64_t now_usec = | 493 int64_t now_usec = |
| 487 (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()) | 494 (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()) |
| 488 .ToInternalValue(); | 495 .ToInternalValue(); |
| 489 SetDefaultExpiryTimestamp(&suggestions, now_usec + kDefaultExpiryUsec); | 496 SetDefaultExpiryTimestamp(&suggestions, now_usec + kDefaultExpiryUsec); |
| 490 PopulateExtraData(&suggestions); | 497 PopulateExtraData(&suggestions); |
| 491 suggestions_store_->StoreSuggestions(suggestions); | 498 suggestions_store_->StoreSuggestions(suggestions); |
| 492 } else { | 499 } else { |
| 493 LogResponseState(RESPONSE_INVALID); | 500 LogResponseState(RESPONSE_INVALID); |
| 494 } | 501 } |
| 495 | 502 |
| 496 callback_list_.Notify(GetSuggestionsDataFromCache()); | 503 callback_list_.Notify( |
| 504 GetSuggestionsDataFromCache().value_or(SuggestionsProfile())); |
| 497 | 505 |
| 498 UpdateBlacklistDelay(true); | 506 UpdateBlacklistDelay(true); |
| 499 ScheduleBlacklistUpload(); | 507 ScheduleBlacklistUpload(); |
| 500 } | 508 } |
| 501 | 509 |
| 502 void SuggestionsService::PopulateExtraData(SuggestionsProfile* suggestions) { | 510 void SuggestionsServiceImpl::PopulateExtraData( |
| 511 SuggestionsProfile* suggestions) { |
| 503 for (int i = 0; i < suggestions->suggestions_size(); ++i) { | 512 for (int i = 0; i < suggestions->suggestions_size(); ++i) { |
| 504 suggestions::ChromeSuggestion* s = suggestions->mutable_suggestions(i); | 513 suggestions::ChromeSuggestion* s = suggestions->mutable_suggestions(i); |
| 505 if (!s->has_favicon_url() || s->favicon_url().empty()) { | 514 if (!s->has_favicon_url() || s->favicon_url().empty()) { |
| 506 s->set_favicon_url(base::StringPrintf(kFaviconURL, s->url().c_str())); | 515 s->set_favicon_url(base::StringPrintf(kFaviconURL, s->url().c_str())); |
| 507 } | 516 } |
| 508 } | 517 } |
| 509 } | 518 } |
| 510 | 519 |
| 511 void SuggestionsService::Shutdown() { | 520 void SuggestionsServiceImpl::Shutdown() { |
| 512 // Cancel pending request. | 521 // Cancel pending request. |
| 513 pending_request_.reset(nullptr); | 522 pending_request_.reset(nullptr); |
| 514 } | 523 } |
| 515 | 524 |
| 516 void SuggestionsService::ScheduleBlacklistUpload() { | 525 void SuggestionsServiceImpl::ScheduleBlacklistUpload() { |
| 517 DCHECK(thread_checker_.CalledOnValidThread()); | 526 DCHECK(thread_checker_.CalledOnValidThread()); |
| 518 TimeDelta time_delta; | 527 TimeDelta time_delta; |
| 519 if (blacklist_store_->GetTimeUntilReadyForUpload(&time_delta)) { | 528 if (blacklist_store_->GetTimeUntilReadyForUpload(&time_delta)) { |
| 520 // Blacklist cache is not empty: schedule. | 529 // Blacklist cache is not empty: schedule. |
| 521 base::Closure blacklist_cb = | 530 base::Closure blacklist_cb = |
| 522 base::Bind(&SuggestionsService::UploadOneFromBlacklist, | 531 base::Bind(&SuggestionsServiceImpl::UploadOneFromBlacklist, |
| 523 weak_ptr_factory_.GetWeakPtr()); | 532 weak_ptr_factory_.GetWeakPtr()); |
| 524 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 533 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 525 FROM_HERE, blacklist_cb, time_delta + scheduling_delay_); | 534 FROM_HERE, blacklist_cb, time_delta + scheduling_delay_); |
| 526 } | 535 } |
| 527 } | 536 } |
| 528 | 537 |
| 529 void SuggestionsService::UploadOneFromBlacklist() { | 538 void SuggestionsServiceImpl::UploadOneFromBlacklist() { |
| 530 DCHECK(thread_checker_.CalledOnValidThread()); | 539 DCHECK(thread_checker_.CalledOnValidThread()); |
| 531 | 540 |
| 532 GURL blacklisted_url; | 541 GURL blacklisted_url; |
| 533 if (blacklist_store_->GetCandidateForUpload(&blacklisted_url)) { | 542 if (blacklist_store_->GetCandidateForUpload(&blacklisted_url)) { |
| 534 // Issue a blacklisting request. Even if this request ends up not being sent | 543 // Issue a blacklisting request. Even if this request ends up not being sent |
| 535 // because of an ongoing request, a blacklist request is later scheduled. | 544 // because of an ongoing request, a blacklist request is later scheduled. |
| 536 IssueRequestIfNoneOngoing(BuildSuggestionsBlacklistURL(blacklisted_url)); | 545 IssueRequestIfNoneOngoing(BuildSuggestionsBlacklistURL(blacklisted_url)); |
| 537 return; | 546 return; |
| 538 } | 547 } |
| 539 | 548 |
| 540 // Even though there's no candidate for upload, the blacklist might not be | 549 // Even though there's no candidate for upload, the blacklist might not be |
| 541 // empty. | 550 // empty. |
| 542 ScheduleBlacklistUpload(); | 551 ScheduleBlacklistUpload(); |
| 543 } | 552 } |
| 544 | 553 |
| 545 void SuggestionsService::UpdateBlacklistDelay(bool last_request_successful) { | 554 void SuggestionsServiceImpl::UpdateBlacklistDelay( |
| 555 bool last_request_successful) { |
| 546 DCHECK(thread_checker_.CalledOnValidThread()); | 556 DCHECK(thread_checker_.CalledOnValidThread()); |
| 547 | 557 |
| 548 if (last_request_successful) { | 558 if (last_request_successful) { |
| 549 scheduling_delay_ = TimeDelta::FromSeconds(kDefaultSchedulingDelaySec); | 559 scheduling_delay_ = TimeDelta::FromSeconds(kDefaultSchedulingDelaySec); |
| 550 } else { | 560 } else { |
| 551 TimeDelta candidate_delay = | 561 TimeDelta candidate_delay = |
| 552 scheduling_delay_ * kSchedulingBackoffMultiplier; | 562 scheduling_delay_ * kSchedulingBackoffMultiplier; |
| 553 if (candidate_delay < TimeDelta::FromSeconds(kSchedulingMaxDelaySec)) | 563 if (candidate_delay < TimeDelta::FromSeconds(kSchedulingMaxDelaySec)) |
| 554 scheduling_delay_ = candidate_delay; | 564 scheduling_delay_ = candidate_delay; |
| 555 } | 565 } |
| 556 } | 566 } |
| 557 | 567 |
| 558 } // namespace suggestions | 568 } // namespace suggestions |
| OLD | NEW |