| 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 91471e02d2bfe824b354be1c6103b655d5339f1e..c77c510fe0773190aabd9d7dbbfad3d4b3bc6488 100644
|
| --- a/chrome/browser/sync/profile_sync_service.cc
|
| +++ b/chrome/browser/sync/profile_sync_service.cc
|
| @@ -376,6 +376,8 @@ void ProfileSyncService::CreateBackend() {
|
| }
|
|
|
| bool ProfileSyncService::IsEncryptedDatatypeEnabled() const {
|
| + if (HasPendingEncryptedTypes())
|
| + return true;
|
| syncable::ModelTypeSet preferred_types;
|
| GetPreferredDataTypes(&preferred_types);
|
| syncable::ModelTypeSet encrypted_types;
|
| @@ -691,31 +693,39 @@ void ProfileSyncService::OnPassphraseRequired(
|
| << sync_api::PassphraseRequiredReasonToString(reason);
|
| passphrase_required_reason_ = reason;
|
|
|
| + // Store any passphrases we have into temps and clear out the originals so
|
| + // we don't hold on to the passphrases any longer than we have to. We
|
| + // then use the passphrases if they're present (after OnPassphraseAccepted).
|
| + std::string gaia_password = gaia_password_;
|
| + std::string cached_passphrase = cached_passphrase_.value;
|
| + bool is_explicit = cached_passphrase_.is_explicit;
|
| + bool is_creation = cached_passphrase_.is_creation;
|
| + gaia_password_ = std::string();
|
| + cached_passphrase_ = CachedPassphrase();
|
| +
|
| // We will skip the passphrase prompt and suppress the warning if the
|
| // passphrase is needed for decryption but the user is not syncing an
|
| // encrypted data type on this machine. Otherwise we look for one.
|
| if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) {
|
| - VLOG(1) << "Not decrypting and no encrypted datatypes enabled"
|
| + VLOG(1) << "Decrypting and no encrypted datatypes enabled"
|
| << ", accepted passphrase.";
|
| OnPassphraseAccepted();
|
| }
|
|
|
| // First try supplying gaia password as the passphrase.
|
| - if (!gaia_password_.empty()) {
|
| + if (!gaia_password.empty()) {
|
| VLOG(1) << "Attempting gaia passphrase.";
|
| - SetPassphrase(gaia_password_, false, true);
|
| - gaia_password_ = std::string();
|
| + // SetPassphrase will set gaia_password_ if the syncer isn't ready.
|
| + SetPassphrase(gaia_password, false, true);
|
| return;
|
| }
|
|
|
| // If the above failed then try the custom passphrase the user might have
|
| // entered in setup.
|
| - if (!cached_passphrase_.value.empty()) {
|
| + if (!cached_passphrase.empty()) {
|
| VLOG(1) << "Attempting cached passphrase.";
|
| - SetPassphrase(cached_passphrase_.value,
|
| - cached_passphrase_.is_explicit,
|
| - cached_passphrase_.is_creation);
|
| - cached_passphrase_ = CachedPassphrase();
|
| + // SetPassphrase will set cached_passphrase_ if the syncer isn't ready.
|
| + SetPassphrase(cached_passphrase, is_explicit, is_creation);
|
| return;
|
| }
|
|
|
| @@ -731,6 +741,10 @@ void ProfileSyncService::OnPassphraseRequired(
|
|
|
| void ProfileSyncService::OnPassphraseAccepted() {
|
| VLOG(1) << "Received OnPassphraseAccepted.";
|
| + // Don't hold on to a passphrase in raw form longer than needed.
|
| + gaia_password_ = std::string();
|
| + cached_passphrase_ = CachedPassphrase();
|
| +
|
| // Make sure the data types that depend on the passphrase are started at
|
| // this time.
|
| syncable::ModelTypeSet types;
|
| @@ -753,6 +767,12 @@ void ProfileSyncService::OnPassphraseAccepted() {
|
|
|
| void ProfileSyncService::OnEncryptionComplete(
|
| const syncable::ModelTypeSet& encrypted_types) {
|
| + if (!pending_types_for_encryption_.empty()) {
|
| + // The user had chosen to encrypt datatypes. This is the last thing to
|
| + // complete, so now that we're done notify the UI.
|
| + wizard_.Step(SyncSetupWizard::DONE);
|
| + }
|
| + pending_types_for_encryption_.clear();
|
| NotifyObservers();
|
| }
|
|
|
| @@ -1182,7 +1202,7 @@ void ProfileSyncService::SetPassphrase(const std::string& passphrase,
|
| bool is_creation) {
|
| if (ShouldPushChanges() || IsPassphraseRequired()) {
|
| VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit")
|
| - << " passphrase " << (is_creation ? " for creation" : "");
|
| + << " passphrase" << (is_creation ? " for creation" : "");
|
| backend_->SetPassphrase(passphrase, is_explicit);
|
| } else {
|
| if (is_explicit) {
|
| @@ -1195,17 +1215,21 @@ void ProfileSyncService::SetPassphrase(const std::string& passphrase,
|
| }
|
| }
|
|
|
| -void ProfileSyncService::EncryptDataTypes(
|
| +void ProfileSyncService::set_pending_types_for_encryption(
|
| const syncable::ModelTypeSet& encrypted_types) {
|
| - if (HasSyncSetupCompleted()) {
|
| - backend_->EncryptDataTypes(encrypted_types);
|
| + if (encrypted_types.empty()) {
|
| + // We can't unencrypt types.
|
| + VLOG(1) << "No datatypes set for encryption, dropping encryption request.";
|
| pending_types_for_encryption_.clear();
|
| - } else {
|
| - pending_types_for_encryption_ = encrypted_types;
|
| + return;
|
| }
|
| + // Setting the pending types for encryption doesn't actually trigger
|
| + // encryption. The actual encryption will occur after the datatype manager
|
| + // is reconfigured.
|
| + pending_types_for_encryption_ = encrypted_types;
|
| }
|
|
|
| -// This would open a transaction to get the encrypted types. Do not call this
|
| +// This will open a transaction to get the encrypted types. Do not call this
|
| // if you already have a transaction open.
|
| void ProfileSyncService::GetEncryptedDataTypes(
|
| syncable::ModelTypeSet* encrypted_types) const {
|
| @@ -1222,6 +1246,10 @@ void ProfileSyncService::GetEncryptedDataTypes(
|
| }
|
| }
|
|
|
| +bool ProfileSyncService::HasPendingEncryptedTypes() const {
|
| + return !pending_types_for_encryption_.empty();
|
| +}
|
| +
|
| void ProfileSyncService::Observe(int type,
|
| const NotificationSource& source,
|
| const NotificationDetails& details) {
|
| @@ -1243,8 +1271,6 @@ void ProfileSyncService::Observe(int type,
|
| expect_sync_configuration_aborted_ = false;
|
| return;
|
| }
|
| - // Clear out the gaia password if it is already there.
|
| - gaia_password_ = std::string();
|
| if (status != DataTypeManager::OK) {
|
| VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected";
|
| std::string message =
|
| @@ -1256,32 +1282,25 @@ void ProfileSyncService::Observe(int type,
|
| return;
|
| }
|
|
|
| - // If the user had entered a custom passphrase use it now.
|
| - if (!cached_passphrase_.value.empty()) {
|
| - // Don't hold on to the passphrase in raw form longer than needed.
|
| - SetPassphrase(cached_passphrase_.value,
|
| - cached_passphrase_.is_explicit,
|
| - cached_passphrase_.is_creation);
|
| - cached_passphrase_ = CachedPassphrase();
|
| - }
|
| -
|
| // We should never get in a state where we have no encrypted datatypes
|
| // enabled, and yet we still think we require a passphrase for decryption.
|
| DCHECK(!(IsPassphraseRequiredForDecryption() &&
|
| !IsEncryptedDatatypeEnabled()));
|
|
|
| - // TODO(sync): Less wizard, more toast.
|
| - wizard_.Step(SyncSetupWizard::DONE);
|
| - NotifyObservers();
|
| -
|
| // In the old world, this would be a no-op. With new syncer thread,
|
| // this is the point where it is safe to switch from config-mode to
|
| // normal operation.
|
| backend_->StartSyncingWithServer();
|
|
|
| - if (!pending_types_for_encryption_.empty()) {
|
| - EncryptDataTypes(pending_types_for_encryption_);
|
| - pending_types_for_encryption_.clear();
|
| + if (pending_types_for_encryption_.empty()) {
|
| + wizard_.Step(SyncSetupWizard::DONE);
|
| + NotifyObservers();
|
| + } else {
|
| + // Will clear pending_types_for_encryption_ on success (via
|
| + // OnEncryptionComplete). Has no effect if pending_types_for_encryption_
|
| + // matches the encrypted types (and will clear
|
| + // pending_types_for_encryption_).
|
| + backend_->EncryptDataTypes(pending_types_for_encryption_);
|
| }
|
| break;
|
| }
|
|
|