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

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

Issue 277033002: [Sync] Make BookmarkChangeProcessor resilient against updates before add (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CreateOrUpdate Created 6 years, 7 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
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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 <map> 7 #include <map>
8 #include <stack> 8 #include <stack>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 } 198 }
199 } else { 199 } else {
200 int64 child_id = node.GetFirstChildId(); 200 int64 child_id = node.GetFirstChildId();
201 if (child_id != syncer::kInvalidId) { 201 if (child_id != syncer::kInvalidId) {
202 dfs_sync_id_stack.push(child_id); 202 dfs_sync_id_stack.push(child_id);
203 } 203 }
204 } 204 }
205 } 205 }
206 } 206 }
207 207
208 void BookmarkChangeProcessor::BookmarkModelLoaded(BookmarkModel* model, 208 void BookmarkChangeProcessor::CreateOrUpdateSyncNode(const BookmarkNode* node) {
209 bool ids_reassigned) { 209 const BookmarkNode* parent = node->parent();
210 NOTREACHED(); 210 int index = node->parent()->GetIndexOf(node);
211 }
212
213 void BookmarkChangeProcessor::BookmarkModelBeingDeleted(
214 BookmarkModel* model) {
215 NOTREACHED();
216 bookmark_model_ = NULL;
217 }
218
219 void BookmarkChangeProcessor::BookmarkNodeAdded(BookmarkModel* model,
220 const BookmarkNode* parent,
221 int index) {
222 DCHECK(share_handle());
223 211
224 int64 new_version = syncer::syncable::kInvalidTransactionVersion; 212 int64 new_version = syncer::syncable::kInvalidTransactionVersion;
225 int64 sync_id = syncer::kInvalidId; 213 int64 sync_id = syncer::kInvalidId;
226 { 214 {
227 // Acquire a scoped write lock via a transaction. 215 // Acquire a scoped write lock via a transaction.
228 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version); 216 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version);
229 sync_id = CreateSyncNode(parent, model, index, &trans, 217 sync_id = model_associator_->GetSyncIdFromChromeId(node->id());
230 model_associator_, error_handler()); 218 if (sync_id != syncer::kInvalidId) {
219 UpdateSyncNode(
220 node, bookmark_model_, &trans, model_associator_, error_handler());
221 } else {
222 sync_id = CreateSyncNode(parent,
223 bookmark_model_,
224 index,
225 &trans,
226 model_associator_,
227 error_handler());
228 }
231 } 229 }
232 230
233 if (syncer::kInvalidId != sync_id) { 231 if (syncer::kInvalidId != sync_id) {
234 // Siblings of added node in sync DB will also be updated to reflect new 232 // Siblings of added node in sync DB will also be updated to reflect new
235 // PREV_ID/NEXT_ID and thus get a new version. But we only update version 233 // PREV_ID/NEXT_ID and thus get a new version. But we only update version
236 // of added node here. After switching to ordinals for positioning, 234 // of added node here. After switching to ordinals for positioning,
237 // PREV_ID/NEXT_ID will be deprecated and siblings will not be updated. 235 // PREV_ID/NEXT_ID will be deprecated and siblings will not be updated.
238 UpdateTransactionVersion( 236 UpdateTransactionVersion(
239 new_version, model, 237 new_version,
238 bookmark_model_,
240 std::vector<const BookmarkNode*>(1, parent->GetChild(index))); 239 std::vector<const BookmarkNode*>(1, parent->GetChild(index)));
241 } 240 }
242 } 241 }
243 242
243 void BookmarkChangeProcessor::BookmarkModelLoaded(BookmarkModel* model,
244 bool ids_reassigned) {
245 NOTREACHED();
246 }
247
248 void BookmarkChangeProcessor::BookmarkModelBeingDeleted(BookmarkModel* model) {
249 NOTREACHED();
250 bookmark_model_ = NULL;
251 }
252
253 void BookmarkChangeProcessor::BookmarkNodeAdded(BookmarkModel* model,
254 const BookmarkNode* parent,
255 int index) {
256 DCHECK(share_handle());
257 CreateOrUpdateSyncNode(parent->GetChild(index));
258 }
259
244 // static 260 // static
245 int64 BookmarkChangeProcessor::CreateSyncNode(const BookmarkNode* parent, 261 int64 BookmarkChangeProcessor::CreateSyncNode(const BookmarkNode* parent,
246 BookmarkModel* model, int index, syncer::WriteTransaction* trans, 262 BookmarkModel* model, int index, syncer::WriteTransaction* trans,
247 BookmarkModelAssociator* associator, 263 BookmarkModelAssociator* associator,
248 DataTypeErrorHandler* error_handler) { 264 DataTypeErrorHandler* error_handler) {
249 const BookmarkNode* child = parent->GetChild(index); 265 const BookmarkNode* child = parent->GetChild(index);
250 DCHECK(child); 266 DCHECK(child);
251 267
252 // Create a WriteNode container to hold the new node. 268 // Create a WriteNode container to hold the new node.
253 syncer::WriteNode sync_child(trans); 269 syncer::WriteNode sync_child(trans);
(...skipping 29 matching lines...) Expand all
283 RemoveAllSyncNodes(); 299 RemoveAllSyncNodes();
284 } 300 }
285 301
286 void BookmarkChangeProcessor::BookmarkNodeChanged(BookmarkModel* model, 302 void BookmarkChangeProcessor::BookmarkNodeChanged(BookmarkModel* model,
287 const BookmarkNode* node) { 303 const BookmarkNode* node) {
288 // We shouldn't see changes to the top-level nodes. 304 // We shouldn't see changes to the top-level nodes.
289 if (model->is_permanent_node(node)) { 305 if (model->is_permanent_node(node)) {
290 NOTREACHED() << "Saw update to permanent node!"; 306 NOTREACHED() << "Saw update to permanent node!";
291 return; 307 return;
292 } 308 }
309 CreateOrUpdateSyncNode(node);
310 }
293 311
294 int64 new_version = syncer::syncable::kInvalidTransactionVersion; 312 // Static.
295 { 313 int64 BookmarkChangeProcessor::UpdateSyncNode(
296 // Acquire a scoped write lock via a transaction. 314 const BookmarkNode* node,
297 syncer::WriteTransaction trans(FROM_HERE, share_handle(), &new_version); 315 BookmarkModel* model,
298 316 syncer::WriteTransaction* trans,
299 // Lookup the sync node that's associated with |node|. 317 BookmarkModelAssociator* associator,
300 syncer::WriteNode sync_node(&trans); 318 DataTypeErrorHandler* error_handler) {
301 if (!model_associator_->InitSyncNodeFromChromeId(node->id(), &sync_node)) { 319 // Lookup the sync node that's associated with |node|.
302 // TODO(tim): Investigating bug 121587. 320 syncer::WriteNode sync_node(trans);
303 if (model_associator_->GetSyncIdFromChromeId(node->id()) == 321 if (!associator->InitSyncNodeFromChromeId(node->id(), &sync_node)) {
304 syncer::kInvalidId) { 322 error_handler->OnSingleDatatypeUnrecoverableError(
305 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, 323 FROM_HERE, "Could not load bookmark node on update.");
306 "Bookmark id not found in model associator on BookmarkNodeChanged"); 324 return syncer::kInvalidId;
307 LOG(ERROR) << "Bad id.";
308 } else if (!sync_node.GetEntry()->good()) {
309 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
310 "Could not InitByIdLookup on BookmarkNodeChanged, good() failed");
311 LOG(ERROR) << "Bad entry.";
312 } else if (sync_node.GetEntry()->GetIsDel()) {
313 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
314 "Could not InitByIdLookup on BookmarkNodeChanged, is_del true");
315 LOG(ERROR) << "Deleted entry.";
316 } else {
317 syncer::Cryptographer* crypto = trans.GetCryptographer();
318 syncer::ModelTypeSet encrypted_types(trans.GetEncryptedTypes());
319 const sync_pb::EntitySpecifics& specifics =
320 sync_node.GetEntry()->GetSpecifics();
321 CHECK(specifics.has_encrypted());
322 const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted());
323 const bool agreement = encrypted_types.Has(syncer::BOOKMARKS);
324 if (!agreement && !can_decrypt) {
325 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
326 "Could not InitByIdLookup on BookmarkNodeChanged, "
327 " Cryptographer thinks bookmarks not encrypted, and CanDecrypt"
328 " failed.");
329 LOG(ERROR) << "Case 1.";
330 } else if (agreement && can_decrypt) {
331 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
332 "Could not InitByIdLookup on BookmarkNodeChanged, "
333 " Cryptographer thinks bookmarks are encrypted, and CanDecrypt"
334 " succeeded (?!), but DecryptIfNecessary failed.");
335 LOG(ERROR) << "Case 2.";
336 } else if (agreement) {
337 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
338 "Could not InitByIdLookup on BookmarkNodeChanged, "
339 " Cryptographer thinks bookmarks are encrypted, but CanDecrypt"
340 " failed.");
341 LOG(ERROR) << "Case 3.";
342 } else {
343 error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
344 "Could not InitByIdLookup on BookmarkNodeChanged, "
345 " Cryptographer thinks bookmarks not encrypted, but CanDecrypt"
346 " succeeded (super weird, btw)");
347 LOG(ERROR) << "Case 4.";
348 }
349 }
350 return;
351 }
352
353 UpdateSyncNodeProperties(node, model, &sync_node);
354
355 DCHECK_EQ(sync_node.GetIsFolder(), node->is_folder());
356 DCHECK_EQ(model_associator_->GetChromeNodeFromSyncId(
357 sync_node.GetParentId()),
358 node->parent());
359 DCHECK_EQ(node->parent()->GetIndexOf(node), sync_node.GetPositionIndex());
360 } 325 }
361 326 UpdateSyncNodeProperties(node, model, &sync_node);
362 UpdateTransactionVersion(new_version, model, 327 DCHECK_EQ(sync_node.GetIsFolder(), node->is_folder());
363 std::vector<const BookmarkNode*>(1, node)); 328 DCHECK_EQ(associator->GetChromeNodeFromSyncId(sync_node.GetParentId()),
329 node->parent());
330 DCHECK_EQ(node->parent()->GetIndexOf(node), sync_node.GetPositionIndex());
331 return sync_node.GetId();
364 } 332 }
365 333
366 void BookmarkChangeProcessor::BookmarkMetaInfoChanged( 334 void BookmarkChangeProcessor::BookmarkMetaInfoChanged(
367 BookmarkModel* model, const BookmarkNode* node) { 335 BookmarkModel* model, const BookmarkNode* node) {
368 BookmarkNodeChanged(model, node); 336 BookmarkNodeChanged(model, node);
369 } 337 }
370 338
371 void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model, 339 void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model,
372 const BookmarkNode* old_parent, int old_index, 340 const BookmarkNode* old_parent, int old_index,
373 const BookmarkNode* new_parent, int new_index) { 341 const BookmarkNode* new_parent, int new_index) {
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 sync_pb::BookmarkSpecifics updated_specifics( 836 sync_pb::BookmarkSpecifics updated_specifics(
869 sync_node->GetBookmarkSpecifics()); 837 sync_node->GetBookmarkSpecifics());
870 updated_specifics.set_favicon(favicon_bytes->front(), 838 updated_specifics.set_favicon(favicon_bytes->front(),
871 favicon_bytes->size()); 839 favicon_bytes->size());
872 updated_specifics.set_icon_url(bookmark_node->icon_url().spec()); 840 updated_specifics.set_icon_url(bookmark_node->icon_url().spec());
873 sync_node->SetBookmarkSpecifics(updated_specifics); 841 sync_node->SetBookmarkSpecifics(updated_specifics);
874 } 842 }
875 } 843 }
876 844
877 } // namespace browser_sync 845 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/bookmark_change_processor.h ('k') | chrome/browser/sync/profile_sync_service_bookmark_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698