Chromium Code Reviews| Index: chrome/browser/sync/profile_sync_service.cc |
| diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc |
| index 466832e6612c3e6cb02ee4ebccbcc1440278a71a..269329ac34aa5a51078c43c3a822d1dc78f27e99 100644 |
| --- a/chrome/browser/sync/profile_sync_service.cc |
| +++ b/chrome/browser/sync/profile_sync_service.cc |
| @@ -15,22 +15,28 @@ |
| #include "base/command_line.h" |
| #include "base/compiler_specific.h" |
| #include "base/logging.h" |
| -#include "base/memory/ref_counted.h" |
| #include "base/message_loop.h" |
| #include "base/metrics/histogram.h" |
| #include "base/string16.h" |
| #include "base/stringprintf.h" |
| #include "base/threading/thread_restrictions.h" |
| +#if defined(OS_WIN) |
| +#include "base/win/windows_version.h" |
| +#endif |
| #include "chrome/browser/about_flags.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/defaults.h" |
| #include "chrome/browser/net/chrome_cookie_notification_details.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/profiles/profile_manager.h" |
| #include "chrome/browser/signin/signin_manager.h" |
| #include "chrome/browser/signin/signin_manager_factory.h" |
| #include "chrome/browser/signin/token_service.h" |
| #include "chrome/browser/signin/token_service_factory.h" |
| #include "chrome/browser/sync/backend_migrator.h" |
| +#if defined(OS_WIN) |
| +#include "chrome/browser/sync/credential_cache_win.h" |
| +#endif |
| #include "chrome/browser/sync/glue/change_processor.h" |
| #include "chrome/browser/sync/glue/chrome_encryptor.h" |
| #include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h" |
| @@ -47,11 +53,13 @@ |
| #include "chrome/browser/ui/global_error_service.h" |
| #include "chrome/browser/ui/global_error_service_factory.h" |
| #include "chrome/common/chrome_notification_types.h" |
| +#include "chrome/common/chrome_paths_internal.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/chrome_version_info.h" |
| #include "chrome/common/net/gaia/gaia_constants.h" |
| #include "chrome/common/time_format.h" |
| #include "chrome/common/url_constants.h" |
| +#include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/notification_details.h" |
| #include "content/public/browser/notification_source.h" |
| #include "grit/generated_resources.h" |
| @@ -134,7 +142,8 @@ ProfileSyncService::ProfileSyncService(ProfileSyncComponentsFactory* factory, |
| auto_start_enabled_(start_behavior == AUTO_START), |
| failed_datatypes_handler_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| configure_status_(DataTypeManager::UNKNOWN), |
| - setup_in_progress_(false) { |
| + setup_in_progress_(false), |
| + setting_up_with_cached_credentials_(false) { |
| #if defined(OS_ANDROID) |
| chrome::VersionInfo version_info; |
| if (version_info.IsOfficialBuild()) { |
| @@ -170,6 +179,26 @@ bool ProfileSyncService::IsSyncEnabledAndLoggedIn() { |
| return !signin_->GetAuthenticatedUsername().empty(); |
| } |
| +#if defined (OS_WIN) |
| + |
| +bool ProfileSyncService::ShouldSigninUsingCachedCredentials() { |
| + // Makes sure that we are running on Windows 8, that the current profile is |
| + // the default profile directory, that sync is not disabled by policy, that |
| + // startup is not suppressed, that setup is not already in progress, that no |
| + // user is already signed in, and that we are not already trying to auto-start |
| + // sync. |
| + return |
| + base::win::GetVersion() >= base::win::VERSION_WIN8 && |
| + csync::CredentialCache::IsDefaultProfileDir(profile()->GetPath()) && |
| + !IsManaged() && |
| + !sync_prefs_.IsStartSuppressed() && |
| + !setup_in_progress_ && |
| + signin_->GetAuthenticatedUsername().empty() && |
| + !setting_up_with_cached_credentials_; |
| +} |
| + |
| +#endif // OS_WIN |
| + |
| bool ProfileSyncService::IsSyncTokenAvailable() { |
| TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
| if (!token_service) |
| @@ -204,6 +233,12 @@ void ProfileSyncService::Initialize() { |
| } |
| void ProfileSyncService::TryStart() { |
| +#if defined(OS_WIN) |
| + if (ShouldSigninUsingCachedCredentials()) { |
|
Andrew T Wilson (Slow)
2012/06/26 23:26:13
What happens if the user is already logged in to a
Raghu Simha
2012/06/27 00:17:04
No. In such cases, signin_->GetAuthenticatedUserna
|
| + TryLoadingCachedCredentials(); |
| + return; |
| + } |
| +#endif // OS_WIN |
| if (!IsSyncEnabledAndLoggedIn()) |
| return; |
| TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
| @@ -229,6 +264,39 @@ void ProfileSyncService::TryStart() { |
| } |
| } |
| +#if defined(OS_WIN) |
| + |
| +void ProfileSyncService::TryLoadingCachedCredentials() { |
| + scoped_refptr<csync::CredentialCache> credentials = |
| + new csync::CredentialCache(profile_->GetPath()); |
| + content::BrowserThread::PostTaskAndReply( |
| + content::BrowserThread::FILE, |
| + FROM_HERE, |
| + base::Bind(&csync::CredentialCache::LoadCredentialsFromAlternateProfile, |
| + credentials), |
| + base::Bind(&ProfileSyncService::OnLoadedCachedCredentials, |
| + weak_factory_.GetWeakPtr(), |
| + credentials)); |
|
Roger Tawa OOO till Jul 10th
2012/06/27 21:23:28
why not bind the path directly instead of creating
Raghu Simha
2012/07/19 06:57:07
We now use a CredentialCacheService to do this.
|
| +} |
| + |
| +void ProfileSyncService::OnLoadedCachedCredentials( |
| + scoped_refptr<csync::CredentialCache> credentials) { |
| + DCHECK(credentials.get() != NULL); |
| + if (!credentials->authenticated_username().empty() && |
| + !credentials->sid().empty() && |
| + !credentials->lsid().empty() && |
| + !credentials->encryption_bootstrap_token().empty()) { |
| + setting_up_with_cached_credentials_ = true; |
| + SetSetupInProgress(true); |
| + sync_prefs_.SetEncryptionBootstrapToken( |
| + credentials->encryption_bootstrap_token()); |
| + signin_->StartSignInWithCachedCredentials(credentials); |
| + } |
| + credentials.release(); |
| +} |
| + |
| +#endif // OS_WIN |
| + |
| void ProfileSyncService::StartSyncingWithServer() { |
| if (backend_.get()) |
| backend_->StartSyncingWithServer(); |
| @@ -375,6 +443,15 @@ void ProfileSyncService::OnSyncConfigureDone( |
| FailedDatatypesHandler::STARTUP)) { |
| ReconfigureDatatypeManager(); |
| } |
| + |
| + // If we were trying to bootstrap sync using cached credentials, this |
| + // signifies the end of a successful auto-start. Set the flag to false and |
| + // mark sync setup as complete. |
| + if (setting_up_with_cached_credentials_) { |
| + setting_up_with_cached_credentials_ = false; |
| + SetSyncSetupCompleted(); |
| + NotifyObservers(); |
| + } |
| } |
| void ProfileSyncService::OnSyncConfigureRetry() { |
| @@ -398,7 +475,6 @@ void ProfileSyncService::OnSyncConfigureRetry() { |
| NotifyObservers(); |
| } |
| - |
| void ProfileSyncService::StartUp() { |
| // Don't start up multiple times. |
| if (backend_.get()) { |
| @@ -664,7 +740,11 @@ void ProfileSyncService::OnBackendInitialized( |
| // If we have a cached passphrase use it to decrypt/encrypt data now that the |
| // backend is initialized. We want to call this before notifying observers in |
| // case this operation affects the "passphrase required" status. |
| - ConsumeCachedPassphraseIfPossible(); |
| + // Note: On Windows 8, if we are signing in using sync credentials cached by |
| + // the alternate Metro / Desktop profile, there is no passphrase to consume, |
| + // since we only store the encryption bootstrap token for sync. |
| + if (!setting_up_with_cached_credentials_) |
|
Andrew T Wilson (Slow)
2012/06/26 23:26:13
Don't need this check since ConsumeCachedPassphras
Raghu Simha
2012/07/19 06:57:07
Removed.
|
| + ConsumeCachedPassphraseIfPossible(); |
| // The very first time the backend initializes is effectively the first time |
| // we can say we successfully "synced". last_synced_time_ will only be null |
| @@ -682,7 +762,9 @@ void ProfileSyncService::OnBackendInitialized( |
| NotifyObservers(); |
| } |
| - if (HasSyncSetupCompleted()) { |
| + // Configure the DTM if we are in the middle of an auto-start, or if we are |
| + // bootstrapping sync using cached sync credentials on Windows 8. |
| + if (HasSyncSetupCompleted() || setting_up_with_cached_credentials_) { |
|
Andrew T Wilson (Slow)
2012/06/26 23:26:13
Seems like it'd be better to just set HasSyncSetup
Raghu Simha
2012/06/27 00:17:04
This is an excellent point. I believe I'm going to
|
| ConfigureDataTypeManager(); |
| } else { |
| DCHECK(FirstSetupInProgress()); |
| @@ -1466,8 +1548,17 @@ void ProfileSyncService::Observe(int type, |
| const GoogleServiceSigninSuccessDetails* successful = |
| content::Details<const GoogleServiceSigninSuccessDetails>( |
| details).ptr(); |
| - DCHECK(!successful->password.empty()); |
| - if (!sync_prefs_.IsStartSuppressed()) { |
| + // The only time the password field is allowed to be empty is when we are |
| + // bootstrapping sync from cached credentials. |
| + DCHECK(setting_up_with_cached_credentials_ || |
| + !successful->password.empty()); |
|
Andrew T Wilson (Slow)
2012/06/26 23:26:13
This is kind of ugly, as it means that people outs
Raghu Simha
2012/06/27 00:17:04
Agreed. Coming up.
Raghu Simha
2012/07/19 06:57:07
Concerns addressed in new design, I hope :)
|
| + |
| + // Do not use the password as a cached passphrase if sync is suppressed. |
| + // Also, if we are starting up sync using cached credentials, do not try |
| + // to use the gaia password as an implicit passphrase, since passwords are |
| + // not persisted in the sync cache, and the password field will be empty. |
| + if (!sync_prefs_.IsStartSuppressed() && |
| + !setting_up_with_cached_credentials_) { |
| cached_passphrase_ = successful->password; |
| // Try to consume the passphrase we just cached. If the sync backend |
| // is not running yet, the passphrase will remain cached until the |