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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 typedef GoogleServiceAuthError AuthError; | 105 typedef GoogleServiceAuthError AuthError; |
104 | 106 |
105 const char* ProfileSyncService::kSyncServerUrl = | 107 const char* ProfileSyncService::kSyncServerUrl = |
106 "https://clients4.google.com/chrome-sync"; | 108 "https://clients4.google.com/chrome-sync"; |
107 | 109 |
108 const char* ProfileSyncService::kDevServerUrl = | 110 const char* ProfileSyncService::kDevServerUrl = |
109 "https://clients4.google.com/chrome-sync/dev"; | 111 "https://clients4.google.com/chrome-sync/dev"; |
110 | 112 |
111 static const int kSyncClearDataTimeoutInSeconds = 60; // 1 minute. | 113 static const int kSyncClearDataTimeoutInSeconds = 60; // 1 minute. |
112 | 114 |
113 static const char* kRelevantTokenServices[] = { | 115 static const char* kOAuth2Scopes[] = { |
114 GaiaConstants::kSyncService | 116 GaiaConstants::kChromeSyncOAuth2Scope, |
117 // GoogleTalk scope is needed for notifications. | |
118 GaiaConstants::kGoogleTalkOAuth2Scope | |
115 }; | 119 }; |
116 static const int kRelevantTokenServicesCount = | 120 |
117 arraysize(kRelevantTokenServices); | |
118 | 121 |
119 static const char* kSyncUnrecoverableErrorHistogram = | 122 static const char* kSyncUnrecoverableErrorHistogram = |
120 "Sync.UnrecoverableErrors"; | 123 "Sync.UnrecoverableErrors"; |
121 | 124 |
122 // Helper to check if the given token service is relevant for sync. | 125 const net::BackoffEntry::Policy kRequestAccessTokenBackoffPolicy = { |
123 static bool IsTokenServiceRelevant(const std::string& service) { | 126 // Number of initial errors (in sequence) to ignore before applying |
124 for (int i = 0; i < kRelevantTokenServicesCount; ++i) { | 127 // exponential back-off rules. |
125 if (service == kRelevantTokenServices[i]) | 128 0, |
126 return true; | 129 |
127 } | 130 // Initial delay for exponential back-off in ms. |
128 return false; | 131 2000, |
129 } | 132 |
133 // Factor by which the waiting time will be multiplied. | |
134 2, | |
135 | |
136 // Fuzzing percentage. ex: 10% will spread requests randomly | |
137 // between 90%-100% of the calculated time. | |
138 0, | |
Andrew T Wilson (Slow)
2013/06/04 14:37:32
Do we want some kind of fuzzing here? I think the
pavely
2013/06/04 20:11:13
Done.
| |
139 | |
140 // Maximum amount of time we are willing to delay our request in ms. | |
141 1000 * 3600 * 4, // 4 hours. | |
Andrew T Wilson (Slow)
2013/06/04 14:37:32
I'm OK with this, but I wonder if maybe we should
pavely
2013/06/04 20:11:13
I put 4 hours here because that's max backoff time
| |
142 | |
143 // Time to keep an entry from being discarded even when it | |
144 // has no significant state, -1 to never discard. | |
145 -1, | |
146 | |
147 // Don't use initial delay unless the last request was an error. | |
148 false, | |
149 }; | |
130 | 150 |
131 bool ShouldShowActionOnUI( | 151 bool ShouldShowActionOnUI( |
132 const syncer::SyncProtocolError& error) { | 152 const syncer::SyncProtocolError& error) { |
133 return (error.action != syncer::UNKNOWN_ACTION && | 153 return (error.action != syncer::UNKNOWN_ACTION && |
134 error.action != syncer::DISABLE_SYNC_ON_CLIENT && | 154 error.action != syncer::DISABLE_SYNC_ON_CLIENT && |
135 error.action != syncer::STOP_SYNC_FOR_DISABLED_ACCOUNT); | 155 error.action != syncer::STOP_SYNC_FOR_DISABLED_ACCOUNT); |
136 } | 156 } |
137 | 157 |
138 ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory, | 158 ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory, |
139 Profile* profile, | 159 Profile* profile, |
(...skipping 16 matching lines...) Expand all Loading... | |
156 unrecoverable_error_reason_(ERROR_REASON_UNSET), | 176 unrecoverable_error_reason_(ERROR_REASON_UNSET), |
157 weak_factory_(this), | 177 weak_factory_(this), |
158 expect_sync_configuration_aborted_(false), | 178 expect_sync_configuration_aborted_(false), |
159 encrypted_types_(syncer::SyncEncryptionHandler::SensitiveTypes()), | 179 encrypted_types_(syncer::SyncEncryptionHandler::SensitiveTypes()), |
160 encrypt_everything_(false), | 180 encrypt_everything_(false), |
161 encryption_pending_(false), | 181 encryption_pending_(false), |
162 auto_start_enabled_(start_behavior == AUTO_START), | 182 auto_start_enabled_(start_behavior == AUTO_START), |
163 failed_datatypes_handler_(this), | 183 failed_datatypes_handler_(this), |
164 configure_status_(DataTypeManager::UNKNOWN), | 184 configure_status_(DataTypeManager::UNKNOWN), |
165 setup_in_progress_(false), | 185 setup_in_progress_(false), |
166 invalidator_state_(syncer::DEFAULT_INVALIDATION_ERROR) { | 186 invalidator_state_(syncer::DEFAULT_INVALIDATION_ERROR), |
187 request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy) { | |
167 // By default, dev, canary, and unbranded Chromium users will go to the | 188 // By default, dev, canary, and unbranded Chromium users will go to the |
168 // development servers. Development servers have more features than standard | 189 // development servers. Development servers have more features than standard |
169 // sync servers. Users with officially-branded Chrome stable and beta builds | 190 // sync servers. Users with officially-branded Chrome stable and beta builds |
170 // will go to the standard sync servers. | 191 // will go to the standard sync servers. |
171 // | 192 // |
172 // GetChannel hits the registry on Windows. See http://crbug.com/70380. | 193 // GetChannel hits the registry on Windows. See http://crbug.com/70380. |
173 base::ThreadRestrictions::ScopedAllowIO allow_io; | 194 base::ThreadRestrictions::ScopedAllowIO allow_io; |
174 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); | 195 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); |
175 if (channel == chrome::VersionInfo::CHANNEL_STABLE || | 196 if (channel == chrome::VersionInfo::CHANNEL_STABLE || |
176 channel == chrome::VersionInfo::CHANNEL_BETA) { | 197 channel == chrome::VersionInfo::CHANNEL_BETA) { |
(...skipping 11 matching lines...) Expand all Loading... | |
188 | 209 |
189 bool ProfileSyncService::IsSyncEnabledAndLoggedIn() { | 210 bool ProfileSyncService::IsSyncEnabledAndLoggedIn() { |
190 // Exit if sync is disabled. | 211 // Exit if sync is disabled. |
191 if (IsManaged() || sync_prefs_.IsStartSuppressed()) | 212 if (IsManaged() || sync_prefs_.IsStartSuppressed()) |
192 return false; | 213 return false; |
193 | 214 |
194 // Sync is logged in if there is a non-empty effective username. | 215 // Sync is logged in if there is a non-empty effective username. |
195 return !GetEffectiveUsername().empty(); | 216 return !GetEffectiveUsername().empty(); |
196 } | 217 } |
197 | 218 |
198 bool ProfileSyncService::IsSyncTokenAvailable() { | 219 bool ProfileSyncService::IsOAuthRefreshTokenAvailable() { |
199 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 220 ProfileOAuth2TokenService* token_service = |
221 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); | |
200 if (!token_service) | 222 if (!token_service) |
201 return false; | 223 return false; |
202 return token_service->HasTokenForService(GaiaConstants::kSyncService); | 224 return token_service->RefreshTokenIsAvailable(); |
203 } | 225 } |
204 #if defined(OS_ANDROID) | 226 #if defined(OS_ANDROID) |
205 bool ProfileSyncService::ShouldEnablePasswordSyncForAndroid() const { | 227 bool ProfileSyncService::ShouldEnablePasswordSyncForAndroid() const { |
206 const syncer::ModelTypeSet registered_types = GetRegisteredDataTypes(); | 228 const syncer::ModelTypeSet registered_types = GetRegisteredDataTypes(); |
207 const syncer::ModelTypeSet preferred_types = | 229 const syncer::ModelTypeSet preferred_types = |
208 sync_prefs_.GetPreferredDataTypes(registered_types); | 230 sync_prefs_.GetPreferredDataTypes(registered_types); |
209 if (!preferred_types.Has(syncer::PASSWORDS)) | 231 if (!preferred_types.Has(syncer::PASSWORDS)) |
210 return false; | 232 return false; |
211 // If backend has not completed initializing we cannot check if the | 233 // If backend has not completed initializing we cannot check if the |
212 // cryptographer is ready. | 234 // cryptographer is ready. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 return; | 309 return; |
288 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 310 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
289 if (!token_service) | 311 if (!token_service) |
290 return; | 312 return; |
291 // Don't start the backend if the token service hasn't finished loading tokens | 313 // Don't start the backend if the token service hasn't finished loading tokens |
292 // yet. Note if the backend is started before the sync token has been loaded, | 314 // yet. Note if the backend is started before the sync token has been loaded, |
293 // GetCredentials() will return bogus credentials. On auto_start platforms | 315 // GetCredentials() will return bogus credentials. On auto_start platforms |
294 // (like ChromeOS) we don't start sync until tokens are loaded, because the | 316 // (like ChromeOS) we don't start sync until tokens are loaded, because the |
295 // user can be "signed in" on those platforms long before the tokens get | 317 // user can be "signed in" on those platforms long before the tokens get |
296 // loaded, and we don't want to generate spurious auth errors. | 318 // loaded, and we don't want to generate spurious auth errors. |
297 if (!IsSyncTokenAvailable() && | 319 if (!IsOAuthRefreshTokenAvailable() && |
298 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { | 320 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { |
299 return; | 321 return; |
300 } | 322 } |
301 | 323 |
324 // If we got here then tokens are loaded and user logged in and sync is | |
325 // enabled. If OAuth refresh token is not available then something is wrong. | |
326 // When PSS requests access token, OAuth2TokenService will return error and | |
327 // PSS will show error to user asking to reauthenticate. | |
328 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", | |
329 !IsOAuthRefreshTokenAvailable()); | |
330 | |
302 // If sync setup has completed we always start the backend. If the user is in | 331 // If sync setup has completed we always start the backend. If the user is in |
303 // the process of setting up now, we should start the backend to download | 332 // the process of setting up now, we should start the backend to download |
304 // account control state / encryption information). If autostart is enabled, | 333 // account control state / encryption information). If autostart is enabled, |
305 // but we haven't completed sync setup, we try to start sync anyway, since | 334 // but we haven't completed sync setup, we try to start sync anyway, since |
306 // it's possible we crashed/shutdown after logging in but before the backend | 335 // it's possible we crashed/shutdown after logging in but before the backend |
307 // finished initializing the last time. | 336 // finished initializing the last time. |
308 // | 337 // |
309 // However, the only time we actually need to start sync _immediately_ is if | 338 // However, the only time we actually need to start sync _immediately_ is if |
310 // we haven't completed sync setup and the user is in the process of setting | 339 // we haven't completed sync setup and the user is in the process of setting |
311 // up - either they just signed in (for the first time) on an auto-start | 340 // up - either they just signed in (for the first time) on an auto-start |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 << "is invalid: " << value; | 450 << "is invalid: " << value; |
422 } | 451 } |
423 } | 452 } |
424 } | 453 } |
425 } | 454 } |
426 | 455 |
427 SyncCredentials ProfileSyncService::GetCredentials() { | 456 SyncCredentials ProfileSyncService::GetCredentials() { |
428 SyncCredentials credentials; | 457 SyncCredentials credentials; |
429 credentials.email = GetEffectiveUsername(); | 458 credentials.email = GetEffectiveUsername(); |
430 DCHECK(!credentials.email.empty()); | 459 DCHECK(!credentials.email.empty()); |
431 TokenService* service = TokenServiceFactory::GetForProfile(profile_); | 460 if (!access_token_.empty()) { |
432 if (service->HasTokenForService(GaiaConstants::kSyncService)) { | 461 credentials.sync_token = access_token_; |
433 credentials.sync_token = service->GetTokenForService( | |
434 GaiaConstants::kSyncService); | |
435 credentials.sync_token_time = | |
436 AboutSigninInternalsFactory::GetForProfile(profile_)-> | |
437 GetTokenTime(GaiaConstants::kSyncService); | |
438 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", false); | |
439 } else { | 462 } else { |
440 // We've lost our sync credentials (crbug.com/121755), so just make up some | |
441 // invalid credentials so the backend will generate an auth error. | |
442 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", true); | |
443 credentials.sync_token = "credentials_lost"; | 463 credentials.sync_token = "credentials_lost"; |
444 } | 464 } |
445 return credentials; | 465 return credentials; |
446 } | 466 } |
447 | 467 |
448 void ProfileSyncService::InitializeBackend(bool delete_stale_data) { | 468 void ProfileSyncService::InitializeBackend(bool delete_stale_data) { |
449 if (!backend_) { | 469 if (!backend_) { |
450 NOTREACHED(); | 470 NOTREACHED(); |
451 return; | 471 return; |
452 } | 472 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
509 | 529 |
510 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { | 530 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { |
511 // Don't start up multiple times. | 531 // Don't start up multiple times. |
512 if (backend_) { | 532 if (backend_) { |
513 DVLOG(1) << "Skipping bringing up backend host."; | 533 DVLOG(1) << "Skipping bringing up backend host."; |
514 return; | 534 return; |
515 } | 535 } |
516 | 536 |
517 DCHECK(IsSyncEnabledAndLoggedIn()); | 537 DCHECK(IsSyncEnabledAndLoggedIn()); |
518 | 538 |
539 if (access_token_.empty()) { | |
540 RequestAccessToken(); | |
541 return; | |
542 } | |
543 | |
519 if (start_up_time_.is_null()) { | 544 if (start_up_time_.is_null()) { |
520 start_up_time_ = base::Time::Now(); | 545 start_up_time_ = base::Time::Now(); |
521 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); | 546 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); |
522 | 547 |
523 #if defined(OS_CHROMEOS) | 548 #if defined(OS_CHROMEOS) |
524 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); | 549 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); |
525 if (bootstrap_token.empty()) { | 550 if (bootstrap_token.empty()) { |
526 sync_prefs_.SetEncryptionBootstrapToken( | 551 sync_prefs_.SetEncryptionBootstrapToken( |
527 sync_prefs_.GetSpareBootstrapToken()); | 552 sync_prefs_.GetSpareBootstrapToken()); |
528 } | 553 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
656 // If |backend_| is NULL, save the acknowledgements to replay when | 681 // If |backend_| is NULL, save the acknowledgements to replay when |
657 // it's created and initialized. | 682 // it's created and initialized. |
658 ack_replay_queue_.push_back(std::make_pair(id, ack_handle)); | 683 ack_replay_queue_.push_back(std::make_pair(id, ack_handle)); |
659 } | 684 } |
660 } | 685 } |
661 | 686 |
662 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const { | 687 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const { |
663 return invalidator_registrar_->GetInvalidatorState(); | 688 return invalidator_registrar_->GetInvalidatorState(); |
664 } | 689 } |
665 | 690 |
691 void ProfileSyncService::OnGetTokenSuccess( | |
692 const OAuth2TokenService::Request* request, | |
693 const std::string& access_token, | |
694 const base::Time& expiration_time) { | |
695 DCHECK_EQ(access_token_request_, request); | |
696 access_token_request_.reset(); | |
697 // Reset backoff time after successful response. | |
698 request_access_token_backoff_.Reset(); | |
699 access_token_ = access_token; | |
700 if (backend_) | |
701 backend_->UpdateCredentials(GetCredentials()); | |
702 else | |
703 TryStart(); | |
704 } | |
705 | |
706 void ProfileSyncService::OnGetTokenFailure( | |
707 const OAuth2TokenService::Request* request, | |
708 const GoogleServiceAuthError& error) { | |
709 DCHECK_EQ(access_token_request_, request); | |
710 DCHECK_NE(error.state(), GoogleServiceAuthError::NONE); | |
711 access_token_request_.reset(); | |
712 switch (error.state()) { | |
713 case GoogleServiceAuthError::CONNECTION_FAILED: | |
714 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: { | |
715 // Transient error. Retry after some time. | |
716 request_access_token_backoff_.InformOfRequest(false); | |
717 request_access_token_retry_timer_.Start( | |
Andrew T Wilson (Slow)
2013/06/04 14:37:32
Should we stop this timer if someone else calls Re
pavely
2013/06/04 20:11:13
Done.
| |
718 FROM_HERE, | |
719 request_access_token_backoff_.GetTimeUntilRelease(), | |
720 base::Bind(&ProfileSyncService::RequestAccessToken, | |
721 weak_factory_.GetWeakPtr())); | |
722 break; | |
723 } | |
724 default: { | |
725 // Report time since token was issued for invalid credentials error. | |
726 if (error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) { | |
Andrew T Wilson (Slow)
2013/06/04 14:37:32
It's weird to check this here given that we're in
pavely
2013/06/04 20:11:13
Done.
| |
727 base::Time auth_token_time = | |
728 AboutSigninInternalsFactory::GetForProfile(profile_)-> | |
729 GetTokenTime(GaiaConstants::kGaiaOAuth2LoginRefreshToken); | |
730 if (!auth_token_time.is_null()) { | |
731 base::TimeDelta age = base::Time::Now() - auth_token_time; | |
732 if (age < base::TimeDelta::FromHours(1)) { | |
733 UMA_HISTOGRAM_CUSTOM_TIMES("Sync.AuthServerRejectedTokenAgeShort", | |
734 age, | |
735 base::TimeDelta::FromSeconds(1), | |
736 base::TimeDelta::FromHours(1), | |
737 50); | |
738 } | |
739 UMA_HISTOGRAM_COUNTS("Sync.AuthServerRejectedTokenAgeLong", | |
740 age.InDays()); | |
741 } | |
742 } | |
743 // Show error to user. | |
744 UpdateAuthErrorState(error); | |
745 } | |
746 } | |
747 | |
Nicolas Zea
2013/06/04 20:13:59
nit: remove newline
| |
748 } | |
749 | |
666 void ProfileSyncService::EmitInvalidationForTest( | 750 void ProfileSyncService::EmitInvalidationForTest( |
667 const invalidation::ObjectId& id, | 751 const invalidation::ObjectId& id, |
668 const std::string& payload) { | 752 const std::string& payload) { |
669 syncer::ObjectIdSet notify_ids; | 753 syncer::ObjectIdSet notify_ids; |
670 notify_ids.insert(id); | 754 notify_ids.insert(id); |
671 | 755 |
672 const syncer::ObjectIdInvalidationMap& invalidation_map = | 756 const syncer::ObjectIdInvalidationMap& invalidation_map = |
673 ObjectIdSetToInvalidationMap(notify_ids, payload); | 757 ObjectIdSetToInvalidationMap(notify_ids, payload); |
674 OnIncomingInvalidation(invalidation_map); | 758 OnIncomingInvalidation(invalidation_map); |
675 } | 759 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
735 is_auth_in_progress_ = false; | 819 is_auth_in_progress_ = false; |
736 backend_initialized_ = false; | 820 backend_initialized_ = false; |
737 // NULL if we're called from Shutdown(). | 821 // NULL if we're called from Shutdown(). |
738 if (invalidator_registrar_) | 822 if (invalidator_registrar_) |
739 UpdateInvalidatorRegistrarState(); | 823 UpdateInvalidatorRegistrarState(); |
740 cached_passphrase_.clear(); | 824 cached_passphrase_.clear(); |
741 encryption_pending_ = false; | 825 encryption_pending_ = false; |
742 encrypt_everything_ = false; | 826 encrypt_everything_ = false; |
743 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes(); | 827 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes(); |
744 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED; | 828 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED; |
745 start_up_time_ = base::Time(); | 829 request_access_token_retry_timer_.Stop(); |
746 // Revert to "no auth error". | 830 // Revert to "no auth error". |
747 if (last_auth_error_.state() != GoogleServiceAuthError::NONE) | 831 if (last_auth_error_.state() != GoogleServiceAuthError::NONE) |
748 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); | 832 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); |
749 | 833 |
750 if (sync_global_error_) { | 834 if (sync_global_error_) { |
751 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( | 835 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( |
752 sync_global_error_.get()); | 836 sync_global_error_.get()); |
753 RemoveObserver(sync_global_error_.get()); | 837 RemoveObserver(sync_global_error_.get()); |
754 sync_global_error_.reset(NULL); | 838 sync_global_error_.reset(NULL); |
755 } | 839 } |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1082 default: | 1166 default: |
1083 NOTREACHED(); | 1167 NOTREACHED(); |
1084 return AuthError(AuthError::CONNECTION_FAILED); | 1168 return AuthError(AuthError::CONNECTION_FAILED); |
1085 } | 1169 } |
1086 } | 1170 } |
1087 | 1171 |
1088 } // namespace | 1172 } // namespace |
1089 | 1173 |
1090 void ProfileSyncService::OnConnectionStatusChange( | 1174 void ProfileSyncService::OnConnectionStatusChange( |
1091 syncer::ConnectionStatus status) { | 1175 syncer::ConnectionStatus status) { |
1092 const GoogleServiceAuthError auth_error = | 1176 if (status == syncer::CONNECTION_AUTH_ERROR) { |
1093 ConnectionStatusToAuthError(status); | 1177 // Sync or Tango server returned error indicating that access token is |
1094 DVLOG(1) << "Connection status change: " << auth_error.ToString(); | 1178 // invalid. It could be either expired or access is revoked. Let's request |
1095 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 } | |
1096 } | 1188 } |
1097 | 1189 |
1098 void ProfileSyncService::OnStopSyncingPermanently() { | 1190 void ProfileSyncService::OnStopSyncingPermanently() { |
1099 sync_prefs_.SetStartSuppressed(true); | 1191 sync_prefs_.SetStartSuppressed(true); |
1100 DisableForUser(); | 1192 DisableForUser(); |
1101 } | 1193 } |
1102 | 1194 |
1103 void ProfileSyncService::OnPassphraseRequired( | 1195 void ProfileSyncService::OnPassphraseRequired( |
1104 syncer::PassphraseRequiredReason reason, | 1196 syncer::PassphraseRequiredReason reason, |
1105 const sync_pb::EncryptedData& pending_keys) { | 1197 const sync_pb::EncryptedData& pending_keys) { |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1834 } | 1926 } |
1835 } | 1927 } |
1836 | 1928 |
1837 // If we get here, we don't have pending keys (or at least, the passphrase | 1929 // If we get here, we don't have pending keys (or at least, the passphrase |
1838 // doesn't decrypt them) - just try to re-encrypt using the encryption | 1930 // doesn't decrypt them) - just try to re-encrypt using the encryption |
1839 // passphrase. | 1931 // passphrase. |
1840 if (!IsUsingSecondaryPassphrase()) | 1932 if (!IsUsingSecondaryPassphrase()) |
1841 SetEncryptionPassphrase(passphrase, IMPLICIT); | 1933 SetEncryptionPassphrase(passphrase, IMPLICIT); |
1842 } | 1934 } |
1843 | 1935 |
1936 void ProfileSyncService::RequestAccessToken() { | |
1937 // Only one active request at a time. | |
1938 if (access_token_request_ != NULL) | |
1939 return; | |
1940 OAuth2TokenService::ScopeSet oauth2_scopes; | |
1941 for (size_t i = 0; i < arraysize(kOAuth2Scopes); i++) | |
1942 oauth2_scopes.insert(kOAuth2Scopes[i]); | |
1943 OAuth2TokenService* token_service = | |
1944 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); | |
1945 // Invalidate previous token, otherwise token service will return the same | |
1946 // token again. | |
1947 token_service->InvalidateToken(oauth2_scopes, access_token_); | |
Andrew T Wilson (Slow)
2013/06/04 14:37:32
Should we only do this if access_token_ is non-emp
pavely
2013/06/04 20:11:13
OAuth2TokenService handles this case correctly and
| |
1948 access_token_.clear(); | |
1949 access_token_request_ = token_service->StartRequest(oauth2_scopes, this); | |
1950 } | |
1951 | |
1844 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, | 1952 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, |
1845 PassphraseType type) { | 1953 PassphraseType type) { |
1846 // This should only be called when the backend has been initialized. | 1954 // This should only be called when the backend has been initialized. |
1847 DCHECK(sync_initialized()); | 1955 DCHECK(sync_initialized()); |
1848 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) << | 1956 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) << |
1849 "Data is already encrypted using an explicit passphrase"; | 1957 "Data is already encrypted using an explicit passphrase"; |
1850 DCHECK(!(type == EXPLICIT && | 1958 DCHECK(!(type == EXPLICIT && |
1851 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) << | 1959 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) << |
1852 "Can not set explicit passphrase when decryption is needed."; | 1960 "Can not set explicit passphrase when decryption is needed."; |
1853 | 1961 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1937 RefreshSpareBootstrapToken(successful->password); | 2045 RefreshSpareBootstrapToken(successful->password); |
1938 #endif | 2046 #endif |
1939 if (!sync_initialized() || | 2047 if (!sync_initialized() || |
1940 GetAuthError().state() != AuthError::NONE) { | 2048 GetAuthError().state() != AuthError::NONE) { |
1941 // Track the fact that we're still waiting for auth to complete. | 2049 // Track the fact that we're still waiting for auth to complete. |
1942 is_auth_in_progress_ = true; | 2050 is_auth_in_progress_ = true; |
1943 } | 2051 } |
1944 break; | 2052 break; |
1945 } | 2053 } |
1946 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { | 2054 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { |
2055 // TODO(atwilson): sync shouldn't report refresh token request failures. | |
2056 // TokenService should do that instead. | |
1947 const TokenService::TokenRequestFailedDetails& token_details = | 2057 const TokenService::TokenRequestFailedDetails& token_details = |
1948 *(content::Details<const TokenService::TokenRequestFailedDetails>( | 2058 *(content::Details<const TokenService::TokenRequestFailedDetails>( |
1949 details).ptr()); | 2059 details).ptr()); |
1950 if (IsTokenServiceRelevant(token_details.service()) && | 2060 if (token_details.service() == |
1951 !IsSyncTokenAvailable()) { | 2061 GaiaConstants::kGaiaOAuth2LoginRefreshToken && |
1952 // The additional check around IsSyncTokenAvailable() above prevents us | 2062 !IsOAuthRefreshTokenAvailable()) { |
1953 // sounding the alarm if we actually have a valid token but a refresh | 2063 // The additional check around IsOAuthRefreshTokenAvailable() above |
1954 // attempt by TokenService failed for any variety of reasons (e.g. flaky | 2064 // prevents us sounding the alarm if we actually have a valid token but |
1955 // network). It's possible the token we do have is also invalid, but in | 2065 // a refresh attempt by TokenService failed for any variety of reasons |
1956 // that case we should already have (or can expect) an auth error sent | 2066 // (e.g. flaky network). It's possible the token we do have is also |
1957 // from the sync backend. | 2067 // invalid, but in that case we should already have (or can expect) an |
2068 // auth error sent from the sync backend. | |
1958 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS); | 2069 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS); |
1959 UpdateAuthErrorState(error); | 2070 UpdateAuthErrorState(error); |
1960 } | 2071 } |
1961 break; | 2072 break; |
1962 } | 2073 } |
1963 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { | 2074 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { |
2075 // TODO(atwilson): Listen for notifications on OAuth2TokenService | |
2076 // (crbug.com/243737) | |
1964 const TokenService::TokenAvailableDetails& token_details = | 2077 const TokenService::TokenAvailableDetails& token_details = |
1965 *(content::Details<const TokenService::TokenAvailableDetails>( | 2078 *(content::Details<const TokenService::TokenAvailableDetails>( |
1966 details).ptr()); | 2079 details).ptr()); |
1967 if (!IsTokenServiceRelevant(token_details.service())) | 2080 if (token_details.service() != |
2081 GaiaConstants::kGaiaOAuth2LoginRefreshToken) | |
1968 break; | 2082 break; |
1969 } // Fall through. | 2083 } // Fall through. |
1970 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { | 2084 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { |
1971 // This notification gets fired when TokenService loads the tokens | 2085 // This notification gets fired when TokenService loads the tokens |
1972 // from storage. | 2086 // from storage. |
1973 // Initialize the backend if sync is enabled. If the sync token was | 2087 // Initialize the backend if sync is enabled. If the sync token was |
1974 // not loaded, GetCredentials() will generate invalid credentials to | 2088 // not loaded, GetCredentials() will generate invalid credentials to |
1975 // cause the backend to generate an auth error (crbug.com/121755). | 2089 // cause the backend to generate an auth error (crbug.com/121755). |
1976 if (backend_) | 2090 if (backend_) |
1977 backend_->UpdateCredentials(GetCredentials()); | 2091 RequestAccessToken(); |
1978 else | 2092 else |
1979 TryStart(); | 2093 TryStart(); |
1980 break; | 2094 break; |
1981 } | 2095 } |
1982 case chrome::NOTIFICATION_TOKENS_CLEARED: { | 2096 case chrome::NOTIFICATION_TOKENS_CLEARED: { |
1983 // GetCredentials() will generate invalid credentials to cause the backend | 2097 // GetCredentials() will generate invalid credentials to cause the backend |
1984 // to generate an auth error. | 2098 // to generate an auth error. |
2099 access_token_.clear(); | |
1985 if (backend_) | 2100 if (backend_) |
1986 backend_->UpdateCredentials(GetCredentials()); | 2101 backend_->UpdateCredentials(GetCredentials()); |
1987 break; | 2102 break; |
1988 } | 2103 } |
1989 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: | 2104 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: |
1990 sync_disabled_by_admin_ = false; | 2105 sync_disabled_by_admin_ = false; |
1991 DisableForUser(); | 2106 DisableForUser(); |
1992 break; | 2107 break; |
1993 default: { | 2108 default: { |
1994 NOTREACHED(); | 2109 NOTREACHED(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2111 std::string ProfileSyncService::GetEffectiveUsername() { | 2226 std::string ProfileSyncService::GetEffectiveUsername() { |
2112 #if defined(ENABLE_MANAGED_USERS) | 2227 #if defined(ENABLE_MANAGED_USERS) |
2113 if (ManagedUserService::ProfileIsManaged(profile_)) { | 2228 if (ManagedUserService::ProfileIsManaged(profile_)) { |
2114 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername()); | 2229 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername()); |
2115 return ManagedUserService::GetManagedUserPseudoEmail(); | 2230 return ManagedUserService::GetManagedUserPseudoEmail(); |
2116 } | 2231 } |
2117 #endif | 2232 #endif |
2118 | 2233 |
2119 return signin_->GetAuthenticatedUsername(); | 2234 return signin_->GetAuthenticatedUsername(); |
2120 } | 2235 } |
2121 | |
OLD | NEW |