Home | History | Annotate | Download | only in internal_api
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sync/internal_api/sync_rollback_manager.h"
      6 
      7 #include "sync/internal_api/public/base/model_type.h"
      8 #include "sync/internal_api/public/read_node.h"
      9 #include "sync/internal_api/public/read_transaction.h"
     10 #include "sync/internal_api/public/util/syncer_error.h"
     11 #include "sync/internal_api/public/write_transaction.h"
     12 #include "sync/syncable/directory.h"
     13 #include "sync/syncable/mutable_entry.h"
     14 
     15 namespace syncer {
     16 
     17 SyncRollbackManager::SyncRollbackManager()
     18     : change_delegate_(NULL) {
     19 }
     20 
     21 SyncRollbackManager::~SyncRollbackManager() {
     22 }
     23 
     24 void SyncRollbackManager::Init(
     25       const base::FilePath& database_location,
     26       const WeakHandle<JsEventHandler>& event_handler,
     27       const std::string& sync_server_and_path,
     28       int sync_server_port,
     29       bool use_ssl,
     30       scoped_ptr<HttpPostProviderFactory> post_factory,
     31       const std::vector<scoped_refptr<ModelSafeWorker> >& workers,
     32       ExtensionsActivity* extensions_activity,
     33       SyncManager::ChangeDelegate* change_delegate,
     34       const SyncCredentials& credentials,
     35       const std::string& invalidator_client_id,
     36       const std::string& restored_key_for_bootstrapping,
     37       const std::string& restored_keystore_key_for_bootstrapping,
     38       InternalComponentsFactory* internal_components_factory,
     39       Encryptor* encryptor,
     40       scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler,
     41       ReportUnrecoverableErrorFunction
     42           report_unrecoverable_error_function,
     43       CancelationSignal* cancelation_signal) {
     44   if (SyncRollbackManagerBase::InitInternal(
     45           database_location,
     46           internal_components_factory,
     47           unrecoverable_error_handler.Pass(),
     48           report_unrecoverable_error_function)) {
     49     change_delegate_ = change_delegate;
     50 
     51     for (size_t i = 0; i < workers.size(); ++i) {
     52       ModelSafeGroup group = workers[i]->GetModelSafeGroup();
     53       CHECK(workers_.find(group) == workers_.end());
     54       workers_[group] = workers[i];
     55     }
     56 
     57     rollback_ready_types_ = GetUserShare()->directory->InitialSyncEndedTypes();
     58     rollback_ready_types_.RetainAll(BackupTypes());
     59   }
     60 }
     61 
     62 void SyncRollbackManager::StartSyncingNormally(
     63     const ModelSafeRoutingInfo& routing_info){
     64   if (rollback_ready_types_.Empty()) {
     65     NotifyRollbackDone();
     66     return;
     67   }
     68 
     69   std::map<ModelType, syncable::Directory::Metahandles> to_delete;
     70   {
     71     WriteTransaction trans(FROM_HERE, GetUserShare());
     72     syncable::Directory::Metahandles unsynced;
     73     GetUserShare()->directory->GetUnsyncedMetaHandles(trans.GetWrappedTrans(),
     74                                                       &unsynced);
     75     for (size_t i = 0; i < unsynced.size(); ++i) {
     76       syncable::MutableEntry e(trans.GetWrappedWriteTrans(),
     77                                syncable::GET_BY_HANDLE, unsynced[i]);
     78       if (!e.good() || e.GetIsDel() || e.GetId().ServerKnows())
     79         continue;
     80 
     81       // TODO(haitaol): roll back entries that are backed up but whose content
     82       //                is merged with local model during association.
     83 
     84       ModelType type = GetModelTypeFromSpecifics(e.GetSpecifics());
     85       if (!rollback_ready_types_.Has(type))
     86         continue;
     87 
     88       to_delete[type].push_back(unsynced[i]);
     89     }
     90   }
     91 
     92   for (std::map<ModelType, syncable::Directory::Metahandles>::iterator it =
     93       to_delete.begin(); it != to_delete.end(); ++it) {
     94     ModelSafeGroup group = routing_info.find(it->first)->second;
     95     CHECK(workers_.find(group) != workers_.end());
     96     workers_[group]->DoWorkAndWaitUntilDone(
     97         base::Bind(&SyncRollbackManager::DeleteOnWorkerThread,
     98                    base::Unretained(this),
     99                    it->first, it->second));
    100   }
    101 
    102   NotifyRollbackDone();
    103 }
    104 
    105 SyncerError SyncRollbackManager::DeleteOnWorkerThread(
    106     ModelType type, std::vector<int64> handles) {
    107   CHECK(change_delegate_);
    108 
    109   {
    110     ChangeRecordList deletes;
    111     WriteTransaction trans(FROM_HERE, GetUserShare());
    112     for (size_t i = 0; i < handles.size(); ++i) {
    113       syncable::MutableEntry e(trans.GetWrappedWriteTrans(),
    114                                syncable::GET_BY_HANDLE, handles[i]);
    115       if (!e.good() || e.GetIsDel())
    116         continue;
    117 
    118       ChangeRecord del;
    119       del.action = ChangeRecord::ACTION_DELETE;
    120       del.id = handles[i];
    121       del.specifics = e.GetSpecifics();
    122       deletes.push_back(del);
    123     }
    124 
    125     change_delegate_->OnChangesApplied(type, 1, &trans,
    126                                        MakeImmutable(&deletes));
    127   }
    128 
    129   change_delegate_->OnChangesComplete(type);
    130   return SYNCER_OK;
    131 }
    132 
    133 void SyncRollbackManager::NotifyRollbackDone() {
    134   SyncProtocolError error;
    135   error.action = ROLLBACK_DONE;
    136   FOR_EACH_OBSERVER(SyncManager::Observer, *GetObservers(),
    137                     OnActionableError(error));
    138 }
    139 
    140 }  // namespace syncer
    141