| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <ostream> | 9 #include <ostream> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 types, | 368 types, |
| 369 credentials, | 369 credentials, |
| 370 delete_sync_data_folder); | 370 delete_sync_data_folder); |
| 371 } | 371 } |
| 372 | 372 |
| 373 void ProfileSyncService::CreateBackend() { | 373 void ProfileSyncService::CreateBackend() { |
| 374 backend_.reset(new SyncBackendHost(profile_)); | 374 backend_.reset(new SyncBackendHost(profile_)); |
| 375 } | 375 } |
| 376 | 376 |
| 377 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { | 377 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { |
| 378 if (HasPendingEncryptedTypes()) |
| 379 return true; |
| 378 syncable::ModelTypeSet preferred_types; | 380 syncable::ModelTypeSet preferred_types; |
| 379 GetPreferredDataTypes(&preferred_types); | 381 GetPreferredDataTypes(&preferred_types); |
| 380 syncable::ModelTypeSet encrypted_types; | 382 syncable::ModelTypeSet encrypted_types; |
| 381 GetEncryptedDataTypes(&encrypted_types); | 383 GetEncryptedDataTypes(&encrypted_types); |
| 382 syncable::ModelTypeBitSet preferred_types_bitset = | 384 syncable::ModelTypeBitSet preferred_types_bitset = |
| 383 syncable::ModelTypeBitSetFromSet(preferred_types); | 385 syncable::ModelTypeBitSetFromSet(preferred_types); |
| 384 syncable::ModelTypeBitSet encrypted_types_bitset = | 386 syncable::ModelTypeBitSet encrypted_types_bitset = |
| 385 syncable::ModelTypeBitSetFromSet(encrypted_types); | 387 syncable::ModelTypeBitSetFromSet(encrypted_types); |
| 386 DCHECK(encrypted_types.count(syncable::PASSWORDS)); | 388 DCHECK(encrypted_types.count(syncable::PASSWORDS)); |
| 387 return (preferred_types_bitset & encrypted_types_bitset).any(); | 389 return (preferred_types_bitset & encrypted_types_bitset).any(); |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 if (unrecoverable_error_detected_) { | 737 if (unrecoverable_error_detected_) { |
| 736 // When unrecoverable error is detected we post a task to shutdown the | 738 // When unrecoverable error is detected we post a task to shutdown the |
| 737 // backend. The task might not have executed yet. | 739 // backend. The task might not have executed yet. |
| 738 return; | 740 return; |
| 739 } | 741 } |
| 740 | 742 |
| 741 VLOG(1) << "Passphrase required with reason: " | 743 VLOG(1) << "Passphrase required with reason: " |
| 742 << sync_api::PassphraseRequiredReasonToString(reason); | 744 << sync_api::PassphraseRequiredReasonToString(reason); |
| 743 passphrase_required_reason_ = reason; | 745 passphrase_required_reason_ = reason; |
| 744 | 746 |
| 747 // Store any passphrases we have into temps and clear out the originals so |
| 748 // we don't hold on to the passphrases any longer than we have to. We |
| 749 // then use the passphrases if they're present (after OnPassphraseAccepted). |
| 750 std::string gaia_password = gaia_password_; |
| 751 std::string cached_passphrase = cached_passphrase_.value; |
| 752 bool is_explicit = cached_passphrase_.is_explicit; |
| 753 bool is_creation = cached_passphrase_.is_creation; |
| 754 gaia_password_ = std::string(); |
| 755 cached_passphrase_ = CachedPassphrase(); |
| 756 |
| 745 // We will skip the passphrase prompt and suppress the warning if the | 757 // We will skip the passphrase prompt and suppress the warning if the |
| 746 // passphrase is needed for decryption but the user is not syncing an | 758 // passphrase is needed for decryption but the user is not syncing an |
| 747 // encrypted data type on this machine. Otherwise we look for one. | 759 // encrypted data type on this machine. Otherwise we look for one. |
| 748 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { | 760 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { |
| 749 VLOG(1) << "Not decrypting and no encrypted datatypes enabled" | 761 VLOG(1) << "Decrypting and no encrypted datatypes enabled" |
| 750 << ", accepted passphrase."; | 762 << ", accepted passphrase."; |
| 751 OnPassphraseAccepted(); | 763 OnPassphraseAccepted(); |
| 752 } | 764 } |
| 753 | 765 |
| 754 // First try supplying gaia password as the passphrase. | 766 // First try supplying gaia password as the passphrase. |
| 755 if (!gaia_password_.empty()) { | 767 if (!gaia_password.empty()) { |
| 756 VLOG(1) << "Attempting gaia passphrase."; | 768 VLOG(1) << "Attempting gaia passphrase."; |
| 757 SetPassphrase(gaia_password_, false, true); | 769 // SetPassphrase will set gaia_password_ if the syncer isn't ready. |
| 758 gaia_password_ = std::string(); | 770 SetPassphrase(gaia_password, false, true); |
| 759 return; | 771 return; |
| 760 } | 772 } |
| 761 | 773 |
| 762 // If the above failed then try the custom passphrase the user might have | 774 // If the above failed then try the custom passphrase the user might have |
| 763 // entered in setup. | 775 // entered in setup. |
| 764 if (!cached_passphrase_.value.empty()) { | 776 if (!cached_passphrase.empty()) { |
| 765 VLOG(1) << "Attempting cached passphrase."; | 777 VLOG(1) << "Attempting cached passphrase."; |
| 766 SetPassphrase(cached_passphrase_.value, | 778 // SetPassphrase will set cached_passphrase_ if the syncer isn't ready. |
| 767 cached_passphrase_.is_explicit, | 779 SetPassphrase(cached_passphrase, is_explicit, is_creation); |
| 768 cached_passphrase_.is_creation); | |
| 769 cached_passphrase_ = CachedPassphrase(); | |
| 770 return; | 780 return; |
| 771 } | 781 } |
| 772 | 782 |
| 773 // Prompt the user for a password. | 783 // Prompt the user for a password. |
| 774 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && | 784 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && |
| 775 IsPassphraseRequiredForDecryption()) { | 785 IsPassphraseRequiredForDecryption()) { |
| 776 VLOG(1) << "Prompting user for passphrase."; | 786 VLOG(1) << "Prompting user for passphrase."; |
| 777 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); | 787 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); |
| 778 } | 788 } |
| 779 | 789 |
| 780 NotifyObservers(); | 790 NotifyObservers(); |
| 781 } | 791 } |
| 782 | 792 |
| 783 void ProfileSyncService::OnPassphraseAccepted() { | 793 void ProfileSyncService::OnPassphraseAccepted() { |
| 784 VLOG(1) << "Received OnPassphraseAccepted."; | 794 VLOG(1) << "Received OnPassphraseAccepted."; |
| 795 // Don't hold on to a passphrase in raw form longer than needed. |
| 796 gaia_password_ = std::string(); |
| 797 cached_passphrase_ = CachedPassphrase(); |
| 798 |
| 785 // Make sure the data types that depend on the passphrase are started at | 799 // Make sure the data types that depend on the passphrase are started at |
| 786 // this time. | 800 // this time. |
| 787 syncable::ModelTypeSet types; | 801 syncable::ModelTypeSet types; |
| 788 GetPreferredDataTypes(&types); | 802 GetPreferredDataTypes(&types); |
| 789 | 803 |
| 790 // Reset passphrase_required_reason_ before configuring the DataTypeManager | 804 // Reset passphrase_required_reason_ before configuring the DataTypeManager |
| 791 // since we know we no longer require the passphrase. | 805 // since we know we no longer require the passphrase. |
| 792 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; | 806 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; |
| 793 | 807 |
| 794 if (data_type_manager_.get()) { | 808 if (data_type_manager_.get()) { |
| 795 // Unblock the data type manager if necessary. | 809 // Unblock the data type manager if necessary. |
| 796 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will | 810 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will |
| 797 // step the UI wizard into DONE state (even if no datatypes have changed). | 811 // step the UI wizard into DONE state (even if no datatypes have changed). |
| 798 data_type_manager_->Configure(types, | 812 data_type_manager_->Configure(types, |
| 799 sync_api::CONFIGURE_REASON_RECONFIGURATION); | 813 sync_api::CONFIGURE_REASON_RECONFIGURATION); |
| 800 } | 814 } |
| 801 | 815 |
| 802 NotifyObservers(); | 816 NotifyObservers(); |
| 803 } | 817 } |
| 804 | 818 |
| 805 void ProfileSyncService::OnEncryptionComplete( | 819 void ProfileSyncService::OnEncryptionComplete( |
| 806 const syncable::ModelTypeSet& encrypted_types) { | 820 const syncable::ModelTypeSet& encrypted_types) { |
| 821 if (!pending_types_for_encryption_.empty()) { |
| 822 // The user had chosen to encrypt datatypes. This is the last thing to |
| 823 // complete, so now that we're done notify the UI. |
| 824 wizard_.Step(SyncSetupWizard::DONE); |
| 825 } |
| 826 pending_types_for_encryption_.clear(); |
| 807 NotifyObservers(); | 827 NotifyObservers(); |
| 808 } | 828 } |
| 809 | 829 |
| 810 void ProfileSyncService::OnMigrationNeededForTypes( | 830 void ProfileSyncService::OnMigrationNeededForTypes( |
| 811 const syncable::ModelTypeSet& types) { | 831 const syncable::ModelTypeSet& types) { |
| 812 DCHECK(backend_initialized_); | 832 DCHECK(backend_initialized_); |
| 813 DCHECK(data_type_manager_.get()); | 833 DCHECK(data_type_manager_.get()); |
| 814 | 834 |
| 815 // Migrator must be valid, because we don't sync until it is created and this | 835 // Migrator must be valid, because we don't sync until it is created and this |
| 816 // callback originates from a sync cycle. | 836 // callback originates from a sync cycle. |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 if (!backend_.get()) | 1234 if (!backend_.get()) |
| 1215 return; | 1235 return; |
| 1216 backend_->DeactivateDataType(data_type_controller, change_processor); | 1236 backend_->DeactivateDataType(data_type_controller, change_processor); |
| 1217 } | 1237 } |
| 1218 | 1238 |
| 1219 void ProfileSyncService::SetPassphrase(const std::string& passphrase, | 1239 void ProfileSyncService::SetPassphrase(const std::string& passphrase, |
| 1220 bool is_explicit, | 1240 bool is_explicit, |
| 1221 bool is_creation) { | 1241 bool is_creation) { |
| 1222 if (ShouldPushChanges() || IsPassphraseRequired()) { | 1242 if (ShouldPushChanges() || IsPassphraseRequired()) { |
| 1223 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") | 1243 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") |
| 1224 << " passphrase " << (is_creation ? " for creation" : ""); | 1244 << " passphrase" << (is_creation ? " for creation" : ""); |
| 1225 backend_->SetPassphrase(passphrase, is_explicit); | 1245 backend_->SetPassphrase(passphrase, is_explicit); |
| 1226 } else { | 1246 } else { |
| 1227 if (is_explicit) { | 1247 if (is_explicit) { |
| 1228 cached_passphrase_.value = passphrase; | 1248 cached_passphrase_.value = passphrase; |
| 1229 cached_passphrase_.is_explicit = is_explicit; | 1249 cached_passphrase_.is_explicit = is_explicit; |
| 1230 cached_passphrase_.is_creation = is_creation; | 1250 cached_passphrase_.is_creation = is_creation; |
| 1231 } else { | 1251 } else { |
| 1232 gaia_password_ = passphrase; | 1252 gaia_password_ = passphrase; |
| 1233 } | 1253 } |
| 1234 } | 1254 } |
| 1235 } | 1255 } |
| 1236 | 1256 |
| 1237 void ProfileSyncService::EncryptDataTypes( | 1257 void ProfileSyncService::set_pending_types_for_encryption( |
| 1238 const syncable::ModelTypeSet& encrypted_types) { | 1258 const syncable::ModelTypeSet& encrypted_types) { |
| 1239 if (HasSyncSetupCompleted()) { | 1259 if (encrypted_types.empty()) { |
| 1240 backend_->EncryptDataTypes(encrypted_types); | 1260 // We can't unencrypt types. |
| 1261 VLOG(1) << "No datatypes set for encryption, dropping encryption request."; |
| 1241 pending_types_for_encryption_.clear(); | 1262 pending_types_for_encryption_.clear(); |
| 1242 } else { | 1263 return; |
| 1243 pending_types_for_encryption_ = encrypted_types; | |
| 1244 } | 1264 } |
| 1265 // Setting the pending types for encryption doesn't actually trigger |
| 1266 // encryption. The actual encryption will occur after the datatype manager |
| 1267 // is reconfigured. |
| 1268 pending_types_for_encryption_ = encrypted_types; |
| 1245 } | 1269 } |
| 1246 | 1270 |
| 1247 // This would open a transaction to get the encrypted types. Do not call this | 1271 // This will open a transaction to get the encrypted types. Do not call this |
| 1248 // if you already have a transaction open. | 1272 // if you already have a transaction open. |
| 1249 void ProfileSyncService::GetEncryptedDataTypes( | 1273 void ProfileSyncService::GetEncryptedDataTypes( |
| 1250 syncable::ModelTypeSet* encrypted_types) const { | 1274 syncable::ModelTypeSet* encrypted_types) const { |
| 1251 CHECK(encrypted_types); | 1275 CHECK(encrypted_types); |
| 1252 if (backend_.get()) { | 1276 if (backend_.get()) { |
| 1253 *encrypted_types = backend_->GetEncryptedDataTypes(); | 1277 *encrypted_types = backend_->GetEncryptedDataTypes(); |
| 1254 DCHECK(encrypted_types->count(syncable::PASSWORDS)); | 1278 DCHECK(encrypted_types->count(syncable::PASSWORDS)); |
| 1255 } else { | 1279 } else { |
| 1256 // Either we are in an unrecoverable error or the sync is not yet done | 1280 // Either we are in an unrecoverable error or the sync is not yet done |
| 1257 // initializing. In either case just return the password type. During | 1281 // initializing. In either case just return the password type. During |
| 1258 // sync initialization the UI might need to know what our encrypted | 1282 // sync initialization the UI might need to know what our encrypted |
| 1259 // types are. | 1283 // types are. |
| 1260 (*encrypted_types).insert(syncable::PASSWORDS); | 1284 (*encrypted_types).insert(syncable::PASSWORDS); |
| 1261 } | 1285 } |
| 1262 } | 1286 } |
| 1263 | 1287 |
| 1288 bool ProfileSyncService::HasPendingEncryptedTypes() const { |
| 1289 return !pending_types_for_encryption_.empty(); |
| 1290 } |
| 1291 |
| 1264 void ProfileSyncService::Observe(int type, | 1292 void ProfileSyncService::Observe(int type, |
| 1265 const NotificationSource& source, | 1293 const NotificationSource& source, |
| 1266 const NotificationDetails& details) { | 1294 const NotificationDetails& details) { |
| 1267 switch (type) { | 1295 switch (type) { |
| 1268 case chrome::NOTIFICATION_SYNC_CONFIGURE_START: { | 1296 case chrome::NOTIFICATION_SYNC_CONFIGURE_START: { |
| 1269 NotifyObservers(); | 1297 NotifyObservers(); |
| 1270 // TODO(sync): Maybe toast? | 1298 // TODO(sync): Maybe toast? |
| 1271 break; | 1299 break; |
| 1272 } | 1300 } |
| 1273 case chrome::NOTIFICATION_SYNC_CONFIGURE_DONE: { | 1301 case chrome::NOTIFICATION_SYNC_CONFIGURE_DONE: { |
| 1274 DataTypeManager::ConfigureResultWithErrorLocation* result_with_location = | 1302 DataTypeManager::ConfigureResultWithErrorLocation* result_with_location = |
| 1275 Details<DataTypeManager::ConfigureResultWithErrorLocation>( | 1303 Details<DataTypeManager::ConfigureResultWithErrorLocation>( |
| 1276 details).ptr(); | 1304 details).ptr(); |
| 1277 | 1305 |
| 1278 DataTypeManager::ConfigureResult result = result_with_location->result; | 1306 DataTypeManager::ConfigureResult result = result_with_location->result; |
| 1279 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with result: " << result; | 1307 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with result: " << result; |
| 1280 if (result == DataTypeManager::ABORTED && | 1308 if (result == DataTypeManager::ABORTED && |
| 1281 expect_sync_configuration_aborted_) { | 1309 expect_sync_configuration_aborted_) { |
| 1282 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; | 1310 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; |
| 1283 expect_sync_configuration_aborted_ = false; | 1311 expect_sync_configuration_aborted_ = false; |
| 1284 return; | 1312 return; |
| 1285 } | 1313 } |
| 1286 // Clear out the gaia password if it is already there. | |
| 1287 gaia_password_ = std::string(); | |
| 1288 if (result != DataTypeManager::OK) { | 1314 if (result != DataTypeManager::OK) { |
| 1289 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; | 1315 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; |
| 1290 std::string message = StringPrintf("Sync Configuration failed with %d", | 1316 std::string message = StringPrintf("Sync Configuration failed with %d", |
| 1291 result); | 1317 result); |
| 1292 OnUnrecoverableError(*(result_with_location->location), message); | 1318 OnUnrecoverableError(*(result_with_location->location), message); |
| 1293 cached_passphrase_ = CachedPassphrase(); | 1319 cached_passphrase_ = CachedPassphrase(); |
| 1294 return; | 1320 return; |
| 1295 } | 1321 } |
| 1296 | 1322 |
| 1297 // If the user had entered a custom passphrase use it now. | |
| 1298 if (!cached_passphrase_.value.empty()) { | |
| 1299 // Don't hold on to the passphrase in raw form longer than needed. | |
| 1300 SetPassphrase(cached_passphrase_.value, | |
| 1301 cached_passphrase_.is_explicit, | |
| 1302 cached_passphrase_.is_creation); | |
| 1303 cached_passphrase_ = CachedPassphrase(); | |
| 1304 } | |
| 1305 | |
| 1306 // We should never get in a state where we have no encrypted datatypes | 1323 // We should never get in a state where we have no encrypted datatypes |
| 1307 // enabled, and yet we still think we require a passphrase for decryption. | 1324 // enabled, and yet we still think we require a passphrase for decryption. |
| 1308 DCHECK(!(IsPassphraseRequiredForDecryption() && | 1325 DCHECK(!(IsPassphraseRequiredForDecryption() && |
| 1309 !IsEncryptedDatatypeEnabled())); | 1326 !IsEncryptedDatatypeEnabled())); |
| 1310 | 1327 |
| 1311 // TODO(sync): Less wizard, more toast. | |
| 1312 wizard_.Step(SyncSetupWizard::DONE); | |
| 1313 NotifyObservers(); | |
| 1314 | |
| 1315 // In the old world, this would be a no-op. With new syncer thread, | 1328 // In the old world, this would be a no-op. With new syncer thread, |
| 1316 // this is the point where it is safe to switch from config-mode to | 1329 // this is the point where it is safe to switch from config-mode to |
| 1317 // normal operation. | 1330 // normal operation. |
| 1318 backend_->StartSyncingWithServer(); | 1331 backend_->StartSyncingWithServer(); |
| 1319 | 1332 |
| 1320 if (!pending_types_for_encryption_.empty()) { | 1333 if (pending_types_for_encryption_.empty()) { |
| 1321 EncryptDataTypes(pending_types_for_encryption_); | 1334 wizard_.Step(SyncSetupWizard::DONE); |
| 1322 pending_types_for_encryption_.clear(); | 1335 NotifyObservers(); |
| 1336 } else { |
| 1337 // Will clear pending_types_for_encryption_ on success (via |
| 1338 // OnEncryptionComplete). Has no effect if pending_types_for_encryption_ |
| 1339 // matches the encrypted types (and will clear |
| 1340 // pending_types_for_encryption_). |
| 1341 backend_->EncryptDataTypes(pending_types_for_encryption_); |
| 1323 } | 1342 } |
| 1324 break; | 1343 break; |
| 1325 } | 1344 } |
| 1326 case chrome::NOTIFICATION_PREF_CHANGED: { | 1345 case chrome::NOTIFICATION_PREF_CHANGED: { |
| 1327 std::string* pref_name = Details<std::string>(details).ptr(); | 1346 std::string* pref_name = Details<std::string>(details).ptr(); |
| 1328 if (*pref_name == prefs::kSyncManaged) { | 1347 if (*pref_name == prefs::kSyncManaged) { |
| 1329 NotifyObservers(); | 1348 NotifyObservers(); |
| 1330 if (*pref_sync_managed_) { | 1349 if (*pref_sync_managed_) { |
| 1331 DisableForUser(); | 1350 DisableForUser(); |
| 1332 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { | 1351 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1427 // is initialized, all enabled data types are consistent with one | 1446 // is initialized, all enabled data types are consistent with one |
| 1428 // another, and no unrecoverable error has transpired. | 1447 // another, and no unrecoverable error has transpired. |
| 1429 if (unrecoverable_error_detected_) | 1448 if (unrecoverable_error_detected_) |
| 1430 return false; | 1449 return false; |
| 1431 | 1450 |
| 1432 if (!data_type_manager_.get()) | 1451 if (!data_type_manager_.get()) |
| 1433 return false; | 1452 return false; |
| 1434 | 1453 |
| 1435 return data_type_manager_->state() == DataTypeManager::CONFIGURED; | 1454 return data_type_manager_->state() == DataTypeManager::CONFIGURED; |
| 1436 } | 1455 } |
| OLD | NEW |