| 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 |