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