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

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: 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 // Siblings of added node in sync DB will also be updated to reflect new
187 // PREV_ID/NEXT_ID and thus get a new version. But we only update version
188 // of added node here. After switching to ordinals for positioning,
189 // PREV_ID/NEXT_ID will be deprecated and siblings will not be updated.
190 UpdateTransactionVersion(
191 new_version, model,
192 std::vector<const BookmarkNode*>(1, parent->GetChild(index)));
193 }
173 } 194 }
174 195
175 // static 196 // static
176 int64 BookmarkChangeProcessor::CreateSyncNode(const BookmarkNode* parent, 197 int64 BookmarkChangeProcessor::CreateSyncNode(const BookmarkNode* parent,
177 BookmarkModel* model, int index, syncer::WriteTransaction* trans, 198 BookmarkModel* model, int index, syncer::WriteTransaction* trans,
178 BookmarkModelAssociator* associator, 199 BookmarkModelAssociator* associator,
179 DataTypeErrorHandler* error_handler) { 200 DataTypeErrorHandler* error_handler) {
180 const BookmarkNode* child = parent->GetChild(index); 201 const BookmarkNode* child = parent->GetChild(index);
181 DCHECK(child); 202 DCHECK(child);
182 203
183 // Create a WriteNode container to hold the new node. 204 // Create a WriteNode container to hold the new node.
184 syncer::WriteNode sync_child(trans); 205 syncer::WriteNode sync_child(trans);
185 206
186 // Actually create the node with the appropriate initial position. 207 // Actually create the node with the appropriate initial position.
187 if (!PlaceSyncNode(CREATE, parent, index, trans, &sync_child, associator)) { 208 if (!PlaceSyncNode(CREATE, parent, index, trans, &sync_child, associator)) {
188 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE, 209 error_handler->OnSingleDatatypeUnrecoverableError(FROM_HERE,
189 "Sync node creation failed; recovery unlikely"); 210 "Sync node creation failed; recovery unlikely");
190 return syncer::kInvalidId; 211 return syncer::kInvalidId;
191 } 212 }
192 213
193 UpdateSyncNodeProperties(child, model, &sync_child); 214 UpdateSyncNodeProperties(child, model, &sync_child);
194 215
195 // Associate the ID from the sync domain with the bookmark node, so that we 216 // Associate the ID from the sync domain with the bookmark node, so that we
196 // can refer back to this item later. 217 // can refer back to this item later.
197 associator->Associate(child, sync_child.GetId()); 218 associator->Associate(child, sync_child.GetId());
198 219
199 return sync_child.GetId(); 220 return sync_child.GetId();
200 } 221 }
201 222
202
203 void BookmarkChangeProcessor::BookmarkNodeRemoved(BookmarkModel* model, 223 void BookmarkChangeProcessor::BookmarkNodeRemoved(BookmarkModel* model,
204 const BookmarkNode* parent, 224 const BookmarkNode* parent,
205 int index, 225 int index,
206 const BookmarkNode* node) { 226 const BookmarkNode* node) {
207 RemoveSyncNodeHierarchy(node); 227 RemoveSyncNodeHierarchy(node);
208 } 228 }
209 229
210 void BookmarkChangeProcessor::BookmarkNodeChanged(BookmarkModel* model, 230 void BookmarkChangeProcessor::BookmarkNodeChanged(BookmarkModel* model,
211 const BookmarkNode* node) { 231 const BookmarkNode* node) {
212 // We shouldn't see changes to the top-level nodes. 232 // We shouldn't see changes to the top-level nodes.
213 if (model->is_permanent_node(node)) { 233 if (model->is_permanent_node(node)) {
214 NOTREACHED() << "Saw update to permanent node!"; 234 NOTREACHED() << "Saw update to permanent node!";
215 return; 235 return;
216 } 236 }
217 237
218 // Acquire a scoped write lock via a transaction. 238 int64 new_version = -1;
219 syncer::WriteTransaction trans(FROM_HERE, share_handle()); 239 {
240 // Acquire a scoped write lock via a transaction.
241 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version);
220 242
221 // Lookup the sync node that's associated with |node|. 243 // Lookup the sync node that's associated with |node|.
222 syncer::WriteNode sync_node(&trans); 244 syncer::WriteNode sync_node(&trans);
223 if (!model_associator_->InitSyncNodeFromChromeId(node->id(), &sync_node)) { 245 if (!model_associator_->InitSyncNodeFromChromeId(node->id(), &sync_node)) {
224 // TODO(tim): Investigating bug 121587. 246 // TODO(tim): Investigating bug 121587.
225 if (model_associator_->GetSyncIdFromChromeId(node->id()) == 247 if (model_associator_->GetSyncIdFromChromeId(node->id()) ==
226 syncer::kInvalidId) { 248 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, 249 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
248 "Could not InitByIdLookup on BookmarkNodeChanged, " 250 "Bookmark id not found in model associator on BookmarkNodeChanged");
249 " Cryptographer thinks bookmarks not encrypted, and CanDecrypt" 251 LOG(ERROR) << "Bad id.";
250 " failed."); 252 } else if (!sync_node.GetEntry()->good()) {
251 LOG(ERROR) << "Case 1.";
252 } else if (agreement && can_decrypt) {
253 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 253 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
254 "Could not InitByIdLookup on BookmarkNodeChanged, " 254 "Could not InitByIdLookup on BookmarkNodeChanged, good() failed");
255 " Cryptographer thinks bookmarks are encrypted, and CanDecrypt" 255 LOG(ERROR) << "Bad entry.";
256 " succeeded (?!), but DecryptIfNecessary failed."); 256 } 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, 257 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
260 "Could not InitByIdLookup on BookmarkNodeChanged, " 258 "Could not InitByIdLookup on BookmarkNodeChanged, is_del true");
261 " Cryptographer thinks bookmarks are encrypted, but CanDecrypt" 259 LOG(ERROR) << "Deleted entry.";
262 " failed.");
263 LOG(ERROR) << "Case 3.";
264 } else { 260 } else {
265 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 261 syncer::Cryptographer* crypto = trans.GetCryptographer();
266 "Could not InitByIdLookup on BookmarkNodeChanged, " 262 syncer::ModelTypeSet encrypted_types(trans.GetEncryptedTypes());
267 " Cryptographer thinks bookmarks not encrypted, but CanDecrypt" 263 const sync_pb::EntitySpecifics& specifics =
268 " succeeded (super weird, btw)"); 264 sync_node.GetEntry()->Get(syncer::syncable::SPECIFICS);
269 LOG(ERROR) << "Case 4."; 265 CHECK(specifics.has_encrypted());
266 const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted());
267 const bool agreement = encrypted_types.Has(syncer::BOOKMARKS);
268 if (!agreement && !can_decrypt) {
269 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
270 "Could not InitByIdLookup on BookmarkNodeChanged, "
271 " Cryptographer thinks bookmarks not encrypted, and CanDecrypt"
272 " failed.");
273 LOG(ERROR) << "Case 1.";
274 } else if (agreement && can_decrypt) {
275 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
276 "Could not InitByIdLookup on BookmarkNodeChanged, "
277 " Cryptographer thinks bookmarks are encrypted, and CanDecrypt"
278 " succeeded (?!), but DecryptIfNecessary failed.");
279 LOG(ERROR) << "Case 2.";
280 } else if (agreement) {
281 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
282 "Could not InitByIdLookup on BookmarkNodeChanged, "
283 " Cryptographer thinks bookmarks are encrypted, but CanDecrypt"
284 " failed.");
285 LOG(ERROR) << "Case 3.";
286 } else {
287 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
288 "Could not InitByIdLookup on BookmarkNodeChanged, "
289 " Cryptographer thinks bookmarks not encrypted, but CanDecrypt"
290 " succeeded (super weird, btw)");
291 LOG(ERROR) << "Case 4.";
292 }
270 } 293 }
294 return;
271 } 295 }
272 return; 296
297 UpdateSyncNodeProperties(node, model, &sync_node);
298
299 DCHECK_EQ(sync_node.GetIsFolder(), node->is_folder());
300 DCHECK_EQ(model_associator_->GetChromeNodeFromSyncId(
301 sync_node.GetParentId()),
302 node->parent());
303 // This node's index should be one more than the predecessor's index.
304 DCHECK_EQ(node->parent()->GetIndexOf(node),
305 CalculateBookmarkModelInsertionIndex(node->parent(),
306 &sync_node,
307 model_associator_));
273 } 308 }
274 309
275 UpdateSyncNodeProperties(node, model, &sync_node); 310 UpdateTransactionVersion(new_version, model,
276 311 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 } 312 }
287 313
288
289 void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model, 314 void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model,
290 const BookmarkNode* old_parent, int old_index, 315 const BookmarkNode* old_parent, int old_index,
291 const BookmarkNode* new_parent, int new_index) { 316 const BookmarkNode* new_parent, int new_index) {
292 const BookmarkNode* child = new_parent->GetChild(new_index); 317 const BookmarkNode* child = new_parent->GetChild(new_index);
293 // We shouldn't see changes to the top-level nodes. 318 // We shouldn't see changes to the top-level nodes.
294 if (model->is_permanent_node(child)) { 319 if (model->is_permanent_node(child)) {
295 NOTREACHED() << "Saw update to permanent node!"; 320 NOTREACHED() << "Saw update to permanent node!";
296 return; 321 return;
297 } 322 }
298 323
299 // Acquire a scoped write lock via a transaction. 324 int64 new_version = -1;
tim (not reviewing) 2012/11/08 17:38:49 This is used in a *lot*of places. I think it'd be
haitaol1 2012/11/08 19:06:53 Done.
300 syncer::WriteTransaction trans(FROM_HERE, share_handle()); 325 {
326 // Acquire a scoped write lock via a transaction.
327 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version);
301 328
302 // Lookup the sync node that's associated with |child|. 329 // Lookup the sync node that's associated with |child|.
303 syncer::WriteNode sync_node(&trans); 330 syncer::WriteNode sync_node(&trans);
304 if (!model_associator_->InitSyncNodeFromChromeId(child->id(), &sync_node)) { 331 if (!model_associator_->InitSyncNodeFromChromeId(child->id(), &sync_node)) {
305 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 332 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
306 std::string()); 333 std::string());
307 return; 334 return;
335 }
336
337 if (!PlaceSyncNode(MOVE, new_parent, new_index, &trans, &sync_node,
338 model_associator_)) {
339 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
340 std::string());
341 return;
342 }
308 } 343 }
309 344
310 if (!PlaceSyncNode(MOVE, new_parent, new_index, &trans, &sync_node, 345 UpdateTransactionVersion(new_version, model,
311 model_associator_)) { 346 std::vector<const BookmarkNode*>(1, child));
312 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
313 std::string());
314 return;
315 }
316 } 347 }
317 348
318 void BookmarkChangeProcessor::BookmarkNodeFaviconChanged( 349 void BookmarkChangeProcessor::BookmarkNodeFaviconChanged(
319 BookmarkModel* model, 350 BookmarkModel* model,
320 const BookmarkNode* node) { 351 const BookmarkNode* node) {
321 BookmarkNodeChanged(model, node); 352 BookmarkNodeChanged(model, node);
322 } 353 }
323 354
324 void BookmarkChangeProcessor::BookmarkNodeChildrenReordered( 355 void BookmarkChangeProcessor::BookmarkNodeChildrenReordered(
325 BookmarkModel* model, const BookmarkNode* node) { 356 BookmarkModel* model, const BookmarkNode* node) {
357 int64 new_version = -1;
358 std::vector<const BookmarkNode*> children;
359 {
360 // Acquire a scoped write lock via a transaction.
361 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version);
326 362
327 // Acquire a scoped write lock via a transaction. 363 // The given node's children got reordered. We need to reorder all the
328 syncer::WriteTransaction trans(FROM_HERE, share_handle()); 364 // children of the corresponding sync node.
365 for (int i = 0; i < node->child_count(); ++i) {
366 const BookmarkNode* child = node->GetChild(i);
367 children.push_back(child);
329 368
330 // The given node's children got reordered. We need to reorder all the 369 syncer::WriteNode sync_child(&trans);
331 // children of the corresponding sync node. 370 if (!model_associator_->InitSyncNodeFromChromeId(child->id(),
332 for (int i = 0; i < node->child_count(); ++i) { 371 &sync_child)) {
333 syncer::WriteNode sync_child(&trans); 372 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
334 if (!model_associator_->InitSyncNodeFromChromeId(node->GetChild(i)->id(), 373 std::string());
335 &sync_child)) { 374 return;
336 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 375 }
337 std::string()); 376 DCHECK_EQ(sync_child.GetParentId(),
338 return; 377 model_associator_->GetSyncIdFromChromeId(node->id()));
339 }
340 DCHECK_EQ(sync_child.GetParentId(),
341 model_associator_->GetSyncIdFromChromeId(node->id()));
342 378
343 if (!PlaceSyncNode(MOVE, node, i, &trans, &sync_child, 379 if (!PlaceSyncNode(MOVE, node, i, &trans, &sync_child,
344 model_associator_)) { 380 model_associator_)) {
345 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 381 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
346 std::string()); 382 std::string());
347 return; 383 return;
384 }
348 } 385 }
349 } 386 }
387
388 // TODO(haitaol): Filter out children that didn't actually change.
389 UpdateTransactionVersion(new_version, model, children);
350 } 390 }
351 391
352 // static 392 // static
353 bool BookmarkChangeProcessor::PlaceSyncNode(MoveOrCreate operation, 393 bool BookmarkChangeProcessor::PlaceSyncNode(MoveOrCreate operation,
354 const BookmarkNode* parent, int index, syncer::WriteTransaction* trans, 394 const BookmarkNode* parent, int index, syncer::WriteTransaction* trans,
355 syncer::WriteNode* dst, BookmarkModelAssociator* associator) { 395 syncer::WriteNode* dst, BookmarkModelAssociator* associator) {
356 syncer::ReadNode sync_parent(trans); 396 syncer::ReadNode sync_parent(trans);
357 if (!associator->InitSyncNodeFromChromeId(parent->id(), &sync_parent)) { 397 if (!associator->InitSyncNodeFromChromeId(parent->id(), &sync_parent)) {
358 LOG(WARNING) << "Parent lookup failed"; 398 LOG(WARNING) << "Parent lookup failed";
359 return false; 399 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."; 538 << "ACTION_ADD should be seen if and only if the node is unknown.";
499 passed_deletes = true; 539 passed_deletes = true;
500 540
501 syncer::ReadNode src(trans); 541 syncer::ReadNode src(trans);
502 if (src.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) { 542 if (src.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) {
503 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 543 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
504 "ApplyModelChanges was passed a bad ID"); 544 "ApplyModelChanges was passed a bad ID");
505 return; 545 return;
506 } 546 }
507 547
508 if (!CreateOrUpdateBookmarkNode(&src, model, model_associator_)) { 548 const BookmarkNode* node = CreateOrUpdateBookmarkNode(&src, model,
549 model_associator_);
550 if (node) {
551 bookmark_model_->SetNodeMetaInfo(node, kBookmarkTransactionVersionKey,
552 base::Int64ToString(model_version));
553 } else {
509 // Because the Synced Bookmarks node can be created server side, it's 554 // 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 555 // possible it'll arrive at the client as an update. In that case it
511 // won't have been associated at startup, the GetChromeNodeFromSyncId 556 // won't have been associated at startup, the GetChromeNodeFromSyncId
512 // call above will return NULL, and we won't detect it as a permanent 557 // 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 558 // node, resulting in us trying to create it here (which will
514 // fail). Therefore, we add special logic here just to detect the 559 // fail). Therefore, we add special logic here just to detect the
515 // Synced Bookmarks folder. 560 // Synced Bookmarks folder.
516 syncer::ReadNode synced_bookmarks(trans); 561 syncer::ReadNode synced_bookmarks(trans);
517 if (synced_bookmarks.InitByTagLookup(kMobileBookmarksTag) == 562 if (synced_bookmarks.InitByTagLookup(kMobileBookmarksTag) ==
518 syncer::BaseNode::INIT_OK && 563 syncer::BaseNode::INIT_OK &&
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 base::Time::FromInternalValue( 636 base::Time::FromInternalValue(
592 src->GetBookmarkSpecifics().creation_time_us())); 637 src->GetBookmarkSpecifics().creation_time_us()));
593 } 638 }
594 639
595 SetBookmarkFavicon(src, dst, model); 640 SetBookmarkFavicon(src, dst, model);
596 } 641 }
597 642
598 return dst; 643 return dst;
599 } 644 }
600 645
646 void BookmarkChangeProcessor::UpdateTransactionVersion(
tim (not reviewing) 2012/11/08 17:38:49 You could re-use this function from BookmarkModelA
haitaol1 2012/11/08 19:06:53 Done.
647 int64 new_version,
648 BookmarkModel* model,
649 const std::vector<const BookmarkNode*>& nodes) {
650 if (new_version > 0) {
651 model->SetNodeMetaInfo(model->root_node(), kBookmarkTransactionVersionKey,
652 base::Int64ToString(new_version));
653 for (uint32 i = 0; i < nodes.size(); ++i) {
tim (not reviewing) 2012/11/08 17:38:49 prefer size_t to uint32 particularly when using th
haitaol1 2012/11/08 19:06:53 Done.
654 model->SetNodeMetaInfo(nodes[i], kBookmarkTransactionVersionKey,
655 base::Int64ToString(new_version));
656 }
657 }
658 }
659
601 // static 660 // static
602 // Creates a bookmark node under the given parent node from the given sync 661 // Creates a bookmark node under the given parent node from the given sync
603 // node. Returns the newly created node. 662 // node. Returns the newly created node.
604 const BookmarkNode* BookmarkChangeProcessor::CreateBookmarkNode( 663 const BookmarkNode* BookmarkChangeProcessor::CreateBookmarkNode(
605 syncer::BaseNode* sync_node, 664 syncer::BaseNode* sync_node,
606 const BookmarkNode* parent, 665 const BookmarkNode* parent,
607 BookmarkModel* model, 666 BookmarkModel* model,
608 int index) { 667 int index) {
609 DCHECK(parent); 668 DCHECK(parent);
610 DCHECK(index >= 0 && index <= parent->child_count()); 669 DCHECK(index >= 0 && index <= parent->child_count());
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 const BookmarkNode* bookmark_node, 735 const BookmarkNode* bookmark_node,
677 BookmarkModel* model, 736 BookmarkModel* model,
678 syncer::WriteNode* sync_node) { 737 syncer::WriteNode* sync_node) {
679 std::vector<unsigned char> favicon_bytes; 738 std::vector<unsigned char> favicon_bytes;
680 EncodeFavicon(bookmark_node, model, &favicon_bytes); 739 EncodeFavicon(bookmark_node, model, &favicon_bytes);
681 if (!favicon_bytes.empty()) 740 if (!favicon_bytes.empty())
682 sync_node->SetFaviconBytes(favicon_bytes); 741 sync_node->SetFaviconBytes(favicon_bytes);
683 } 742 }
684 743
685 } // namespace browser_sync 744 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698