84367b082b05de7e085b09c50c696c68d4935966
[platform/framework/web/crosswalk.git] / src / sync / internal_api / sync_rollback_manager.cc
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   SyncRollbackManagerBase::Init(database_location, event_handler,
45                                 sync_server_and_path, sync_server_port,
46                                 use_ssl, post_factory.Pass(),
47                                 workers, extensions_activity, change_delegate,
48                                 credentials, invalidator_client_id,
49                                 restored_key_for_bootstrapping,
50                                 restored_keystore_key_for_bootstrapping,
51                                 internal_components_factory, encryptor,
52                                 unrecoverable_error_handler.Pass(),
53                                 report_unrecoverable_error_function,
54                                 cancelation_signal);
55
56   change_delegate_ = change_delegate;
57
58   for (size_t i = 0; i < workers.size(); ++i) {
59     ModelSafeGroup group = workers[i]->GetModelSafeGroup();
60     CHECK(workers_.find(group) == workers_.end());
61     workers_[group] = workers[i];
62   }
63
64   rollback_ready_types_ = GetUserShare()->directory->InitialSyncEndedTypes();
65   rollback_ready_types_.RetainAll(BackupTypes());
66 }
67
68 void SyncRollbackManager::StartSyncingNormally(
69     const ModelSafeRoutingInfo& routing_info){
70   if (rollback_ready_types_.Empty()) {
71     NotifyRollbackDone();
72     return;
73   }
74
75   std::map<ModelType, syncable::Directory::Metahandles> to_delete;
76   {
77     WriteTransaction trans(FROM_HERE, GetUserShare());
78     syncable::Directory::Metahandles unsynced;
79     GetUserShare()->directory->GetUnsyncedMetaHandles(trans.GetWrappedTrans(),
80                                                       &unsynced);
81     for (size_t i = 0; i < unsynced.size(); ++i) {
82       syncable::MutableEntry e(trans.GetWrappedWriteTrans(),
83                                syncable::GET_BY_HANDLE, unsynced[i]);
84       if (!e.good() || e.GetIsDel() || e.GetId().ServerKnows())
85         continue;
86
87       // TODO(haitaol): roll back entries that are backed up but whose content
88       //                is merged with local model during association.
89
90       ModelType type = GetModelTypeFromSpecifics(e.GetSpecifics());
91       if (!rollback_ready_types_.Has(type))
92         continue;
93
94       to_delete[type].push_back(unsynced[i]);
95     }
96   }
97
98   for (std::map<ModelType, syncable::Directory::Metahandles>::iterator it =
99       to_delete.begin(); it != to_delete.end(); ++it) {
100     ModelSafeGroup group = routing_info.find(it->first)->second;
101     CHECK(workers_.find(group) != workers_.end());
102     workers_[group]->DoWorkAndWaitUntilDone(
103         base::Bind(&SyncRollbackManager::DeleteOnWorkerThread,
104                    base::Unretained(this),
105                    it->first, it->second));
106   }
107
108   NotifyRollbackDone();
109 }
110
111 SyncerError SyncRollbackManager::DeleteOnWorkerThread(
112     ModelType type, std::vector<int64> handles) {
113   CHECK(change_delegate_);
114
115   {
116     ChangeRecordList deletes;
117     WriteTransaction trans(FROM_HERE, GetUserShare());
118     for (size_t i = 0; i < handles.size(); ++i) {
119       syncable::MutableEntry e(trans.GetWrappedWriteTrans(),
120                                syncable::GET_BY_HANDLE, handles[i]);
121       if (!e.good() || e.GetIsDel())
122         continue;
123
124       ChangeRecord del;
125       del.action = ChangeRecord::ACTION_DELETE;
126       del.id = handles[i];
127       del.specifics = e.GetSpecifics();
128       deletes.push_back(del);
129     }
130
131     change_delegate_->OnChangesApplied(type, 1, &trans,
132                                        MakeImmutable(&deletes));
133   }
134
135   change_delegate_->OnChangesComplete(type);
136   return SYNCER_OK;
137 }
138
139 void SyncRollbackManager::NotifyRollbackDone() {
140   SyncProtocolError error;
141   error.action = ROLLBACK_DONE;
142   FOR_EACH_OBSERVER(SyncManager::Observer, *GetObservers(),
143                     OnActionableError(error));
144 }
145
146 }  // namespace syncer