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 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 } | 773 } |
782 } | 774 } |
783 | 775 |
784 ModelTypeSet | 776 ModelTypeSet |
785 SyncManagerImpl::HandleTransactionEndingChangeEvent( | 777 SyncManagerImpl::HandleTransactionEndingChangeEvent( |
786 const ImmutableWriteTransactionInfo& write_transaction_info, | 778 const ImmutableWriteTransactionInfo& write_transaction_info, |
787 syncable::BaseTransaction* trans) { | 779 syncable::BaseTransaction* trans) { |
788 // This notification happens immediately before a syncable WriteTransaction | 780 // This notification happens immediately before a syncable WriteTransaction |
789 // falls out of scope. It happens while the channel mutex is still held, | 781 // falls out of scope. It happens while the channel mutex is still held, |
790 // and while the transaction mutex is held, so it cannot be re-entrant. | 782 // and while the transaction mutex is held, so it cannot be re-entrant. |
791 if (!change_delegate_ || ChangeBuffersAreEmpty()) | 783 if (!change_delegate_ || change_records_.empty()) |
792 return ModelTypeSet(); | 784 return ModelTypeSet(); |
793 | 785 |
794 // This will continue the WriteTransaction using a read only wrapper. | 786 // This will continue the WriteTransaction using a read only wrapper. |
795 // This is the last chance for read to occur in the WriteTransaction | 787 // This is the last chance for read to occur in the WriteTransaction |
796 // that's closing. This special ReadTransaction will not close the | 788 // that's closing. This special ReadTransaction will not close the |
797 // underlying transaction. | 789 // underlying transaction. |
798 ReadTransaction read_trans(GetUserShare(), trans); | 790 ReadTransaction read_trans(GetUserShare(), trans); |
799 | 791 |
800 ModelTypeSet models_with_changes; | 792 ModelTypeSet models_with_changes; |
801 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { | 793 for (ChangeRecordMap::const_iterator it = change_records_.begin(); |
802 const ModelType type = ModelTypeFromInt(i); | 794 it != change_records_.end(); ++it) { |
803 if (change_buffers_[type].IsEmpty()) | 795 DCHECK(!it->second.Get().empty()); |
804 continue; | 796 ModelType type = ModelTypeFromInt(it->first); |
805 | 797 change_delegate_-> |
806 ImmutableChangeRecordList ordered_changes; | 798 OnChangesApplied(type, trans->directory()->GetTransactionVersion(type), |
807 // TODO(akalin): Propagate up the error further (see | 799 &read_trans, it->second); |
808 // http://crbug.com/100907). | 800 change_observer_.Call(FROM_HERE, |
809 CHECK(change_buffers_[type].GetAllChangesInTreeOrder(&read_trans, | 801 &SyncManager::ChangeObserver::OnChangesApplied, |
810 &ordered_changes)); | 802 type, write_transaction_info.Get().id, it->second); |
811 if (!ordered_changes.Get().empty()) { | 803 models_with_changes.Put(type); |
812 // Increment transaction version so that change processor can read | |
813 // updated value and set it in native model after changes are applied. | |
814 trans->directory()->IncrementTransactionVersion(type); | |
815 | |
816 change_delegate_-> | |
817 OnChangesApplied(type, | |
818 trans->directory()->GetTransactionVersion(type), | |
819 &read_trans, ordered_changes); | |
820 change_observer_.Call(FROM_HERE, | |
821 &SyncManager::ChangeObserver::OnChangesApplied, | |
822 type, write_transaction_info.Get().id, ordered_changes); | |
823 models_with_changes.Put(type); | |
824 } | |
825 change_buffers_[i].Clear(); | |
826 } | 804 } |
| 805 change_records_.clear(); |
827 return models_with_changes; | 806 return models_with_changes; |
828 } | 807 } |
829 | 808 |
830 void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncApi( | 809 void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncApi( |
831 const ImmutableWriteTransactionInfo& write_transaction_info, | 810 const ImmutableWriteTransactionInfo& write_transaction_info, |
832 syncable::BaseTransaction* trans) { | 811 syncable::BaseTransaction* trans, |
| 812 std::vector<int64>* entries_changed) { |
833 // We have been notified about a user action changing a sync model. | 813 // We have been notified about a user action changing a sync model. |
834 LOG_IF(WARNING, !ChangeBuffersAreEmpty()) << | 814 LOG_IF(WARNING, !change_records_.empty()) << |
835 "CALCULATE_CHANGES called with unapplied old changes."; | 815 "CALCULATE_CHANGES called with unapplied old changes."; |
836 | 816 |
837 // The mutated model type, or UNSPECIFIED if nothing was mutated. | 817 // The mutated model type, or UNSPECIFIED if nothing was mutated. |
838 ModelTypeSet mutated_model_types; | 818 ModelTypeSet mutated_model_types; |
839 | 819 |
840 const syncable::ImmutableEntryKernelMutationMap& mutations = | 820 const syncable::ImmutableEntryKernelMutationMap& mutations = |
841 write_transaction_info.Get().mutations; | 821 write_transaction_info.Get().mutations; |
842 for (syncable::EntryKernelMutationMap::const_iterator it = | 822 for (syncable::EntryKernelMutationMap::const_iterator it = |
843 mutations.Get().begin(); it != mutations.Get().end(); ++it) { | 823 mutations.Get().begin(); it != mutations.Get().end(); ++it) { |
844 if (!it->second.mutated.ref(syncable::IS_UNSYNCED)) { | 824 if (!it->second.mutated.ref(syncable::IS_UNSYNCED)) { |
845 continue; | 825 continue; |
846 } | 826 } |
847 | 827 |
848 ModelType model_type = | 828 ModelType model_type = |
849 GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); | 829 GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); |
850 if (model_type < FIRST_REAL_MODEL_TYPE) { | 830 if (model_type < FIRST_REAL_MODEL_TYPE) { |
851 NOTREACHED() << "Permanent or underspecified item changed via syncapi."; | 831 NOTREACHED() << "Permanent or underspecified item changed via syncapi."; |
852 continue; | 832 continue; |
853 } | 833 } |
854 | 834 |
855 // Found real mutation. | 835 // Found real mutation. |
856 if (model_type != UNSPECIFIED) { | 836 if (model_type != UNSPECIFIED) { |
857 mutated_model_types.Put(model_type); | 837 mutated_model_types.Put(model_type); |
| 838 entries_changed->push_back(it->second.mutated.ref(syncable::META_HANDLE)); |
858 } | 839 } |
859 } | 840 } |
860 | 841 |
861 // Nudge if necessary. | 842 // Nudge if necessary. |
862 if (!mutated_model_types.Empty()) { | 843 if (!mutated_model_types.Empty()) { |
863 if (weak_handle_this_.IsInitialized()) { | 844 if (weak_handle_this_.IsInitialized()) { |
864 weak_handle_this_.Call(FROM_HERE, | 845 weak_handle_this_.Call(FROM_HERE, |
865 &SyncManagerImpl::RequestNudgeForDataTypes, | 846 &SyncManagerImpl::RequestNudgeForDataTypes, |
866 FROM_HERE, | 847 FROM_HERE, |
867 mutated_model_types); | 848 mutated_model_types); |
(...skipping 28 matching lines...) Expand all Loading... |
896 NOTREACHED(); | 877 NOTREACHED(); |
897 return; | 878 return; |
898 } | 879 } |
899 } | 880 } |
900 buffer->SetSpecificsForId(id, original_specifics); | 881 buffer->SetSpecificsForId(id, original_specifics); |
901 } | 882 } |
902 } | 883 } |
903 | 884 |
904 void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncer( | 885 void SyncManagerImpl::HandleCalculateChangesChangeEventFromSyncer( |
905 const ImmutableWriteTransactionInfo& write_transaction_info, | 886 const ImmutableWriteTransactionInfo& write_transaction_info, |
906 syncable::BaseTransaction* trans) { | 887 syncable::BaseTransaction* trans, |
| 888 std::vector<int64>* entries_changed) { |
907 // We only expect one notification per sync step, so change_buffers_ should | 889 // We only expect one notification per sync step, so change_buffers_ should |
908 // contain no pending entries. | 890 // contain no pending entries. |
909 LOG_IF(WARNING, !ChangeBuffersAreEmpty()) << | 891 LOG_IF(WARNING, !change_records_.empty()) << |
910 "CALCULATE_CHANGES called with unapplied old changes."; | 892 "CALCULATE_CHANGES called with unapplied old changes."; |
911 | 893 |
| 894 ChangeReorderBuffer change_buffers[MODEL_TYPE_COUNT]; |
| 895 |
912 Cryptographer* crypto = directory()->GetCryptographer(trans); | 896 Cryptographer* crypto = directory()->GetCryptographer(trans); |
913 const syncable::ImmutableEntryKernelMutationMap& mutations = | 897 const syncable::ImmutableEntryKernelMutationMap& mutations = |
914 write_transaction_info.Get().mutations; | 898 write_transaction_info.Get().mutations; |
915 for (syncable::EntryKernelMutationMap::const_iterator it = | 899 for (syncable::EntryKernelMutationMap::const_iterator it = |
916 mutations.Get().begin(); it != mutations.Get().end(); ++it) { | 900 mutations.Get().begin(); it != mutations.Get().end(); ++it) { |
917 bool existed_before = !it->second.original.ref(syncable::IS_DEL); | 901 bool existed_before = !it->second.original.ref(syncable::IS_DEL); |
918 bool exists_now = !it->second.mutated.ref(syncable::IS_DEL); | 902 bool exists_now = !it->second.mutated.ref(syncable::IS_DEL); |
919 | 903 |
920 // Omit items that aren't associated with a model. | 904 // Omit items that aren't associated with a model. |
921 ModelType type = | 905 ModelType type = |
922 GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); | 906 GetModelTypeFromSpecifics(it->second.mutated.ref(SPECIFICS)); |
923 if (type < FIRST_REAL_MODEL_TYPE) | 907 if (type < FIRST_REAL_MODEL_TYPE) |
924 continue; | 908 continue; |
925 | 909 |
926 int64 handle = it->first; | 910 int64 handle = it->first; |
927 if (exists_now && !existed_before) | 911 if (exists_now && !existed_before) |
928 change_buffers_[type].PushAddedItem(handle); | 912 change_buffers[type].PushAddedItem(handle); |
929 else if (!exists_now && existed_before) | 913 else if (!exists_now && existed_before) |
930 change_buffers_[type].PushDeletedItem(handle); | 914 change_buffers[type].PushDeletedItem(handle); |
931 else if (exists_now && existed_before && | 915 else if (exists_now && existed_before && |
932 VisiblePropertiesDiffer(it->second, crypto)) { | 916 VisiblePropertiesDiffer(it->second, crypto)) { |
933 change_buffers_[type].PushUpdatedItem( | 917 change_buffers[type].PushUpdatedItem( |
934 handle, VisiblePositionsDiffer(it->second)); | 918 handle, VisiblePositionsDiffer(it->second)); |
935 } | 919 } |
936 | 920 |
937 SetExtraChangeRecordData(handle, type, &change_buffers_[type], crypto, | 921 SetExtraChangeRecordData(handle, type, &change_buffers[type], crypto, |
938 it->second.original, existed_before, exists_now); | 922 it->second.original, existed_before, exists_now); |
939 } | 923 } |
| 924 |
| 925 ReadTransaction read_trans(GetUserShare(), trans); |
| 926 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { |
| 927 if (!change_buffers[i].IsEmpty()) { |
| 928 if (change_buffers[i].GetAllChangesInTreeOrder(&read_trans, |
| 929 &(change_records_[i]))) { |
| 930 for (size_t j = 0; j < change_records_[i].Get().size(); ++j) |
| 931 entries_changed->push_back((change_records_[i].Get())[j].id); |
| 932 } |
| 933 if (change_records_[i].Get().empty()) |
| 934 change_records_.erase(i); |
| 935 } |
| 936 } |
940 } | 937 } |
941 | 938 |
942 TimeDelta SyncManagerImpl::GetNudgeDelayTimeDelta( | 939 TimeDelta SyncManagerImpl::GetNudgeDelayTimeDelta( |
943 const ModelType& model_type) { | 940 const ModelType& model_type) { |
944 return NudgeStrategy::GetNudgeDelayTimeDelta(model_type, this); | 941 return NudgeStrategy::GetNudgeDelayTimeDelta(model_type, this); |
945 } | 942 } |
946 | 943 |
947 void SyncManagerImpl::RequestNudgeForDataTypes( | 944 void SyncManagerImpl::RequestNudgeForDataTypes( |
948 const tracked_objects::Location& nudge_location, | 945 const tracked_objects::Location& nudge_location, |
949 ModelTypeSet types) { | 946 ModelTypeSet types) { |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 int SyncManagerImpl::GetDefaultNudgeDelay() { | 1324 int SyncManagerImpl::GetDefaultNudgeDelay() { |
1328 return kDefaultNudgeDelayMilliseconds; | 1325 return kDefaultNudgeDelayMilliseconds; |
1329 } | 1326 } |
1330 | 1327 |
1331 // static. | 1328 // static. |
1332 int SyncManagerImpl::GetPreferencesNudgeDelay() { | 1329 int SyncManagerImpl::GetPreferencesNudgeDelay() { |
1333 return kPreferencesNudgeDelayMilliseconds; | 1330 return kPreferencesNudgeDelayMilliseconds; |
1334 } | 1331 } |
1335 | 1332 |
1336 } // namespace syncer | 1333 } // namespace syncer |
OLD | NEW |