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_base.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/write_transaction.h"
11#include "sync/syncable/directory_backing_store.h"
12#include "sync/syncable/mutable_entry.h"
13
14namespace {
15
16// Permanent bookmark folders as defined in bookmark_model_associator.cc.
17// No mobile bookmarks because they only exists with sync enabled.
18const char kBookmarkBarTag[] = "bookmark_bar";
19const char kOtherBookmarksTag[] = "other_bookmarks";
20
21class DummyEntryptionHandler : public syncer::SyncEncryptionHandler {
22  virtual void AddObserver(Observer* observer) OVERRIDE {}
23  virtual void RemoveObserver(Observer* observer) OVERRIDE {}
24  virtual void Init() OVERRIDE {}
25  virtual void SetEncryptionPassphrase(const std::string& passphrase,
26                                       bool is_explicit) OVERRIDE {}
27  virtual void SetDecryptionPassphrase(const std::string& passphrase)
28      OVERRIDE {}
29  virtual void EnableEncryptEverything() OVERRIDE {}
30  virtual bool EncryptEverythingEnabled() const OVERRIDE {
31    return false;
32  }
33  virtual syncer::PassphraseType GetPassphraseType() const OVERRIDE {
34    return syncer::KEYSTORE_PASSPHRASE;
35  }
36};
37
38}  // anonymous namespace
39
40namespace syncer {
41
42SyncRollbackManagerBase::SyncRollbackManagerBase()
43    : report_unrecoverable_error_function_(NULL),
44      dummy_handler_(new DummyEntryptionHandler),
45      initialized_(false),
46      weak_ptr_factory_(this) {
47}
48
49SyncRollbackManagerBase::~SyncRollbackManagerBase() {
50}
51
52bool SyncRollbackManagerBase::InitInternal(
53    const base::FilePath& database_location,
54    InternalComponentsFactory* internal_components_factory,
55    InternalComponentsFactory::StorageOption storage,
56    scoped_ptr<UnrecoverableErrorHandler> unrecoverable_error_handler,
57    ReportUnrecoverableErrorFunction report_unrecoverable_error_function) {
58  unrecoverable_error_handler_ = unrecoverable_error_handler.Pass();
59  report_unrecoverable_error_function_ = report_unrecoverable_error_function;
60
61  if (!InitBackupDB(database_location, internal_components_factory, storage)) {
62    NotifyInitializationFailure();
63    return false;
64  }
65
66  initialized_ = true;
67  NotifyInitializationSuccess();
68  return true;
69}
70
71ModelTypeSet SyncRollbackManagerBase::InitialSyncEndedTypes() {
72  return share_.directory->InitialSyncEndedTypes();
73}
74
75ModelTypeSet SyncRollbackManagerBase::GetTypesWithEmptyProgressMarkerToken(
76      ModelTypeSet types) {
77  ModelTypeSet inited_types = share_.directory->InitialSyncEndedTypes();
78  types.RemoveAll(inited_types);
79  return types;
80}
81
82bool SyncRollbackManagerBase::PurgePartiallySyncedTypes() {
83  NOTREACHED();
84  return true;
85}
86
87void SyncRollbackManagerBase::UpdateCredentials(
88    const SyncCredentials& credentials) {
89}
90
91void SyncRollbackManagerBase::StartSyncingNormally(
92    const ModelSafeRoutingInfo& routing_info){
93}
94
95void SyncRollbackManagerBase::ConfigureSyncer(
96      ConfigureReason reason,
97      ModelTypeSet to_download,
98      ModelTypeSet to_purge,
99      ModelTypeSet to_journal,
100      ModelTypeSet to_unapply,
101      const ModelSafeRoutingInfo& new_routing_info,
102      const base::Closure& ready_task,
103      const base::Closure& retry_task) {
104  for (ModelTypeSet::Iterator type = to_download.First();
105      type.Good(); type.Inc()) {
106    if (InitTypeRootNode(type.Get())) {
107      if (type.Get() == BOOKMARKS) {
108        InitBookmarkFolder(kBookmarkBarTag);
109        InitBookmarkFolder(kOtherBookmarksTag);
110      }
111    }
112  }
113
114  ready_task.Run();
115}
116
117void SyncRollbackManagerBase::SetInvalidatorEnabled(bool invalidator_enabled) {
118}
119
120void SyncRollbackManagerBase::OnIncomingInvalidation(
121    syncer::ModelType type,
122    scoped_ptr<InvalidationInterface> invalidation) {
123  NOTREACHED();
124}
125
126void SyncRollbackManagerBase::AddObserver(SyncManager::Observer* observer) {
127  observers_.AddObserver(observer);
128}
129
130void SyncRollbackManagerBase::RemoveObserver(SyncManager::Observer* observer) {
131  observers_.RemoveObserver(observer);
132}
133
134SyncStatus SyncRollbackManagerBase::GetDetailedStatus() const {
135  return SyncStatus();
136}
137
138void SyncRollbackManagerBase::SaveChanges() {
139}
140
141void SyncRollbackManagerBase::ShutdownOnSyncThread(ShutdownReason reason) {
142  if (initialized_) {
143    share_.directory->Close();
144    share_.directory.reset();
145    initialized_ = false;
146  }
147}
148
149UserShare* SyncRollbackManagerBase::GetUserShare() {
150  return &share_;
151}
152
153const std::string SyncRollbackManagerBase::cache_guid() {
154  return share_.directory->cache_guid();
155}
156
157bool SyncRollbackManagerBase::ReceivedExperiment(Experiments* experiments) {
158  return false;
159}
160
161bool SyncRollbackManagerBase::HasUnsyncedItems() {
162  ReadTransaction trans(FROM_HERE, &share_);
163  syncable::Directory::Metahandles unsynced;
164  share_.directory->GetUnsyncedMetaHandles(trans.GetWrappedTrans(), &unsynced);
165  return !unsynced.empty();
166}
167
168SyncEncryptionHandler* SyncRollbackManagerBase::GetEncryptionHandler() {
169  return dummy_handler_.get();
170}
171
172void SyncRollbackManagerBase::RefreshTypes(ModelTypeSet types) {
173
174}
175
176void SyncRollbackManagerBase::HandleTransactionCompleteChangeEvent(
177    ModelTypeSet models_with_changes) {
178}
179
180ModelTypeSet SyncRollbackManagerBase::HandleTransactionEndingChangeEvent(
181      const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
182      syncable::BaseTransaction* trans) {
183  return ModelTypeSet();
184}
185
186void SyncRollbackManagerBase::HandleCalculateChangesChangeEventFromSyncApi(
187      const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
188      syncable::BaseTransaction* trans,
189      std::vector<int64>* entries_changed) {
190}
191
192void SyncRollbackManagerBase::HandleCalculateChangesChangeEventFromSyncer(
193      const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
194      syncable::BaseTransaction* trans,
195      std::vector<int64>* entries_changed) {
196}
197
198void SyncRollbackManagerBase::OnTransactionWrite(
199    const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
200    ModelTypeSet models_with_changes) {
201}
202
203void SyncRollbackManagerBase::NotifyInitializationSuccess() {
204  FOR_EACH_OBSERVER(
205      SyncManager::Observer, observers_,
206      OnInitializationComplete(
207          MakeWeakHandle(base::WeakPtr<JsBackend>()),
208          MakeWeakHandle(base::WeakPtr<DataTypeDebugInfoListener>()),
209          true, InitialSyncEndedTypes()));
210}
211
212void SyncRollbackManagerBase::NotifyInitializationFailure() {
213  FOR_EACH_OBSERVER(
214      SyncManager::Observer, observers_,
215      OnInitializationComplete(
216          MakeWeakHandle(base::WeakPtr<JsBackend>()),
217          MakeWeakHandle(base::WeakPtr<DataTypeDebugInfoListener>()),
218          false, ModelTypeSet()));
219}
220
221syncer::SyncContextProxy* SyncRollbackManagerBase::GetSyncContextProxy() {
222  return NULL;
223}
224
225ScopedVector<syncer::ProtocolEvent>
226SyncRollbackManagerBase::GetBufferedProtocolEvents() {
227  return ScopedVector<syncer::ProtocolEvent>().Pass();
228}
229
230scoped_ptr<base::ListValue> SyncRollbackManagerBase::GetAllNodesForType(
231    syncer::ModelType type) {
232  ReadTransaction trans(FROM_HERE, GetUserShare());
233  scoped_ptr<base::ListValue> nodes(
234      trans.GetDirectory()->GetNodeDetailsForType(trans.GetWrappedTrans(),
235                                                  type));
236  return nodes.Pass();
237}
238
239bool SyncRollbackManagerBase::InitBackupDB(
240    const base::FilePath& sync_folder,
241    InternalComponentsFactory* internal_components_factory,
242    InternalComponentsFactory::StorageOption storage) {
243  base::FilePath backup_db_path = sync_folder.Append(
244      syncable::Directory::kSyncDatabaseFilename);
245  scoped_ptr<syncable::DirectoryBackingStore> backing_store =
246      internal_components_factory->BuildDirectoryBackingStore(
247          storage, "backup", backup_db_path).Pass();
248
249  DCHECK(backing_store.get());
250  share_.directory.reset(
251      new syncable::Directory(
252          backing_store.release(),
253          unrecoverable_error_handler_.get(),
254          report_unrecoverable_error_function_,
255          NULL,
256          NULL));
257  return syncable::OPENED ==
258      share_.directory->Open(
259          "backup", this,
260          MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()));
261}
262
263bool SyncRollbackManagerBase::InitTypeRootNode(ModelType type) {
264  WriteTransaction trans(FROM_HERE, &share_);
265  ReadNode root(&trans);
266  if (BaseNode::INIT_OK == root.InitTypeRoot(type))
267    return true;
268
269  syncable::MutableEntry entry(trans.GetWrappedWriteTrans(),
270                               syncable::CREATE_NEW_UPDATE_ITEM,
271                               syncable::Id::CreateFromServerId(
272                                   ModelTypeToString(type)));
273  if (!entry.good())
274    return false;
275
276  entry.PutParentId(syncable::Id());
277  entry.PutBaseVersion(1);
278  entry.PutUniqueServerTag(ModelTypeToRootTag(type));
279  entry.PutNonUniqueName(ModelTypeToString(type));
280  entry.PutIsDel(false);
281  entry.PutIsDir(true);
282
283  sync_pb::EntitySpecifics specifics;
284  AddDefaultFieldValue(type, &specifics);
285  entry.PutSpecifics(specifics);
286
287  return true;
288}
289
290void SyncRollbackManagerBase::InitBookmarkFolder(const std::string& folder) {
291  WriteTransaction trans(FROM_HERE, &share_);
292  syncable::Entry bookmark_root(trans.GetWrappedTrans(),
293                                syncable::GET_TYPE_ROOT,
294                                BOOKMARKS);
295  if (!bookmark_root.good())
296    return;
297
298  syncable::MutableEntry entry(trans.GetWrappedWriteTrans(),
299                               syncable::CREATE_NEW_UPDATE_ITEM,
300                               syncable::Id::CreateFromServerId(folder));
301  if (!entry.good())
302    return;
303
304  entry.PutParentId(bookmark_root.GetId());
305  entry.PutBaseVersion(1);
306  entry.PutUniqueServerTag(folder);
307  entry.PutNonUniqueName(folder);
308  entry.PutIsDel(false);
309  entry.PutIsDir(true);
310
311  sync_pb::EntitySpecifics specifics;
312  AddDefaultFieldValue(BOOKMARKS, &specifics);
313  entry.PutSpecifics(specifics);
314}
315
316ObserverList<SyncManager::Observer>* SyncRollbackManagerBase::GetObservers() {
317  return &observers_;
318}
319
320void SyncRollbackManagerBase::RegisterDirectoryTypeDebugInfoObserver(
321    syncer::TypeDebugInfoObserver* observer) {}
322
323void SyncRollbackManagerBase::UnregisterDirectoryTypeDebugInfoObserver(
324    syncer::TypeDebugInfoObserver* observer) {}
325
326bool SyncRollbackManagerBase::HasDirectoryTypeDebugInfoObserver(
327    syncer::TypeDebugInfoObserver* observer) { return false; }
328
329void SyncRollbackManagerBase::RequestEmitDebugInfo() {}
330
331}  // namespace syncer
332