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_impl.h" | 5 #include "components/suggestions/suggestions_service_impl.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" |
11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/memory/ptr_util.h" |
12 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
13 #include "base/metrics/sparse_histogram.h" | 14 #include "base/metrics/sparse_histogram.h" |
14 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
17 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
18 #include "build/build_config.h" | 19 #include "build/build_config.h" |
19 #include "components/data_use_measurement/core/data_use_user_data.h" | 20 #include "components/data_use_measurement/core/data_use_user_data.h" |
20 #include "components/google/core/browser/google_util.h" | 21 #include "components/google/core/browser/google_util.h" |
21 #include "components/pref_registry/pref_registry_syncable.h" | 22 #include "components/pref_registry/pref_registry_syncable.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s"; | 130 const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s"; |
130 | 131 |
131 const char kFaviconURL[] = | 132 const char kFaviconURL[] = |
132 "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"; |
133 | 134 |
134 // The default expiry timeout is 168 hours. | 135 // The default expiry timeout is 168 hours. |
135 const int64_t kDefaultExpiryUsec = 168 * base::Time::kMicrosecondsPerHour; | 136 const int64_t kDefaultExpiryUsec = 168 * base::Time::kMicrosecondsPerHour; |
136 | 137 |
137 } // namespace | 138 } // namespace |
138 | 139 |
139 // Helper class for fetching OAuth2 access tokens. | |
140 // To get a token, call |GetAccessToken|. Does not support multiple concurrent | |
141 // token requests, i.e. check |HasPendingRequest| first. | |
142 class SuggestionsServiceImpl::AccessTokenFetcher | |
143 : public OAuth2TokenService::Consumer { | |
144 public: | |
145 using TokenCallback = base::Callback<void(const std::string&)>; | |
146 | |
147 AccessTokenFetcher(const SigninManagerBase* signin_manager, | |
148 OAuth2TokenService* token_service) | |
149 : OAuth2TokenService::Consumer("suggestions_service"), | |
150 signin_manager_(signin_manager), | |
151 token_service_(token_service) {} | |
152 | |
153 void GetAccessToken(const TokenCallback& callback) { | |
154 callback_ = callback; | |
155 std::string account_id; | |
156 // |signin_manager_| can be null in unit tests. | |
157 if (signin_manager_) | |
158 account_id = signin_manager_->GetAuthenticatedAccountId(); | |
159 OAuth2TokenService::ScopeSet scopes; | |
160 scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope); | |
161 token_request_ = token_service_->StartRequest(account_id, scopes, this); | |
162 } | |
163 | |
164 bool HasPendingRequest() const { return !!token_request_.get(); } | |
165 | |
166 private: | |
167 void OnGetTokenSuccess(const OAuth2TokenService::Request* request, | |
168 const std::string& access_token, | |
169 const base::Time& expiration_time) override { | |
170 DCHECK_EQ(request, token_request_.get()); | |
171 callback_.Run(access_token); | |
172 token_request_.reset(nullptr); | |
173 } | |
174 | |
175 void OnGetTokenFailure(const OAuth2TokenService::Request* request, | |
176 const GoogleServiceAuthError& error) override { | |
177 DCHECK_EQ(request, token_request_.get()); | |
178 LOG(WARNING) << "Token error: " << error.ToString(); | |
179 callback_.Run(std::string()); | |
180 token_request_.reset(nullptr); | |
181 } | |
182 | |
183 const SigninManagerBase* signin_manager_; | |
184 OAuth2TokenService* token_service_; | |
185 | |
186 TokenCallback callback_; | |
187 std::unique_ptr<OAuth2TokenService::Request> token_request_; | |
188 }; | |
189 | |
190 SuggestionsServiceImpl::SuggestionsServiceImpl( | 140 SuggestionsServiceImpl::SuggestionsServiceImpl( |
191 const SigninManagerBase* signin_manager, | 141 SigninManagerBase* signin_manager, |
192 OAuth2TokenService* token_service, | 142 OAuth2TokenService* token_service, |
193 syncer::SyncService* sync_service, | 143 syncer::SyncService* sync_service, |
194 net::URLRequestContextGetter* url_request_context, | 144 net::URLRequestContextGetter* url_request_context, |
195 std::unique_ptr<SuggestionsStore> suggestions_store, | 145 std::unique_ptr<SuggestionsStore> suggestions_store, |
196 std::unique_ptr<ImageManager> thumbnail_manager, | 146 std::unique_ptr<ImageManager> thumbnail_manager, |
197 std::unique_ptr<BlacklistStore> blacklist_store) | 147 std::unique_ptr<BlacklistStore> blacklist_store) |
198 : sync_service_(sync_service), | 148 : signin_manager_(signin_manager), |
| 149 token_service_(token_service), |
| 150 sync_service_(sync_service), |
199 sync_service_observer_(this), | 151 sync_service_observer_(this), |
200 url_request_context_(url_request_context), | 152 url_request_context_(url_request_context), |
201 suggestions_store_(std::move(suggestions_store)), | 153 suggestions_store_(std::move(suggestions_store)), |
202 thumbnail_manager_(std::move(thumbnail_manager)), | 154 thumbnail_manager_(std::move(thumbnail_manager)), |
203 blacklist_store_(std::move(blacklist_store)), | 155 blacklist_store_(std::move(blacklist_store)), |
204 scheduling_delay_(TimeDelta::FromSeconds(kDefaultSchedulingDelaySec)), | 156 scheduling_delay_(TimeDelta::FromSeconds(kDefaultSchedulingDelaySec)), |
205 token_fetcher_(new AccessTokenFetcher(signin_manager, token_service)), | |
206 weak_ptr_factory_(this) { | 157 weak_ptr_factory_(this) { |
207 // |sync_service_| is null if switches::kDisableSync is set (tests use that). | 158 // |sync_service_| is null if switches::kDisableSync is set (tests use that). |
208 if (sync_service_) | 159 if (sync_service_) |
209 sync_service_observer_.Add(sync_service_); | 160 sync_service_observer_.Add(sync_service_); |
210 // Immediately get the current sync state, so we'll flush the cache if | 161 // Immediately get the current sync state, so we'll flush the cache if |
211 // necessary. | 162 // necessary. |
212 OnStateChanged(); | 163 OnStateChanged(); |
213 } | 164 } |
214 | 165 |
215 SuggestionsServiceImpl::~SuggestionsServiceImpl() {} | 166 SuggestionsServiceImpl::~SuggestionsServiceImpl() {} |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 } | 331 } |
381 } | 332 } |
382 } | 333 } |
383 | 334 |
384 void SuggestionsServiceImpl::IssueRequestIfNoneOngoing(const GURL& url) { | 335 void SuggestionsServiceImpl::IssueRequestIfNoneOngoing(const GURL& url) { |
385 // If there is an ongoing request, let it complete. | 336 // If there is an ongoing request, let it complete. |
386 if (pending_request_.get()) { | 337 if (pending_request_.get()) { |
387 return; | 338 return; |
388 } | 339 } |
389 // If there is an ongoing token request, also wait for that. | 340 // If there is an ongoing token request, also wait for that. |
390 if (token_fetcher_->HasPendingRequest()) { | 341 if (token_fetcher_) { |
391 return; | 342 return; |
392 } | 343 } |
393 token_fetcher_->GetAccessToken( | 344 |
394 base::Bind(&SuggestionsServiceImpl::IssueSuggestionsRequest, | 345 OAuth2TokenService::ScopeSet scopes{GaiaConstants::kChromeSyncOAuth2Scope}; |
395 base::Unretained(this), url)); | 346 token_fetcher_ = base::MakeUnique<AccessTokenFetcher>( |
| 347 "suggestions_service", signin_manager_, token_service_, scopes, |
| 348 base::BindOnce(&SuggestionsServiceImpl::AccessTokenAvailable, |
| 349 base::Unretained(this), url)); |
| 350 } |
| 351 |
| 352 void SuggestionsServiceImpl::AccessTokenAvailable( |
| 353 const GURL& url, |
| 354 const GoogleServiceAuthError& error, |
| 355 const std::string& access_token) { |
| 356 DCHECK(token_fetcher_); |
| 357 std::unique_ptr<AccessTokenFetcher> token_fetcher_deleter( |
| 358 std::move(token_fetcher_)); |
| 359 |
| 360 if (error.state() != GoogleServiceAuthError::NONE) { |
| 361 UpdateBlacklistDelay(false); |
| 362 ScheduleBlacklistUpload(); |
| 363 return; |
| 364 } |
| 365 |
| 366 DCHECK(!access_token.empty()); |
| 367 |
| 368 IssueSuggestionsRequest(url, access_token); |
396 } | 369 } |
397 | 370 |
398 void SuggestionsServiceImpl::IssueSuggestionsRequest( | 371 void SuggestionsServiceImpl::IssueSuggestionsRequest( |
399 const GURL& url, | 372 const GURL& url, |
400 const std::string& access_token) { | 373 const std::string& access_token) { |
401 if (access_token.empty()) { | 374 DCHECK(!access_token.empty()); |
402 UpdateBlacklistDelay(false); | |
403 ScheduleBlacklistUpload(); | |
404 return; | |
405 } | |
406 pending_request_ = CreateSuggestionsRequest(url, access_token); | 375 pending_request_ = CreateSuggestionsRequest(url, access_token); |
407 pending_request_->Start(); | 376 pending_request_->Start(); |
408 last_request_started_time_ = TimeTicks::Now(); | 377 last_request_started_time_ = TimeTicks::Now(); |
409 } | 378 } |
410 | 379 |
411 std::unique_ptr<net::URLFetcher> | 380 std::unique_ptr<net::URLFetcher> |
412 SuggestionsServiceImpl::CreateSuggestionsRequest( | 381 SuggestionsServiceImpl::CreateSuggestionsRequest( |
413 const GURL& url, | 382 const GURL& url, |
414 const std::string& access_token) { | 383 const std::string& access_token) { |
415 std::unique_ptr<net::URLFetcher> request = | 384 std::unique_ptr<net::URLFetcher> request = |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 scheduling_delay_ = TimeDelta::FromSeconds(kDefaultSchedulingDelaySec); | 527 scheduling_delay_ = TimeDelta::FromSeconds(kDefaultSchedulingDelaySec); |
559 } else { | 528 } else { |
560 TimeDelta candidate_delay = | 529 TimeDelta candidate_delay = |
561 scheduling_delay_ * kSchedulingBackoffMultiplier; | 530 scheduling_delay_ * kSchedulingBackoffMultiplier; |
562 if (candidate_delay < TimeDelta::FromSeconds(kSchedulingMaxDelaySec)) | 531 if (candidate_delay < TimeDelta::FromSeconds(kSchedulingMaxDelaySec)) |
563 scheduling_delay_ = candidate_delay; | 532 scheduling_delay_ = candidate_delay; |
564 } | 533 } |
565 } | 534 } |
566 | 535 |
567 } // namespace suggestions | 536 } // namespace suggestions |
OLD | NEW |