Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1487)

Side by Side Diff: chrome/browser/sync/profile_sync_service.cc

Issue 15421011: Use OAuth2 token for sync (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove token prefetch. Move UMA counters. Fix some tests. Etc. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698