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

Unified Diff: chrome/browser/sync/profile_sync_service.cc

Issue 10656033: [sync] Automatic bootstrapping of Sync on Win 8 from cached credentials (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: "" Created 8 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698