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

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: Inverse command line flag to "disable oauth2". Set it by default for android. 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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() {
tim (not reviewing) 2013/06/12 21:54:49 Are we sure this isn't called from any place that
199 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 222 if (use_oauth2_token_) {
200 if (!token_service) 223 ProfileOAuth2TokenService* token_service =
201 return false; 224 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
202 return token_service->HasTokenForService(GaiaConstants::kSyncService); 225 if (!token_service)
226 return false;
227 return token_service->RefreshTokenIsAvailable();
228 } else {
229 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
230 if (!token_service)
231 return false;
232 return token_service->HasTokenForService(GaiaConstants::kSyncService);
233 }
203 } 234 }
204 235
205 void ProfileSyncService::Initialize() { 236 void ProfileSyncService::Initialize() {
206 DCHECK(!invalidator_registrar_.get()); 237 DCHECK(!invalidator_registrar_.get());
207 invalidator_registrar_.reset(new syncer::InvalidatorRegistrar()); 238 invalidator_registrar_.reset(new syncer::InvalidatorRegistrar());
208 239
209 InitSettings(); 240 InitSettings();
210 241
211 // We clear this here (vs Shutdown) because we want to remember that an error 242 // We clear this here (vs Shutdown) because we want to remember that an error
212 // happened on shutdown so we can display details (message, location) about it 243 // happened on shutdown so we can display details (message, location) about it
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 return; 301 return;
271 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 302 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
272 if (!token_service) 303 if (!token_service)
273 return; 304 return;
274 // Don't start the backend if the token service hasn't finished loading tokens 305 // Don't start the backend if the token service hasn't finished loading tokens
275 // yet. Note if the backend is started before the sync token has been loaded, 306 // yet. Note if the backend is started before the sync token has been loaded,
276 // GetCredentials() will return bogus credentials. On auto_start platforms 307 // GetCredentials() will return bogus credentials. On auto_start platforms
277 // (like ChromeOS) we don't start sync until tokens are loaded, because the 308 // (like ChromeOS) we don't start sync until tokens are loaded, because the
278 // user can be "signed in" on those platforms long before the tokens get 309 // user can be "signed in" on those platforms long before the tokens get
279 // loaded, and we don't want to generate spurious auth errors. 310 // loaded, and we don't want to generate spurious auth errors.
280 if (!IsSyncTokenAvailable() && 311 if (!IsOAuthRefreshTokenAvailable() &&
281 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) { 312 !(!auto_start_enabled_ && token_service->TokensLoadedFromDB())) {
282 return; 313 return;
283 } 314 }
284 315
316 if (use_oauth2_token_) {
317 // If we got here then tokens are loaded and user logged in and sync is
318 // enabled. If OAuth refresh token is not available then something is wrong.
319 // When PSS requests access token, OAuth2TokenService will return error and
320 // PSS will show error to user asking to reauthenticate.
321 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost",
tim (not reviewing) 2013/06/12 21:54:49 What's the rationale for moving this from GetCrede
pavely 2013/06/12 23:12:32 In OAuth2 world if access_token_ is empty in GetCr
322 !IsOAuthRefreshTokenAvailable());
323 }
324
285 // If sync setup has completed we always start the backend. If the user is in 325 // If sync setup has completed we always start the backend. If the user is in
286 // the process of setting up now, we should start the backend to download 326 // the process of setting up now, we should start the backend to download
287 // account control state / encryption information). If autostart is enabled, 327 // account control state / encryption information). If autostart is enabled,
288 // but we haven't completed sync setup, we try to start sync anyway, since 328 // but we haven't completed sync setup, we try to start sync anyway, since
289 // it's possible we crashed/shutdown after logging in but before the backend 329 // it's possible we crashed/shutdown after logging in but before the backend
290 // finished initializing the last time. 330 // finished initializing the last time.
291 // 331 //
292 // However, the only time we actually need to start sync _immediately_ is if 332 // However, the only time we actually need to start sync _immediately_ is if
293 // we haven't completed sync setup and the user is in the process of setting 333 // we haven't completed sync setup and the user is in the process of setting
294 // up - either they just signed in (for the first time) on an auto-start 334 // up - either they just signed in (for the first time) on an auto-start
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 if (!value.empty()) { 438 if (!value.empty()) {
399 GURL custom_sync_url(value); 439 GURL custom_sync_url(value);
400 if (custom_sync_url.is_valid()) { 440 if (custom_sync_url.is_valid()) {
401 sync_service_url_ = custom_sync_url; 441 sync_service_url_ = custom_sync_url;
402 } else { 442 } else {
403 LOG(WARNING) << "The following sync URL specified at the command-line " 443 LOG(WARNING) << "The following sync URL specified at the command-line "
404 << "is invalid: " << value; 444 << "is invalid: " << value;
405 } 445 }
406 } 446 }
407 } 447 }
448
449 use_oauth2_token_ = !command_line.HasSwitch(
450 switches::kSyncDisableOAuth2Token);
408 } 451 }
409 452
410 SyncCredentials ProfileSyncService::GetCredentials() { 453 SyncCredentials ProfileSyncService::GetCredentials() {
411 SyncCredentials credentials; 454 SyncCredentials credentials;
412 credentials.email = GetEffectiveUsername(); 455 credentials.email = GetEffectiveUsername();
413 DCHECK(!credentials.email.empty()); 456 DCHECK(!credentials.email.empty());
414 TokenService* service = TokenServiceFactory::GetForProfile(profile_); 457 if (use_oauth2_token_) {
415 if (service->HasTokenForService(GaiaConstants::kSyncService)) { 458 credentials.sync_token = access_token_;
416 credentials.sync_token = service->GetTokenForService(
417 GaiaConstants::kSyncService);
418 credentials.sync_token_time =
419 AboutSigninInternalsFactory::GetForProfile(profile_)->
420 GetTokenTime(GaiaConstants::kSyncService);
421 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", false);
422 } else { 459 } else {
423 // We've lost our sync credentials (crbug.com/121755), so just make up some 460 TokenService* service = TokenServiceFactory::GetForProfile(profile_);
424 // invalid credentials so the backend will generate an auth error. 461 if (service->HasTokenForService(GaiaConstants::kSyncService)) {
425 UMA_HISTOGRAM_BOOLEAN("Sync.CredentialsLost", true); 462 credentials.sync_token = service->GetTokenForService(
463 GaiaConstants::kSyncService);
464 }
465 }
466
467 if (credentials.sync_token.empty())
426 credentials.sync_token = "credentials_lost"; 468 credentials.sync_token = "credentials_lost";
427 }
428 return credentials; 469 return credentials;
429 } 470 }
430 471
431 void ProfileSyncService::InitializeBackend(bool delete_stale_data) { 472 void ProfileSyncService::InitializeBackend(bool delete_stale_data) {
432 if (!backend_) { 473 if (!backend_) {
433 NOTREACHED(); 474 NOTREACHED();
434 return; 475 return;
435 } 476 }
436 477
437 SyncCredentials credentials = GetCredentials(); 478 SyncCredentials credentials = GetCredentials();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 525
485 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) { 526 void ProfileSyncService::StartUp(StartUpDeferredOption deferred_option) {
486 // Don't start up multiple times. 527 // Don't start up multiple times.
487 if (backend_) { 528 if (backend_) {
488 DVLOG(1) << "Skipping bringing up backend host."; 529 DVLOG(1) << "Skipping bringing up backend host.";
489 return; 530 return;
490 } 531 }
491 532
492 DCHECK(IsSyncEnabledAndLoggedIn()); 533 DCHECK(IsSyncEnabledAndLoggedIn());
493 534
535 if (use_oauth2_token_ && access_token_.empty()) {
536 RequestAccessToken();
537 return;
538 }
539
494 if (start_up_time_.is_null()) { 540 if (start_up_time_.is_null()) {
495 start_up_time_ = base::Time::Now(); 541 start_up_time_ = base::Time::Now();
496 last_synced_time_ = sync_prefs_.GetLastSyncedTime(); 542 last_synced_time_ = sync_prefs_.GetLastSyncedTime();
497 543
498 #if defined(OS_CHROMEOS) 544 #if defined(OS_CHROMEOS)
499 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken(); 545 std::string bootstrap_token = sync_prefs_.GetEncryptionBootstrapToken();
500 if (bootstrap_token.empty()) { 546 if (bootstrap_token.empty()) {
501 sync_prefs_.SetEncryptionBootstrapToken( 547 sync_prefs_.SetEncryptionBootstrapToken(
502 sync_prefs_.GetSpareBootstrapToken()); 548 sync_prefs_.GetSpareBootstrapToken());
503 } 549 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 // If |backend_| is NULL, save the acknowledgements to replay when 677 // If |backend_| is NULL, save the acknowledgements to replay when
632 // it's created and initialized. 678 // it's created and initialized.
633 ack_replay_queue_.push_back(std::make_pair(id, ack_handle)); 679 ack_replay_queue_.push_back(std::make_pair(id, ack_handle));
634 } 680 }
635 } 681 }
636 682
637 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const { 683 syncer::InvalidatorState ProfileSyncService::GetInvalidatorState() const {
638 return invalidator_registrar_->GetInvalidatorState(); 684 return invalidator_registrar_->GetInvalidatorState();
639 } 685 }
640 686
687 void ProfileSyncService::OnGetTokenSuccess(
688 const OAuth2TokenService::Request* request,
689 const std::string& access_token,
690 const base::Time& expiration_time) {
691 DCHECK_EQ(access_token_request_, request);
692 access_token_request_.reset();
693 // Reset backoff time after successful response.
694 request_access_token_backoff_.Reset();
695 access_token_ = access_token;
696 if (backend_)
697 backend_->UpdateCredentials(GetCredentials());
698 else
699 TryStart();
700 }
701
702 void ProfileSyncService::OnGetTokenFailure(
703 const OAuth2TokenService::Request* request,
704 const GoogleServiceAuthError& error) {
705 DCHECK_EQ(access_token_request_, request);
706 DCHECK_NE(error.state(), GoogleServiceAuthError::NONE);
707 access_token_request_.reset();
708 switch (error.state()) {
709 case GoogleServiceAuthError::CONNECTION_FAILED:
710 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: {
711 // Transient error. Retry after some time.
712 request_access_token_backoff_.InformOfRequest(false);
713 request_access_token_retry_timer_.Start(
714 FROM_HERE,
715 request_access_token_backoff_.GetTimeUntilRelease(),
716 base::Bind(&ProfileSyncService::RequestAccessToken,
717 weak_factory_.GetWeakPtr()));
718 break;
719 }
720 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: {
721 // Report time since token was issued for invalid credentials error.
722 // TODO(pavely): crbug.com/246817 Collect UMA histogram for auth token
723 // rejections from invalidation service.
724 base::Time auth_token_time =
725 AboutSigninInternalsFactory::GetForProfile(profile_)->
726 GetTokenTime(GaiaConstants::kGaiaOAuth2LoginRefreshToken);
727 if (!auth_token_time.is_null()) {
728 base::TimeDelta age = base::Time::Now() - auth_token_time;
729 if (age < base::TimeDelta::FromHours(1)) {
730 UMA_HISTOGRAM_CUSTOM_TIMES("Sync.AuthServerRejectedTokenAgeShort",
731 age,
732 base::TimeDelta::FromSeconds(1),
733 base::TimeDelta::FromHours(1),
734 50);
735 }
736 UMA_HISTOGRAM_COUNTS("Sync.AuthServerRejectedTokenAgeLong",
737 age.InDays());
738 }
739 // Fallthrough.
740 }
741 default: {
742 // Show error to user.
743 UpdateAuthErrorState(error);
744 }
745 }
746 }
747
641 void ProfileSyncService::EmitInvalidationForTest( 748 void ProfileSyncService::EmitInvalidationForTest(
642 const invalidation::ObjectId& id, 749 const invalidation::ObjectId& id,
643 const std::string& payload) { 750 const std::string& payload) {
644 syncer::ObjectIdSet notify_ids; 751 syncer::ObjectIdSet notify_ids;
645 notify_ids.insert(id); 752 notify_ids.insert(id);
646 753
647 const syncer::ObjectIdInvalidationMap& invalidation_map = 754 const syncer::ObjectIdInvalidationMap& invalidation_map =
648 ObjectIdSetToInvalidationMap(notify_ids, payload); 755 ObjectIdSetToInvalidationMap(notify_ids, payload);
649 OnIncomingInvalidation(invalidation_map); 756 OnIncomingInvalidation(invalidation_map);
650 } 757 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 is_auth_in_progress_ = false; 817 is_auth_in_progress_ = false;
711 backend_initialized_ = false; 818 backend_initialized_ = false;
712 // NULL if we're called from Shutdown(). 819 // NULL if we're called from Shutdown().
713 if (invalidator_registrar_) 820 if (invalidator_registrar_)
714 UpdateInvalidatorRegistrarState(); 821 UpdateInvalidatorRegistrarState();
715 cached_passphrase_.clear(); 822 cached_passphrase_.clear();
716 encryption_pending_ = false; 823 encryption_pending_ = false;
717 encrypt_everything_ = false; 824 encrypt_everything_ = false;
718 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes(); 825 encrypted_types_ = syncer::SyncEncryptionHandler::SensitiveTypes();
719 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED; 826 passphrase_required_reason_ = syncer::REASON_PASSPHRASE_NOT_REQUIRED;
720 start_up_time_ = base::Time(); 827 request_access_token_retry_timer_.Stop();
721 // Revert to "no auth error". 828 // Revert to "no auth error".
722 if (last_auth_error_.state() != GoogleServiceAuthError::NONE) 829 if (last_auth_error_.state() != GoogleServiceAuthError::NONE)
723 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); 830 UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone());
724 831
725 if (sync_global_error_) { 832 if (sync_global_error_) {
726 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError( 833 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError(
727 sync_global_error_.get()); 834 sync_global_error_.get());
728 RemoveObserver(sync_global_error_.get()); 835 RemoveObserver(sync_global_error_.get());
729 sync_global_error_.reset(NULL); 836 sync_global_error_.reset(NULL);
730 } 837 }
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 default: 1167 default:
1061 NOTREACHED(); 1168 NOTREACHED();
1062 return AuthError(AuthError::CONNECTION_FAILED); 1169 return AuthError(AuthError::CONNECTION_FAILED);
1063 } 1170 }
1064 } 1171 }
1065 1172
1066 } // namespace 1173 } // namespace
1067 1174
1068 void ProfileSyncService::OnConnectionStatusChange( 1175 void ProfileSyncService::OnConnectionStatusChange(
1069 syncer::ConnectionStatus status) { 1176 syncer::ConnectionStatus status) {
1070 const GoogleServiceAuthError auth_error = 1177 if (use_oauth2_token_ && status == syncer::CONNECTION_AUTH_ERROR) {
1071 ConnectionStatusToAuthError(status); 1178 // Sync or Tango server returned error indicating that access token is
1072 DVLOG(1) << "Connection status change: " << auth_error.ToString(); 1179 // invalid. It could be either expired or access is revoked. Let's request
1073 UpdateAuthErrorState(auth_error); 1180 // another access token and if access is revoked then request for token will
1181 // fail with corresponding error.
1182 RequestAccessToken();
1183 } else {
1184 const GoogleServiceAuthError auth_error =
1185 ConnectionStatusToAuthError(status);
1186 DVLOG(1) << "Connection status change: " << auth_error.ToString();
1187 UpdateAuthErrorState(auth_error);
1188 }
1074 } 1189 }
1075 1190
1076 void ProfileSyncService::OnStopSyncingPermanently() { 1191 void ProfileSyncService::OnStopSyncingPermanently() {
1077 sync_prefs_.SetStartSuppressed(true); 1192 sync_prefs_.SetStartSuppressed(true);
1078 DisableForUser(); 1193 DisableForUser();
1079 } 1194 }
1080 1195
1081 void ProfileSyncService::OnPassphraseRequired( 1196 void ProfileSyncService::OnPassphraseRequired(
1082 syncer::PassphraseRequiredReason reason, 1197 syncer::PassphraseRequiredReason reason,
1083 const sync_pb::EncryptedData& pending_keys) { 1198 const sync_pb::EncryptedData& pending_keys) {
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after
1787 } 1902 }
1788 } 1903 }
1789 1904
1790 // If we get here, we don't have pending keys (or at least, the passphrase 1905 // If we get here, we don't have pending keys (or at least, the passphrase
1791 // doesn't decrypt them) - just try to re-encrypt using the encryption 1906 // doesn't decrypt them) - just try to re-encrypt using the encryption
1792 // passphrase. 1907 // passphrase.
1793 if (!IsUsingSecondaryPassphrase()) 1908 if (!IsUsingSecondaryPassphrase())
1794 SetEncryptionPassphrase(passphrase, IMPLICIT); 1909 SetEncryptionPassphrase(passphrase, IMPLICIT);
1795 } 1910 }
1796 1911
1912 void ProfileSyncService::RequestAccessToken() {
1913 // Only one active request at a time.
1914 if (access_token_request_ != NULL)
1915 return;
1916 request_access_token_retry_timer_.Stop();
1917 OAuth2TokenService::ScopeSet oauth2_scopes;
1918 for (size_t i = 0; i < arraysize(kOAuth2Scopes); i++)
1919 oauth2_scopes.insert(kOAuth2Scopes[i]);
1920 OAuth2TokenService* token_service =
1921 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
1922 // Invalidate previous token, otherwise token service will return the same
1923 // token again.
1924 token_service->InvalidateToken(oauth2_scopes, access_token_);
1925 access_token_.clear();
1926 access_token_request_ = token_service->StartRequest(oauth2_scopes, this);
1927 }
1928
1797 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, 1929 void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase,
1798 PassphraseType type) { 1930 PassphraseType type) {
1799 // This should only be called when the backend has been initialized. 1931 // This should only be called when the backend has been initialized.
1800 DCHECK(sync_initialized()); 1932 DCHECK(sync_initialized());
1801 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) << 1933 DCHECK(!(type == IMPLICIT && IsUsingSecondaryPassphrase())) <<
1802 "Data is already encrypted using an explicit passphrase"; 1934 "Data is already encrypted using an explicit passphrase";
1803 DCHECK(!(type == EXPLICIT && 1935 DCHECK(!(type == EXPLICIT &&
1804 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) << 1936 passphrase_required_reason_ == syncer::REASON_DECRYPTION)) <<
1805 "Can not set explicit passphrase when decryption is needed."; 1937 "Can not set explicit passphrase when decryption is needed.";
1806 1938
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1866 DisableForUser(); 1998 DisableForUser();
1867 } else { 1999 } else {
1868 // Sync is no longer disabled by policy. Try starting it up if appropriate. 2000 // Sync is no longer disabled by policy. Try starting it up if appropriate.
1869 TryStart(); 2001 TryStart();
1870 } 2002 }
1871 } 2003 }
1872 2004
1873 void ProfileSyncService::Observe(int type, 2005 void ProfileSyncService::Observe(int type,
1874 const content::NotificationSource& source, 2006 const content::NotificationSource& source,
1875 const content::NotificationDetails& details) { 2007 const content::NotificationDetails& details) {
2008 const char* sync_token_service = use_oauth2_token_ ?
2009 GaiaConstants::kGaiaOAuth2LoginRefreshToken : GaiaConstants::kSyncService;
1876 switch (type) { 2010 switch (type) {
1877 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { 2011 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: {
1878 const GoogleServiceSigninSuccessDetails* successful = 2012 const GoogleServiceSigninSuccessDetails* successful =
1879 content::Details<const GoogleServiceSigninSuccessDetails>( 2013 content::Details<const GoogleServiceSigninSuccessDetails>(
1880 details).ptr(); 2014 details).ptr();
1881 if (!sync_prefs_.IsStartSuppressed() && 2015 if (!sync_prefs_.IsStartSuppressed() &&
1882 !successful->password.empty()) { 2016 !successful->password.empty()) {
1883 cached_passphrase_ = successful->password; 2017 cached_passphrase_ = successful->password;
1884 // Try to consume the passphrase we just cached. If the sync backend 2018 // Try to consume the passphrase we just cached. If the sync backend
1885 // is not running yet, the passphrase will remain cached until the 2019 // is not running yet, the passphrase will remain cached until the
1886 // backend starts up. 2020 // backend starts up.
1887 ConsumeCachedPassphraseIfPossible(); 2021 ConsumeCachedPassphraseIfPossible();
1888 } 2022 }
1889 #if defined(OS_CHROMEOS) 2023 #if defined(OS_CHROMEOS)
1890 RefreshSpareBootstrapToken(successful->password); 2024 RefreshSpareBootstrapToken(successful->password);
1891 #endif 2025 #endif
1892 if (!sync_initialized() || 2026 if (!sync_initialized() ||
1893 GetAuthError().state() != AuthError::NONE) { 2027 GetAuthError().state() != AuthError::NONE) {
1894 // Track the fact that we're still waiting for auth to complete. 2028 // Track the fact that we're still waiting for auth to complete.
1895 is_auth_in_progress_ = true; 2029 is_auth_in_progress_ = true;
1896 } 2030 }
1897 break; 2031 break;
1898 } 2032 }
1899 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: { 2033 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: {
2034 // TODO(atwilson): sync shouldn't report refresh token request failures.
2035 // TokenService should do that instead.
1900 const TokenService::TokenRequestFailedDetails& token_details = 2036 const TokenService::TokenRequestFailedDetails& token_details =
1901 *(content::Details<const TokenService::TokenRequestFailedDetails>( 2037 *(content::Details<const TokenService::TokenRequestFailedDetails>(
1902 details).ptr()); 2038 details).ptr());
1903 if (IsTokenServiceRelevant(token_details.service()) && 2039 if (token_details.service() == sync_token_service &&
1904 !IsSyncTokenAvailable()) { 2040 !IsOAuthRefreshTokenAvailable()) {
1905 // The additional check around IsSyncTokenAvailable() above prevents us 2041 // The additional check around IsOAuthRefreshTokenAvailable() above
1906 // sounding the alarm if we actually have a valid token but a refresh 2042 // prevents us sounding the alarm if we actually have a valid token but
1907 // attempt by TokenService failed for any variety of reasons (e.g. flaky 2043 // a refresh attempt by TokenService failed for any variety of reasons
1908 // network). It's possible the token we do have is also invalid, but in 2044 // (e.g. flaky network). It's possible the token we do have is also
1909 // that case we should already have (or can expect) an auth error sent 2045 // invalid, but in that case we should already have (or can expect) an
1910 // from the sync backend. 2046 // auth error sent from the sync backend.
1911 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS); 2047 AuthError error(AuthError::INVALID_GAIA_CREDENTIALS);
1912 UpdateAuthErrorState(error); 2048 UpdateAuthErrorState(error);
1913 } 2049 }
1914 break; 2050 break;
1915 } 2051 }
1916 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { 2052 case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
2053 // TODO(atwilson): Listen for notifications on OAuth2TokenService
2054 // (crbug.com/243737)
1917 const TokenService::TokenAvailableDetails& token_details = 2055 const TokenService::TokenAvailableDetails& token_details =
1918 *(content::Details<const TokenService::TokenAvailableDetails>( 2056 *(content::Details<const TokenService::TokenAvailableDetails>(
1919 details).ptr()); 2057 details).ptr());
1920 if (!IsTokenServiceRelevant(token_details.service())) 2058 if (token_details.service() != sync_token_service)
1921 break; 2059 break;
1922 } // Fall through. 2060 } // Fall through.
1923 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: { 2061 case chrome::NOTIFICATION_TOKEN_LOADING_FINISHED: {
1924 // This notification gets fired when TokenService loads the tokens 2062 // This notification gets fired when TokenService loads the tokens
1925 // from storage. 2063 // from storage.
1926 // Initialize the backend if sync is enabled. If the sync token was 2064 // Initialize the backend if sync is enabled. If the sync token was
1927 // not loaded, GetCredentials() will generate invalid credentials to 2065 // not loaded, GetCredentials() will generate invalid credentials to
1928 // cause the backend to generate an auth error (crbug.com/121755). 2066 // cause the backend to generate an auth error (crbug.com/121755).
1929 if (backend_) 2067 if (backend_) {
1930 backend_->UpdateCredentials(GetCredentials()); 2068 if (use_oauth2_token_)
1931 else 2069 RequestAccessToken();
2070 else
2071 backend_->UpdateCredentials(GetCredentials());
2072 } else {
1932 TryStart(); 2073 TryStart();
2074 }
1933 break; 2075 break;
1934 } 2076 }
1935 case chrome::NOTIFICATION_TOKENS_CLEARED: { 2077 case chrome::NOTIFICATION_TOKENS_CLEARED: {
1936 // GetCredentials() will generate invalid credentials to cause the backend 2078 // GetCredentials() will generate invalid credentials to cause the backend
1937 // to generate an auth error. 2079 // to generate an auth error.
2080 access_token_.clear();
1938 if (backend_) 2081 if (backend_)
1939 backend_->UpdateCredentials(GetCredentials()); 2082 backend_->UpdateCredentials(GetCredentials());
1940 break; 2083 break;
1941 } 2084 }
1942 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: 2085 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
1943 sync_disabled_by_admin_ = false; 2086 sync_disabled_by_admin_ = false;
1944 DisableForUser(); 2087 DisableForUser();
1945 break; 2088 break;
1946 default: { 2089 default: {
1947 NOTREACHED(); 2090 NOTREACHED();
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2064 std::string ProfileSyncService::GetEffectiveUsername() { 2207 std::string ProfileSyncService::GetEffectiveUsername() {
2065 #if defined(ENABLE_MANAGED_USERS) 2208 #if defined(ENABLE_MANAGED_USERS)
2066 if (ManagedUserService::ProfileIsManaged(profile_)) { 2209 if (ManagedUserService::ProfileIsManaged(profile_)) {
2067 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername()); 2210 DCHECK_EQ(std::string(), signin_->GetAuthenticatedUsername());
2068 return ManagedUserService::GetManagedUserPseudoEmail(); 2211 return ManagedUserService::GetManagedUserPseudoEmail();
2069 } 2212 }
2070 #endif 2213 #endif
2071 2214
2072 return signin_->GetAuthenticatedUsername(); 2215 return signin_->GetAuthenticatedUsername();
2073 } 2216 }
2074
OLDNEW
« no previous file with comments | « chrome/browser/sync/profile_sync_service.h ('k') | chrome/browser/sync/profile_sync_service_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698