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 |