| Index: sync/engine/syncer.cc
|
| diff --git a/sync/engine/syncer.cc b/sync/engine/syncer.cc
|
| index c4ef67155019cf359358022bc5a2071179b96eff..9b1adb3791e0c84f5ea4a0c26d54a5f88a91cb5b 100644
|
| --- a/sync/engine/syncer.cc
|
| +++ b/sync/engine/syncer.cc
|
| @@ -15,13 +15,13 @@
|
| #include "sync/engine/build_commit_command.h"
|
| #include "sync/engine/commit.h"
|
| #include "sync/engine/conflict_resolver.h"
|
| -#include "sync/engine/download_updates_command.h"
|
| +#include "sync/engine/download.h"
|
| #include "sync/engine/net/server_connection_manager.h"
|
| #include "sync/engine/process_commit_response_command.h"
|
| -#include "sync/engine/process_updates_command.h"
|
| -#include "sync/engine/store_timestamps_command.h"
|
| #include "sync/engine/syncer_types.h"
|
| #include "sync/internal_api/public/base/unique_position.h"
|
| +#include "sync/internal_api/public/util/syncer_error.h"
|
| +#include "sync/sessions/nudge_tracker.h"
|
| #include "sync/syncable/mutable_entry.h"
|
| #include "sync/syncable/syncable-inl.h"
|
|
|
| @@ -31,35 +31,17 @@ using sync_pb::ClientCommand;
|
|
|
| namespace syncer {
|
|
|
| +// TODO(akalin): We may want to propagate this switch up
|
| +// eventually.
|
| +#if defined(OS_ANDROID) || defined(OS_IOS)
|
| +static const bool kCreateMobileBookmarksFolder = true;
|
| +#else
|
| +static const bool kCreateMobileBookmarksFolder = false;
|
| +#endif
|
| +
|
| using sessions::StatusController;
|
| using sessions::SyncSession;
|
| -using syncable::IS_UNAPPLIED_UPDATE;
|
| -using syncable::SERVER_CTIME;
|
| -using syncable::SERVER_IS_DEL;
|
| -using syncable::SERVER_IS_DIR;
|
| -using syncable::SERVER_MTIME;
|
| -using syncable::SERVER_NON_UNIQUE_NAME;
|
| -using syncable::SERVER_PARENT_ID;
|
| -using syncable::SERVER_SPECIFICS;
|
| -using syncable::SERVER_UNIQUE_POSITION;
|
| -using syncable::SERVER_VERSION;
|
| -
|
| -#define ENUM_CASE(x) case x: return #x
|
| -const char* SyncerStepToString(const SyncerStep step)
|
| -{
|
| - switch (step) {
|
| - ENUM_CASE(SYNCER_BEGIN);
|
| - ENUM_CASE(DOWNLOAD_UPDATES);
|
| - ENUM_CASE(PROCESS_UPDATES);
|
| - ENUM_CASE(STORE_TIMESTAMPS);
|
| - ENUM_CASE(APPLY_UPDATES);
|
| - ENUM_CASE(COMMIT);
|
| - ENUM_CASE(SYNCER_END);
|
| - }
|
| - NOTREACHED();
|
| - return "";
|
| -}
|
| -#undef ENUM_CASE
|
| +using sessions::NudgeTracker;
|
|
|
| Syncer::Syncer()
|
| : early_exit_requested_(false) {
|
| @@ -77,121 +59,100 @@ void Syncer::RequestEarlyExit() {
|
| early_exit_requested_ = true;
|
| }
|
|
|
| -bool Syncer::SyncShare(sessions::SyncSession* session,
|
| - SyncerStep first_step,
|
| - SyncerStep last_step) {
|
| +bool Syncer::NormalSyncShare(ModelTypeSet request_types,
|
| + const NudgeTracker& nudge_tracker,
|
| + SyncSession* session) {
|
| + HandleCycleBegin(session);
|
| + VLOG(1) << "Downloading types " << ModelTypeSetToString(request_types);
|
| + if (!DownloadAndApplyUpdates(
|
| + session,
|
| + base::Bind(&NormalDownloadUpdates,
|
| + session,
|
| + kCreateMobileBookmarksFolder,
|
| + request_types,
|
| + base::ConstRef(nudge_tracker)))) {
|
| + return HandleCycleEnd(session);
|
| + }
|
| +
|
| + VLOG(1) << "Committing from types " << ModelTypeSetToString(request_types);
|
| + SyncerError commit_result = BuildAndPostCommits(request_types, this, session);
|
| + session->mutable_status_controller()->set_commit_result(commit_result);
|
| +
|
| + return HandleCycleEnd(session);
|
| +}
|
| +
|
| +bool Syncer::ConfigureSyncShare(ModelTypeSet request_types,
|
| + SyncSession* session) {
|
| + HandleCycleBegin(session);
|
| + VLOG(1) << "Configuring types " << ModelTypeSetToString(request_types);
|
| + DownloadAndApplyUpdates(
|
| + session,
|
| + base::Bind(&DownloadUpdatesForConfigure,
|
| + session,
|
| + kCreateMobileBookmarksFolder,
|
| + session->source(),
|
| + request_types));
|
| + return HandleCycleEnd(session);
|
| +}
|
| +
|
| +bool Syncer::PollSyncShare(ModelTypeSet request_types,
|
| + SyncSession* session) {
|
| + HandleCycleBegin(session);
|
| + VLOG(1) << "Polling types " << ModelTypeSetToString(request_types);
|
| + DownloadAndApplyUpdates(
|
| + session,
|
| + base::Bind(&DownloadUpdatesForPoll,
|
| + session,
|
| + kCreateMobileBookmarksFolder,
|
| + request_types));
|
| + return HandleCycleEnd(session);
|
| +}
|
| +
|
| +void Syncer::ApplyUpdates(SyncSession* session) {
|
| + TRACE_EVENT0("sync", "ApplyUpdates");
|
| +
|
| + ApplyControlDataUpdates(session);
|
| +
|
| + ApplyUpdatesAndResolveConflictsCommand apply_updates;
|
| + apply_updates.Execute(session);
|
| +
|
| + session->context()->set_hierarchy_conflict_detected(
|
| + session->status_controller().num_hierarchy_conflicts() > 0);
|
| +
|
| + session->SendEventNotification(SyncEngineEvent::STATUS_CHANGED);
|
| +}
|
| +
|
| +bool Syncer::DownloadAndApplyUpdates(
|
| + SyncSession* session,
|
| + base::Callback<SyncerError(void)> download_fn) {
|
| + while (!session->status_controller().ServerSaysNothingMoreToDownload()) {
|
| + SyncerError download_result = download_fn.Run();
|
| + session->mutable_status_controller()->set_last_download_updates_result(
|
| + download_result);
|
| + if (download_result != SYNCER_OK) {
|
| + return false;
|
| + }
|
| + }
|
| + if (ExitRequested())
|
| + return false;
|
| + ApplyUpdates(session);
|
| + if (ExitRequested())
|
| + return false;
|
| + return true;
|
| +}
|
| +
|
| +void Syncer::HandleCycleBegin(SyncSession* session) {
|
| session->mutable_status_controller()->UpdateStartTime();
|
| - SyncerStep current_step = first_step;
|
| -
|
| - SyncerStep next_step = current_step;
|
| - while (!ExitRequested()) {
|
| - TRACE_EVENT1("sync", "SyncerStateMachine",
|
| - "state", SyncerStepToString(current_step));
|
| - DVLOG(1) << "Syncer step:" << SyncerStepToString(current_step);
|
| -
|
| - switch (current_step) {
|
| - case SYNCER_BEGIN:
|
| - session->SendEventNotification(SyncEngineEvent::SYNC_CYCLE_BEGIN);
|
| -
|
| - next_step = DOWNLOAD_UPDATES;
|
| - break;
|
| - case DOWNLOAD_UPDATES: {
|
| - // TODO(akalin): We may want to propagate this switch up
|
| - // eventually.
|
| -#if defined(OS_ANDROID) || defined(OS_IOS)
|
| - const bool kCreateMobileBookmarksFolder = true;
|
| -#else
|
| - const bool kCreateMobileBookmarksFolder = false;
|
| -#endif
|
| - DownloadUpdatesCommand download_updates(kCreateMobileBookmarksFolder);
|
| - session->mutable_status_controller()->set_last_download_updates_result(
|
| - download_updates.Execute(session));
|
| - next_step = PROCESS_UPDATES;
|
| - break;
|
| - }
|
| - case PROCESS_UPDATES: {
|
| - ProcessUpdatesCommand process_updates;
|
| - process_updates.Execute(session);
|
| - next_step = STORE_TIMESTAMPS;
|
| - break;
|
| - }
|
| - case STORE_TIMESTAMPS: {
|
| - StoreTimestampsCommand store_timestamps;
|
| - store_timestamps.Execute(session);
|
| - session->SendEventNotification(SyncEngineEvent::STATUS_CHANGED);
|
| - // We download all of the updates before attempting to apply them.
|
| - if (!session->status_controller().download_updates_succeeded()) {
|
| - // We may have downloaded some updates, but if the latest download
|
| - // attempt failed then we don't have all the updates. We'll leave
|
| - // it to a retry job to pick up where we left off.
|
| - last_step = SYNCER_END; // Necessary for CONFIGURATION mode.
|
| - next_step = SYNCER_END;
|
| - DVLOG(1) << "Aborting sync cycle due to download updates failure";
|
| - } else if (!session->status_controller()
|
| - .ServerSaysNothingMoreToDownload()) {
|
| - next_step = DOWNLOAD_UPDATES;
|
| - } else {
|
| - next_step = APPLY_UPDATES;
|
| - }
|
| - break;
|
| - }
|
| - case APPLY_UPDATES: {
|
| - // These include encryption updates that should be applied early.
|
| - ApplyControlDataUpdates(session);
|
| -
|
| - ApplyUpdatesAndResolveConflictsCommand apply_updates;
|
| - apply_updates.Execute(session);
|
| -
|
| - session->context()->set_hierarchy_conflict_detected(
|
| - session->status_controller().num_hierarchy_conflicts() > 0);
|
| -
|
| - session->SendEventNotification(SyncEngineEvent::STATUS_CHANGED);
|
| - if (last_step == APPLY_UPDATES) {
|
| - // We're in configuration mode, but we still need to run the
|
| - // SYNCER_END step.
|
| - last_step = SYNCER_END;
|
| - next_step = SYNCER_END;
|
| - } else {
|
| - next_step = COMMIT;
|
| - }
|
| - break;
|
| - }
|
| - case COMMIT: {
|
| - session->mutable_status_controller()->set_commit_result(
|
| - BuildAndPostCommits(this, session));
|
| - next_step = SYNCER_END;
|
| - break;
|
| - }
|
| - case SYNCER_END: {
|
| - session->SendEventNotification(SyncEngineEvent::SYNC_CYCLE_ENDED);
|
| - next_step = SYNCER_END;
|
| - break;
|
| - }
|
| - default:
|
| - LOG(ERROR) << "Unknown command: " << current_step;
|
| - } // switch
|
| - DVLOG(2) << "last step: " << SyncerStepToString(last_step) << ", "
|
| - << "current step: " << SyncerStepToString(current_step) << ", "
|
| - << "next step: " << SyncerStepToString(next_step) << ", "
|
| - << "snapshot: " << session->TakeSnapshot().ToString();
|
| - if (last_step == current_step)
|
| - return true;
|
| - current_step = next_step;
|
| - } // while
|
| - return false;
|
| + session->SendEventNotification(SyncEngineEvent::SYNC_CYCLE_BEGIN);
|
| }
|
|
|
| -void CopyServerFields(syncable::Entry* src, syncable::MutableEntry* dest) {
|
| - dest->Put(SERVER_NON_UNIQUE_NAME, src->Get(SERVER_NON_UNIQUE_NAME));
|
| - dest->Put(SERVER_PARENT_ID, src->Get(SERVER_PARENT_ID));
|
| - dest->Put(SERVER_MTIME, src->Get(SERVER_MTIME));
|
| - dest->Put(SERVER_CTIME, src->Get(SERVER_CTIME));
|
| - dest->Put(SERVER_VERSION, src->Get(SERVER_VERSION));
|
| - dest->Put(SERVER_IS_DIR, src->Get(SERVER_IS_DIR));
|
| - dest->Put(SERVER_IS_DEL, src->Get(SERVER_IS_DEL));
|
| - dest->Put(IS_UNAPPLIED_UPDATE, src->Get(IS_UNAPPLIED_UPDATE));
|
| - dest->Put(SERVER_SPECIFICS, src->Get(SERVER_SPECIFICS));
|
| - dest->Put(SERVER_UNIQUE_POSITION, src->Get(SERVER_UNIQUE_POSITION));
|
| +bool Syncer::HandleCycleEnd(SyncSession* session) {
|
| + if (!ExitRequested()) {
|
| + session->SendEventNotification(SyncEngineEvent::SYNC_CYCLE_ENDED);
|
| + return true;
|
| + } else {
|
| + return false;
|
| + }
|
| }
|
|
|
| } // namespace syncer
|
|
|