OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "sync/internal_api/public/sync_manager.h" | 5 #include "sync/internal_api/public/sync_manager.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 UnrecoverableErrorHandler* unrecoverable_error_handler, | 190 UnrecoverableErrorHandler* unrecoverable_error_handler, |
191 ReportUnrecoverableErrorFunction | 191 ReportUnrecoverableErrorFunction |
192 report_unrecoverable_error_function); | 192 report_unrecoverable_error_function); |
193 | 193 |
194 // Sign into sync with given credentials. | 194 // Sign into sync with given credentials. |
195 // We do not verify the tokens given. After this call, the tokens are set | 195 // We do not verify the tokens given. After this call, the tokens are set |
196 // and the sync DB is open. True if successful, false if something | 196 // and the sync DB is open. True if successful, false if something |
197 // went wrong. | 197 // went wrong. |
198 bool SignIn(const SyncCredentials& credentials); | 198 bool SignIn(const SyncCredentials& credentials); |
199 | 199 |
| 200 // Purge from the directory those types with non-empty progress markers |
| 201 // but without initial synced ended set. |
| 202 // Returns false if an error occurred, true otherwise. |
| 203 bool PurgePartiallySyncedTypes(); |
| 204 |
200 // Update tokens that we're using in Sync. Email must stay the same. | 205 // Update tokens that we're using in Sync. Email must stay the same. |
201 void UpdateCredentials(const SyncCredentials& credentials); | 206 void UpdateCredentials(const SyncCredentials& credentials); |
202 | 207 |
203 // Called when the user disables or enables a sync type. | 208 // Called when the user disables or enables a sync type. |
204 void UpdateEnabledTypes(const ModelTypeSet& enabled_types); | 209 void UpdateEnabledTypes(const ModelTypeSet& enabled_types); |
205 | 210 |
206 // Tell the sync engine to start the syncing process. | 211 // Tell the sync engine to start the syncing process. |
207 void StartSyncingNormally( | 212 void StartSyncingNormally( |
208 const syncer::ModelSafeRoutingInfo& routing_info); | 213 const syncer::ModelSafeRoutingInfo& routing_info); |
209 | 214 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 syncer::ModelType type, | 355 syncer::ModelType type, |
351 ChangeReorderBuffer* buffer, | 356 ChangeReorderBuffer* buffer, |
352 Cryptographer* cryptographer, | 357 Cryptographer* cryptographer, |
353 const syncable::EntryKernel& original, | 358 const syncable::EntryKernel& original, |
354 bool existed_before, | 359 bool existed_before, |
355 bool exists_now); | 360 bool exists_now); |
356 | 361 |
357 // Called only by our NetworkChangeNotifier. | 362 // Called only by our NetworkChangeNotifier. |
358 virtual void OnIPAddressChanged() OVERRIDE; | 363 virtual void OnIPAddressChanged() OVERRIDE; |
359 | 364 |
| 365 ModelTypeSet GetTypesWithEmptyProgressMarkerToken(ModelTypeSet types) { |
| 366 DCHECK(initialized_); |
| 367 syncer::ModelTypeSet result; |
| 368 for (syncer::ModelTypeSet::Iterator i = types.First(); |
| 369 i.Good(); i.Inc()) { |
| 370 sync_pb::DataTypeProgressMarker marker; |
| 371 directory()->GetDownloadProgress(i.Get(), &marker); |
| 372 |
| 373 if (marker.token().empty()) |
| 374 result.Put(i.Get()); |
| 375 |
| 376 } |
| 377 return result; |
| 378 } |
| 379 |
360 syncer::ModelTypeSet InitialSyncEndedTypes() { | 380 syncer::ModelTypeSet InitialSyncEndedTypes() { |
361 DCHECK(initialized_); | 381 DCHECK(initialized_); |
362 return directory()->initial_sync_ended_types(); | 382 return directory()->initial_sync_ended_types(); |
363 } | 383 } |
364 | 384 |
365 // SyncEngineEventListener implementation. | 385 // SyncEngineEventListener implementation. |
366 virtual void OnSyncEngineEvent(const SyncEngineEvent& event) OVERRIDE; | 386 virtual void OnSyncEngineEvent(const SyncEngineEvent& event) OVERRIDE; |
367 | 387 |
368 // ServerConnectionEventListener implementation. | 388 // ServerConnectionEventListener implementation. |
369 virtual void OnServerConnectionEvent( | 389 virtual void OnServerConnectionEvent( |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 DCHECK(thread_checker_.CalledOnValidThread()); | 764 DCHECK(thread_checker_.CalledOnValidThread()); |
745 ReadTransaction trans(FROM_HERE, GetUserShare()); | 765 ReadTransaction trans(FROM_HERE, GetUserShare()); |
746 trans.GetWrappedTrans()->OnUnrecoverableError( | 766 trans.GetWrappedTrans()->OnUnrecoverableError( |
747 FROM_HERE, "Simulating unrecoverable error for testing purposes."); | 767 FROM_HERE, "Simulating unrecoverable error for testing purposes."); |
748 } | 768 } |
749 | 769 |
750 syncer::ModelTypeSet SyncManager::InitialSyncEndedTypes() { | 770 syncer::ModelTypeSet SyncManager::InitialSyncEndedTypes() { |
751 return data_->InitialSyncEndedTypes(); | 771 return data_->InitialSyncEndedTypes(); |
752 } | 772 } |
753 | 773 |
| 774 syncer::ModelTypeSet SyncManager::GetTypesWithEmptyProgressMarkerToken( |
| 775 syncer::ModelTypeSet types) { |
| 776 return data_->GetTypesWithEmptyProgressMarkerToken(types); |
| 777 } |
| 778 |
| 779 bool SyncManager::PurgePartiallySyncedTypes() { |
| 780 return data_->PurgePartiallySyncedTypes(); |
| 781 } |
| 782 |
754 void SyncManager::StartSyncingNormally( | 783 void SyncManager::StartSyncingNormally( |
755 const syncer::ModelSafeRoutingInfo& routing_info) { | 784 const syncer::ModelSafeRoutingInfo& routing_info) { |
756 DCHECK(thread_checker_.CalledOnValidThread()); | 785 DCHECK(thread_checker_.CalledOnValidThread()); |
757 data_->StartSyncingNormally(routing_info); | 786 data_->StartSyncingNormally(routing_info); |
758 } | 787 } |
759 | 788 |
760 void SyncManager::SetEncryptionPassphrase(const std::string& passphrase, | 789 void SyncManager::SetEncryptionPassphrase(const std::string& passphrase, |
761 bool is_explicit) { | 790 bool is_explicit) { |
762 DCHECK(thread_checker_.CalledOnValidThread()); | 791 DCHECK(thread_checker_.CalledOnValidThread()); |
763 data_->SetEncryptionPassphrase(passphrase, is_explicit); | 792 data_->SetEncryptionPassphrase(passphrase, is_explicit); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 workers, | 946 workers, |
918 extensions_activity_monitor, | 947 extensions_activity_monitor, |
919 &throttled_data_type_tracker_, | 948 &throttled_data_type_tracker_, |
920 listeners, | 949 listeners, |
921 &debug_info_event_listener_, | 950 &debug_info_event_listener_, |
922 &traffic_recorder_)); | 951 &traffic_recorder_)); |
923 session_context()->set_account_name(credentials.email); | 952 session_context()->set_account_name(credentials.email); |
924 scheduler_.reset(new SyncScheduler(name_, session_context(), new Syncer())); | 953 scheduler_.reset(new SyncScheduler(name_, session_context(), new Syncer())); |
925 } | 954 } |
926 | 955 |
927 bool signed_in = SignIn(credentials); | 956 bool success = SignIn(credentials); |
928 | 957 |
929 if (signed_in) { | 958 if (success) { |
930 if (scheduler()) { | 959 if (scheduler()) { |
931 scheduler()->Start(syncer::SyncScheduler::CONFIGURATION_MODE); | 960 scheduler()->Start(syncer::SyncScheduler::CONFIGURATION_MODE); |
932 } | 961 } |
933 | 962 |
934 initialized_ = true; | 963 initialized_ = true; |
935 | 964 |
| 965 // Unapplied datatypes (those that do not have initial sync ended set) get |
| 966 // re-downloaded during any configuration. But, it's possible for a datatype |
| 967 // to have a progress marker but not have initial sync ended yet, making |
| 968 // it a candidate for migration. This is a problem, as the DataTypeManager |
| 969 // does not support a migration while it's already in the middle of a |
| 970 // configuration. As a result, any partially synced datatype can stall the |
| 971 // DTM, waiting for the configuration to complete, which it never will due |
| 972 // to the migration error. In addition, a partially synced nigori will |
| 973 // trigger the migration logic before the backend is initialized, resulting |
| 974 // in crashes. We therefore detect and purge any partially synced types as |
| 975 // part of initialization. |
| 976 if (!PurgePartiallySyncedTypes()) |
| 977 success = false; |
| 978 |
936 // Cryptographer should only be accessed while holding a | 979 // Cryptographer should only be accessed while holding a |
937 // transaction. Grabbing the user share for the transaction | 980 // transaction. Grabbing the user share for the transaction |
938 // checks the initialization state, so this must come after | 981 // checks the initialization state, so this must come after |
939 // |initialized_| is set to true. | 982 // |initialized_| is set to true. |
940 ReadTransaction trans(FROM_HERE, GetUserShare()); | 983 ReadTransaction trans(FROM_HERE, GetUserShare()); |
941 trans.GetCryptographer()->Bootstrap(restored_key_for_bootstrapping); | 984 trans.GetCryptographer()->Bootstrap(restored_key_for_bootstrapping); |
942 trans.GetCryptographer()->AddObserver(this); | 985 trans.GetCryptographer()->AddObserver(this); |
943 } | 986 } |
944 | 987 |
945 // Notify that initialization is complete. Note: This should be the last to | 988 // Notify that initialization is complete. Note: This should be the last to |
946 // execute if |signed_in| is false. Reason being in that case we would | 989 // execute if |signed_in| is false. Reason being in that case we would |
947 // post a task to shutdown sync. But if this function posts any other tasks | 990 // post a task to shutdown sync. But if this function posts any other tasks |
948 // on the UI thread and if shutdown wins then that tasks would execute on | 991 // on the UI thread and if shutdown wins then that tasks would execute on |
949 // a freed pointer. This is because UI thread is not shut down. | 992 // a freed pointer. This is because UI thread is not shut down. |
950 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, | 993 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, |
951 OnInitializationComplete( | 994 OnInitializationComplete( |
952 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), | 995 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), |
953 signed_in)); | 996 success)); |
954 | 997 |
955 if (!signed_in && testing_mode_ == NON_TEST) | 998 if (!success && testing_mode_ == NON_TEST) |
956 return false; | 999 return false; |
957 | 1000 |
958 sync_notifier_->AddObserver(this); | 1001 sync_notifier_->AddObserver(this); |
959 | 1002 |
960 return signed_in; | 1003 return success; |
961 } | 1004 } |
962 | 1005 |
963 void SyncManager::SyncInternal::UpdateCryptographerAndNigori( | 1006 void SyncManager::SyncInternal::UpdateCryptographerAndNigori( |
964 const std::string& chrome_version, | 1007 const std::string& chrome_version, |
965 const base::Closure& done_callback) { | 1008 const base::Closure& done_callback) { |
966 DCHECK(initialized_); | 1009 DCHECK(initialized_); |
967 syncer::GetSessionName( | 1010 syncer::GetSessionName( |
968 blocking_task_runner_, | 1011 blocking_task_runner_, |
969 base::Bind( | 1012 base::Bind( |
970 &SyncManager::SyncInternal::UpdateCryptographerAndNigoriCallback, | 1013 &SyncManager::SyncInternal::UpdateCryptographerAndNigoriCallback, |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 allstatus_.SetUniqueId(unique_id); | 1198 allstatus_.SetUniqueId(unique_id); |
1156 sync_notifier_->SetUniqueId(unique_id); | 1199 sync_notifier_->SetUniqueId(unique_id); |
1157 // TODO(tim): Remove once invalidation state has been migrated to new | 1200 // TODO(tim): Remove once invalidation state has been migrated to new |
1158 // InvalidationStateTracker store. Bug 124140. | 1201 // InvalidationStateTracker store. Bug 124140. |
1159 sync_notifier_->SetStateDeprecated(state); | 1202 sync_notifier_->SetStateDeprecated(state); |
1160 | 1203 |
1161 UpdateCredentials(credentials); | 1204 UpdateCredentials(credentials); |
1162 return true; | 1205 return true; |
1163 } | 1206 } |
1164 | 1207 |
| 1208 bool SyncManager::SyncInternal::PurgePartiallySyncedTypes() { |
| 1209 syncer::ModelTypeSet partially_synced_types = |
| 1210 syncer::ModelTypeSet::All(); |
| 1211 partially_synced_types.RemoveAll(InitialSyncEndedTypes()); |
| 1212 partially_synced_types.RemoveAll(GetTypesWithEmptyProgressMarkerToken( |
| 1213 syncer::ModelTypeSet::All())); |
| 1214 |
| 1215 UMA_HISTOGRAM_COUNTS("Sync.PartiallySyncedTypes", |
| 1216 partially_synced_types.Size()); |
| 1217 if (partially_synced_types.Empty()) |
| 1218 return true; |
| 1219 return directory()->PurgeEntriesWithTypeIn(partially_synced_types); |
| 1220 } |
| 1221 |
1165 void SyncManager::SyncInternal::UpdateCredentials( | 1222 void SyncManager::SyncInternal::UpdateCredentials( |
1166 const SyncCredentials& credentials) { | 1223 const SyncCredentials& credentials) { |
1167 DCHECK(thread_checker_.CalledOnValidThread()); | 1224 DCHECK(thread_checker_.CalledOnValidThread()); |
1168 DCHECK_EQ(credentials.email, share_.name); | 1225 DCHECK_EQ(credentials.email, share_.name); |
1169 DCHECK(!credentials.email.empty()); | 1226 DCHECK(!credentials.email.empty()); |
1170 DCHECK(!credentials.sync_token.empty()); | 1227 DCHECK(!credentials.sync_token.empty()); |
1171 | 1228 |
1172 observing_ip_address_changes_ = true; | 1229 observing_ip_address_changes_ = true; |
1173 if (connection_manager()->set_auth_token(credentials.sync_token)) { | 1230 if (connection_manager()->set_auth_token(credentials.sync_token)) { |
1174 sync_notifier_->UpdateCredentials( | 1231 sync_notifier_->UpdateCredentials( |
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2465 bool InitialSyncEndedForTypes(syncer::ModelTypeSet types, | 2522 bool InitialSyncEndedForTypes(syncer::ModelTypeSet types, |
2466 syncer::UserShare* share) { | 2523 syncer::UserShare* share) { |
2467 for (syncer::ModelTypeSet::Iterator i = types.First(); | 2524 for (syncer::ModelTypeSet::Iterator i = types.First(); |
2468 i.Good(); i.Inc()) { | 2525 i.Good(); i.Inc()) { |
2469 if (!share->directory->initial_sync_ended_for_type(i.Get())) | 2526 if (!share->directory->initial_sync_ended_for_type(i.Get())) |
2470 return false; | 2527 return false; |
2471 } | 2528 } |
2472 return true; | 2529 return true; |
2473 } | 2530 } |
2474 | 2531 |
2475 syncer::ModelTypeSet GetTypesWithEmptyProgressMarkerToken( | |
2476 syncer::ModelTypeSet types, | |
2477 syncer::UserShare* share) { | |
2478 syncer::ModelTypeSet result; | |
2479 for (syncer::ModelTypeSet::Iterator i = types.First(); | |
2480 i.Good(); i.Inc()) { | |
2481 sync_pb::DataTypeProgressMarker marker; | |
2482 share->directory->GetDownloadProgress(i.Get(), &marker); | |
2483 | |
2484 if (marker.token().empty()) | |
2485 result.Put(i.Get()); | |
2486 | |
2487 } | |
2488 return result; | |
2489 } | |
2490 | |
2491 } // namespace syncer | 2532 } // namespace syncer |
OLD | NEW |