| 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 ProfileOAuth2TokenService* token_service = |
| 223 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
| 200 if (!token_service) | 224 if (!token_service) |
| 201 return false; | 225 return false; |
| 202 return token_service->HasTokenForService(GaiaConstants::kSyncService); | 226 return token_service->RefreshTokenIsAvailable(); |
| 203 } | 227 } |
| 204 #if defined(OS_ANDROID) | 228 #if defined(OS_ANDROID) |
| 205 bool ProfileSyncService::ShouldEnablePasswordSyncForAndroid() const { | 229 bool ProfileSyncService::ShouldEnablePasswordSyncForAndroid() const { |
| 206 if (!GetPreferredDataTypes().Has(syncer::PASSWORDS)) | 230 if (!GetPreferredDataTypes().Has(syncer::PASSWORDS)) |
| 207 return false; | 231 return false; |
| 208 // If backend has not completed initializing we cannot check if the | 232 // If backend has not completed initializing we cannot check if the |
| 209 // cryptographer is ready. | 233 // cryptographer is ready. |
| 210 if (!sync_initialized()) | 234 if (!sync_initialized()) |
| 211 return false; | 235 return false; |
| 212 // On Android we do not want to prompt user to enter a passphrase. If | 236 // On Android we do not want to prompt user to enter a passphrase. If |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 return; | 308 return; |
| 285 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 309 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
| 286 if (!token_service) | 310 if (!token_service) |
| 287 return; | 311 return; |
| 288 // Don't start the backend if the token service hasn't finished loading tokens | 312 // Don't start the backend if the token service hasn't finished loading tokens |
| 289 // yet. Note if the backend is started before the sync token has been loaded, | 313 // yet. Note if the backend is started before the sync token has been loaded, |
| 290 // GetCredentials() will return bogus credentials. On auto_start platforms | 314 // GetCredentials() will return bogus credentials. On auto_start platforms |
| 291 // (like ChromeOS) we don't start sync until tokens are loaded, because the | 315 // (like ChromeOS) we don't start sync until tokens are loaded, because the |
| 292 // user can be "signed in" on those platforms long before the tokens get | 316 // user can be "signed in" on those platforms long before the tokens get |
| 293 // loaded, and we don't want to generate spurious auth errors. | 317 // loaded, and we don't want to generate spurious auth errors. |
| 294 if (!IsSyncTokenAvailable() && | 318 if (!IsOAuthRefreshTokenAvailable() && |
| 295 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { | 319 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { |
| 296 return; | 320 return; |
| 297 } | 321 } |
| 298 | 322 |
| 323 // If we got here then tokens are loaded and user logged in and sync is |
| 324 // enabled. If OAuth refresh token is not available then something is wrong. |
| 325 // When PSS requests access token, OAuth2TokenService will return error and |
| 326 // PSS will show error to user asking to reauthenticate. |
| 327 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", |
| 328 !IsOAuthRefreshTokenAvailable()); |
| 329 |
| 299 // If sync setup has completed we always start the backend. If the user is in | 330 // If sync setup has completed we always start the backend. If the user is in |
| 300 // the process of setting up now, we should start the backend to download | 331 // the process of setting up now, we should start the backend to download |
| 301 // account control state / encryption information). If autostart is enabled, | 332 // account control state / encryption information). If autostart is enabled, |
| 302 // but we haven't completed sync setup, we try to start sync anyway, since | 333 // but we haven't completed sync setup, we try to start sync anyway, since |
| 303 // it's possible we crashed/shutdown after logging in but before the backend | 334 // it's possible we crashed/shutdown after logging in but before the backend |
| 304 // finished initializing the last time. | 335 // finished initializing the last time. |
| 305 // | 336 // |
| 306 // However, the only time we actually need to start sync _immediately_ is if | 337 // However, the only time we actually need to start sync _immediately_ is if |
| 307 // we haven't completed sync setup and the user is in the process of setting | 338 // we haven't completed sync setup and the user is in the process of setting |
| 308 // up - either they just signed in (for the first time) on an auto-start | 339 // 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... |
| 418 << "is invalid: " << value; | 449 << "is invalid: " << value; |
| 419 } | 450 } |
| 420 } | 451 } |
| 421 } | 452 } |
| 422 } | 453 } |
| 423 | 454 |
| 424 SyncCredentials ProfileSyncService::GetCredentials() { | 455 SyncCredentials ProfileSyncService::GetCredentials() { |
| 425 SyncCredentials credentials; | 456 SyncCredentials credentials; |
| 426 credentials.email = GetEffectiveUsername(); | 457 credentials.email = GetEffectiveUsername(); |
| 427 DCHECK(!credentials.email.empty()); | 458 DCHECK(!credentials.email.empty()); |
| 428 TokenService* service = TokenServiceFactory::GetForProfile(profile_); | 459 if (!access_token_.empty()) { |
| 429 if (service->HasTokenForService(GaiaConstants::kSyncService)) { | 460 credentials.sync_token = access_token_; |
| 430 credentials.sync_token = service->GetTokenForService( | |
| 431 GaiaConstants::kSyncService); | |
| 432 credentials.sync_token_time = | |
| 433 AboutSigninInternalsFactory::GetForProfile(profile_)-> | |
| 434 GetTokenTime(GaiaConstants::kSyncService); | |
| 435 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", false); | |
| 436 } else { | 461 } else { |
| 437 // We've lost our sync credentials (crbug.com/121755), so just make up some | |
| 438 // invalid credentials so the backend will generate an auth error. | |
| 439 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", true); | |
| 440 credentials.sync_token = "credentials_lost"; | 462 credentials.sync_token = "credentials_lost"; |
| 441 } | 463 } |
| 442 return credentials; | 464 return credentials; |
| 443 } | 465 } |
| 444 | 466 |
| 445 void ProfileSyncService::InitializeBackend(bool delete_stale_data) { | 467 void ProfileSyncService::InitializeBackend(bool delete_stale_data) { |
| 446 if (!backend_) { | 468 if (!backend_) { |
| 447 NOTREACHED(); | 469 NOTREACHED(); |
| 448 return; | 470 return; |
| 449 } | 471 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 | 529 |
| 508 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { | 530 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { |
| 509 // Don't start up multiple times. | 531 // Don't start up multiple times. |
| 510 if (backend_) { | 532 if (backend_) { |
| 511 DVLOG(1) << "Skipping bringing up backend host."; | 533 DVLOG(1) << "Skipping bringing up backend host."; |
| 512 return; | 534 return; |
| 513 } | 535 } |
| 514 | 536 |
| 515 DCHECK(IsSyncEnabledAndLoggedIn()); | 537 DCHECK(IsSyncEnabledAndLoggedIn()); |
| 516 | 538 |
| 539 if (access_token_.empty()) { |
| 540 RequestAccessToken(); |
| 541 return; |
| 542 } |
| 543 |
| 517 if (start_up_time_.is_null()) { | 544 if (start_up_time_.is_null()) { |
| 518 start_up_time_ = base::Time::Now(); | 545 start_up_time_ = base::Time::Now(); |
| 519 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); | 546 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); |
| 520 | 547 |
| 521 #if defined(OS_CHROMEOS) | 548 #if defined(OS_CHROMEOS) |
| 522 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); | 549 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); |
| 523 if (bootstrap_token.empty()) { | 550 if (bootstrap_token.empty()) { |
| 524 sync_prefs_.SetEncryptionBootstrapToken( | 551 sync_prefs_.SetEncryptionBootstrapToken( |
| 525 sync_prefs_.GetSpareBootstrapToken()); | 552 sync_prefs_.GetSpareBootstrapToken()); |
| 526 } | 553 } |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 // If |backend_| is NULL, save the acknowledgements to replay when | 681 // If |backend_| is NULL, save the acknowledgements to replay when |
| 655 // it's created and initialized. | 682 // it's created and initialized. |
| 656 ack_replay_queue_.push_back(std::make_pair(id, ack_handle)); | 683 ack_replay_queue_.push_back(std::make_pair(id, ack_handle)); |
| 657 } | 684 } |
| 658 } | 685 } |
| 659 | 686 |
| 660 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const { | 687 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const { |
| 661 return invalidator_registrar_->GetInvalidatorState(); | 688 return invalidator_registrar_->GetInvalidatorState(); |
| 662 } | 689 } |
| 663 | 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( |
| 718 FROM_HERE, |
| 719 request_access_token_backoff_.GetTimeUntilRelease(), |
| 720 base::Bind(&ProfileSyncService::RequestAccessToken, |
| 721 weak_factory_.GetWeakPtr())); |
| 722 break; |
| 723 } |
| 724 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: { |
| 725 // Report time since token was issued for invalid credentials error. |
| 726 // TODO(pavely): crbug.com/246817 Collect UMA histogram for auth token |
| 727 // rejections from invalidation service. |
| 728 base::Time auth_token_time = |
| 729 AboutSigninInternalsFactory::GetForProfile(profile_)-> |
| 730 GetTokenTime(GaiaConstants::kGaiaOAuth2LoginRefreshToken); |
| 731 if (!auth_token_time.is_null()) { |
| 732 base::TimeDelta age = base::Time::Now() - auth_token_time; |
| 733 if (age < base::TimeDelta::FromHours(1)) { |
| 734 UMA_HISTOGRAM_CUSTOM_TIMES("Sync.AuthServerRejectedTokenAgeShort", |
| 735 age, |
| 736 base::TimeDelta::FromSeconds(1), |
| 737 base::TimeDelta::FromHours(1), |
| 738 50); |
| 739 } |
| 740 UMA_HISTOGRAM_COUNTS("Sync.AuthServerRejectedTokenAgeLong", |
| 741 age.InDays()); |
| 742 } |
| 743 // Fallthrough. |
| 744 } |
| 745 default: { |
| 746 // Show error to user. |
| 747 UpdateAuthErrorState(error); |
| 748 } |
| 749 } |
| 750 } |
| 751 |
| 664 void ProfileSyncService::EmitInvalidationForTest( | 752 void ProfileSyncService::EmitInvalidationForTest( |
| 665 const invalidation::ObjectId& id, | 753 const invalidation::ObjectId& id, |
| 666 const std::string& payload) { | 754 const std::string& payload) { |
| 667 syncer::ObjectIdSet notify_ids; | 755 syncer::ObjectIdSet notify_ids; |
| 668 notify_ids.insert(id); | 756 notify_ids.insert(id); |
| 669 | 757 |
| 670 const syncer::ObjectIdInvalidationMap& invalidation_map = | 758 const syncer::ObjectIdInvalidationMap& invalidation_map = |
| 671 ObjectIdSetToInvalidationMap(notify_ids, payload); | 759 ObjectIdSetToInvalidationMap(notify_ids, payload); |
| 672 OnIncomingInvalidation(invalidation_map); | 760 OnIncomingInvalidation(invalidation_map); |
| 673 } | 761 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 is_auth_in_progress_ = false; | 821 is_auth_in_progress_ = false; |
| 734 backend_initialized_ = false; | 822 backend_initialized_ = false; |
| 735 // NULL if we're called from Shutdown(). | 823 // NULL if we're called from Shutdown(). |
| 736 if (invalidator_registrar_) | 824 if (invalidator_registrar_) |
| 737 UpdateInvalidatorRegistrarState(); | 825 UpdateInvalidatorRegistrarState(); |
| 738 cached_passphrase_.clear(); | 826 cached_passphrase_.clear(); |
| 739 encryption_pending_ = false; | 827 encryption_pending_ = false; |
| 740 encrypt_everything_ = false; | 828 encrypt_everything_ = false; |
| 741 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes(); | 829 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes(); |
| 742 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED; | 830 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED; |
| 743 start_up_time_ = base::Time(); | 831 request_access_token_retry_timer_.Stop(); |
| 744 // Revert to "no auth error". | 832 // Revert to "no auth error". |
| 745 if (last_auth_error_.state() != GoogleServiceAuthError::NONE) | 833 if (last_auth_error_.state() != GoogleServiceAuthError::NONE) |
| 746 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); | 834 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); |
| 747 | 835 |
| 748 if (sync_global_error_) { | 836 if (sync_global_error_) { |
| 749 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( | 837 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( |
| 750 sync_global_error_.get()); | 838 sync_global_error_.get()); |
| 751 RemoveObserver(sync_global_error_.get()); | 839 RemoveObserver(sync_global_error_.get()); |
| 752 sync_global_error_.reset(NULL); | 840 sync_global_error_.reset(NULL); |
| 753 } | 841 } |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 default: | 1170 default: |
| 1083 NOTREACHED(); | 1171 NOTREACHED(); |
| 1084 return AuthError(AuthError::CONNECTION_FAILED); | 1172 return AuthError(AuthError::CONNECTION_FAILED); |
| 1085 } | 1173 } |
| 1086 } | 1174 } |
| 1087 | 1175 |
| 1088 } // namespace | 1176 } // namespace |
| 1089 | 1177 |
| 1090 void ProfileSyncService::OnConnectionStatusChange( | 1178 void ProfileSyncService::OnConnectionStatusChange( |
| 1091 syncer::ConnectionStatus status) { | 1179 syncer::ConnectionStatus status) { |
| 1092 const GoogleServiceAuthError auth_error = | 1180 if (status == syncer::CONNECTION_AUTH_ERROR) { |
| 1093 ConnectionStatusToAuthError(status); | 1181 // Sync or Tango server returned error indicating that access token is |
| 1094 DVLOG(1) << "Connection status change: " << auth_error.ToString(); | 1182 // invalid. It could be either expired or access is revoked. Let's request |
| 1095 UpdateAuthErrorState(auth_error); | 1183 // another access token and if access is revoked then request for token will |
| 1184 // fail with corresponding error. |
| 1185 RequestAccessToken(); |
| 1186 } else { |
| 1187 const GoogleServiceAuthError auth_error = |
| 1188 ConnectionStatusToAuthError(status); |
| 1189 DVLOG(1) << "Connection status change: " << auth_error.ToString(); |
| 1190 UpdateAuthErrorState(auth_error); |
| 1191 } |
| 1096 } | 1192 } |
| 1097 | 1193 |
| 1098 void ProfileSyncService::OnStopSyncingPermanently() { | 1194 void ProfileSyncService::OnStopSyncingPermanently() { |
| 1099 sync_prefs_.SetStartSuppressed(true); | 1195 sync_prefs_.SetStartSuppressed(true); |
| 1100 DisableForUser(); | 1196 DisableForUser(); |
| 1101 } | 1197 } |
| 1102 | 1198 |
| 1103 void ProfileSyncService::OnPassphraseRequired( | 1199 void ProfileSyncService::OnPassphraseRequired( |
| 1104 syncer::PassphraseRequiredReason reason, | 1200 syncer::PassphraseRequiredReason reason, |
| 1105 const sync_pb::EncryptedData& pending_keys) { | 1201 const sync_pb::EncryptedData& pending_keys) { |
| (...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1833 } | 1929 } |
| 1834 } | 1930 } |
| 1835 | 1931 |
| 1836 // If we get here, we don't have pending keys (or at least, the passphrase | 1932 // If we get here, we don't have pending keys (or at least, the passphrase |
| 1837 // doesn't decrypt them) - just try to re-encrypt using the encryption | 1933 // doesn't decrypt them) - just try to re-encrypt using the encryption |
| 1838 // passphrase. | 1934 // passphrase. |
| 1839 if (!IsUsingSecondaryPassphrase()) | 1935 if (!IsUsingSecondaryPassphrase()) |
| 1840 SetEncryptionPassphrase(passphrase, IMPLICIT); | 1936 SetEncryptionPassphrase(passphrase, IMPLICIT); |
| 1841 } | 1937 } |
| 1842 | 1938 |
| 1939 void ProfileSyncService::RequestAccessToken() { |
| 1940 // Only one active request at a time. |
| 1941 if (access_token_request_ != NULL) |
| 1942 return; |
| 1943 request_access_token_retry_timer_.Stop(); |
| 1944 OAuth2TokenService::ScopeSet oauth2_scopes; |
| 1945 for (size_t i = 0; i < arraysize(kOAuth2Scopes); i++) |
| 1946 oauth2_scopes.insert(kOAuth2Scopes[i]); |
| 1947 OAuth2TokenService* token_service = |
| 1948 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
| 1949 // Invalidate previous token, otherwise token service will return the same |
| 1950 // token again. |
| 1951 token_service->InvalidateToken(oauth2_scopes, access_token_); |
| 1952 access_token_.clear(); |
| 1953 access_token_request_ = token_service->StartRequest(oauth2_scopes, this); |
| 1954 } |
| 1955 |
| 1843 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, | 1956 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, |
| 1844 PassphraseType type) { | 1957 PassphraseType type) { |
| 1845 // This should only be called when the backend has been initialized. | 1958 // This should only be called when the backend has been initialized. |
| 1846 DCHECK(sync_initialized()); | 1959 DCHECK(sync_initialized()); |
| 1847 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) << | 1960 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) << |
| 1848 "Data is already encrypted using an explicit passphrase"; | 1961 "Data is already encrypted using an explicit passphrase"; |
| 1849 DCHECK(!(type == EXPLICIT && | 1962 DCHECK(!(type == EXPLICIT && |
| 1850 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) << | 1963 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) << |
| 1851 "Can not set explicit passphrase when decryption is needed."; | 1964 "Can not set explicit passphrase when decryption is needed."; |
| 1852 | 1965 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1936 RefreshSpareBootstrapToken(successful->password); | 2049 RefreshSpareBootstrapToken(successful->password); |
| 1937 #endif | 2050 #endif |
| 1938 if (!sync_initialized() || | 2051 if (!sync_initialized() || |
| 1939 GetAuthError().state() != AuthError::NONE) { | 2052 GetAuthError().state() != AuthError::NONE) { |
| 1940 // Track the fact that we're still waiting for auth to complete. | 2053 // Track the fact that we're still waiting for auth to complete. |
| 1941 is_auth_in_progress_ = true; | 2054 is_auth_in_progress_ = true; |
| 1942 } | 2055 } |
| 1943 break; | 2056 break; |
| 1944 } | 2057 } |
| 1945 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { | 2058 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { |
| 2059 // TODO(atwilson): sync shouldn't report refresh token request failures. |
| 2060 // TokenService should do that instead. |
| 1946 const TokenService::TokenRequestFailedDetails& token_details = | 2061 const TokenService::TokenRequestFailedDetails& token_details = |
| 1947 *(content::Details<const TokenService::TokenRequestFailedDetails>( | 2062 *(content::Details<const TokenService::TokenRequestFailedDetails>( |
| 1948 details).ptr()); | 2063 details).ptr()); |
| 1949 if (IsTokenServiceRelevant(token_details.service()) && | 2064 if (token_details.service() == |
| 1950 !IsSyncTokenAvailable()) { | 2065 GaiaConstants::kGaiaOAuth2LoginRefreshToken && |
| 1951 // The additional check around IsSyncTokenAvailable() above prevents us | 2066 !IsOAuthRefreshTokenAvailable()) { |
| 1952 // sounding the alarm if we actually have a valid token but a refresh | 2067 // The additional check around IsOAuthRefreshTokenAvailable() above |
| 1953 // attempt by TokenService failed for any variety of reasons (e.g. flaky | 2068 // prevents us sounding the alarm if we actually have a valid token but |
| 1954 // network). It's possible the token we do have is also invalid, but in | 2069 // a refresh attempt by TokenService failed for any variety of reasons |
| 1955 // that case we should already have (or can expect) an auth error sent | 2070 // (e.g. flaky network). It's possible the token we do have is also |
| 1956 // from the sync backend. | 2071 // invalid, but in that case we should already have (or can expect) an |
| 2072 // auth error sent from the sync backend. |
| 1957 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS); | 2073 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS); |
| 1958 UpdateAuthErrorState(error); | 2074 UpdateAuthErrorState(error); |
| 1959 } | 2075 } |
| 1960 break; | 2076 break; |
| 1961 } | 2077 } |
| 1962 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { | 2078 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { |
| 2079 // TODO(atwilson): Listen for notifications on OAuth2TokenService |
| 2080 // (crbug.com/243737) |
| 1963 const TokenService::TokenAvailableDetails& token_details = | 2081 const TokenService::TokenAvailableDetails& token_details = |
| 1964 *(content::Details<const TokenService::TokenAvailableDetails>( | 2082 *(content::Details<const TokenService::TokenAvailableDetails>( |
| 1965 details).ptr()); | 2083 details).ptr()); |
| 1966 if (!IsTokenServiceRelevant(token_details.service())) | 2084 if (token_details.service() != |
| 2085 GaiaConstants::kGaiaOAuth2LoginRefreshToken) |
| 1967 break; | 2086 break; |
| 1968 } // Fall through. | 2087 } // Fall through. |
| 1969 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { | 2088 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { |
| 1970 // This notification gets fired when TokenService loads the tokens | 2089 // This notification gets fired when TokenService loads the tokens |
| 1971 // from storage. | 2090 // from storage. |
| 1972 // Initialize the backend if sync is enabled. If the sync token was | 2091 // Initialize the backend if sync is enabled. If the sync token was |
| 1973 // not loaded, GetCredentials() will generate invalid credentials to | 2092 // not loaded, GetCredentials() will generate invalid credentials to |
| 1974 // cause the backend to generate an auth error (crbug.com/121755). | 2093 // cause the backend to generate an auth error (crbug.com/121755). |
| 1975 if (backend_) | 2094 if (backend_) |
| 1976 backend_->UpdateCredentials(GetCredentials()); | 2095 RequestAccessToken(); |
| 1977 else | 2096 else |
| 1978 TryStart(); | 2097 TryStart(); |
| 1979 break; | 2098 break; |
| 1980 } | 2099 } |
| 1981 case chrome::NOTIFICATION_TOKENS_CLEARED: { | 2100 case chrome::NOTIFICATION_TOKENS_CLEARED: { |
| 1982 // GetCredentials() will generate invalid credentials to cause the backend | 2101 // GetCredentials() will generate invalid credentials to cause the backend |
| 1983 // to generate an auth error. | 2102 // to generate an auth error. |
| 2103 access_token_.clear(); |
| 1984 if (backend_) | 2104 if (backend_) |
| 1985 backend_->UpdateCredentials(GetCredentials()); | 2105 backend_->UpdateCredentials(GetCredentials()); |
| 1986 break; | 2106 break; |
| 1987 } | 2107 } |
| 1988 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: | 2108 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: |
| 1989 sync_disabled_by_admin_ = false; | 2109 sync_disabled_by_admin_ = false; |
| 1990 DisableForUser(); | 2110 DisableForUser(); |
| 1991 break; | 2111 break; |
| 1992 default: { | 2112 default: { |
| 1993 NOTREACHED(); | 2113 NOTREACHED(); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2110 std::string ProfileSyncService::GetEffectiveUsername() { | 2230 std::string ProfileSyncService::GetEffectiveUsername() { |
| 2111 #if defined(ENABLE_MANAGED_USERS) | 2231 #if defined(ENABLE_MANAGED_USERS) |
| 2112 if (ManagedUserService::ProfileIsManaged(profile_)) { | 2232 if (ManagedUserService::ProfileIsManaged(profile_)) { |
| 2113 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername()); | 2233 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername()); |
| 2114 return ManagedUserService::GetManagedUserPseudoEmail(); | 2234 return ManagedUserService::GetManagedUserPseudoEmail(); |
| 2115 } | 2235 } |
| 2116 #endif | 2236 #endif |
| 2117 | 2237 |
| 2118 return signin_->GetAuthenticatedUsername(); | 2238 return signin_->GetAuthenticatedUsername(); |
| 2119 } | 2239 } |
| 2120 | |
| OLD | NEW |