• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SyncRollbackManager()17 SyncRollbackManager::SyncRollbackManager()
18     : change_delegate_(NULL) {
19 }
20 
~SyncRollbackManager()21 SyncRollbackManager::~SyncRollbackManager() {
22 }
23 
Init(const base::FilePath & database_location,const WeakHandle<JsEventHandler> & event_handler,const std::string & sync_server_and_path,int sync_server_port,bool use_ssl,scoped_ptr<HttpPostProviderFactory> post_factory,const std::vector<scoped_refptr<ModelSafeWorker>> & workers,ExtensionsActivity * extensions_activity,SyncManager::ChangeDelegate * change_delegate,const SyncCredentials & credentials,const std::string & invalidator_client_id,const std::string & restored_key_for_bootstrapping,const std::string & restored_keystore_key_for_bootstrapping,InternalComponentsFactory * internal_components_factory,Encryptor * encryptor,scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler,ReportUnrecoverableErrorFunction report_unrecoverable_error_function,CancelationSignal * cancelation_signal)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 
StartSyncingNormally(const ModelSafeRoutingInfo & routing_info)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 
DeleteOnWorkerThread(ModelType type,std::vector<int64> handles)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 
NotifyRollbackDone()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