• 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_backup_manager.h"
6 
7 #include "sync/internal_api/public/read_node.h"
8 #include "sync/internal_api/public/write_transaction.h"
9 #include "sync/syncable/directory.h"
10 #include "sync/syncable/mutable_entry.h"
11 #include "url/gurl.h"
12 
13 namespace syncer {
14 
SyncBackupManager()15 SyncBackupManager::SyncBackupManager()
16     : in_normalization_(false) {
17 }
18 
~SyncBackupManager()19 SyncBackupManager::~SyncBackupManager() {
20 }
21 
Init(InitArgs * args)22 void SyncBackupManager::Init(InitArgs* args) {
23   if (SyncRollbackManagerBase::InitInternal(
24           args->database_location,
25           args->internal_components_factory.get(),
26           InternalComponentsFactory::STORAGE_ON_DISK_DEFERRED,
27           args->unrecoverable_error_handler.Pass(),
28           args->report_unrecoverable_error_function)) {
29     GetUserShare()->directory->CollectMetaHandleCounts(
30         &status_.num_entries_by_type, &status_.num_to_delete_entries_by_type);
31 
32     HideSyncPreference(PRIORITY_PREFERENCES);
33     HideSyncPreference(PREFERENCES);
34   }
35 }
36 
SaveChanges()37 void SyncBackupManager::SaveChanges() {
38   if (initialized())
39     NormalizeEntries();
40 }
41 
GetDetailedStatus() const42 SyncStatus SyncBackupManager::GetDetailedStatus() const {
43   return status_;
44 }
45 
HandleTransactionEndingChangeEvent(const syncable::ImmutableWriteTransactionInfo & write_transaction_info,syncable::BaseTransaction * trans)46 ModelTypeSet SyncBackupManager::HandleTransactionEndingChangeEvent(
47     const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
48     syncable::BaseTransaction* trans) {
49   ModelTypeSet types;
50   if (in_normalization_) {
51     // Skip if in our own WriteTransaction from NormalizeEntries().
52     in_normalization_ = false;
53     return types;
54   }
55 
56   for (syncable::EntryKernelMutationMap::const_iterator it =
57       write_transaction_info.Get().mutations.Get().begin();
58       it != write_transaction_info.Get().mutations.Get().end(); ++it) {
59     int64 id = it->first;
60     if (unsynced_.find(id) == unsynced_.end()) {
61       unsynced_.insert(id);
62 
63       const syncable::EntryKernel& e = it->second.mutated;
64       ModelType type = e.GetModelType();
65       types.Put(type);
66       if (!e.ref(syncable::ID).ServerKnows())
67         status_.num_entries_by_type[type]++;
68       if (e.ref(syncable::IS_DEL))
69         status_.num_to_delete_entries_by_type[type]++;
70     }
71   }
72   return types;
73 }
74 
NormalizeEntries()75 void SyncBackupManager::NormalizeEntries() {
76   WriteTransaction trans(FROM_HERE, GetUserShare());
77   in_normalization_ = true;
78   for (std::set<int64>::const_iterator it = unsynced_.begin();
79       it != unsynced_.end(); ++it) {
80     syncable::MutableEntry entry(trans.GetWrappedWriteTrans(),
81                                  syncable::GET_BY_HANDLE, *it);
82     CHECK(entry.good());
83 
84     if (!entry.GetId().ServerKnows())
85       entry.PutId(syncable::Id::CreateFromServerId(entry.GetId().value()));
86     if (!entry.GetParentId().ServerKnows()) {
87       entry.PutParentIdPropertyOnly(syncable::Id::CreateFromServerId(
88           entry.GetParentId().value()));
89     }
90     entry.PutBaseVersion(1);
91     entry.PutIsUnsynced(false);
92   }
93   unsynced_.clear();
94 }
95 
HideSyncPreference(ModelType type)96 void SyncBackupManager::HideSyncPreference(ModelType type) {
97   WriteTransaction trans(FROM_HERE, GetUserShare());
98   ReadNode pref_root(&trans);
99   if (BaseNode::INIT_OK != pref_root.InitTypeRoot(type))
100     return;
101 
102   std::vector<int64> pref_ids;
103   pref_root.GetChildIds(&pref_ids);
104   for (uint32 i = 0; i < pref_ids.size(); ++i) {
105     syncable::MutableEntry entry(trans.GetWrappedWriteTrans(),
106                                  syncable::GET_BY_HANDLE, pref_ids[i]);
107     if (entry.good()) {
108       // HACKY: Set IS_DEL to true to remove entry from parent-children
109       // index so that it's not returned when syncable service asks
110       // for sync data. Syncable service then creates entry for local
111       // model. Then the existing entry is undeleted and set to local value
112       // because it has the same unique client tag.
113       entry.PutIsDel(true);
114       entry.PutIsUnsynced(false);
115 
116       // Don't persist on disk so that if backup is aborted before receiving
117       // local preference values, values in sync DB are saved.
118       GetUserShare()->directory->UnmarkDirtyEntry(
119           trans.GetWrappedWriteTrans(), &entry);
120     }
121   }
122 }
123 
ShutdownOnSyncThread(ShutdownReason reason)124 void SyncBackupManager::ShutdownOnSyncThread(ShutdownReason reason) {
125   if (reason == SWITCH_MODE_SYNC) {
126     NormalizeEntries();
127     GetUserShare()->directory->SaveChanges();
128   }
129 
130   SyncRollbackManagerBase::ShutdownOnSyncThread(reason);
131 }
132 
RegisterDirectoryTypeDebugInfoObserver(syncer::TypeDebugInfoObserver * observer)133 void SyncBackupManager::RegisterDirectoryTypeDebugInfoObserver(
134     syncer::TypeDebugInfoObserver* observer) {}
135 
UnregisterDirectoryTypeDebugInfoObserver(syncer::TypeDebugInfoObserver * observer)136 void SyncBackupManager::UnregisterDirectoryTypeDebugInfoObserver(
137     syncer::TypeDebugInfoObserver* observer) {}
138 
HasDirectoryTypeDebugInfoObserver(syncer::TypeDebugInfoObserver * observer)139 bool SyncBackupManager::HasDirectoryTypeDebugInfoObserver(
140     syncer::TypeDebugInfoObserver* observer) { return false; }
141 
RequestEmitDebugInfo()142 void SyncBackupManager::RequestEmitDebugInfo() {}
143 
144 }  // namespace syncer
145