Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: chrome/browser/sync/engine/process_updates_command.cc

Issue 9699057: [Sync] Move 'sync' target to sync/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Tim's comments Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "chrome/browser/sync/engine/process_updates_command.h"
6
7 #include <vector>
8
9 #include "base/basictypes.h"
10 #include "base/location.h"
11 #include "chrome/browser/sync/engine/syncer.h"
12 #include "chrome/browser/sync/engine/syncer_proto_util.h"
13 #include "chrome/browser/sync/engine/syncer_util.h"
14 #include "chrome/browser/sync/engine/syncproto.h"
15 #include "chrome/browser/sync/sessions/sync_session.h"
16 #include "chrome/browser/sync/syncable/syncable.h"
17 #include "chrome/browser/sync/util/cryptographer.h"
18
19 using std::vector;
20
21 namespace browser_sync {
22
23 using sessions::SyncSession;
24 using sessions::StatusController;
25 using sessions::UpdateProgress;
26
27 ProcessUpdatesCommand::ProcessUpdatesCommand() {}
28 ProcessUpdatesCommand::~ProcessUpdatesCommand() {}
29
30 std::set<ModelSafeGroup> ProcessUpdatesCommand::GetGroupsToChange(
31 const sessions::SyncSession& session) const {
32 return session.GetEnabledGroupsWithVerifiedUpdates();
33 }
34
35 SyncerError ProcessUpdatesCommand::ModelChangingExecuteImpl(
36 SyncSession* session) {
37 syncable::Directory* dir = session->context()->directory();
38
39 const sessions::UpdateProgress* progress =
40 session->status_controller().update_progress();
41 if (!progress)
42 return SYNCER_OK; // Nothing to do.
43
44 syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER, dir);
45 vector<sessions::VerifiedUpdate>::const_iterator it;
46 for (it = progress->VerifiedUpdatesBegin();
47 it != progress->VerifiedUpdatesEnd();
48 ++it) {
49 const sync_pb::SyncEntity& update = it->second;
50
51 if (it->first != VERIFY_SUCCESS && it->first != VERIFY_UNDELETE)
52 continue;
53 switch (ProcessUpdate(update,
54 dir->GetCryptographer(&trans),
55 &trans)) {
56 case SUCCESS_PROCESSED:
57 case SUCCESS_STORED:
58 break;
59 default:
60 NOTREACHED();
61 break;
62 }
63 }
64
65 StatusController* status = session->mutable_status_controller();
66 status->mutable_update_progress()->ClearVerifiedUpdates();
67 return SYNCER_OK;
68 }
69
70 namespace {
71 // Returns true if the entry is still ok to process.
72 bool ReverifyEntry(syncable::WriteTransaction* trans, const SyncEntity& entry,
73 syncable::MutableEntry* same_id) {
74
75 const bool deleted = entry.has_deleted() && entry.deleted();
76 const bool is_directory = entry.IsFolder();
77 const syncable::ModelType model_type = entry.GetModelType();
78
79 return VERIFY_SUCCESS == SyncerUtil::VerifyUpdateConsistency(trans,
80 entry,
81 same_id,
82 deleted,
83 is_directory,
84 model_type);
85 }
86 } // namespace
87
88 // Process a single update. Will avoid touching global state.
89 ServerUpdateProcessingResult ProcessUpdatesCommand::ProcessUpdate(
90 const sync_pb::SyncEntity& proto_update,
91 const Cryptographer* cryptographer,
92 syncable::WriteTransaction* const trans) {
93
94 const SyncEntity& update = *static_cast<const SyncEntity*>(&proto_update);
95 syncable::Id server_id = update.id();
96 const std::string name = SyncerProtoUtil::NameFromSyncEntity(update);
97
98 // Look to see if there's a local item that should recieve this update,
99 // maybe due to a duplicate client tag or a lost commit response.
100 syncable::Id local_id = SyncerUtil::FindLocalIdToUpdate(trans, update);
101
102 // FindLocalEntryToUpdate has veto power.
103 if (local_id.IsNull()) {
104 return SUCCESS_PROCESSED; // The entry has become irrelevant.
105 }
106
107 SyncerUtil::CreateNewEntry(trans, local_id);
108
109 // We take a two step approach. First we store the entries data in the
110 // server fields of a local entry and then move the data to the local fields
111 syncable::MutableEntry target_entry(trans, syncable::GET_BY_ID, local_id);
112
113 // We need to run the Verify checks again; the world could have changed
114 // since VerifyUpdatesCommand.
115 if (!ReverifyEntry(trans, update, &target_entry)) {
116 return SUCCESS_PROCESSED; // The entry has become irrelevant.
117 }
118
119 // If we're repurposing an existing local entry with a new server ID,
120 // change the ID now, after we're sure that the update can succeed.
121 if (local_id != server_id) {
122 DCHECK(!update.deleted());
123 SyncerUtil::ChangeEntryIDAndUpdateChildren(trans, &target_entry,
124 server_id);
125 // When IDs change, versions become irrelevant. Forcing BASE_VERSION
126 // to zero would ensure that this update gets applied, but would indicate
127 // creation or undeletion if it were committed that way. Instead, prefer
128 // forcing BASE_VERSION to entry.version() while also forcing
129 // IS_UNAPPLIED_UPDATE to true. If the item is UNSYNCED, it's committable
130 // from the new state; it may commit before the conflict resolver gets
131 // a crack at it.
132 if (target_entry.Get(syncable::IS_UNSYNCED) ||
133 target_entry.Get(syncable::BASE_VERSION) > 0) {
134 // If either of these conditions are met, then we can expect valid client
135 // fields for this entry. When BASE_VERSION is positive, consistency is
136 // enforced on the client fields at update-application time. Otherwise,
137 // we leave the BASE_VERSION field alone; it'll get updated the first time
138 // we successfully apply this update.
139 target_entry.Put(syncable::BASE_VERSION, update.version());
140 }
141 // Force application of this update, no matter what.
142 target_entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
143 }
144
145 // If this is a newly received undecryptable update, and the only thing that
146 // has changed are the specifics, store the original decryptable specifics,
147 // (on which any current or future local changes are based) before we
148 // overwrite SERVER_SPECIFICS.
149 // MTIME, CTIME, and NON_UNIQUE_NAME are not enforced.
150 if (!update.deleted() && !target_entry.Get(syncable::SERVER_IS_DEL) &&
151 (update.parent_id() == target_entry.Get(syncable::SERVER_PARENT_ID)) &&
152 (update.position_in_parent() ==
153 target_entry.Get(syncable::SERVER_POSITION_IN_PARENT)) &&
154 update.has_specifics() && update.specifics().has_encrypted() &&
155 !cryptographer->CanDecrypt(update.specifics().encrypted())) {
156 sync_pb::EntitySpecifics prev_specifics =
157 target_entry.Get(syncable::SERVER_SPECIFICS);
158 // We only store the old specifics if they were decryptable and applied and
159 // there is no BASE_SERVER_SPECIFICS already. Else do nothing.
160 if (!target_entry.Get(syncable::IS_UNAPPLIED_UPDATE) &&
161 !syncable::IsRealDataType(syncable::GetModelTypeFromSpecifics(
162 target_entry.Get(syncable::BASE_SERVER_SPECIFICS))) &&
163 (!prev_specifics.has_encrypted() ||
164 cryptographer->CanDecrypt(prev_specifics.encrypted()))) {
165 DVLOG(2) << "Storing previous server specifcs: "
166 << prev_specifics.SerializeAsString();
167 target_entry.Put(syncable::BASE_SERVER_SPECIFICS, prev_specifics);
168 }
169 } else if (syncable::IsRealDataType(syncable::GetModelTypeFromSpecifics(
170 target_entry.Get(syncable::BASE_SERVER_SPECIFICS)))) {
171 // We have a BASE_SERVER_SPECIFICS, but a subsequent non-specifics-only
172 // change arrived. As a result, we can't use the specifics alone to detect
173 // changes, so we clear BASE_SERVER_SPECIFICS.
174 target_entry.Put(syncable::BASE_SERVER_SPECIFICS,
175 sync_pb::EntitySpecifics());
176 }
177
178 SyncerUtil::UpdateServerFieldsFromUpdate(&target_entry, update, name);
179
180 return SUCCESS_PROCESSED;
181 }
182
183 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/process_updates_command.h ('k') | chrome/browser/sync/engine/process_updates_command_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698