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

Side by Side Diff: chrome/browser/sync/glue/bookmark_change_processor.cc

Issue 11341048: Populate versions on individual nodes in sync model and native bookmark model. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: lock dir Created 8 years, 1 month 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/glue/bookmark_change_processor.h" 5 #include "chrome/browser/sync/glue/bookmark_change_processor.h"
6 6
7 #include <stack> 7 #include <stack>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 } 106 }
107 // This node should have no children. 107 // This node should have no children.
108 DCHECK(!sync_node.HasChildren()); 108 DCHECK(!sync_node.HasChildren());
109 // Remove association and delete the sync node. 109 // Remove association and delete the sync node.
110 model_associator_->Disassociate(sync_node.GetId()); 110 model_associator_->Disassociate(sync_node.GetId());
111 sync_node.Remove(); 111 sync_node.Remove();
112 } 112 }
113 113
114 void BookmarkChangeProcessor::RemoveSyncNodeHierarchy( 114 void BookmarkChangeProcessor::RemoveSyncNodeHierarchy(
115 const BookmarkNode* topmost) { 115 const BookmarkNode* topmost) {
116 syncer::WriteTransaction trans(FROM_HERE, share_handle()); 116 int64 new_version = -1;
117 {
118 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version);
117 119
118 // Later logic assumes that |topmost| has been unlinked. 120 // Later logic assumes that |topmost| has been unlinked.
119 DCHECK(topmost->is_root()); 121 DCHECK(topmost->is_root());
120 122
121 // A BookmarkModel deletion event means that |node| and all its children were 123 // A BookmarkModel deletion event means that |node| and all its children
122 // deleted. Sync backend expects children to be deleted individually, so we do 124 // were deleted. Sync backend expects children to be deleted individually,
123 // a depth-first-search here. At each step, we consider the |index|-th child 125 // so we do a depth-first-search here. At each step, we consider the
124 // of |node|. |index_stack| stores index values for the parent levels. 126 // |index|-th child of |node|. |index_stack| stores index values for the
125 std::stack<int> index_stack; 127 // parent levels.
126 index_stack.push(0); // For the final pop. It's never used. 128 std::stack<int> index_stack;
127 const BookmarkNode* node = topmost; 129 index_stack.push(0); // For the final pop. It's never used.
128 int index = 0; 130 const BookmarkNode* node = topmost;
129 while (node) { 131 int index = 0;
130 // The top of |index_stack| should always be |node|'s index. 132 while (node) {
131 DCHECK(node->is_root() || (node->parent()->GetIndexOf(node) == 133 // The top of |index_stack| should always be |node|'s index.
132 index_stack.top())); 134 DCHECK(node->is_root() || (node->parent()->GetIndexOf(node) ==
133 if (index == node->child_count()) { 135 index_stack.top()));
134 // If we've processed all of |node|'s children, delete |node| and move 136 if (index == node->child_count()) {
135 // on to its successor. 137 // If we've processed all of |node|'s children, delete |node| and move
136 RemoveOneSyncNode(&trans, node); 138 // on to its successor.
137 node = node->parent(); 139 RemoveOneSyncNode(&trans, node);
138 index = index_stack.top() + 1; // (top() + 0) was what we removed. 140 node = node->parent();
139 index_stack.pop(); 141 index = index_stack.top() + 1; // (top() + 0) was what we removed.
140 } else { 142 index_stack.pop();
141 // If |node| has an unprocessed child, process it next after pushing the 143 } else {
142 // current state onto the stack. 144 // If |node| has an unprocessed child, process it next after pushing the
143 DCHECK_LT(index, node->child_count()); 145 // current state onto the stack.
144 index_stack.push(index); 146 DCHECK_LT(index, node->child_count());
145 node = node->GetChild(index); 147 index_stack.push(index);
146 index = 0; 148 node = node->GetChild(index);
149 index = 0;
150 }
147 } 151 }
152 DCHECK(index_stack.empty()); // Nothing should be left on the stack.
148 } 153 }
149 DCHECK(index_stack.empty()); // Nothing should be left on the stack. 154
155 // Don't need to update versions of deleted nodes.
156 UpdateTransactionVersion(new_version, bookmark_model_,
157 std::vector<const BookmarkNode*>());
150 } 158 }
151 159
152 void BookmarkChangeProcessor::Loaded(BookmarkModel* model, 160 void BookmarkChangeProcessor::Loaded(BookmarkModel* model,
153 bool ids_reassigned) { 161 bool ids_reassigned) {
154 NOTREACHED(); 162 NOTREACHED();
155 } 163 }
156 164
157 void BookmarkChangeProcessor::BookmarkModelBeingDeleted( 165 void BookmarkChangeProcessor::BookmarkModelBeingDeleted(
158 BookmarkModel* model) { 166 BookmarkModel* model) {
159 NOTREACHED(); 167 NOTREACHED();
160 bookmark_model_ = NULL; 168 bookmark_model_ = NULL;
161 } 169 }
162 170
163 void BookmarkChangeProcessor::BookmarkNodeAdded(BookmarkModel* model, 171 void BookmarkChangeProcessor::BookmarkNodeAdded(BookmarkModel* model,
164 const BookmarkNode* parent, 172 const BookmarkNode* parent,
165 int index) { 173 int index) {
166 DCHECK(share_handle()); 174 DCHECK(share_handle());
167 175
168 // Acquire a scoped write lock via a transaction. 176 int64 new_version = -1;
169 syncer::WriteTransaction trans(FROM_HERE, share_handle()); 177 int64 sync_id = syncer::kInvalidId;
178 {
179 // Acquire a scoped write lock via a transaction.
180 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version);
181 sync_id = CreateSyncNode(parent, model, index, &trans,
182 model_associator_, error_handler());
183 }
170 184
171 CreateSyncNode(parent, model, index, &trans, model_associator_, 185 if (syncer::kInvalidId != sync_id) {
172 error_handler()); 186 // NOTE(haitaol): Siblings of added node in sync DB will also be updated to
Nicolas Zea 2012/11/02 21:02:25 I don't think you need to mark this as a note for
haitaol1 2012/11/02 22:58:18 Done.
187 // reflect new PREV_ID/NEXT_ID and thus get a new version.
188 // But we only update version of added node here. After
189 // switching to ordinals for positioning, PREV_ID/NEXT_ID
190 // will be deprecated and siblings will not be updated.
191 UpdateTransactionVersion(
192 new_version, model,
193 std::vector<const BookmarkNode*>(1, parent->GetChild(index)));
194 }
173 } 195 }
174 196
175 // static 197 // static
176 int64 BookmarkChangeProcessor::CreateSyncNode(const BookmarkNode* parent, 198 int64 BookmarkChangeProcessor::CreateSyncNode(const BookmarkNode* parent,
177 BookmarkModel* model, int index, syncer::WriteTransaction* trans, 199 BookmarkModel* model, int index, syncer::WriteTransaction* trans,
178 BookmarkModelAssociator* associator, 200 BookmarkModelAssociator* associator,
179 DataTypeErrorHandler* error_handler) { 201 DataTypeErrorHandler* error_handler) {
180 const BookmarkNode* child = parent->GetChild(index); 202 const BookmarkNode* child = parent->GetChild(index);
181 DCHECK(child); 203 DCHECK(child);
182 204
183 // Create a WriteNode container to hold the new node. 205 // Create a WriteNode container to hold the new node.
184 syncer::WriteNode sync_child(trans); 206 syncer::WriteNode sync_child(trans);
185 207
186 // Actually create the node with the appropriate initial position. 208 // Actually create the node with the appropriate initial position.
187 if (!PlaceSyncNode(CREATE, parent, index, trans, &sync_child, associator)) { 209 if (!PlaceSyncNode(CREATE, parent, index, trans, &sync_child, associator)) {
188 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, 210 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE,
189 "Sync node creation failed; recovery unlikely"); 211 "Sync node creation failed; recovery unlikely");
190 return syncer::kInvalidId; 212 return syncer::kInvalidId;
191 } 213 }
192 214
193 UpdateSyncNodeProperties(child, model, &sync_child); 215 UpdateSyncNodeProperties(child, model, &sync_child);
194 216
195 // Associate the ID from the sync domain with the bookmark node, so that we 217 // Associate the ID from the sync domain with the bookmark node, so that we
196 // can refer back to this item later. 218 // can refer back to this item later.
197 associator->Associate(child, sync_child.GetId()); 219 associator->Associate(child, sync_child.GetId());
198 220
199 return sync_child.GetId(); 221 return sync_child.GetId();
200 } 222 }
201 223
202
203 void BookmarkChangeProcessor::BookmarkNodeRemoved(BookmarkModel* model, 224 void BookmarkChangeProcessor::BookmarkNodeRemoved(BookmarkModel* model,
204 const BookmarkNode* parent, 225 const BookmarkNode* parent,
Nicolas Zea 2012/11/02 21:02:25 fix indent
haitaol1 2012/11/02 22:58:18 This looks fine on my desktop and I verified that
205 int index, 226 int index,
206 const BookmarkNode* node) { 227 const BookmarkNode* node) {
207 RemoveSyncNodeHierarchy(node); 228 RemoveSyncNodeHierarchy(node);
208 } 229 }
209 230
210 void BookmarkChangeProcessor::BookmarkNodeChanged(BookmarkModel* model, 231 void BookmarkChangeProcessor::BookmarkNodeChanged(BookmarkModel* model,
211 const BookmarkNode* node) { 232 const BookmarkNode* node) {
212 // We shouldn't see changes to the top-level nodes. 233 // We shouldn't see changes to the top-level nodes.
213 if (model->is_permanent_node(node)) { 234 if (model->is_permanent_node(node)) {
214 NOTREACHED() << "Saw update to permanent node!"; 235 NOTREACHED() << "Saw update to permanent node!";
215 return; 236 return;
216 } 237 }
217 238
218 // Acquire a scoped write lock via a transaction. 239 int64 new_version = -1;
219 syncer::WriteTransaction trans(FROM_HERE, share_handle()); 240 {
241 // Acquire a scoped write lock via a transaction.
242 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version);
220 243
221 // Lookup the sync node that's associated with |node|. 244 // Lookup the sync node that's associated with |node|.
222 syncer::WriteNode sync_node(&trans); 245 syncer::WriteNode sync_node(&trans);
223 if (!model_associator_->InitSyncNodeFromChromeId(node->id(), &sync_node)) { 246 if (!model_associator_->InitSyncNodeFromChromeId(node->id(), &sync_node)) {
224 // TODO(tim): Investigating bug 121587. 247 // TODO(tim): Investigating bug 121587.
225 if (model_associator_->GetSyncIdFromChromeId(node->id()) == 248 if (model_associator_->GetSyncIdFromChromeId(node->id()) ==
226 syncer::kInvalidId) { 249 syncer::kInvalidId) {
227 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
228 "Bookmark id not found in model associator on BookmarkNodeChanged");
229 LOG(ERROR) << "Bad id.";
230 } else if (!sync_node.GetEntry()->good()) {
231 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
232 "Could not InitByIdLookup on BookmarkNodeChanged, good() failed");
233 LOG(ERROR) << "Bad entry.";
234 } else if (sync_node.GetEntry()->Get(syncer::syncable::IS_DEL)) {
235 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
236 "Could not InitByIdLookup on BookmarkNodeChanged, is_del true");
237 LOG(ERROR) << "Deleted entry.";
238 } else {
239 syncer::Cryptographer* crypto = trans.GetCryptographer();
240 syncer::ModelTypeSet encrypted_types(trans.GetEncryptedTypes());
241 const sync_pb::EntitySpecifics& specifics =
242 sync_node.GetEntry()->Get(syncer::syncable::SPECIFICS);
243 CHECK(specifics.has_encrypted());
244 const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted());
245 const bool agreement = encrypted_types.Has(syncer::BOOKMARKS);
246 if (!agreement && !can_decrypt) {
247 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 250 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
248 "Could not InitByIdLookup on BookmarkNodeChanged, " 251 "Bookmark id not found in model associator on BookmarkNodeChanged");
249 " Cryptographer thinks bookmarks not encrypted, and CanDecrypt" 252 LOG(ERROR) << "Bad id.";
250 " failed."); 253 } else if (!sync_node.GetEntry()->good()) {
251 LOG(ERROR) << "Case 1.";
252 } else if (agreement && can_decrypt) {
253 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 254 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
254 "Could not InitByIdLookup on BookmarkNodeChanged, " 255 "Could not InitByIdLookup on BookmarkNodeChanged, good() failed");
255 " Cryptographer thinks bookmarks are encrypted, and CanDecrypt" 256 LOG(ERROR) << "Bad entry.";
256 " succeeded (?!), but DecryptIfNecessary failed."); 257 } else if (sync_node.GetEntry()->Get(syncer::syncable::IS_DEL)) {
257 LOG(ERROR) << "Case 2.";
258 } else if (agreement) {
259 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 258 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
260 "Could not InitByIdLookup on BookmarkNodeChanged, " 259 "Could not InitByIdLookup on BookmarkNodeChanged, is_del true");
261 " Cryptographer thinks bookmarks are encrypted, but CanDecrypt" 260 LOG(ERROR) << "Deleted entry.";
262 " failed.");
263 LOG(ERROR) << "Case 3.";
264 } else { 261 } else {
265 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 262 syncer::Cryptographer* crypto = trans.GetCryptographer();
266 "Could not InitByIdLookup on BookmarkNodeChanged, " 263 syncer::ModelTypeSet encrypted_types(trans.GetEncryptedTypes());
267 " Cryptographer thinks bookmarks not encrypted, but CanDecrypt" 264 const sync_pb::EntitySpecifics& specifics =
268 " succeeded (super weird, btw)"); 265 sync_node.GetEntry()->Get(syncer::syncable::SPECIFICS);
269 LOG(ERROR) << "Case 4."; 266 CHECK(specifics.has_encrypted());
267 const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted());
268 const bool agreement = encrypted_types.Has(syncer::BOOKMARKS);
269 if (!agreement && !can_decrypt) {
270 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
271 "Could not InitByIdLookup on BookmarkNodeChanged, "
272 " Cryptographer thinks bookmarks not encrypted, and CanDecrypt"
273 " failed.");
274 LOG(ERROR) << "Case 1.";
275 } else if (agreement && can_decrypt) {
276 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
277 "Could not InitByIdLookup on BookmarkNodeChanged, "
278 " Cryptographer thinks bookmarks are encrypted, and CanDecrypt"
279 " succeeded (?!), but DecryptIfNecessary failed.");
280 LOG(ERROR) << "Case 2.";
281 } else if (agreement) {
282 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
283 "Could not InitByIdLookup on BookmarkNodeChanged, "
284 " Cryptographer thinks bookmarks are encrypted, but CanDecrypt"
285 " failed.");
286 LOG(ERROR) << "Case 3.";
287 } else {
288 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
289 "Could not InitByIdLookup on BookmarkNodeChanged, "
290 " Cryptographer thinks bookmarks not encrypted, but CanDecrypt"
291 " succeeded (super weird, btw)");
292 LOG(ERROR) << "Case 4.";
293 }
270 } 294 }
295 return;
271 } 296 }
272 return; 297
298 UpdateSyncNodeProperties(node, model, &sync_node);
299
300 DCHECK_EQ(sync_node.GetIsFolder(), node->is_folder());
301 DCHECK_EQ(model_associator_->GetChromeNodeFromSyncId(
302 sync_node.GetParentId()),
303 node->parent());
304 // This node's index should be one more than the predecessor's index.
305 DCHECK_EQ(node->parent()->GetIndexOf(node),
306 CalculateBookmarkModelInsertionIndex(node->parent(),
307 &sync_node,
308 model_associator_));
273 } 309 }
274 310
275 UpdateSyncNodeProperties(node, model, &sync_node); 311 UpdateTransactionVersion(new_version, model,
276 312 std::vector<const BookmarkNode*>(1, node));
277 DCHECK_EQ(sync_node.GetIsFolder(), node->is_folder());
278 DCHECK_EQ(model_associator_->GetChromeNodeFromSyncId(
279 sync_node.GetParentId()),
280 node->parent());
281 // This node's index should be one more than the predecessor's index.
282 DCHECK_EQ(node->parent()->GetIndexOf(node),
283 CalculateBookmarkModelInsertionIndex(node->parent(),
284 &sync_node,
285 model_associator_));
286 } 313 }
287 314
288
289 void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model, 315 void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model,
290 const BookmarkNode* old_parent, int old_index, 316 const BookmarkNode* old_parent, int old_index,
291 const BookmarkNode* new_parent, int new_index) { 317 const BookmarkNode* new_parent, int new_index) {
292 const BookmarkNode* child = new_parent->GetChild(new_index); 318 const BookmarkNode* child = new_parent->GetChild(new_index);
293 // We shouldn't see changes to the top-level nodes. 319 // We shouldn't see changes to the top-level nodes.
294 if (model->is_permanent_node(child)) { 320 if (model->is_permanent_node(child)) {
295 NOTREACHED() << "Saw update to permanent node!"; 321 NOTREACHED() << "Saw update to permanent node!";
296 return; 322 return;
297 } 323 }
298 324
299 // Acquire a scoped write lock via a transaction. 325 int64 new_version = -1;
300 syncer::WriteTransaction trans(FROM_HERE, share_handle()); 326 {
327 // Acquire a scoped write lock via a transaction.
328 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version);
301 329
302 // Lookup the sync node that's associated with |child|. 330 // Lookup the sync node that's associated with |child|.
303 syncer::WriteNode sync_node(&trans); 331 syncer::WriteNode sync_node(&trans);
304 if (!model_associator_->InitSyncNodeFromChromeId(child->id(), &sync_node)) { 332 if (!model_associator_->InitSyncNodeFromChromeId(child->id(), &sync_node)) {
305 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 333 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
306 std::string()); 334 std::string());
307 return; 335 return;
336 }
337
338 if (!PlaceSyncNode(MOVE, new_parent, new_index, &trans, &sync_node,
339 model_associator_)) {
340 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
341 std::string());
342 return;
343 }
308 } 344 }
309 345
310 if (!PlaceSyncNode(MOVE, new_parent, new_index, &trans, &sync_node, 346 UpdateTransactionVersion(new_version, model,
311 model_associator_)) { 347 std::vector<const BookmarkNode*>(1, child));
312 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
313 std::string());
314 return;
315 }
316 } 348 }
317 349
318 void BookmarkChangeProcessor::BookmarkNodeFaviconChanged( 350 void BookmarkChangeProcessor::BookmarkNodeFaviconChanged(
319 BookmarkModel* model, 351 BookmarkModel* model,
320 const BookmarkNode* node) { 352 const BookmarkNode* node) {
321 BookmarkNodeChanged(model, node); 353 BookmarkNodeChanged(model, node);
322 } 354 }
323 355
324 void BookmarkChangeProcessor::BookmarkNodeChildrenReordered( 356 void BookmarkChangeProcessor::BookmarkNodeChildrenReordered(
325 BookmarkModel* model, const BookmarkNode* node) { 357 BookmarkModel* model, const BookmarkNode* node) {
358 int64 new_version = -1;
359 std::vector<const BookmarkNode*> children;
360 {
361 // Acquire a scoped write lock via a transaction.
362 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version);
326 363
327 // Acquire a scoped write lock via a transaction. 364 // The given node's children got reordered. We need to reorder all the
328 syncer::WriteTransaction trans(FROM_HERE, share_handle()); 365 // children of the corresponding sync node.
366 for (int i = 0; i < node->child_count(); ++i) {
367 const BookmarkNode* child = node->GetChild(i);
368 children.push_back(child);
329 369
330 // The given node's children got reordered. We need to reorder all the 370 syncer::WriteNode sync_child(&trans);
331 // children of the corresponding sync node. 371 if (!model_associator_->InitSyncNodeFromChromeId(child->id(),
332 for (int i = 0; i < node->child_count(); ++i) { 372 &sync_child)) {
333 syncer::WriteNode sync_child(&trans); 373 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
334 if (!model_associator_->InitSyncNodeFromChromeId(node->GetChild(i)->id(), 374 std::string());
335 &sync_child)) { 375 return;
336 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 376 }
337 std::string()); 377 DCHECK_EQ(sync_child.GetParentId(),
338 return; 378 model_associator_->GetSyncIdFromChromeId(node->id()));
339 }
340 DCHECK_EQ(sync_child.GetParentId(),
341 model_associator_->GetSyncIdFromChromeId(node->id()));
342 379
343 if (!PlaceSyncNode(MOVE, node, i, &trans, &sync_child, 380 if (!PlaceSyncNode(MOVE, node, i, &trans, &sync_child,
344 model_associator_)) { 381 model_associator_)) {
345 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 382 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
346 std::string()); 383 std::string());
347 return; 384 return;
385 }
348 } 386 }
349 } 387 }
388
389 // TODO(haitaol): Filter out children that didn't actually change.
390 UpdateTransactionVersion(new_version, model, children);
350 } 391 }
351 392
352 // static 393 // static
353 bool BookmarkChangeProcessor::PlaceSyncNode(MoveOrCreate operation, 394 bool BookmarkChangeProcessor::PlaceSyncNode(MoveOrCreate operation,
354 const BookmarkNode* parent, int index, syncer::WriteTransaction* trans, 395 const BookmarkNode* parent, int index, syncer::WriteTransaction* trans,
355 syncer::WriteNode* dst, BookmarkModelAssociator* associator) { 396 syncer::WriteNode* dst, BookmarkModelAssociator* associator) {
356 syncer::ReadNode sync_parent(trans); 397 syncer::ReadNode sync_parent(trans);
357 if (!associator->InitSyncNodeFromChromeId(parent->id(), &sync_parent)) { 398 if (!associator->InitSyncNodeFromChromeId(parent->id(), &sync_parent)) {
358 LOG(WARNING) << "Parent lookup failed"; 399 LOG(WARNING) << "Parent lookup failed";
359 return false; 400 return false;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 << "ACTION_ADD should be seen if and only if the node is unknown."; 539 << "ACTION_ADD should be seen if and only if the node is unknown.";
499 passed_deletes = true; 540 passed_deletes = true;
500 541
501 syncer::ReadNode src(trans); 542 syncer::ReadNode src(trans);
502 if (src.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) { 543 if (src.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) {
503 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 544 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
504 "ApplyModelChanges was passed a bad ID"); 545 "ApplyModelChanges was passed a bad ID");
505 return; 546 return;
506 } 547 }
507 548
508 if (!CreateOrUpdateBookmarkNode(&src, model, model_associator_)) { 549 const BookmarkNode* node = CreateOrUpdateBookmarkNode(&src, model,
550 model_associator_);
551 if (node) {
552 bookmark_model_->SetNodeMetaInfo(node, kBookmarkTransactionVersionKey,
553 base::Int64ToString(model_version));
554 } else {
509 // Because the Synced Bookmarks node can be created server side, it's 555 // Because the Synced Bookmarks node can be created server side, it's
510 // possible it'll arrive at the client as an update. In that case it 556 // possible it'll arrive at the client as an update. In that case it
511 // won't have been associated at startup, the GetChromeNodeFromSyncId 557 // won't have been associated at startup, the GetChromeNodeFromSyncId
512 // call above will return NULL, and we won't detect it as a permanent 558 // call above will return NULL, and we won't detect it as a permanent
513 // node, resulting in us trying to create it here (which will 559 // node, resulting in us trying to create it here (which will
514 // fail). Therefore, we add special logic here just to detect the 560 // fail). Therefore, we add special logic here just to detect the
515 // Synced Bookmarks folder. 561 // Synced Bookmarks folder.
516 syncer::ReadNode synced_bookmarks(trans); 562 syncer::ReadNode synced_bookmarks(trans);
517 if (synced_bookmarks.InitByTagLookup(kMobileBookmarksTag) == 563 if (synced_bookmarks.InitByTagLookup(kMobileBookmarksTag) ==
518 syncer::BaseNode::INIT_OK && 564 syncer::BaseNode::INIT_OK &&
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 base::Time::FromInternalValue( 637 base::Time::FromInternalValue(
592 src->GetBookmarkSpecifics().creation_time_us())); 638 src->GetBookmarkSpecifics().creation_time_us()));
593 } 639 }
594 640
595 SetBookmarkFavicon(src, dst, model); 641 SetBookmarkFavicon(src, dst, model);
596 } 642 }
597 643
598 return dst; 644 return dst;
599 } 645 }
600 646
647 void BookmarkChangeProcessor::UpdateTransactionVersion(
648 int64 new_version,
649 BookmarkModel* model,
650 const std::vector<const BookmarkNode*>& nodes) {
651 if (new_version > 0) {
Nicolas Zea 2012/11/02 21:02:25 is it possible to verify that new_version is > exi
haitaol1 2012/11/02 22:58:18 To do that, I'll need to query old version after t
652 model->SetNodeMetaInfo(model->root_node(), kBookmarkTransactionVersionKey,
653 base::Int64ToString(new_version));
654 for (uint32 i = 0; i < nodes.size(); ++i) {
655 model->SetNodeMetaInfo(nodes[i], kBookmarkTransactionVersionKey,
656 base::Int64ToString(new_version));
657 }
658 }
659 }
660
601 // static 661 // static
602 // Creates a bookmark node under the given parent node from the given sync 662 // Creates a bookmark node under the given parent node from the given sync
603 // node. Returns the newly created node. 663 // node. Returns the newly created node.
604 const BookmarkNode* BookmarkChangeProcessor::CreateBookmarkNode( 664 const BookmarkNode* BookmarkChangeProcessor::CreateBookmarkNode(
605 syncer::BaseNode* sync_node, 665 syncer::BaseNode* sync_node,
606 const BookmarkNode* parent, 666 const BookmarkNode* parent,
607 BookmarkModel* model, 667 BookmarkModel* model,
608 int index) { 668 int index) {
609 DCHECK(parent); 669 DCHECK(parent);
610 DCHECK(index >= 0 && index <= parent->child_count()); 670 DCHECK(index >= 0 && index <= parent->child_count());
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 const BookmarkNode* bookmark_node, 736 const BookmarkNode* bookmark_node,
677 BookmarkModel* model, 737 BookmarkModel* model,
678 syncer::WriteNode* sync_node) { 738 syncer::WriteNode* sync_node) {
679 std::vector<unsigned char> favicon_bytes; 739 std::vector<unsigned char> favicon_bytes;
680 EncodeFavicon(bookmark_node, model, &favicon_bytes); 740 EncodeFavicon(bookmark_node, model, &favicon_bytes);
681 if (!favicon_bytes.empty()) 741 if (!favicon_bytes.empty())
682 sync_node->SetFaviconBytes(favicon_bytes); 742 sync_node->SetFaviconBytes(favicon_bytes);
683 } 743 }
684 744
685 } // namespace browser_sync 745 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698