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/sync_manager_impl.h" | 5 #include "sync/internal_api/sync_manager_impl.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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 // We only care if the name has changed if neither specifics is encrypted | 263 // We only care if the name has changed if neither specifics is encrypted |
264 // (encrypted nodes blow away the NON_UNIQUE_NAME). | 264 // (encrypted nodes blow away the NON_UNIQUE_NAME). |
265 if (!a_specifics.has_encrypted() && !b_specifics.has_encrypted() && | 265 if (!a_specifics.has_encrypted() && !b_specifics.has_encrypted() && |
266 a.ref(syncable::NON_UNIQUE_NAME) != b.ref(syncable::NON_UNIQUE_NAME)) | 266 a.ref(syncable::NON_UNIQUE_NAME) != b.ref(syncable::NON_UNIQUE_NAME)) |
267 return true; | 267 return true; |
268 if (VisiblePositionsDiffer(mutation)) | 268 if (VisiblePositionsDiffer(mutation)) |
269 return true; | 269 return true; |
270 return false; | 270 return false; |
271 } | 271 } |
272 | 272 |
273 bool SyncManagerImpl::ChangeBuffersAreEmpty() { | |
274 for (int i = 0; i < MODEL_TYPE_COUNT; ++i) { | |
275 if (!change_buffers_[i].IsEmpty()) | |
276 return false; | |
277 } | |
278 return true; | |
279 } | |
280 | |
281 void SyncManagerImpl::ThrowUnrecoverableError() { | 273 void SyncManagerImpl::ThrowUnrecoverableError() { |
282 DCHECK(thread_checker_.CalledOnValidThread()); | 274 DCHECK(thread_checker_.CalledOnValidThread()); |
283 ReadTransaction trans(FROM_HERE, GetUserShare()); | 275 ReadTransaction trans(FROM_HERE, GetUserShare()); |
284 trans.GetWrappedTrans()->OnUnrecoverableError( | 276 trans.GetWrappedTrans()->OnUnrecoverableError( |
285 FROM_HERE, "Simulating unrecoverable error for testing purposes."); | 277 FROM_HERE, "Simulating unrecoverable error for testing purposes."); |
286 } | 278 } |
287 | 279 |
288 ModelTypeSet SyncManagerImpl::InitialSyncEndedTypes() { | 280 ModelTypeSet SyncManagerImpl::InitialSyncEndedTypes() { |
289 return directory()->initial_sync_ended_types(); | 281 return directory()->initial_sync_ended_types(); |
290 } | 282 } |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
767 } | 759 } |
768 } | 760 } |
769 | 761 |
770 ModelTypeSet | 762 ModelTypeSet |
771 SyncManagerImpl::HandleTransactionEndingChangeEvent( | 763 SyncManagerImpl::HandleTransactionEndingChangeEvent( |
772 const ImmutableWriteTransactionInfo& write_transaction_info, | 764 const ImmutableWriteTransactionInfo& write_transaction_info, |
773 syncable::BaseTransaction* trans) { | 765 syncable::BaseTransaction* trans) { |
774 // This notification happens immediately before a syncable WriteTransaction | 766 // This notification happens immediately before a syncable WriteTransaction |
775 // falls out of scope. It happens while the channel mutex is still held, | 767 // falls out of scope. It happens while the channel mutex is still held, |
776 // and while the transaction mutex is held, so it cannot be re-entrant. | 768 // and while the transaction mutex is held, so it cannot be re-entrant. |
777 if (!change_delegate_ || ChangeBuffersAreEmpty()) | 769 if (!change_delegate_ || change_records_.empty()) |
778 return ModelTypeSet(); | 770 return ModelTypeSet(); |
779 | 771 |
780 // This will continue the WriteTransaction using a read only wrapper. | 772 // This will continue the WriteTransaction using a read only wrapper. |
781 // This is the last chance for read to occur in the WriteTransaction | 773 // This is the last chance for read to occur in the WriteTransaction |
782 // that's closing. This special ReadTransaction will not close the | 774 // that's closing. This special ReadTransaction will not close the |
783 // underlying transaction. | 775 // underlying transaction. |
784 ReadTransaction read_trans(GetUserShare(), trans); | 776 ReadTransaction read_trans(GetUserShare(), trans); |
785 | 777 |
786 ModelTypeSet models_with_changes; | 778 ModelTypeSet models_with_changes; |
787 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { | 779 for (ChangeRecordMap::const_iterator it = change_records_.begin(); |
788 const ModelType type = ModelTypeFromInt(i); | 780 it != change_records_.end(); ++it) { |
789 if (change_buffers_[type].IsEmpty()) | 781 DCHECK(!it->second.Get().empty()); |
790 continue; | 782 ModelType type = ModelTypeFromInt(it->first); |
791 | 783 change_delegate_-> |
792 ImmutableChangeRecordList ordered_changes; | 784 OnChangesApplied(type, trans->directory()->GetTransactionVersion(type), |
793 // TODO(akalin): Propagate up the error further (see | 785 &read_trans, it->second); |
794 // http://crbug.com/100907). | 786 change_observer_.Call(FROM_HERE, |
795 CHECK(change_buffers_[type].GetAllChangesInTreeOrder(&read_trans, | 787 &SyncManager::ChangeObserver::OnChangesApplied, |
796 &ordered_changes)); | 788 type, write_transaction_info.Get().id, it->second); |
797 if (!ordered_changes.Get().empty()) { | 789 models_with_changes.Put(type); |
798 // Increment transaction version so that change processor can read | |
799 // updated value and set it in native model after changes are applied. | |
800 trans->directory()->IncrementTransactionVersion(type); | |
801 | |
802 change_delegate_-> | |
803 OnChangesApplied(type, | |
804 trans->directory()->GetTransactionVersion(type), | |
805 &read_trans, ordered_changes); | |
806 change_observer_.Call(FROM_HERE, | |
807 &SyncManager::ChangeObserver::OnChangesApplied, | |
808 type, write_transaction_info.Get().id, ordered_changes); | |
809 models_with_changes.Put(type); | |
810 } | |
811 change_buffers_[i].Clear(); | |
812 } | 790 } |
791 change_records_.clear(); | |
813 return models_with_changes; | 792 return models_with_changes; |
814 } | 793 } |
815 | 794 |
816 void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncApi( | 795 void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncApi( |
817 const ImmutableWriteTransactionInfo& write_transaction_info, | 796 const ImmutableWriteTransactionInfo& write_transaction_info, |
818 syncable::BaseTransaction* trans) { | 797 syncable::BaseTransaction* trans, |
798 std::vector<int64>* entry_changed) { | |
819 // We have been notified about a user action changing a sync model. | 799 // We have been notified about a user action changing a sync model. |
820 LOG_IF(WARNING, !ChangeBuffersAreEmpty()) << | 800 LOG_IF(WARNING, !change_records_.empty()) << |
821 "CALCULATE_CHANGES called with unapplied old changes."; | 801 "CALCULATE_CHANGES called with unapplied old changes."; |
822 | 802 |
823 // The mutated model type, or UNSPECIFIED if nothing was mutated. | 803 // The mutated model type, or UNSPECIFIED if nothing was mutated. |
824 ModelTypeSet mutated_model_types; | 804 ModelTypeSet mutated_model_types; |
825 | 805 |
826 const syncable::ImmutableEntryKernelMutationMap& mutations = | 806 const syncable::ImmutableEntryKernelMutationMap& mutations = |
827 write_transaction_info.Get().mutations; | 807 write_transaction_info.Get().mutations; |
828 for (syncable::EntryKernelMutationMap::const_iterator it = | 808 for (syncable::EntryKernelMutationMap::const_iterator it = |
829 mutations.Get().begin(); it != mutations.Get().end(); ++it) { | 809 mutations.Get().begin(); it != mutations.Get().end(); ++it) { |
830 if (!it->second.mutated.ref(syncable::IS_UNSYNCED)) { | 810 if (!it->second.mutated.ref(syncable::IS_UNSYNCED)) { |
831 continue; | 811 continue; |
832 } | 812 } |
833 | 813 |
834 ModelType model_type = | 814 ModelType model_type = |
835 GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); | 815 GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); |
836 if (model_type < FIRST_REAL_MODEL_TYPE) { | 816 if (model_type < FIRST_REAL_MODEL_TYPE) { |
837 NOTREACHED() << "Permanent or underspecified item changed via syncapi."; | 817 NOTREACHED() << "Permanent or underspecified item changed via syncapi."; |
838 continue; | 818 continue; |
839 } | 819 } |
840 | 820 |
841 // Found real mutation. | 821 // Found real mutation. |
842 if (model_type != UNSPECIFIED) { | 822 if (model_type != UNSPECIFIED) { |
843 mutated_model_types.Put(model_type); | 823 mutated_model_types.Put(model_type); |
824 entry_changed->push_back(it->second.mutated.ref(syncable::META_HANDLE)); | |
844 } | 825 } |
845 } | 826 } |
846 | 827 |
847 // Nudge if necessary. | 828 // Nudge if necessary. |
848 if (!mutated_model_types.Empty()) { | 829 if (!mutated_model_types.Empty()) { |
849 if (weak_handle_this_.IsInitialized()) { | 830 if (weak_handle_this_.IsInitialized()) { |
850 weak_handle_this_.Call(FROM_HERE, | 831 weak_handle_this_.Call(FROM_HERE, |
851 &SyncManagerImpl::RequestNudgeForDataTypes, | 832 &SyncManagerImpl::RequestNudgeForDataTypes, |
852 FROM_HERE, | 833 FROM_HERE, |
853 mutated_model_types); | 834 mutated_model_types); |
(...skipping 28 matching lines...) Expand all Loading... | |
882 NOTREACHED(); | 863 NOTREACHED(); |
883 return; | 864 return; |
884 } | 865 } |
885 } | 866 } |
886 buffer->SetSpecificsForId(id, original_specifics); | 867 buffer->SetSpecificsForId(id, original_specifics); |
887 } | 868 } |
888 } | 869 } |
889 | 870 |
890 void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncer( | 871 void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncer( |
891 const ImmutableWriteTransactionInfo& write_transaction_info, | 872 const ImmutableWriteTransactionInfo& write_transaction_info, |
892 syncable::BaseTransaction* trans) { | 873 syncable::BaseTransaction* trans, |
874 std::vector<int64> *entry_changed) { | |
Nicolas Zea
2012/11/02 21:02:25
nit: "std::vector<int64>* entry_changed" (no space
haitaol1
2012/11/02 22:58:18
Done.
| |
893 // We only expect one notification per sync step, so change_buffers_ should | 875 // We only expect one notification per sync step, so change_buffers_ should |
894 // contain no pending entries. | 876 // contain no pending entries. |
895 LOG_IF(WARNING, !ChangeBuffersAreEmpty()) << | 877 LOG_IF(WARNING, !change_records_.empty()) << |
896 "CALCULATE_CHANGES called with unapplied old changes."; | 878 "CALCULATE_CHANGES called with unapplied old changes."; |
897 | 879 |
880 ChangeReorderBuffer change_buffers[MODEL_TYPE_COUNT]; | |
881 | |
898 Cryptographer* crypto = directory()->GetCryptographer(trans); | 882 Cryptographer* crypto = directory()->GetCryptographer(trans); |
899 const syncable::ImmutableEntryKernelMutationMap& mutations = | 883 const syncable::ImmutableEntryKernelMutationMap& mutations = |
900 write_transaction_info.Get().mutations; | 884 write_transaction_info.Get().mutations; |
901 for (syncable::EntryKernelMutationMap::const_iterator it = | 885 for (syncable::EntryKernelMutationMap::const_iterator it = |
902 mutations.Get().begin(); it != mutations.Get().end(); ++it) { | 886 mutations.Get().begin(); it != mutations.Get().end(); ++it) { |
903 bool existed_before = !it->second.original.ref(syncable::IS_DEL); | 887 bool existed_before = !it->second.original.ref(syncable::IS_DEL); |
904 bool exists_now = !it->second.mutated.ref(syncable::IS_DEL); | 888 bool exists_now = !it->second.mutated.ref(syncable::IS_DEL); |
905 | 889 |
906 // Omit items that aren't associated with a model. | 890 // Omit items that aren't associated with a model. |
907 ModelType type = | 891 ModelType type = |
908 GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); | 892 GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); |
909 if (type < FIRST_REAL_MODEL_TYPE) | 893 if (type < FIRST_REAL_MODEL_TYPE) |
910 continue; | 894 continue; |
911 | 895 |
912 int64 handle = it->first; | 896 int64 handle = it->first; |
913 if (exists_now && !existed_before) | 897 if (exists_now && !existed_before) |
914 change_buffers_[type].PushAddedItem(handle); | 898 change_buffers[type].PushAddedItem(handle); |
915 else if (!exists_now && existed_before) | 899 else if (!exists_now && existed_before) |
916 change_buffers_[type].PushDeletedItem(handle); | 900 change_buffers[type].PushDeletedItem(handle); |
917 else if (exists_now && existed_before && | 901 else if (exists_now && existed_before && |
918 VisiblePropertiesDiffer(it->second, crypto)) { | 902 VisiblePropertiesDiffer(it->second, crypto)) { |
919 change_buffers_[type].PushUpdatedItem( | 903 change_buffers[type].PushUpdatedItem( |
920 handle, VisiblePositionsDiffer(it->second)); | 904 handle, VisiblePositionsDiffer(it->second)); |
921 } | 905 } |
922 | 906 |
923 SetExtraChangeRecordData(handle, type, &change_buffers_[type], crypto, | 907 SetExtraChangeRecordData(handle, type, &change_buffers[type], crypto, |
924 it->second.original, existed_before, exists_now); | 908 it->second.original, existed_before, exists_now); |
925 } | 909 } |
910 | |
911 ReadTransaction read_trans(GetUserShare(), trans); | |
912 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { | |
913 if (!change_buffers[i].IsEmpty()) { | |
914 if (change_buffers[i].GetAllChangesInTreeOrder(&read_trans, | |
915 &(change_records_[i]))) { | |
916 for (uint32 j = 0; j < change_records_[i].Get().size(); ++j) | |
917 entry_changed->push_back((change_records_[i].Get())[j].id); | |
918 } | |
919 if (change_records_[i].Get().empty()) | |
920 change_records_.erase(i); | |
921 } | |
922 } | |
926 } | 923 } |
927 | 924 |
928 TimeDelta SyncManagerImpl::GetNudgeDelayTimeDelta( | 925 TimeDelta SyncManagerImpl::GetNudgeDelayTimeDelta( |
929 const ModelType& model_type) { | 926 const ModelType& model_type) { |
930 return NudgeStrategy::GetNudgeDelayTimeDelta(model_type, this); | 927 return NudgeStrategy::GetNudgeDelayTimeDelta(model_type, this); |
931 } | 928 } |
932 | 929 |
933 void SyncManagerImpl::RequestNudgeForDataTypes( | 930 void SyncManagerImpl::RequestNudgeForDataTypes( |
934 const tracked_objects::Location& nudge_location, | 931 const tracked_objects::Location& nudge_location, |
935 ModelTypeSet types) { | 932 ModelTypeSet types) { |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1313 int SyncManagerImpl::GetDefaultNudgeDelay() { | 1310 int SyncManagerImpl::GetDefaultNudgeDelay() { |
1314 return kDefaultNudgeDelayMilliseconds; | 1311 return kDefaultNudgeDelayMilliseconds; |
1315 } | 1312 } |
1316 | 1313 |
1317 // static. | 1314 // static. |
1318 int SyncManagerImpl::GetPreferencesNudgeDelay() { | 1315 int SyncManagerImpl::GetPreferencesNudgeDelay() { |
1319 return kPreferencesNudgeDelayMilliseconds; | 1316 return kPreferencesNudgeDelayMilliseconds; |
1320 } | 1317 } |
1321 | 1318 |
1322 } // namespace syncer | 1319 } // namespace syncer |
OLD | NEW |