| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCER_H_ |
| #define CHROME_BROWSER_SYNC_ENGINE_SYNCER_H_ |
| #pragma once |
| |
| #include <utility> |
| #include <vector> |
| |
| #include "base/basictypes.h" |
| #include "base/callback.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/synchronization/lock.h" |
| #include "chrome/browser/sync/engine/conflict_resolver.h" |
| #include "chrome/browser/sync/engine/syncer_types.h" |
| #include "chrome/browser/sync/engine/syncproto.h" |
| #include "chrome/browser/sync/sessions/sync_session.h" |
| #include "chrome/browser/sync/syncable/directory_event.h" |
| #include "chrome/browser/sync/syncable/model_type.h" |
| #include "chrome/browser/sync/util/extensions_activity_monitor.h" |
| #include "chrome/common/deprecated/event_sys.h" |
| #include "chrome/common/deprecated/event_sys-inl.h" |
| |
| namespace syncable { |
| class Directory; |
| class DirectoryManager; |
| class Entry; |
| class Id; |
| class MutableEntry; |
| class WriteTransaction; |
| } // namespace syncable |
| |
| namespace browser_sync { |
| |
| class ModelSafeWorker; |
| class ServerConnectionManager; |
| class SyncProcessState; |
| class URLFactory; |
| struct HttpResponse; |
| |
| enum SyncerStep { |
| SYNCER_BEGIN, |
| CLEANUP_DISABLED_TYPES, |
| DOWNLOAD_UPDATES, |
| PROCESS_CLIENT_COMMAND, |
| VERIFY_UPDATES, |
| PROCESS_UPDATES, |
| STORE_TIMESTAMPS, |
| APPLY_UPDATES, |
| BUILD_COMMIT_REQUEST, |
| POST_COMMIT_MESSAGE, |
| PROCESS_COMMIT_RESPONSE, |
| BUILD_AND_PROCESS_CONFLICT_SETS, |
| RESOLVE_CONFLICTS, |
| APPLY_UPDATES_TO_RESOLVE_CONFLICTS, |
| CLEAR_PRIVATE_DATA, // TODO(tim): Rename 'private' to 'user'. |
| SYNCER_END |
| }; |
| |
| // A Syncer provides a control interface for driving the individual steps |
| // of the sync cycle. Each cycle (hopefully) moves the client into closer |
| // synchronization with the server. The individual steps are modeled |
| // as SyncerCommands, and the ordering of the steps is expressed using |
| // the SyncerStep enum. |
| // |
| // A Syncer instance expects to run on a dedicated thread. Calls |
| // to SyncShare() may take an unbounded amount of time, as SyncerCommands |
| // may block on network i/o, on lock contention, or on tasks posted to |
| // other threads. |
| class Syncer { |
| public: |
| typedef std::vector<int64> UnsyncedMetaHandles; |
| |
| // The constructor may be called from a thread that is not the Syncer's |
| // dedicated thread, to allow some flexibility in the setup. |
| Syncer(); |
| virtual ~Syncer(); |
| |
| // Called by other threads to tell the syncer to stop what it's doing |
| // and return early from SyncShare, if possible. |
| bool ExitRequested(); |
| void RequestEarlyExit(); |
| |
| // TODO(tim): Deprecated. |
| // Cause one sync cycle to occur. Like a good parent, it is the caller's |
| // responsibility to clean up after the syncer when it finishes a sync share |
| // operation and honor server mandated throttles. |
| virtual void SyncShare(sessions::SyncSession* session); |
| |
| // Like SyncShare() above, but |first_step| and |last_step| are provided to |
| // perform a partial sync cycle, stopping after |last_step| is performed. |
| virtual void SyncShare(sessions::SyncSession* session, |
| SyncerStep first_step, |
| SyncerStep last_step); |
| |
| private: |
| // Implements the PROCESS_CLIENT_COMMAND syncer step. |
| void ProcessClientCommand(sessions::SyncSession* session); |
| |
| bool early_exit_requested_; |
| base::Lock early_exit_requested_lock_; |
| |
| ConflictResolver resolver_; |
| |
| // A callback hook used in unittests to simulate changes between conflict set |
| // building and conflict resolution. |
| Callback0::Type* pre_conflict_resolution_closure_; |
| |
| friend class SyncerTest; |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, NameClashWithResolver); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, IllegalAndLegalUpdates); |
| FRIEND_TEST_ALL_PREFIXES(SusanDeletingTest, |
| NewServerItemInAFolderHierarchyWeHaveDeleted3); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingAndNewParent); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, |
| TestCommitListOrderingAndNewParentAndChild); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingCounterexample); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingWithNesting); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestCommitListOrderingWithNewItems); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestGetUnsyncedAndSimpleCommit); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestPurgeWhileUnsynced); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, TestPurgeWhileUnapplied); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, UnappliedUpdateDuringCommit); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, DeletingEntryInFolder); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, |
| LongChangelistCreatesFakeOrphanedEntries); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, QuicklyMergeDualCreatedHierarchy); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, LongChangelistWithApplicationConflict); |
| FRIEND_TEST_ALL_PREFIXES(SyncerTest, DeletingEntryWithLocalEdits); |
| FRIEND_TEST_ALL_PREFIXES(EntryCreatedInNewFolderTest, |
| EntryCreatedInNewFolderMidSync); |
| |
| DISALLOW_COPY_AND_ASSIGN(Syncer); |
| }; |
| |
| // Inline utility functions. |
| |
| // Given iterator ranges from two collections sorted according to a common |
| // strict weak ordering, return true if the two ranges contain any common |
| // items, and false if they do not. This function is in this header so that it |
| // can be tested. |
| template <class Iterator1, class Iterator2> |
| bool SortedCollectionsIntersect(Iterator1 begin1, Iterator1 end1, |
| Iterator2 begin2, Iterator2 end2) { |
| Iterator1 i1 = begin1; |
| Iterator2 i2 = begin2; |
| while (i1 != end1 && i2 != end2) { |
| if (*i1 == *i2) |
| return true; |
| if (*i1 > *i2) |
| ++i2; |
| else |
| ++i1; |
| } |
| return false; |
| } |
| // Utility function declarations. |
| void CopyServerFields(syncable::Entry* src, syncable::MutableEntry* dest); |
| void ClearServerData(syncable::MutableEntry* entry); |
| |
| } // namespace browser_sync |
| |
| #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCER_H_ |
| |