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

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

Issue 9978017: [Sync] - Upload the callstacks for errors so that the line number of error is in callstack. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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 (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_model_associator.h" 5 #include "chrome/browser/sync/glue/bookmark_model_associator.h"
6 6
7 #include <stack> 7 #include <stack>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 206
207 void BookmarkModelAssociator::UpdatePermanentNodeVisibility() { 207 void BookmarkModelAssociator::UpdatePermanentNodeVisibility() {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209 DCHECK(bookmark_model_->IsLoaded()); 209 DCHECK(bookmark_model_->IsLoaded());
210 210
211 bookmark_model_->SetPermanentNodeVisible( 211 bookmark_model_->SetPermanentNodeVisible(
212 BookmarkNode::MOBILE, 212 BookmarkNode::MOBILE,
213 id_map_.find(bookmark_model_->mobile_node()->id()) != id_map_.end()); 213 id_map_.find(bookmark_model_->mobile_node()->id()) != id_map_.end());
214 } 214 }
215 215
216 bool BookmarkModelAssociator::DisassociateModels(SyncError* error) { 216 SyncError BookmarkModelAssociator::DisassociateModels() {
217 id_map_.clear(); 217 id_map_.clear();
218 id_map_inverse_.clear(); 218 id_map_inverse_.clear();
219 dirty_associations_sync_ids_.clear(); 219 dirty_associations_sync_ids_.clear();
220 return true; 220 return SyncError();
221 } 221 }
222 222
223 int64 BookmarkModelAssociator::GetSyncIdFromChromeId(const int64& node_id) { 223 int64 BookmarkModelAssociator::GetSyncIdFromChromeId(const int64& node_id) {
224 BookmarkIdToSyncIdMap::const_iterator iter = id_map_.find(node_id); 224 BookmarkIdToSyncIdMap::const_iterator iter = id_map_.find(node_id);
225 return iter == id_map_.end() ? sync_api::kInvalidId : iter->second; 225 return iter == id_map_.end() ? sync_api::kInvalidId : iter->second;
226 } 226 }
227 227
228 const BookmarkNode* BookmarkModelAssociator::GetChromeNodeFromSyncId( 228 const BookmarkNode* BookmarkModelAssociator::GetChromeNodeFromSyncId(
229 int64 sync_id) { 229 int64 sync_id) {
230 SyncIdToBookmarkNodeMap::const_iterator iter = id_map_inverse_.find(sync_id); 230 SyncIdToBookmarkNodeMap::const_iterator iter = id_map_inverse_.find(sync_id);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 if (bookmark->is_url()) { 321 if (bookmark->is_url()) {
322 if (bookmark->url() != sync_node->GetURL()) 322 if (bookmark->url() != sync_node->GetURL())
323 return false; 323 return false;
324 } 324 }
325 // Don't compare favicons here, because they are not really 325 // Don't compare favicons here, because they are not really
326 // user-updated and we don't have versioning information -- a site changing 326 // user-updated and we don't have versioning information -- a site changing
327 // its favicon shouldn't result in a bookmark mismatch. 327 // its favicon shouldn't result in a bookmark mismatch.
328 return true; 328 return true;
329 } 329 }
330 330
331 bool BookmarkModelAssociator::AssociateTaggedPermanentNode( 331 SyncError BookmarkModelAssociator::AssociateTaggedPermanentNode(
332 const BookmarkNode* permanent_node, const std::string&tag) { 332 const BookmarkNode* permanent_node, const std::string&tag) {
333 // Do nothing if |permanent_node| is already initialized and associated. 333 // Do nothing if |permanent_node| is already initialized and associated.
334 int64 sync_id = GetSyncIdFromChromeId(permanent_node->id()); 334 int64 sync_id = GetSyncIdFromChromeId(permanent_node->id());
335 if (sync_id != sync_api::kInvalidId) 335 if (sync_id != sync_api::kInvalidId)
336 return true; 336 return SyncError();
337 if (!GetSyncIdForTaggedNode(tag, &sync_id)) 337 if (!GetSyncIdForTaggedNode(tag, &sync_id))
338 return false; 338 return unrecoverable_error_handler_->CreateAndUploadError(
339 FROM_HERE,
340 "Permanent node not found",
341 model_type());
339 342
340 Associate(permanent_node, sync_id); 343 Associate(permanent_node, sync_id);
341 return true; 344 return SyncError();
342 } 345 }
343 346
344 bool BookmarkModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, 347 bool BookmarkModelAssociator::GetSyncIdForTaggedNode(const std::string& tag,
345 int64* sync_id) { 348 int64* sync_id) {
346 sync_api::ReadTransaction trans(FROM_HERE, user_share_); 349 sync_api::ReadTransaction trans(FROM_HERE, user_share_);
347 sync_api::ReadNode sync_node(&trans); 350 sync_api::ReadNode sync_node(&trans);
348 if (!sync_node.InitByTagLookup(tag.c_str())) 351 if (!sync_node.InitByTagLookup(tag.c_str()))
349 return false; 352 return false;
350 *sync_id = sync_node.GetId(); 353 *sync_id = sync_node.GetId();
351 return true; 354 return true;
352 } 355 }
353 356
354 bool BookmarkModelAssociator::AssociateModels(SyncError* error) { 357 SyncError BookmarkModelAssociator::AssociateModels() {
355 scoped_ptr<ScopedAssociationUpdater> association_updater( 358 scoped_ptr<ScopedAssociationUpdater> association_updater(
356 new ScopedAssociationUpdater(bookmark_model_)); 359 new ScopedAssociationUpdater(bookmark_model_));
357 // Try to load model associations from persisted associations first. If that 360 // Try to load model associations from persisted associations first. If that
358 // succeeds, we don't need to run the complex model matching algorithm. 361 // succeeds, we don't need to run the complex model matching algorithm.
359 if (LoadAssociations()) 362 if (LoadAssociations())
360 return true; 363 return SyncError();
361 364
362 DisassociateModels(error); 365 DisassociateModels();
363 366
364 // We couldn't load model associations from persisted associations. So build 367 // We couldn't load model associations from persisted associations. So build
365 // them. 368 // them.
366 return BuildAssociations(error); 369 return BuildAssociations();
367 } 370 }
368 371
369 bool BookmarkModelAssociator::BuildAssociations(SyncError* error) { 372 SyncError BookmarkModelAssociator::BuildAssociations() {
370 // Algorithm description: 373 // Algorithm description:
371 // Match up the roots and recursively do the following: 374 // Match up the roots and recursively do the following:
372 // * For each sync node for the current sync parent node, find the best 375 // * For each sync node for the current sync parent node, find the best
373 // matching bookmark node under the corresponding bookmark parent node. 376 // matching bookmark node under the corresponding bookmark parent node.
374 // If no matching node is found, create a new bookmark node in the same 377 // If no matching node is found, create a new bookmark node in the same
375 // position as the corresponding sync node. 378 // position as the corresponding sync node.
376 // If a matching node is found, update the properties of it from the 379 // If a matching node is found, update the properties of it from the
377 // corresponding sync node. 380 // corresponding sync node.
378 // * When all children sync nodes are done, add the extra children bookmark 381 // * When all children sync nodes are done, add the extra children bookmark
379 // nodes to the sync parent node. 382 // nodes to the sync parent node.
380 // 383 //
381 // This algorithm will do a good job of merging when folder names are a good 384 // This algorithm will do a good job of merging when folder names are a good
382 // indicator of the two folders being the same. It will handle reordering and 385 // indicator of the two folders being the same. It will handle reordering and
383 // new node addition very well (without creating duplicates). 386 // new node addition very well (without creating duplicates).
384 // This algorithm will not do well if the folder name has changes but the 387 // This algorithm will not do well if the folder name has changes but the
385 // children under them are all the same. 388 // children under them are all the same.
386 389
390 SyncError error;
387 DCHECK(bookmark_model_->IsLoaded()); 391 DCHECK(bookmark_model_->IsLoaded());
388 392
389 // To prime our association, we associate the top-level nodes, Bookmark Bar 393 // To prime our association, we associate the top-level nodes, Bookmark Bar
390 // and Other Bookmarks. 394 // and Other Bookmarks.
391 if (!AssociateTaggedPermanentNode(bookmark_model_->other_node(), 395 error = AssociateTaggedPermanentNode(bookmark_model_->other_node(),
392 kOtherBookmarksTag)) { 396 kOtherBookmarksTag);
393 error->Reset(FROM_HERE, kServerError, model_type()); 397 if (error.IsSet()) {
394 return false; 398 return error;
395 } 399 }
396 if (!AssociateTaggedPermanentNode(bookmark_model_->bookmark_bar_node(), 400
397 kBookmarkBarTag)) { 401 error = AssociateTaggedPermanentNode(bookmark_model_->bookmark_bar_node(),
398 error->Reset(FROM_HERE, kServerError, model_type()); 402 kBookmarkBarTag);
399 return false; 403 if (error.IsSet()) {
404 return error;
400 } 405 }
401 if (!AssociateTaggedPermanentNode(bookmark_model_->mobile_node(), 406
402 kMobileBookmarksTag) && 407 if (expect_mobile_bookmarks_folder_) {
403 expect_mobile_bookmarks_folder_) { 408 error = AssociateTaggedPermanentNode(bookmark_model_->mobile_node(),
404 error->Reset(FROM_HERE, kServerError, model_type()); 409 kMobileBookmarksTag);
405 return false; 410 if (error.IsSet()) {
411 return error;
412 }
406 } 413 }
407 414
408 int64 bookmark_bar_sync_id = GetSyncIdFromChromeId( 415 int64 bookmark_bar_sync_id = GetSyncIdFromChromeId(
409 bookmark_model_->bookmark_bar_node()->id()); 416 bookmark_model_->bookmark_bar_node()->id());
410 DCHECK_NE(bookmark_bar_sync_id, sync_api::kInvalidId); 417 DCHECK_NE(bookmark_bar_sync_id, sync_api::kInvalidId);
411 int64 other_bookmarks_sync_id = GetSyncIdFromChromeId( 418 int64 other_bookmarks_sync_id = GetSyncIdFromChromeId(
412 bookmark_model_->other_node()->id()); 419 bookmark_model_->other_node()->id());
413 DCHECK_NE(other_bookmarks_sync_id, sync_api::kInvalidId); 420 DCHECK_NE(other_bookmarks_sync_id, sync_api::kInvalidId);
414 int64 mobile_bookmarks_sync_id = GetSyncIdFromChromeId( 421 int64 mobile_bookmarks_sync_id = GetSyncIdFromChromeId(
415 bookmark_model_->mobile_node()->id()); 422 bookmark_model_->mobile_node()->id());
416 if (expect_mobile_bookmarks_folder_) { 423 if (expect_mobile_bookmarks_folder_) {
417 DCHECK_NE(sync_api::kInvalidId, mobile_bookmarks_sync_id); 424 DCHECK_NE(sync_api::kInvalidId, mobile_bookmarks_sync_id);
418 } 425 }
419 426
420 std::stack<int64> dfs_stack; 427 std::stack<int64> dfs_stack;
421 if (mobile_bookmarks_sync_id != sync_api::kInvalidId) 428 if (mobile_bookmarks_sync_id != sync_api::kInvalidId)
422 dfs_stack.push(mobile_bookmarks_sync_id); 429 dfs_stack.push(mobile_bookmarks_sync_id);
423 dfs_stack.push(other_bookmarks_sync_id); 430 dfs_stack.push(other_bookmarks_sync_id);
424 dfs_stack.push(bookmark_bar_sync_id); 431 dfs_stack.push(bookmark_bar_sync_id);
425 432
426 sync_api::WriteTransaction trans(FROM_HERE, user_share_); 433 sync_api::WriteTransaction trans(FROM_HERE, user_share_);
427 434
428 while (!dfs_stack.empty()) { 435 while (!dfs_stack.empty()) {
429 int64 sync_parent_id = dfs_stack.top(); 436 int64 sync_parent_id = dfs_stack.top();
430 dfs_stack.pop(); 437 dfs_stack.pop();
431 438
432 sync_api::ReadNode sync_parent(&trans); 439 sync_api::ReadNode sync_parent(&trans);
433 if (!sync_parent.InitByIdLookup(sync_parent_id)) { 440 if (!sync_parent.InitByIdLookup(sync_parent_id)) {
434 error->Reset(FROM_HERE, "Failed to lookup node.", model_type()); 441 return unrecoverable_error_handler_->CreateAndUploadError(
435 return false; 442 FROM_HERE,
443 "Failed to lookup node.",
444 model_type());
436 } 445 }
437 // Only folder nodes are pushed on to the stack. 446 // Only folder nodes are pushed on to the stack.
438 DCHECK(sync_parent.GetIsFolder()); 447 DCHECK(sync_parent.GetIsFolder());
439 448
440 const BookmarkNode* parent_node = GetChromeNodeFromSyncId(sync_parent_id); 449 const BookmarkNode* parent_node = GetChromeNodeFromSyncId(sync_parent_id);
441 DCHECK(parent_node->is_folder()); 450 DCHECK(parent_node->is_folder());
442 451
443 BookmarkNodeFinder node_finder(parent_node); 452 BookmarkNodeFinder node_finder(parent_node);
444 453
445 int index = 0; 454 int index = 0;
446 int64 sync_child_id = sync_parent.GetFirstChildId(); 455 int64 sync_child_id = sync_parent.GetFirstChildId();
447 while (sync_child_id != sync_api::kInvalidId) { 456 while (sync_child_id != sync_api::kInvalidId) {
448 sync_api::WriteNode sync_child_node(&trans); 457 sync_api::WriteNode sync_child_node(&trans);
449 if (!sync_child_node.InitByIdLookup(sync_child_id)) { 458 if (!sync_child_node.InitByIdLookup(sync_child_id)) {
450 error->Reset(FROM_HERE, "Failed to lookup node.", model_type()); 459 return unrecoverable_error_handler_->CreateAndUploadError(
451 return false; 460 FROM_HERE,
461 "Failed to lookup node.",
462 model_type());
452 } 463 }
453 464
454 const BookmarkNode* child_node = NULL; 465 const BookmarkNode* child_node = NULL;
455 child_node = node_finder.FindBookmarkNode(sync_child_node); 466 child_node = node_finder.FindBookmarkNode(sync_child_node);
456 if (child_node) { 467 if (child_node) {
457 bookmark_model_->Move(child_node, parent_node, index); 468 bookmark_model_->Move(child_node, parent_node, index);
458 // Set the favicon for bookmark node from sync node or vice versa. 469 // Set the favicon for bookmark node from sync node or vice versa.
459 if (BookmarkChangeProcessor::SetBookmarkFavicon( 470 if (BookmarkChangeProcessor::SetBookmarkFavicon(
460 &sync_child_node, child_node, bookmark_model_)) { 471 &sync_child_node, child_node, bookmark_model_)) {
461 BookmarkChangeProcessor::SetSyncNodeFavicon( 472 BookmarkChangeProcessor::SetSyncNodeFavicon(
(...skipping 25 matching lines...) Expand all
487 // At this point all the children nodes of the parent sync node have 498 // At this point all the children nodes of the parent sync node have
488 // corresponding children in the parent bookmark node and they are all in 499 // corresponding children in the parent bookmark node and they are all in
489 // the right positions: from 0 to index - 1. 500 // the right positions: from 0 to index - 1.
490 // So the children starting from index in the parent bookmark node are the 501 // So the children starting from index in the parent bookmark node are the
491 // ones that are not present in the parent sync node. So create them. 502 // ones that are not present in the parent sync node. So create them.
492 for (int i = index; i < parent_node->child_count(); ++i) { 503 for (int i = index; i < parent_node->child_count(); ++i) {
493 sync_child_id = BookmarkChangeProcessor::CreateSyncNode( 504 sync_child_id = BookmarkChangeProcessor::CreateSyncNode(
494 parent_node, bookmark_model_, i, &trans, this, 505 parent_node, bookmark_model_, i, &trans, this,
495 unrecoverable_error_handler_); 506 unrecoverable_error_handler_);
496 if (sync_api::kInvalidId == sync_child_id) { 507 if (sync_api::kInvalidId == sync_child_id) {
497 error->Reset(FROM_HERE, "Failed to create sync node.", model_type()); 508 return unrecoverable_error_handler_->CreateAndUploadError(
498 return false; // Creation failed. 509 FROM_HERE,
510 "Failed to create sync node.",
511 model_type());
499 } 512 }
500 if (parent_node->GetChild(i)->is_folder()) 513 if (parent_node->GetChild(i)->is_folder())
501 dfs_stack.push(sync_child_id); 514 dfs_stack.push(sync_child_id);
502 number_of_new_sync_nodes_created_at_association_++; 515 number_of_new_sync_nodes_created_at_association_++;
503 } 516 }
504 } 517 }
505 518
506 return true; 519 return SyncError();
507 } 520 }
508 521
509 void BookmarkModelAssociator::PostPersistAssociationsTask() { 522 void BookmarkModelAssociator::PostPersistAssociationsTask() {
510 // No need to post a task if a task is already pending. 523 // No need to post a task if a task is already pending.
511 if (weak_factory_.HasWeakPtrs()) 524 if (weak_factory_.HasWeakPtrs())
512 return; 525 return;
513 MessageLoop::current()->PostTask( 526 MessageLoop::current()->PostTask(
514 FROM_HERE, 527 FROM_HERE,
515 base::Bind( 528 base::Bind(
516 &BookmarkModelAssociator::PersistAssociations, 529 &BookmarkModelAssociator::PersistAssociations,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 bool BookmarkModelAssociator::CryptoReadyIfNecessary() { 657 bool BookmarkModelAssociator::CryptoReadyIfNecessary() {
645 // We only access the cryptographer while holding a transaction. 658 // We only access the cryptographer while holding a transaction.
646 sync_api::ReadTransaction trans(FROM_HERE, user_share_); 659 sync_api::ReadTransaction trans(FROM_HERE, user_share_);
647 const syncable::ModelTypeSet encrypted_types = 660 const syncable::ModelTypeSet encrypted_types =
648 sync_api::GetEncryptedTypes(&trans); 661 sync_api::GetEncryptedTypes(&trans);
649 return !encrypted_types.Has(syncable::BOOKMARKS) || 662 return !encrypted_types.Has(syncable::BOOKMARKS) ||
650 trans.GetCryptographer()->is_ready(); 663 trans.GetCryptographer()->is_ready();
651 } 664 }
652 665
653 } // namespace browser_sync 666 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/bookmark_model_associator.h ('k') | chrome/browser/sync/glue/change_processor_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698