| 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) { |
| 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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1318 int SyncManagerImpl::GetDefaultNudgeDelay() { | 1315 int SyncManagerImpl::GetDefaultNudgeDelay() { |
| 1319 return kDefaultNudgeDelayMilliseconds; | 1316 return kDefaultNudgeDelayMilliseconds; |
| 1320 } | 1317 } |
| 1321 | 1318 |
| 1322 // static. | 1319 // static. |
| 1323 int SyncManagerImpl::GetPreferencesNudgeDelay() { | 1320 int SyncManagerImpl::GetPreferencesNudgeDelay() { |
| 1324 return kPreferencesNudgeDelayMilliseconds; | 1321 return kPreferencesNudgeDelayMilliseconds; |
| 1325 } | 1322 } |
| 1326 | 1323 |
| 1327 } // namespace syncer | 1324 } // namespace syncer |
| OLD | NEW |