10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file. 40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/sync_rollback_manager.h" 60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/base/model_type.h" 80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/read_node.h" 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/read_transaction.h" 100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/util/syncer_error.h" 110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/write_transaction.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/syncable/directory.h" 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/syncable/mutable_entry.h" 140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace syncer { 160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 170529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochSyncRollbackManager::SyncRollbackManager() 180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : change_delegate_(NULL) { 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 210529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochSyncRollbackManager::~SyncRollbackManager() { 220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SyncRollbackManager::Init( 250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const base::FilePath& database_location, 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const WeakHandle<JsEventHandler>& event_handler, 270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& sync_server_and_path, 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int sync_server_port, 290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool use_ssl, 300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<HttpPostProviderFactory> post_factory, 310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::vector<scoped_refptr<ModelSafeWorker> >& workers, 320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ExtensionsActivity* extensions_activity, 330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SyncManager::ChangeDelegate* change_delegate, 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const SyncCredentials& credentials, 350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& invalidator_client_id, 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& restored_key_for_bootstrapping, 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& restored_keystore_key_for_bootstrapping, 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch InternalComponentsFactory* internal_components_factory, 390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Encryptor* encryptor, 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler, 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReportUnrecoverableErrorFunction 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch report_unrecoverable_error_function, 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CancelationSignal* cancelation_signal) { 448f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu if (SyncRollbackManagerBase::InitInternal( 458f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu database_location, 468f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu internal_components_factory, 478f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu unrecoverable_error_handler.Pass(), 488f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu report_unrecoverable_error_function)) { 498f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu change_delegate_ = change_delegate; 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 518f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu for (size_t i = 0; i < workers.size(); ++i) { 528f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu ModelSafeGroup group = workers[i]->GetModelSafeGroup(); 538f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu CHECK(workers_.find(group) == workers_.end()); 548f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu workers_[group] = workers[i]; 558f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu } 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 578f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu rollback_ready_types_ = GetUserShare()->directory->InitialSyncEndedTypes(); 588f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu rollback_ready_types_.RetainAll(BackupTypes()); 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SyncRollbackManager::StartSyncingNormally( 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const ModelSafeRoutingInfo& routing_info){ 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (rollback_ready_types_.Empty()) { 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyRollbackDone(); 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::map<ModelType, syncable::Directory::Metahandles> to_delete; 700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch WriteTransaction trans(FROM_HERE, GetUserShare()); 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch syncable::Directory::Metahandles unsynced; 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GetUserShare()->directory->GetUnsyncedMetaHandles(trans.GetWrappedTrans(), 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch &unsynced); 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (size_t i = 0; i < unsynced.size(); ++i) { 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch syncable::MutableEntry e(trans.GetWrappedWriteTrans(), 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch syncable::GET_BY_HANDLE, unsynced[i]); 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!e.good() || e.GetIsDel() || e.GetId().ServerKnows()) 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch continue; 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(haitaol): roll back entries that are backed up but whose content 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // is merged with local model during association. 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ModelType type = GetModelTypeFromSpecifics(e.GetSpecifics()); 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!rollback_ready_types_.Has(type)) 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch continue; 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch to_delete[type].push_back(unsynced[i]); 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (std::map<ModelType, syncable::Directory::Metahandles>::iterator it = 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch to_delete.begin(); it != to_delete.end(); ++it) { 940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ModelSafeGroup group = routing_info.find(it->first)->second; 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CHECK(workers_.find(group) != workers_.end()); 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch workers_[group]->DoWorkAndWaitUntilDone( 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(&SyncRollbackManager::DeleteOnWorkerThread, 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Unretained(this), 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch it->first, it->second)); 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NotifyRollbackDone(); 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1050529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochSyncerError SyncRollbackManager::DeleteOnWorkerThread( 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ModelType type, std::vector<int64> handles) { 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CHECK(change_delegate_); 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { 1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ChangeRecordList deletes; 1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch WriteTransaction trans(FROM_HERE, GetUserShare()); 1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch for (size_t i = 0; i < handles.size(); ++i) { 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch syncable::MutableEntry e(trans.GetWrappedWriteTrans(), 1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch syncable::GET_BY_HANDLE, handles[i]); 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!e.good() || e.GetIsDel()) 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch continue; 1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ChangeRecord del; 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch del.action = ChangeRecord::ACTION_DELETE; 1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch del.id = handles[i]; 1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch del.specifics = e.GetSpecifics(); 1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch deletes.push_back(del); 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch change_delegate_->OnChangesApplied(type, 1, &trans, 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MakeImmutable(&deletes)); 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch change_delegate_->OnChangesComplete(type); 1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return SYNCER_OK; 1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void SyncRollbackManager::NotifyRollbackDone() { 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SyncProtocolError error; 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error.action = ROLLBACK_DONE; 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FOR_EACH_OBSERVER(SyncManager::Observer, *GetObservers(), 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnActionableError(error)); 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} // namespace syncer 141