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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_H_ 6 #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_H_ 7 #pragma once 8 9 #include <utility> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/callback.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/synchronization/lock.h" 17 #include "chrome/browser/sync/engine/conflict_resolver.h" 18 #include "chrome/browser/sync/engine/syncer_types.h" 19 #include "chrome/browser/sync/engine/syncproto.h" 20 #include "chrome/browser/sync/sessions/sync_session.h" 21 #include "chrome/browser/sync/syncable/directory_event.h" 22 #include "chrome/browser/sync/syncable/model_type.h" 23 #include "chrome/browser/sync/util/extensions_activity_monitor.h" 24 #include "chrome/common/deprecated/event_sys.h" 25 #include "chrome/common/deprecated/event_sys-inl.h" 26 27 namespace syncable { 28 class Directory; 29 class DirectoryManager; 30 class Entry; 31 class Id; 32 class MutableEntry; 33 class WriteTransaction; 34 } // namespace syncable 35 36 namespace browser_sync { 37 38 class ModelSafeWorker; 39 class ServerConnectionManager; 40 class SyncProcessState; 41 class URLFactory; 42 struct HttpResponse; 43 44 enum SyncerStep { 45 SYNCER_BEGIN, 46 CLEANUP_DISABLED_TYPES, 47 DOWNLOAD_UPDATES, 48 PROCESS_CLIENT_COMMAND, 49 VERIFY_UPDATES, 50 PROCESS_UPDATES, 51 STORE_TIMESTAMPS, 52 APPLY_UPDATES, 53 BUILD_COMMIT_REQUEST, 54 POST_COMMIT_MESSAGE, 55 PROCESS_COMMIT_RESPONSE, 56 BUILD_AND_PROCESS_CONFLICT_SETS, 57 RESOLVE_CONFLICTS, 58 APPLY_UPDATES_TO_RESOLVE_CONFLICTS, 59 CLEAR_PRIVATE_DATA, // TODO(tim): Rename 'private' to 'user'. 60 SYNCER_END 61 }; 62 63 // A Syncer provides a control interface for driving the individual steps 64 // of the sync cycle. Each cycle (hopefully) moves the client into closer 65 // synchronization with the server. The individual steps are modeled 66 // as SyncerCommands, and the ordering of the steps is expressed using 67 // the SyncerStep enum. 68 // 69 // A Syncer instance expects to run on a dedicated thread. Calls 70 // to SyncShare() may take an unbounded amount of time, as SyncerCommands 71 // may block on network i/o, on lock contention, or on tasks posted to 72 // other threads. 73 class Syncer { 74 public: 75 typedef std::vector<int64> UnsyncedMetaHandles; 76 77 // The constructor may be called from a thread that is not the Syncer's 78 // dedicated thread, to allow some flexibility in the setup. 79 Syncer(); 80 virtual ~Syncer(); 81 82 // Called by other threads to tell the syncer to stop what it's doing 83 // and return early from SyncShare, if possible. 84 bool ExitRequested(); 85 void RequestEarlyExit(); 86 87 // TODO(tim): Deprecated. 88 // Cause one sync cycle to occur. Like a good parent, it is the caller's 89 // responsibility to clean up after the syncer when it finishes a sync share 90 // operation and honor server mandated throttles. 91 virtual void SyncShare(sessions::SyncSession* session); 92 93 // Like SyncShare() above, but |first_step| and |last_step| are provided to 94 // perform a partial sync cycle, stopping after |last_step| is performed. 95 virtual void SyncShare(sessions::SyncSession* session, 96 SyncerStep first_step, 97 SyncerStep last_step); 98 99 private: 100 // Implements the PROCESS_CLIENT_COMMAND syncer step. 101 void ProcessClientCommand(sessions::SyncSession* session); 102 103 bool early_exit_requested_; 104 base::Lock early_exit_requested_lock_; 105 106 ConflictResolver resolver_; 107 108 // A callback hook used in unittests to simulate changes between conflict set 109 // building and conflict resolution. 110 Callback0::Type* pre_conflict_resolution_closure_; 111 112 friend class SyncerTest; 113 FRIEND_TEST_ALL_PREFIXES(SyncerTest, NameClashWithResolver); 114 FRIEND_TEST_ALL_PREFIXES(SyncerTest, IllegalAndLegalUpdates); 115 FRIEND_TEST_ALL_PREFIXES(SusanDeletingTest, 116 NewServerItemInAFolderHierarchyWeHaveDeleted3); 117 FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingAndNewParent); 118 FRIEND_TEST_ALL_PREFIXES(SyncerTest, 119 TestCommitListOrderingAndNewParentAndChild); 120 FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingCounterexample); 121 FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingWithNesting); 122 FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingWithNewItems); 123 FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestGetUnsyncedAndSimpleCommit); 124 FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestPurgeWhileUnsynced); 125 FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestPurgeWhileUnapplied); 126 FRIEND_TEST_ALL_PREFIXES(SyncerTest, UnappliedUpdateDuringCommit); 127 FRIEND_TEST_ALL_PREFIXES(SyncerTest, DeletingEntryInFolder); 128 FRIEND_TEST_ALL_PREFIXES(SyncerTest, 129 LongChangelistCreatesFakeOrphanedEntries); 130 FRIEND_TEST_ALL_PREFIXES(SyncerTest, QuicklyMergeDualCreatedHierarchy); 131 FRIEND_TEST_ALL_PREFIXES(SyncerTest, LongChangelistWithApplicationConflict); 132 FRIEND_TEST_ALL_PREFIXES(SyncerTest, DeletingEntryWithLocalEdits); 133 FRIEND_TEST_ALL_PREFIXES(EntryCreatedInNewFolderTest, 134 EntryCreatedInNewFolderMidSync); 135 136 DISALLOW_COPY_AND_ASSIGN(Syncer); 137 }; 138 139 // Inline utility functions. 140 141 // Given iterator ranges from two collections sorted according to a common 142 // strict weak ordering, return true if the two ranges contain any common 143 // items, and false if they do not. This function is in this header so that it 144 // can be tested. 145 template <class Iterator1, class Iterator2> 146 bool SortedCollectionsIntersect(Iterator1 begin1, Iterator1 end1, 147 Iterator2 begin2, Iterator2 end2) { 148 Iterator1 i1 = begin1; 149 Iterator2 i2 = begin2; 150 while (i1 != end1 && i2 != end2) { 151 if (*i1 == *i2) 152 return true; 153 if (*i1 > *i2) 154 ++i2; 155 else 156 ++i1; 157 } 158 return false; 159 } 160 // Utility function declarations. 161 void CopyServerFields(syncable::Entry* src, syncable::MutableEntry* dest); 162 void ClearServerData(syncable::MutableEntry* entry); 163 164 } // namespace browser_sync 165 166 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_H_ 167 168