OLD | NEW |
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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 return iter == id_map_inverse_.end() ? NULL : iter->second; | 231 return iter == id_map_inverse_.end() ? NULL : iter->second; |
232 } | 232 } |
233 | 233 |
234 bool BookmarkModelAssociator::InitSyncNodeFromChromeId( | 234 bool BookmarkModelAssociator::InitSyncNodeFromChromeId( |
235 const int64& node_id, | 235 const int64& node_id, |
236 sync_api::BaseNode* sync_node) { | 236 sync_api::BaseNode* sync_node) { |
237 DCHECK(sync_node); | 237 DCHECK(sync_node); |
238 int64 sync_id = GetSyncIdFromChromeId(node_id); | 238 int64 sync_id = GetSyncIdFromChromeId(node_id); |
239 if (sync_id == sync_api::kInvalidId) | 239 if (sync_id == sync_api::kInvalidId) |
240 return false; | 240 return false; |
241 if (!sync_node->InitByIdLookup(sync_id)) | 241 if (sync_node->InitByIdLookup(sync_id) != sync_api::BaseNode::INIT_OK) |
242 return false; | 242 return false; |
243 DCHECK(sync_node->GetId() == sync_id); | 243 DCHECK(sync_node->GetId() == sync_id); |
244 return true; | 244 return true; |
245 } | 245 } |
246 | 246 |
247 void BookmarkModelAssociator::Associate(const BookmarkNode* node, | 247 void BookmarkModelAssociator::Associate(const BookmarkNode* node, |
248 int64 sync_id) { | 248 int64 sync_id) { |
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
250 int64 node_id = node->id(); | 250 int64 node_id = node->id(); |
251 DCHECK_NE(sync_id, sync_api::kInvalidId); | 251 DCHECK_NE(sync_id, sync_api::kInvalidId); |
(...skipping 29 matching lines...) Expand all Loading... |
281 return false; | 281 return false; |
282 } | 282 } |
283 int64 mobile_bookmarks_sync_id; | 283 int64 mobile_bookmarks_sync_id; |
284 if (!GetSyncIdForTaggedNode(kMobileBookmarksTag, &mobile_bookmarks_sync_id)) { | 284 if (!GetSyncIdForTaggedNode(kMobileBookmarksTag, &mobile_bookmarks_sync_id)) { |
285 has_mobile_folder = false; | 285 has_mobile_folder = false; |
286 } | 286 } |
287 | 287 |
288 sync_api::ReadTransaction trans(FROM_HERE, user_share_); | 288 sync_api::ReadTransaction trans(FROM_HERE, user_share_); |
289 | 289 |
290 sync_api::ReadNode bookmark_bar_node(&trans); | 290 sync_api::ReadNode bookmark_bar_node(&trans); |
291 if (!bookmark_bar_node.InitByIdLookup(bookmark_bar_sync_id)) { | 291 if (bookmark_bar_node.InitByIdLookup(bookmark_bar_sync_id) != |
| 292 sync_api::BaseNode::INIT_OK) { |
292 return false; | 293 return false; |
293 } | 294 } |
294 | 295 |
295 sync_api::ReadNode other_bookmarks_node(&trans); | 296 sync_api::ReadNode other_bookmarks_node(&trans); |
296 if (!other_bookmarks_node.InitByIdLookup(other_bookmarks_sync_id)) { | 297 if (other_bookmarks_node.InitByIdLookup(other_bookmarks_sync_id) != |
| 298 sync_api::BaseNode::INIT_OK) { |
297 return false; | 299 return false; |
298 } | 300 } |
299 | 301 |
300 sync_api::ReadNode mobile_bookmarks_node(&trans); | 302 sync_api::ReadNode mobile_bookmarks_node(&trans); |
301 if (has_mobile_folder && | 303 if (has_mobile_folder && |
302 !mobile_bookmarks_node.InitByIdLookup(mobile_bookmarks_sync_id)) { | 304 mobile_bookmarks_node.InitByIdLookup(mobile_bookmarks_sync_id) != |
| 305 sync_api::BaseNode::INIT_OK) { |
303 return false; | 306 return false; |
304 } | 307 } |
305 | 308 |
306 // Sync model has user created nodes if any of the permanent nodes has | 309 // Sync model has user created nodes if any of the permanent nodes has |
307 // children. | 310 // children. |
308 *has_nodes = bookmark_bar_node.HasChildren() || | 311 *has_nodes = bookmark_bar_node.HasChildren() || |
309 other_bookmarks_node.HasChildren() || | 312 other_bookmarks_node.HasChildren() || |
310 (has_mobile_folder && mobile_bookmarks_node.HasChildren()); | 313 (has_mobile_folder && mobile_bookmarks_node.HasChildren()); |
311 return true; | 314 return true; |
312 } | 315 } |
(...skipping 28 matching lines...) Expand all Loading... |
341 model_type()); | 344 model_type()); |
342 | 345 |
343 Associate(permanent_node, sync_id); | 346 Associate(permanent_node, sync_id); |
344 return SyncError(); | 347 return SyncError(); |
345 } | 348 } |
346 | 349 |
347 bool BookmarkModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, | 350 bool BookmarkModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, |
348 int64* sync_id) { | 351 int64* sync_id) { |
349 sync_api::ReadTransaction trans(FROM_HERE, user_share_); | 352 sync_api::ReadTransaction trans(FROM_HERE, user_share_); |
350 sync_api::ReadNode sync_node(&trans); | 353 sync_api::ReadNode sync_node(&trans); |
351 if (!sync_node.InitByTagLookup(tag.c_str())) | 354 if (sync_node.InitByTagLookup(tag.c_str()) != sync_api::BaseNode::INIT_OK) |
352 return false; | 355 return false; |
353 *sync_id = sync_node.GetId(); | 356 *sync_id = sync_node.GetId(); |
354 return true; | 357 return true; |
355 } | 358 } |
356 | 359 |
357 SyncError BookmarkModelAssociator::AssociateModels() { | 360 SyncError BookmarkModelAssociator::AssociateModels() { |
358 scoped_ptr<ScopedAssociationUpdater> association_updater( | 361 scoped_ptr<ScopedAssociationUpdater> association_updater( |
359 new ScopedAssociationUpdater(bookmark_model_)); | 362 new ScopedAssociationUpdater(bookmark_model_)); |
360 // Try to load model associations from persisted associations first. If that | 363 // Try to load model associations from persisted associations first. If that |
361 // succeeds, we don't need to run the complex model matching algorithm. | 364 // succeeds, we don't need to run the complex model matching algorithm. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 dfs_stack.push(other_bookmarks_sync_id); | 433 dfs_stack.push(other_bookmarks_sync_id); |
431 dfs_stack.push(bookmark_bar_sync_id); | 434 dfs_stack.push(bookmark_bar_sync_id); |
432 | 435 |
433 sync_api::WriteTransaction trans(FROM_HERE, user_share_); | 436 sync_api::WriteTransaction trans(FROM_HERE, user_share_); |
434 | 437 |
435 while (!dfs_stack.empty()) { | 438 while (!dfs_stack.empty()) { |
436 int64 sync_parent_id = dfs_stack.top(); | 439 int64 sync_parent_id = dfs_stack.top(); |
437 dfs_stack.pop(); | 440 dfs_stack.pop(); |
438 | 441 |
439 sync_api::ReadNode sync_parent(&trans); | 442 sync_api::ReadNode sync_parent(&trans); |
440 if (!sync_parent.InitByIdLookup(sync_parent_id)) { | 443 if (sync_parent.InitByIdLookup(sync_parent_id) != |
| 444 sync_api::BaseNode::INIT_OK) { |
441 return unrecoverable_error_handler_->CreateAndUploadError( | 445 return unrecoverable_error_handler_->CreateAndUploadError( |
442 FROM_HERE, | 446 FROM_HERE, |
443 "Failed to lookup node.", | 447 "Failed to lookup node.", |
444 model_type()); | 448 model_type()); |
445 } | 449 } |
446 // Only folder nodes are pushed on to the stack. | 450 // Only folder nodes are pushed on to the stack. |
447 DCHECK(sync_parent.GetIsFolder()); | 451 DCHECK(sync_parent.GetIsFolder()); |
448 | 452 |
449 const BookmarkNode* parent_node = GetChromeNodeFromSyncId(sync_parent_id); | 453 const BookmarkNode* parent_node = GetChromeNodeFromSyncId(sync_parent_id); |
450 DCHECK(parent_node->is_folder()); | 454 DCHECK(parent_node->is_folder()); |
451 | 455 |
452 BookmarkNodeFinder node_finder(parent_node); | 456 BookmarkNodeFinder node_finder(parent_node); |
453 | 457 |
454 int index = 0; | 458 int index = 0; |
455 int64 sync_child_id = sync_parent.GetFirstChildId(); | 459 int64 sync_child_id = sync_parent.GetFirstChildId(); |
456 while (sync_child_id != sync_api::kInvalidId) { | 460 while (sync_child_id != sync_api::kInvalidId) { |
457 sync_api::WriteNode sync_child_node(&trans); | 461 sync_api::WriteNode sync_child_node(&trans); |
458 if (!sync_child_node.InitByIdLookup(sync_child_id)) { | 462 if (sync_child_node.InitByIdLookup(sync_child_id) != |
| 463 sync_api::BaseNode::INIT_OK) { |
459 return unrecoverable_error_handler_->CreateAndUploadError( | 464 return unrecoverable_error_handler_->CreateAndUploadError( |
460 FROM_HERE, | 465 FROM_HERE, |
461 "Failed to lookup node.", | 466 "Failed to lookup node.", |
462 model_type()); | 467 model_type()); |
463 } | 468 } |
464 | 469 |
465 const BookmarkNode* child_node = NULL; | 470 const BookmarkNode* child_node = NULL; |
466 child_node = node_finder.FindBookmarkNode(sync_child_node); | 471 child_node = node_finder.FindBookmarkNode(sync_child_node); |
467 if (child_node) { | 472 if (child_node) { |
468 bookmark_model_->Move(child_node, parent_node, index); | 473 bookmark_model_->Move(child_node, parent_node, index); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 return; | 545 return; |
541 } | 546 } |
542 | 547 |
543 sync_api::WriteTransaction trans(FROM_HERE, user_share_); | 548 sync_api::WriteTransaction trans(FROM_HERE, user_share_); |
544 DirtyAssociationsSyncIds::iterator iter; | 549 DirtyAssociationsSyncIds::iterator iter; |
545 for (iter = dirty_associations_sync_ids_.begin(); | 550 for (iter = dirty_associations_sync_ids_.begin(); |
546 iter != dirty_associations_sync_ids_.end(); | 551 iter != dirty_associations_sync_ids_.end(); |
547 ++iter) { | 552 ++iter) { |
548 int64 sync_id = *iter; | 553 int64 sync_id = *iter; |
549 sync_api::WriteNode sync_node(&trans); | 554 sync_api::WriteNode sync_node(&trans); |
550 if (!sync_node.InitByIdLookup(sync_id)) { | 555 if (sync_node.InitByIdLookup(sync_id) != sync_api::BaseNode::INIT_OK) { |
551 unrecoverable_error_handler_->OnUnrecoverableError(FROM_HERE, | 556 unrecoverable_error_handler_->OnUnrecoverableError(FROM_HERE, |
552 "Could not lookup bookmark node for ID persistence."); | 557 "Could not lookup bookmark node for ID persistence."); |
553 return; | 558 return; |
554 } | 559 } |
555 const BookmarkNode* node = GetChromeNodeFromSyncId(sync_id); | 560 const BookmarkNode* node = GetChromeNodeFromSyncId(sync_id); |
556 if (node) | 561 if (node) |
557 sync_node.SetExternalId(node->id()); | 562 sync_node.SetExternalId(node->id()); |
558 else | 563 else |
559 NOTREACHED(); | 564 NOTREACHED(); |
560 } | 565 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 sync_api::ReadTransaction trans(FROM_HERE, user_share_); | 609 sync_api::ReadTransaction trans(FROM_HERE, user_share_); |
605 | 610 |
606 // Count total number of nodes in sync model so that we can compare that | 611 // Count total number of nodes in sync model so that we can compare that |
607 // with the total number of nodes in the bookmark model. | 612 // with the total number of nodes in the bookmark model. |
608 size_t sync_node_count = 0; | 613 size_t sync_node_count = 0; |
609 while (!dfs_stack.empty()) { | 614 while (!dfs_stack.empty()) { |
610 int64 parent_id = dfs_stack.top(); | 615 int64 parent_id = dfs_stack.top(); |
611 dfs_stack.pop(); | 616 dfs_stack.pop(); |
612 ++sync_node_count; | 617 ++sync_node_count; |
613 sync_api::ReadNode sync_parent(&trans); | 618 sync_api::ReadNode sync_parent(&trans); |
614 if (!sync_parent.InitByIdLookup(parent_id)) { | 619 if (sync_parent.InitByIdLookup(parent_id) != sync_api::BaseNode::INIT_OK) { |
615 return false; | 620 return false; |
616 } | 621 } |
617 | 622 |
618 int64 external_id = sync_parent.GetExternalId(); | 623 int64 external_id = sync_parent.GetExternalId(); |
619 if (external_id == 0) | 624 if (external_id == 0) |
620 return false; | 625 return false; |
621 | 626 |
622 const BookmarkNode* node = id_index.Find(external_id); | 627 const BookmarkNode* node = id_index.Find(external_id); |
623 if (!node) | 628 if (!node) |
624 return false; | 629 return false; |
625 | 630 |
626 // Don't try to call NodesMatch on permanent nodes like bookmark bar and | 631 // Don't try to call NodesMatch on permanent nodes like bookmark bar and |
627 // other bookmarks. They are not expected to match. | 632 // other bookmarks. They are not expected to match. |
628 if (node != bookmark_model_->bookmark_bar_node() && | 633 if (node != bookmark_model_->bookmark_bar_node() && |
629 node != bookmark_model_->mobile_node() && | 634 node != bookmark_model_->mobile_node() && |
630 node != bookmark_model_->other_node() && | 635 node != bookmark_model_->other_node() && |
631 !NodesMatch(node, &sync_parent)) | 636 !NodesMatch(node, &sync_parent)) |
632 return false; | 637 return false; |
633 | 638 |
634 Associate(node, sync_parent.GetId()); | 639 Associate(node, sync_parent.GetId()); |
635 | 640 |
636 // Add all children of the current node to the stack. | 641 // Add all children of the current node to the stack. |
637 int64 child_id = sync_parent.GetFirstChildId(); | 642 int64 child_id = sync_parent.GetFirstChildId(); |
638 while (child_id != sync_api::kInvalidId) { | 643 while (child_id != sync_api::kInvalidId) { |
639 dfs_stack.push(child_id); | 644 dfs_stack.push(child_id); |
640 sync_api::ReadNode child_node(&trans); | 645 sync_api::ReadNode child_node(&trans); |
641 if (!child_node.InitByIdLookup(child_id)) { | 646 if (child_node.InitByIdLookup(child_id) != sync_api::BaseNode::INIT_OK) { |
642 return false; | 647 return false; |
643 } | 648 } |
644 child_id = child_node.GetSuccessorId(); | 649 child_id = child_node.GetSuccessorId(); |
645 } | 650 } |
646 } | 651 } |
647 DCHECK(dfs_stack.empty()); | 652 DCHECK(dfs_stack.empty()); |
648 | 653 |
649 // It's possible that the number of nodes in the bookmark model is not the | 654 // It's possible that the number of nodes in the bookmark model is not the |
650 // same as number of nodes in the sync model. This can happen when the sync | 655 // same as number of nodes in the sync model. This can happen when the sync |
651 // model doesn't get a chance to persist its changes, for example when | 656 // model doesn't get a chance to persist its changes, for example when |
652 // Chrome does not shut down gracefully. In such cases we can't trust the | 657 // Chrome does not shut down gracefully. In such cases we can't trust the |
653 // loaded associations. | 658 // loaded associations. |
654 return sync_node_count == id_index.count(); | 659 return sync_node_count == id_index.count(); |
655 } | 660 } |
656 | 661 |
657 bool BookmarkModelAssociator::CryptoReadyIfNecessary() { | 662 bool BookmarkModelAssociator::CryptoReadyIfNecessary() { |
658 // We only access the cryptographer while holding a transaction. | 663 // We only access the cryptographer while holding a transaction. |
659 sync_api::ReadTransaction trans(FROM_HERE, user_share_); | 664 sync_api::ReadTransaction trans(FROM_HERE, user_share_); |
660 const syncable::ModelTypeSet encrypted_types = | 665 const syncable::ModelTypeSet encrypted_types = |
661 sync_api::GetEncryptedTypes(&trans); | 666 sync_api::GetEncryptedTypes(&trans); |
662 return !encrypted_types.Has(syncable::BOOKMARKS) || | 667 return !encrypted_types.Has(syncable::BOOKMARKS) || |
663 trans.GetCryptographer()->is_ready(); | 668 trans.GetCryptographer()->is_ready(); |
664 } | 669 } |
665 | 670 |
666 } // namespace browser_sync | 671 } // namespace browser_sync |
OLD | NEW |