15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/syncer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/apply_control_data_updates.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/commit.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "sync/engine/commit_processor.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/conflict_resolver.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "sync/engine/get_updates_delegate.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "sync/engine/get_updates_processor.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/net/server_connection_manager.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/syncer_types.h" 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "sync/internal_api/public/base/cancelation_signal.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "sync/internal_api/public/base/unique_position.h" 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "sync/internal_api/public/util/syncer_error.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "sync/sessions/nudge_tracker.h" 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "sync/syncable/directory.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/mutable_entry.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/syncable-inl.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_pb::ClientCommand; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(akalin): We may want to propagate this switch up 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// eventually. 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID) || defined(OS_IOS) 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const bool kCreateMobileBookmarksFolder = true; 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const bool kCreateMobileBookmarksFolder = false; 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sessions::StatusController; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sessions::SyncSession; 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing sessions::NudgeTracker; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)Syncer::Syncer(syncer::CancelationSignal* cancelation_signal) 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : cancelation_signal_(cancelation_signal) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Syncer::~Syncer() {} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Syncer::ExitRequested() { 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return cancelation_signal_->IsSignalled(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool Syncer::NormalSyncShare(ModelTypeSet request_types, 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const NudgeTracker& nudge_tracker, 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SyncSession* session) { 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HandleCycleBegin(session); 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (nudge_tracker.IsGetUpdatesRequired() || 62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session->context()->ShouldFetchUpdatesBeforeCommit()) { 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "Downloading types " << ModelTypeSetToString(request_types); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NormalGetUpdatesDelegate normal_delegate(nudge_tracker); 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetUpdatesProcessor get_updates_processor( 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->context()->model_type_registry()->update_handler_map(), 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) normal_delegate); 68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!DownloadAndApplyUpdates( 691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) request_types, 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &get_updates_processor, 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kCreateMobileBookmarksFolder)) { 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return HandleCycleEnd(session, nudge_tracker.GetLegacySource()); 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VLOG(1) << "Committing from types " << ModelTypeSetToString(request_types); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CommitProcessor commit_processor( 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->context()->model_type_registry()->commit_contributor_map()); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SyncerError commit_result = 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BuildAndPostCommits(request_types, session, &commit_processor); 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session->mutable_status_controller()->set_commit_result(commit_result); 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return HandleCycleEnd(session, nudge_tracker.GetLegacySource()); 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool Syncer::ConfigureSyncShare( 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ModelTypeSet request_types, 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncSession* session) { 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VLOG(1) << "Configuring types " << ModelTypeSetToString(request_types); 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HandleCycleBegin(session); 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConfigureGetUpdatesDelegate configure_delegate(source); 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetUpdatesProcessor get_updates_processor( 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->context()->model_type_registry()->update_handler_map(), 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) configure_delegate); 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DownloadAndApplyUpdates( 981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) request_types, 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &get_updates_processor, 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kCreateMobileBookmarksFolder); 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return HandleCycleEnd(session, source); 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool Syncer::PollSyncShare(ModelTypeSet request_types, 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SyncSession* session) { 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VLOG(1) << "Polling types " << ModelTypeSetToString(request_types); 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HandleCycleBegin(session); 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PollGetUpdatesDelegate poll_delegate; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetUpdatesProcessor get_updates_processor( 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->context()->model_type_registry()->update_handler_map(), 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) poll_delegate); 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DownloadAndApplyUpdates( 1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) request_types, 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session, 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &get_updates_processor, 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kCreateMobileBookmarksFolder); 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return HandleCycleEnd(session, sync_pb::GetUpdatesCallerInfo::PERIODIC); 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool Syncer::DownloadAndApplyUpdates( 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ModelTypeSet request_types, 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SyncSession* session, 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetUpdatesProcessor* get_updates_processor, 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool create_mobile_bookmarks_folder) { 126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SyncerError download_result = UNSET; 127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) do { 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) download_result = get_updates_processor->DownloadUpdates( 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_types, 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) session, 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_mobile_bookmarks_folder); 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } while (download_result == SERVER_MORE_TO_DOWNLOAD); 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Exit without applying if we're shutting down or an error was detected. 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (download_result != SYNCER_OK) 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ExitRequested()) 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TRACE_EVENT0("sync", "ApplyUpdates"); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Control type updates always get applied first. 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ApplyControlDataUpdates(session->context()->directory()); 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Apply upates to the other types. May or may not involve cross-thread 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // traffic, depending on the underlying update handlers and the GU type's 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // delegate. 149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch get_updates_processor->ApplyUpdates(request_types, 150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch session->mutable_status_controller()); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->context()->set_hierarchy_conflict_detected( 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->status_controller().num_hierarchy_conflicts() > 0); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->SendEventNotification(SyncCycleEvent::STATUS_CHANGED); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ExitRequested()) 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)SyncerError Syncer::BuildAndPostCommits(ModelTypeSet requested_types, 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sessions::SyncSession* session, 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CommitProcessor* commit_processor) { 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // The ExitRequested() check is unnecessary, since we should start getting 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // errors from the ServerConnectionManager if an exist has been requested. 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // However, it doesn't hurt to check it anyway. 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) while (!ExitRequested()) { 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<Commit> commit( 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Commit::Init( 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) requested_types, 17223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) session->context()->GetEnabledTypes(), 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session->context()->max_commit_batch_size(), 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session->context()->account_name(), 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session->context()->directory()->cache_guid(), 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) commit_processor, 1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session->context()->extensions_activity())); 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!commit) { 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SyncerError error = commit->PostAndProcessResponse( 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session, 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session->mutable_status_controller(), 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) session->context()->extensions_activity()); 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) commit->CleanUp(); 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (error != SYNCER_OK) { 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return error; 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return SYNCER_OK; 1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid Syncer::HandleCycleBegin(SyncSession* session) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session->mutable_status_controller()->UpdateStartTime(); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session->SendEventNotification(SyncCycleEvent::SYNC_CYCLE_BEGIN); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool Syncer::HandleCycleEnd( 201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncSession* session, 202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source) { 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!ExitRequested()) { 204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) session->SendSyncCycleEndEventNotification(source); 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace syncer 212