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/sync/profile_sync_service.h" | 5 #include "chrome/browser/sync/profile_sync_service.h" |
6 | 6 |
7 #include <cstddef> | 7 #include <cstddef> |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <utility> | 10 #include <utility> |
(...skipping 12 matching lines...) Expand all Loading... | |
23 #include "base/threading/thread_restrictions.h" | 23 #include "base/threading/thread_restrictions.h" |
24 #include "build/build_config.h" | 24 #include "build/build_config.h" |
25 #include "chrome/browser/about_flags.h" | 25 #include "chrome/browser/about_flags.h" |
26 #include "chrome/browser/browser_process.h" | 26 #include "chrome/browser/browser_process.h" |
27 #include "chrome/browser/defaults.h" | 27 #include "chrome/browser/defaults.h" |
28 #include "chrome/browser/net/chrome_cookie_notification_details.h" | 28 #include "chrome/browser/net/chrome_cookie_notification_details.h" |
29 #include "chrome/browser/prefs/pref_service_syncable.h" | 29 #include "chrome/browser/prefs/pref_service_syncable.h" |
30 #include "chrome/browser/profiles/profile.h" | 30 #include "chrome/browser/profiles/profile.h" |
31 #include "chrome/browser/signin/about_signin_internals.h" | 31 #include "chrome/browser/signin/about_signin_internals.h" |
32 #include "chrome/browser/signin/about_signin_internals_factory.h" | 32 #include "chrome/browser/signin/about_signin_internals_factory.h" |
33 #include "chrome/browser/signin/profile_oauth2_token_service.h" | |
34 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | |
33 #include "chrome/browser/signin/signin_manager.h" | 35 #include "chrome/browser/signin/signin_manager.h" |
34 #include "chrome/browser/signin/signin_manager_factory.h" | 36 #include "chrome/browser/signin/signin_manager_factory.h" |
35 #include "chrome/browser/signin/token_service.h" | 37 #include "chrome/browser/signin/token_service.h" |
36 #include "chrome/browser/signin/token_service_factory.h" | 38 #include "chrome/browser/signin/token_service_factory.h" |
37 #include "chrome/browser/sync/backend_migrator.h" | 39 #include "chrome/browser/sync/backend_migrator.h" |
38 #include "chrome/browser/sync/glue/change_processor.h" | 40 #include "chrome/browser/sync/glue/change_processor.h" |
39 #include "chrome/browser/sync/glue/chrome_encryptor.h" | 41 #include "chrome/browser/sync/glue/chrome_encryptor.h" |
40 #include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h" | 42 #include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h" |
41 #include "chrome/browser/sync/glue/data_type_controller.h" | 43 #include "chrome/browser/sync/glue/data_type_controller.h" |
42 #include "chrome/browser/sync/glue/device_info.h" | 44 #include "chrome/browser/sync/glue/device_info.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 typedef GoogleServiceAuthError AuthError; | 106 typedef GoogleServiceAuthError AuthError; |
105 | 107 |
106 const char* ProfileSyncService::kSyncServerUrl = | 108 const char* ProfileSyncService::kSyncServerUrl = |
107 "https://clients4.google.com/chrome-sync"; | 109 "https://clients4.google.com/chrome-sync"; |
108 | 110 |
109 const char* ProfileSyncService::kDevServerUrl = | 111 const char* ProfileSyncService::kDevServerUrl = |
110 "https://clients4.google.com/chrome-sync/dev"; | 112 "https://clients4.google.com/chrome-sync/dev"; |
111 | 113 |
112 static const int kSyncClearDataTimeoutInSeconds = 60; // 1 minute. | 114 static const int kSyncClearDataTimeoutInSeconds = 60; // 1 minute. |
113 | 115 |
114 static const char* kRelevantTokenServices[] = { | 116 static const char* kOAuth2Scopes[] = { |
115 GaiaConstants::kSyncService | 117 GaiaConstants::kChromeSyncOAuth2Scope, |
118 // GoogleTalk scope is needed for notifications. | |
119 GaiaConstants::kGoogleTalkOAuth2Scope | |
116 }; | 120 }; |
117 static const int kRelevantTokenServicesCount = | 121 |
118 arraysize(kRelevantTokenServices); | |
119 | 122 |
120 static const char* kSyncUnrecoverableErrorHistogram = | 123 static const char* kSyncUnrecoverableErrorHistogram = |
121 "Sync.UnrecoverableErrors"; | 124 "Sync.UnrecoverableErrors"; |
122 | 125 |
123 // Helper to check if the given token service is relevant for sync. | 126 const net::BackoffEntry::Policy kRequestAccessTokenBackoffPolicy = { |
124 static bool IsTokenServiceRelevant(const std::string& service) { | 127 // Number of initial errors (in sequence) to ignore before applying |
125 for (int i = 0; i < kRelevantTokenServicesCount; ++i) { | 128 // exponential back-off rules. |
126 if (service == kRelevantTokenServices[i]) | 129 0, |
127 return true; | 130 |
128 } | 131 // Initial delay for exponential back-off in ms. |
129 return false; | 132 2000, |
130 } | 133 |
134 // Factor by which the waiting time will be multiplied. | |
135 2, | |
136 | |
137 // Fuzzing percentage. ex: 10% will spread requests randomly | |
138 // between 90%-100% of the calculated time. | |
139 0.2, // 20% | |
140 | |
141 // Maximum amount of time we are willing to delay our request in ms. | |
142 // TODO(pavely): crbug.com/246686 ProfileSyncService should retry | |
143 // RequestAccessToken on connection state change after backoff | |
144 1000 * 3600 * 4, // 4 hours. | |
145 | |
146 // Time to keep an entry from being discarded even when it | |
147 // has no significant state, -1 to never discard. | |
148 -1, | |
149 | |
150 // Don't use initial delay unless the last request was an error. | |
151 false, | |
152 }; | |
131 | 153 |
132 bool ShouldShowActionOnUI( | 154 bool ShouldShowActionOnUI( |
133 const syncer::SyncProtocolError& error) { | 155 const syncer::SyncProtocolError& error) { |
134 return (error.action != syncer::UNKNOWN_ACTION && | 156 return (error.action != syncer::UNKNOWN_ACTION && |
135 error.action != syncer::DISABLE_SYNC_ON_CLIENT && | 157 error.action != syncer::DISABLE_SYNC_ON_CLIENT && |
136 error.action != syncer::STOP_SYNC_FOR_DISABLED_ACCOUNT); | 158 error.action != syncer::STOP_SYNC_FOR_DISABLED_ACCOUNT); |
137 } | 159 } |
138 | 160 |
139 ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory, | 161 ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory, |
140 Profile* profile, | 162 Profile* profile, |
(...skipping 15 matching lines...) Expand all Loading... | |
156 signin_(signin_manager), | 178 signin_(signin_manager), |
157 unrecoverable_error_reason_(ERROR_REASON_UNSET), | 179 unrecoverable_error_reason_(ERROR_REASON_UNSET), |
158 weak_factory_(this), | 180 weak_factory_(this), |
159 expect_sync_configuration_aborted_(false), | 181 expect_sync_configuration_aborted_(false), |
160 encrypted_types_(syncer::SyncEncryptionHandler::SensitiveTypes()), | 182 encrypted_types_(syncer::SyncEncryptionHandler::SensitiveTypes()), |
161 encrypt_everything_(false), | 183 encrypt_everything_(false), |
162 encryption_pending_(false), | 184 encryption_pending_(false), |
163 auto_start_enabled_(start_behavior == AUTO_START), | 185 auto_start_enabled_(start_behavior == AUTO_START), |
164 configure_status_(DataTypeManager::UNKNOWN), | 186 configure_status_(DataTypeManager::UNKNOWN), |
165 setup_in_progress_(false), | 187 setup_in_progress_(false), |
166 invalidator_state_(syncer::DEFAULT_INVALIDATION_ERROR) { | 188 invalidator_state_(syncer::DEFAULT_INVALIDATION_ERROR), |
189 request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy) { | |
167 // By default, dev, canary, and unbranded Chromium users will go to the | 190 // By default, dev, canary, and unbranded Chromium users will go to the |
168 // development servers. Development servers have more features than standard | 191 // development servers. Development servers have more features than standard |
169 // sync servers. Users with officially-branded Chrome stable and beta builds | 192 // sync servers. Users with officially-branded Chrome stable and beta builds |
170 // will go to the standard sync servers. | 193 // will go to the standard sync servers. |
171 // | 194 // |
172 // GetChannel hits the registry on Windows. See http://crbug.com/70380. | 195 // GetChannel hits the registry on Windows. See http://crbug.com/70380. |
173 base::ThreadRestrictions::ScopedAllowIO allow_io; | 196 base::ThreadRestrictions::ScopedAllowIO allow_io; |
174 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); | 197 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); |
175 if (channel == chrome::VersionInfo::CHANNEL_STABLE || | 198 if (channel == chrome::VersionInfo::CHANNEL_STABLE || |
176 channel == chrome::VersionInfo::CHANNEL_BETA) { | 199 channel == chrome::VersionInfo::CHANNEL_BETA) { |
(...skipping 11 matching lines...) Expand all Loading... | |
188 | 211 |
189 bool ProfileSyncService::IsSyncEnabledAndLoggedIn() { | 212 bool ProfileSyncService::IsSyncEnabledAndLoggedIn() { |
190 // Exit if sync is disabled. | 213 // Exit if sync is disabled. |
191 if (IsManaged() || sync_prefs_.IsStartSuppressed()) | 214 if (IsManaged() || sync_prefs_.IsStartSuppressed()) |
192 return false; | 215 return false; |
193 | 216 |
194 // Sync is logged in if there is a non-empty effective username. | 217 // Sync is logged in if there is a non-empty effective username. |
195 return !GetEffectiveUsername().empty(); | 218 return !GetEffectiveUsername().empty(); |
196 } | 219 } |
197 | 220 |
198 bool ProfileSyncService::IsSyncTokenAvailable() { | 221 bool ProfileSyncService::IsOAuthRefreshTokenAvailable() { |
199 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 222 if (use_oauth2_token_) { |
200 if (!token_service) | 223 ProfileOAuth2TokenService* token_service = |
201 return false; | 224 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
202 return token_service->HasTokenForService(GaiaConstants::kSyncService); | 225 if (!token_service) |
226 return false; | |
227 return token_service->RefreshTokenIsAvailable(); | |
228 } else { | |
229 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | |
230 if (!token_service) | |
231 return false; | |
232 return token_service->HasTokenForService(GaiaConstants::kSyncService); | |
233 } | |
203 } | 234 } |
204 | 235 |
205 void ProfileSyncService::Initialize() { | 236 void ProfileSyncService::Initialize() { |
206 DCHECK(!invalidator_registrar_.get()); | 237 DCHECK(!invalidator_registrar_.get()); |
207 invalidator_registrar_.reset(new syncer::InvalidatorRegistrar()); | 238 invalidator_registrar_.reset(new syncer::InvalidatorRegistrar()); |
208 | 239 |
209 InitSettings(); | 240 InitSettings(); |
210 | 241 |
211 // We clear this here (vs Shutdown) because we want to remember that an error | 242 // We clear this here (vs Shutdown) because we want to remember that an error |
212 // happened on shutdown so we can display details (message, location) about it | 243 // happened on shutdown so we can display details (message, location) about it |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 return; | 301 return; |
271 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 302 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
272 if (!token_service) | 303 if (!token_service) |
273 return; | 304 return; |
274 // Don't start the backend if the token service hasn't finished loading tokens | 305 // Don't start the backend if the token service hasn't finished loading tokens |
275 // yet. Note if the backend is started before the sync token has been loaded, | 306 // yet. Note if the backend is started before the sync token has been loaded, |
276 // GetCredentials() will return bogus credentials. On auto_start platforms | 307 // GetCredentials() will return bogus credentials. On auto_start platforms |
277 // (like ChromeOS) we don't start sync until tokens are loaded, because the | 308 // (like ChromeOS) we don't start sync until tokens are loaded, because the |
278 // user can be "signed in" on those platforms long before the tokens get | 309 // user can be "signed in" on those platforms long before the tokens get |
279 // loaded, and we don't want to generate spurious auth errors. | 310 // loaded, and we don't want to generate spurious auth errors. |
280 if (!IsSyncTokenAvailable() && | 311 if (!IsOAuthRefreshTokenAvailable() && |
281 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { | 312 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { |
282 return; | 313 return; |
283 } | 314 } |
284 | 315 |
316 if (use_oauth2_token_) { | |
317 // If we got here then tokens are loaded and user logged in and sync is | |
318 // enabled. If OAuth refresh token is not available then something is wrong. | |
319 // When PSS requests access token, OAuth2TokenService will return error and | |
320 // PSS will show error to user asking to reauthenticate. | |
321 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", | |
322 !IsOAuthRefreshTokenAvailable()); | |
323 } | |
324 | |
285 // If sync setup has completed we always start the backend. If the user is in | 325 // If sync setup has completed we always start the backend. If the user is in |
286 // the process of setting up now, we should start the backend to download | 326 // the process of setting up now, we should start the backend to download |
287 // account control state / encryption information). If autostart is enabled, | 327 // account control state / encryption information). If autostart is enabled, |
288 // but we haven't completed sync setup, we try to start sync anyway, since | 328 // but we haven't completed sync setup, we try to start sync anyway, since |
289 // it's possible we crashed/shutdown after logging in but before the backend | 329 // it's possible we crashed/shutdown after logging in but before the backend |
290 // finished initializing the last time. | 330 // finished initializing the last time. |
291 // | 331 // |
292 // However, the only time we actually need to start sync _immediately_ is if | 332 // However, the only time we actually need to start sync _immediately_ is if |
293 // we haven't completed sync setup and the user is in the process of setting | 333 // we haven't completed sync setup and the user is in the process of setting |
294 // up - either they just signed in (for the first time) on an auto-start | 334 // up - either they just signed in (for the first time) on an auto-start |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 if (!value.empty()) { | 438 if (!value.empty()) { |
399 GURL custom_sync_url(value); | 439 GURL custom_sync_url(value); |
400 if (custom_sync_url.is_valid()) { | 440 if (custom_sync_url.is_valid()) { |
401 sync_service_url_ = custom_sync_url; | 441 sync_service_url_ = custom_sync_url; |
402 } else { | 442 } else { |
403 LOG(WARNING) << "The following sync URL specified at the command-line " | 443 LOG(WARNING) << "The following sync URL specified at the command-line " |
404 << "is invalid: " << value; | 444 << "is invalid: " << value; |
405 } | 445 } |
406 } | 446 } |
407 } | 447 } |
448 | |
449 use_oauth2_token_ = command_line.HasSwitch(switches::kSyncEnableOAuth2Token); | |
tim (not reviewing)
2013/06/12 20:07:37
Should the flag not be to disable OAuth2, and then
| |
408 } | 450 } |
409 | 451 |
410 SyncCredentials ProfileSyncService::GetCredentials() { | 452 SyncCredentials ProfileSyncService::GetCredentials() { |
411 SyncCredentials credentials; | 453 SyncCredentials credentials; |
412 credentials.email = GetEffectiveUsername(); | 454 credentials.email = GetEffectiveUsername(); |
413 DCHECK(!credentials.email.empty()); | 455 DCHECK(!credentials.email.empty()); |
414 TokenService* service = TokenServiceFactory::GetForProfile(profile_); | 456 if (use_oauth2_token_) { |
415 if (service->HasTokenForService(GaiaConstants::kSyncService)) { | 457 credentials.sync_token = access_token_; |
416 credentials.sync_token = service->GetTokenForService( | |
417 GaiaConstants::kSyncService); | |
418 credentials.sync_token_time = | |
419 AboutSigninInternalsFactory::GetForProfile(profile_)-> | |
420 GetTokenTime(GaiaConstants::kSyncService); | |
421 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", false); | |
422 } else { | 458 } else { |
423 // We've lost our sync credentials (crbug.com/121755), so just make up some | 459 TokenService* service = TokenServiceFactory::GetForProfile(profile_); |
424 // invalid credentials so the backend will generate an auth error. | 460 if (service->HasTokenForService(GaiaConstants::kSyncService)) { |
425 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", true); | 461 credentials.sync_token = service->GetTokenForService( |
462 GaiaConstants::kSyncService); | |
463 } | |
464 } | |
465 | |
466 if (credentials.sync_token.empty()) | |
426 credentials.sync_token = "credentials_lost"; | 467 credentials.sync_token = "credentials_lost"; |
427 } | |
428 return credentials; | 468 return credentials; |
429 } | 469 } |
430 | 470 |
431 void ProfileSyncService::InitializeBackend(bool delete_stale_data) { | 471 void ProfileSyncService::InitializeBackend(bool delete_stale_data) { |
432 if (!backend_) { | 472 if (!backend_) { |
433 NOTREACHED(); | 473 NOTREACHED(); |
434 return; | 474 return; |
435 } | 475 } |
436 | 476 |
437 SyncCredentials credentials = GetCredentials(); | 477 SyncCredentials credentials = GetCredentials(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 | 524 |
485 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { | 525 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { |
486 // Don't start up multiple times. | 526 // Don't start up multiple times. |
487 if (backend_) { | 527 if (backend_) { |
488 DVLOG(1) << "Skipping bringing up backend host."; | 528 DVLOG(1) << "Skipping bringing up backend host."; |
489 return; | 529 return; |
490 } | 530 } |
491 | 531 |
492 DCHECK(IsSyncEnabledAndLoggedIn()); | 532 DCHECK(IsSyncEnabledAndLoggedIn()); |
493 | 533 |
534 if (use_oauth2_token_ && access_token_.empty()) { | |
535 RequestAccessToken(); | |
536 return; | |
537 } | |
538 | |
494 if (start_up_time_.is_null()) { | 539 if (start_up_time_.is_null()) { |
495 start_up_time_ = base::Time::Now(); | 540 start_up_time_ = base::Time::Now(); |
496 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); | 541 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); |
497 | 542 |
498 #if defined(OS_CHROMEOS) | 543 #if defined(OS_CHROMEOS) |
499 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); | 544 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); |
500 if (bootstrap_token.empty()) { | 545 if (bootstrap_token.empty()) { |
501 sync_prefs_.SetEncryptionBootstrapToken( | 546 sync_prefs_.SetEncryptionBootstrapToken( |
502 sync_prefs_.GetSpareBootstrapToken()); | 547 sync_prefs_.GetSpareBootstrapToken()); |
503 } | 548 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
631 // If |backend_| is NULL, save the acknowledgements to replay when | 676 // If |backend_| is NULL, save the acknowledgements to replay when |
632 // it's created and initialized. | 677 // it's created and initialized. |
633 ack_replay_queue_.push_back(std::make_pair(id, ack_handle)); | 678 ack_replay_queue_.push_back(std::make_pair(id, ack_handle)); |
634 } | 679 } |
635 } | 680 } |
636 | 681 |
637 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const { | 682 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const { |
638 return invalidator_registrar_->GetInvalidatorState(); | 683 return invalidator_registrar_->GetInvalidatorState(); |
639 } | 684 } |
640 | 685 |
686 void ProfileSyncService::OnGetTokenSuccess( | |
687 const OAuth2TokenService::Request* request, | |
688 const std::string& access_token, | |
689 const base::Time& expiration_time) { | |
690 DCHECK_EQ(access_token_request_, request); | |
691 access_token_request_.reset(); | |
692 // Reset backoff time after successful response. | |
693 request_access_token_backoff_.Reset(); | |
694 access_token_ = access_token; | |
695 if (backend_) | |
696 backend_->UpdateCredentials(GetCredentials()); | |
697 else | |
698 TryStart(); | |
699 } | |
700 | |
701 void ProfileSyncService::OnGetTokenFailure( | |
702 const OAuth2TokenService::Request* request, | |
703 const GoogleServiceAuthError& error) { | |
704 DCHECK_EQ(access_token_request_, request); | |
705 DCHECK_NE(error.state(), GoogleServiceAuthError::NONE); | |
706 access_token_request_.reset(); | |
707 switch (error.state()) { | |
708 case GoogleServiceAuthError::CONNECTION_FAILED: | |
709 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: { | |
710 // Transient error. Retry after some time. | |
711 request_access_token_backoff_.InformOfRequest(false); | |
712 request_access_token_retry_timer_.Start( | |
713 FROM_HERE, | |
714 request_access_token_backoff_.GetTimeUntilRelease(), | |
715 base::Bind(&ProfileSyncService::RequestAccessToken, | |
716 weak_factory_.GetWeakPtr())); | |
717 break; | |
718 } | |
719 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: { | |
720 // Report time since token was issued for invalid credentials error. | |
721 // TODO(pavely): crbug.com/246817 Collect UMA histogram for auth token | |
722 // rejections from invalidation service. | |
723 base::Time auth_token_time = | |
724 AboutSigninInternalsFactory::GetForProfile(profile_)-> | |
725 GetTokenTime(GaiaConstants::kGaiaOAuth2LoginRefreshToken); | |
726 if (!auth_token_time.is_null()) { | |
727 base::TimeDelta age = base::Time::Now() - auth_token_time; | |
728 if (age < base::TimeDelta::FromHours(1)) { | |
729 UMA_HISTOGRAM_CUSTOM_TIMES("Sync.AuthServerRejectedTokenAgeShort", | |
730 age, | |
731 base::TimeDelta::FromSeconds(1), | |
732 base::TimeDelta::FromHours(1), | |
733 50); | |
734 } | |
735 UMA_HISTOGRAM_COUNTS("Sync.AuthServerRejectedTokenAgeLong", | |
736 age.InDays()); | |
737 } | |
738 // Fallthrough. | |
739 } | |
740 default: { | |
741 // Show error to user. | |
742 UpdateAuthErrorState(error); | |
743 } | |
744 } | |
745 } | |
746 | |
641 void ProfileSyncService::EmitInvalidationForTest( | 747 void ProfileSyncService::EmitInvalidationForTest( |
642 const invalidation::ObjectId& id, | 748 const invalidation::ObjectId& id, |
643 const std::string& payload) { | 749 const std::string& payload) { |
644 syncer::ObjectIdSet notify_ids; | 750 syncer::ObjectIdSet notify_ids; |
645 notify_ids.insert(id); | 751 notify_ids.insert(id); |
646 | 752 |
647 const syncer::ObjectIdInvalidationMap& invalidation_map = | 753 const syncer::ObjectIdInvalidationMap& invalidation_map = |
648 ObjectIdSetToInvalidationMap(notify_ids, payload); | 754 ObjectIdSetToInvalidationMap(notify_ids, payload); |
649 OnIncomingInvalidation(invalidation_map); | 755 OnIncomingInvalidation(invalidation_map); |
650 } | 756 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
710 is_auth_in_progress_ = false; | 816 is_auth_in_progress_ = false; |
711 backend_initialized_ = false; | 817 backend_initialized_ = false; |
712 // NULL if we're called from Shutdown(). | 818 // NULL if we're called from Shutdown(). |
713 if (invalidator_registrar_) | 819 if (invalidator_registrar_) |
714 UpdateInvalidatorRegistrarState(); | 820 UpdateInvalidatorRegistrarState(); |
715 cached_passphrase_.clear(); | 821 cached_passphrase_.clear(); |
716 encryption_pending_ = false; | 822 encryption_pending_ = false; |
717 encrypt_everything_ = false; | 823 encrypt_everything_ = false; |
718 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes(); | 824 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes(); |
719 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED; | 825 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED; |
720 start_up_time_ = base::Time(); | 826 request_access_token_retry_timer_.Stop(); |
721 // Revert to "no auth error". | 827 // Revert to "no auth error". |
722 if (last_auth_error_.state() != GoogleServiceAuthError::NONE) | 828 if (last_auth_error_.state() != GoogleServiceAuthError::NONE) |
723 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); | 829 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); |
724 | 830 |
725 if (sync_global_error_) { | 831 if (sync_global_error_) { |
726 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( | 832 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( |
727 sync_global_error_.get()); | 833 sync_global_error_.get()); |
728 RemoveObserver(sync_global_error_.get()); | 834 RemoveObserver(sync_global_error_.get()); |
729 sync_global_error_.reset(NULL); | 835 sync_global_error_.reset(NULL); |
730 } | 836 } |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1060 default: | 1166 default: |
1061 NOTREACHED(); | 1167 NOTREACHED(); |
1062 return AuthError(AuthError::CONNECTION_FAILED); | 1168 return AuthError(AuthError::CONNECTION_FAILED); |
1063 } | 1169 } |
1064 } | 1170 } |
1065 | 1171 |
1066 } // namespace | 1172 } // namespace |
1067 | 1173 |
1068 void ProfileSyncService::OnConnectionStatusChange( | 1174 void ProfileSyncService::OnConnectionStatusChange( |
1069 syncer::ConnectionStatus status) { | 1175 syncer::ConnectionStatus status) { |
1070 const GoogleServiceAuthError auth_error = | 1176 if (use_oauth2_token_ && status == syncer::CONNECTION_AUTH_ERROR) { |
1071 ConnectionStatusToAuthError(status); | 1177 // Sync or Tango server returned error indicating that access token is |
1072 DVLOG(1) << "Connection status change: " << auth_error.ToString(); | 1178 // invalid. It could be either expired or access is revoked. Let's request |
1073 UpdateAuthErrorState(auth_error); | 1179 // another access token and if access is revoked then request for token will |
1180 // fail with corresponding error. | |
1181 RequestAccessToken(); | |
1182 } else { | |
1183 const GoogleServiceAuthError auth_error = | |
1184 ConnectionStatusToAuthError(status); | |
1185 DVLOG(1) << "Connection status change: " << auth_error.ToString(); | |
1186 UpdateAuthErrorState(auth_error); | |
1187 } | |
1074 } | 1188 } |
1075 | 1189 |
1076 void ProfileSyncService::OnStopSyncingPermanently() { | 1190 void ProfileSyncService::OnStopSyncingPermanently() { |
1077 sync_prefs_.SetStartSuppressed(true); | 1191 sync_prefs_.SetStartSuppressed(true); |
1078 DisableForUser(); | 1192 DisableForUser(); |
1079 } | 1193 } |
1080 | 1194 |
1081 void ProfileSyncService::OnPassphraseRequired( | 1195 void ProfileSyncService::OnPassphraseRequired( |
1082 syncer::PassphraseRequiredReason reason, | 1196 syncer::PassphraseRequiredReason reason, |
1083 const sync_pb::EncryptedData& pending_keys) { | 1197 const sync_pb::EncryptedData& pending_keys) { |
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1787 } | 1901 } |
1788 } | 1902 } |
1789 | 1903 |
1790 // If we get here, we don't have pending keys (or at least, the passphrase | 1904 // If we get here, we don't have pending keys (or at least, the passphrase |
1791 // doesn't decrypt them) - just try to re-encrypt using the encryption | 1905 // doesn't decrypt them) - just try to re-encrypt using the encryption |
1792 // passphrase. | 1906 // passphrase. |
1793 if (!IsUsingSecondaryPassphrase()) | 1907 if (!IsUsingSecondaryPassphrase()) |
1794 SetEncryptionPassphrase(passphrase, IMPLICIT); | 1908 SetEncryptionPassphrase(passphrase, IMPLICIT); |
1795 } | 1909 } |
1796 | 1910 |
1911 void ProfileSyncService::RequestAccessToken() { | |
1912 // Only one active request at a time. | |
1913 if (access_token_request_ != NULL) | |
1914 return; | |
1915 request_access_token_retry_timer_.Stop(); | |
1916 OAuth2TokenService::ScopeSet oauth2_scopes; | |
1917 for (size_t i = 0; i < arraysize(kOAuth2Scopes); i++) | |
1918 oauth2_scopes.insert(kOAuth2Scopes[i]); | |
1919 OAuth2TokenService* token_service = | |
1920 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); | |
1921 // Invalidate previous token, otherwise token service will return the same | |
1922 // token again. | |
1923 token_service->InvalidateToken(oauth2_scopes, access_token_); | |
1924 access_token_.clear(); | |
1925 access_token_request_ = token_service->StartRequest(oauth2_scopes, this); | |
1926 } | |
1927 | |
1797 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, | 1928 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, |
1798 PassphraseType type) { | 1929 PassphraseType type) { |
1799 // This should only be called when the backend has been initialized. | 1930 // This should only be called when the backend has been initialized. |
1800 DCHECK(sync_initialized()); | 1931 DCHECK(sync_initialized()); |
1801 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) << | 1932 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) << |
1802 "Data is already encrypted using an explicit passphrase"; | 1933 "Data is already encrypted using an explicit passphrase"; |
1803 DCHECK(!(type == EXPLICIT && | 1934 DCHECK(!(type == EXPLICIT && |
1804 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) << | 1935 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) << |
1805 "Can not set explicit passphrase when decryption is needed."; | 1936 "Can not set explicit passphrase when decryption is needed."; |
1806 | 1937 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1866 DisableForUser(); | 1997 DisableForUser(); |
1867 } else { | 1998 } else { |
1868 // Sync is no longer disabled by policy. Try starting it up if appropriate. | 1999 // Sync is no longer disabled by policy. Try starting it up if appropriate. |
1869 TryStart(); | 2000 TryStart(); |
1870 } | 2001 } |
1871 } | 2002 } |
1872 | 2003 |
1873 void ProfileSyncService::Observe(int type, | 2004 void ProfileSyncService::Observe(int type, |
1874 const content::NotificationSource& source, | 2005 const content::NotificationSource& source, |
1875 const content::NotificationDetails& details) { | 2006 const content::NotificationDetails& details) { |
2007 const char* sync_token_service = use_oauth2_token_ ? | |
2008 GaiaConstants::kGaiaOAuth2LoginRefreshToken : GaiaConstants::kSyncService; | |
1876 switch (type) { | 2009 switch (type) { |
1877 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { | 2010 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { |
1878 const GoogleServiceSigninSuccessDetails* successful = | 2011 const GoogleServiceSigninSuccessDetails* successful = |
1879 content::Details<const GoogleServiceSigninSuccessDetails>( | 2012 content::Details<const GoogleServiceSigninSuccessDetails>( |
1880 details).ptr(); | 2013 details).ptr(); |
1881 if (!sync_prefs_.IsStartSuppressed() && | 2014 if (!sync_prefs_.IsStartSuppressed() && |
1882 !successful->password.empty()) { | 2015 !successful->password.empty()) { |
1883 cached_passphrase_ = successful->password; | 2016 cached_passphrase_ = successful->password; |
1884 // Try to consume the passphrase we just cached. If the sync backend | 2017 // Try to consume the passphrase we just cached. If the sync backend |
1885 // is not running yet, the passphrase will remain cached until the | 2018 // is not running yet, the passphrase will remain cached until the |
1886 // backend starts up. | 2019 // backend starts up. |
1887 ConsumeCachedPassphraseIfPossible(); | 2020 ConsumeCachedPassphraseIfPossible(); |
1888 } | 2021 } |
1889 #if defined(OS_CHROMEOS) | 2022 #if defined(OS_CHROMEOS) |
1890 RefreshSpareBootstrapToken(successful->password); | 2023 RefreshSpareBootstrapToken(successful->password); |
1891 #endif | 2024 #endif |
1892 if (!sync_initialized() || | 2025 if (!sync_initialized() || |
1893 GetAuthError().state() != AuthError::NONE) { | 2026 GetAuthError().state() != AuthError::NONE) { |
1894 // Track the fact that we're still waiting for auth to complete. | 2027 // Track the fact that we're still waiting for auth to complete. |
1895 is_auth_in_progress_ = true; | 2028 is_auth_in_progress_ = true; |
1896 } | 2029 } |
1897 break; | 2030 break; |
1898 } | 2031 } |
1899 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { | 2032 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { |
2033 // TODO(atwilson): sync shouldn't report refresh token request failures. | |
2034 // TokenService should do that instead. | |
1900 const TokenService::TokenRequestFailedDetails& token_details = | 2035 const TokenService::TokenRequestFailedDetails& token_details = |
1901 *(content::Details<const TokenService::TokenRequestFailedDetails>( | 2036 *(content::Details<const TokenService::TokenRequestFailedDetails>( |
1902 details).ptr()); | 2037 details).ptr()); |
1903 if (IsTokenServiceRelevant(token_details.service()) && | 2038 if (token_details.service() == sync_token_service && |
1904 !IsSyncTokenAvailable()) { | 2039 !IsOAuthRefreshTokenAvailable()) { |
1905 // The additional check around IsSyncTokenAvailable() above prevents us | 2040 // The additional check around IsOAuthRefreshTokenAvailable() above |
1906 // sounding the alarm if we actually have a valid token but a refresh | 2041 // prevents us sounding the alarm if we actually have a valid token but |
1907 // attempt by TokenService failed for any variety of reasons (e.g. flaky | 2042 // a refresh attempt by TokenService failed for any variety of reasons |
1908 // network). It's possible the token we do have is also invalid, but in | 2043 // (e.g. flaky network). It's possible the token we do have is also |
1909 // that case we should already have (or can expect) an auth error sent | 2044 // invalid, but in that case we should already have (or can expect) an |
1910 // from the sync backend. | 2045 // auth error sent from the sync backend. |
1911 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS); | 2046 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS); |
1912 UpdateAuthErrorState(error); | 2047 UpdateAuthErrorState(error); |
1913 } | 2048 } |
1914 break; | 2049 break; |
1915 } | 2050 } |
1916 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { | 2051 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { |
2052 // TODO(atwilson): Listen for notifications on OAuth2TokenService | |
2053 // (crbug.com/243737) | |
1917 const TokenService::TokenAvailableDetails& token_details = | 2054 const TokenService::TokenAvailableDetails& token_details = |
1918 *(content::Details<const TokenService::TokenAvailableDetails>( | 2055 *(content::Details<const TokenService::TokenAvailableDetails>( |
1919 details).ptr()); | 2056 details).ptr()); |
1920 if (!IsTokenServiceRelevant(token_details.service())) | 2057 if (token_details.service() != sync_token_service) |
1921 break; | 2058 break; |
1922 } // Fall through. | 2059 } // Fall through. |
1923 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { | 2060 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { |
1924 // This notification gets fired when TokenService loads the tokens | 2061 // This notification gets fired when TokenService loads the tokens |
1925 // from storage. | 2062 // from storage. |
1926 // Initialize the backend if sync is enabled. If the sync token was | 2063 // Initialize the backend if sync is enabled. If the sync token was |
1927 // not loaded, GetCredentials() will generate invalid credentials to | 2064 // not loaded, GetCredentials() will generate invalid credentials to |
1928 // cause the backend to generate an auth error (crbug.com/121755). | 2065 // cause the backend to generate an auth error (crbug.com/121755). |
1929 if (backend_) | 2066 if (backend_) { |
1930 backend_->UpdateCredentials(GetCredentials()); | 2067 if (use_oauth2_token_) |
1931 else | 2068 RequestAccessToken(); |
2069 else | |
2070 backend_->UpdateCredentials(GetCredentials()); | |
2071 } else { | |
1932 TryStart(); | 2072 TryStart(); |
2073 } | |
1933 break; | 2074 break; |
1934 } | 2075 } |
1935 case chrome::NOTIFICATION_TOKENS_CLEARED: { | 2076 case chrome::NOTIFICATION_TOKENS_CLEARED: { |
1936 // GetCredentials() will generate invalid credentials to cause the backend | 2077 // GetCredentials() will generate invalid credentials to cause the backend |
1937 // to generate an auth error. | 2078 // to generate an auth error. |
2079 access_token_.clear(); | |
1938 if (backend_) | 2080 if (backend_) |
1939 backend_->UpdateCredentials(GetCredentials()); | 2081 backend_->UpdateCredentials(GetCredentials()); |
1940 break; | 2082 break; |
1941 } | 2083 } |
1942 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: | 2084 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: |
1943 sync_disabled_by_admin_ = false; | 2085 sync_disabled_by_admin_ = false; |
1944 DisableForUser(); | 2086 DisableForUser(); |
1945 break; | 2087 break; |
1946 default: { | 2088 default: { |
1947 NOTREACHED(); | 2089 NOTREACHED(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2064 std::string ProfileSyncService::GetEffectiveUsername() { | 2206 std::string ProfileSyncService::GetEffectiveUsername() { |
2065 #if defined(ENABLE_MANAGED_USERS) | 2207 #if defined(ENABLE_MANAGED_USERS) |
2066 if (ManagedUserService::ProfileIsManaged(profile_)) { | 2208 if (ManagedUserService::ProfileIsManaged(profile_)) { |
2067 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername()); | 2209 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername()); |
2068 return ManagedUserService::GetManagedUserPseudoEmail(); | 2210 return ManagedUserService::GetManagedUserPseudoEmail(); |
2069 } | 2211 } |
2070 #endif | 2212 #endif |
2071 | 2213 |
2072 return signin_->GetAuthenticatedUsername(); | 2214 return signin_->GetAuthenticatedUsername(); |
2073 } | 2215 } |
2074 | |
OLD | NEW |