| 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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 SyncError BookmarkModelAssociator::DisassociateModels() { | 216 csync::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 SyncError(); | 220 return csync::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() ? csync::kInvalidId : iter->second; | 225 return iter == id_map_.end() ? csync::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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 if (bookmark->is_url()) { | 324 if (bookmark->is_url()) { |
| 325 if (bookmark->url() != sync_node->GetURL()) | 325 if (bookmark->url() != sync_node->GetURL()) |
| 326 return false; | 326 return false; |
| 327 } | 327 } |
| 328 // Don't compare favicons here, because they are not really | 328 // Don't compare favicons here, because they are not really |
| 329 // user-updated and we don't have versioning information -- a site changing | 329 // user-updated and we don't have versioning information -- a site changing |
| 330 // its favicon shouldn't result in a bookmark mismatch. | 330 // its favicon shouldn't result in a bookmark mismatch. |
| 331 return true; | 331 return true; |
| 332 } | 332 } |
| 333 | 333 |
| 334 SyncError BookmarkModelAssociator::AssociateTaggedPermanentNode( | 334 csync::SyncError BookmarkModelAssociator::AssociateTaggedPermanentNode( |
| 335 const BookmarkNode* permanent_node, const std::string&tag) { | 335 const BookmarkNode* permanent_node, const std::string&tag) { |
| 336 // Do nothing if |permanent_node| is already initialized and associated. | 336 // Do nothing if |permanent_node| is already initialized and associated. |
| 337 int64 sync_id = GetSyncIdFromChromeId(permanent_node->id()); | 337 int64 sync_id = GetSyncIdFromChromeId(permanent_node->id()); |
| 338 if (sync_id != csync::kInvalidId) | 338 if (sync_id != csync::kInvalidId) |
| 339 return SyncError(); | 339 return csync::SyncError(); |
| 340 if (!GetSyncIdForTaggedNode(tag, &sync_id)) | 340 if (!GetSyncIdForTaggedNode(tag, &sync_id)) |
| 341 return unrecoverable_error_handler_->CreateAndUploadError( | 341 return unrecoverable_error_handler_->CreateAndUploadError( |
| 342 FROM_HERE, | 342 FROM_HERE, |
| 343 "Permanent node not found", | 343 "Permanent node not found", |
| 344 model_type()); | 344 model_type()); |
| 345 | 345 |
| 346 Associate(permanent_node, sync_id); | 346 Associate(permanent_node, sync_id); |
| 347 return SyncError(); | 347 return csync::SyncError(); |
| 348 } | 348 } |
| 349 | 349 |
| 350 bool BookmarkModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, | 350 bool BookmarkModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, |
| 351 int64* sync_id) { | 351 int64* sync_id) { |
| 352 csync::ReadTransaction trans(FROM_HERE, user_share_); | 352 csync::ReadTransaction trans(FROM_HERE, user_share_); |
| 353 csync::ReadNode sync_node(&trans); | 353 csync::ReadNode sync_node(&trans); |
| 354 if (sync_node.InitByTagLookup(tag.c_str()) != csync::BaseNode::INIT_OK) | 354 if (sync_node.InitByTagLookup(tag.c_str()) != csync::BaseNode::INIT_OK) |
| 355 return false; | 355 return false; |
| 356 *sync_id = sync_node.GetId(); | 356 *sync_id = sync_node.GetId(); |
| 357 return true; | 357 return true; |
| 358 } | 358 } |
| 359 | 359 |
| 360 SyncError BookmarkModelAssociator::AssociateModels() { | 360 csync::SyncError BookmarkModelAssociator::AssociateModels() { |
| 361 scoped_ptr<ScopedAssociationUpdater> association_updater( | 361 scoped_ptr<ScopedAssociationUpdater> association_updater( |
| 362 new ScopedAssociationUpdater(bookmark_model_)); | 362 new ScopedAssociationUpdater(bookmark_model_)); |
| 363 // Try to load model associations from persisted associations first. If that | 363 // Try to load model associations from persisted associations first. If that |
| 364 // 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. |
| 365 if (LoadAssociations()) | 365 if (LoadAssociations()) |
| 366 return SyncError(); | 366 return csync::SyncError(); |
| 367 | 367 |
| 368 DisassociateModels(); | 368 DisassociateModels(); |
| 369 | 369 |
| 370 // We couldn't load model associations from persisted associations. So build | 370 // We couldn't load model associations from persisted associations. So build |
| 371 // them. | 371 // them. |
| 372 return BuildAssociations(); | 372 return BuildAssociations(); |
| 373 } | 373 } |
| 374 | 374 |
| 375 SyncError BookmarkModelAssociator::BuildAssociations() { | 375 csync::SyncError BookmarkModelAssociator::BuildAssociations() { |
| 376 // Algorithm description: | 376 // Algorithm description: |
| 377 // Match up the roots and recursively do the following: | 377 // Match up the roots and recursively do the following: |
| 378 // * For each sync node for the current sync parent node, find the best | 378 // * For each sync node for the current sync parent node, find the best |
| 379 // matching bookmark node under the corresponding bookmark parent node. | 379 // matching bookmark node under the corresponding bookmark parent node. |
| 380 // If no matching node is found, create a new bookmark node in the same | 380 // If no matching node is found, create a new bookmark node in the same |
| 381 // position as the corresponding sync node. | 381 // position as the corresponding sync node. |
| 382 // If a matching node is found, update the properties of it from the | 382 // If a matching node is found, update the properties of it from the |
| 383 // corresponding sync node. | 383 // corresponding sync node. |
| 384 // * When all children sync nodes are done, add the extra children bookmark | 384 // * When all children sync nodes are done, add the extra children bookmark |
| 385 // nodes to the sync parent node. | 385 // nodes to the sync parent node. |
| 386 // | 386 // |
| 387 // This algorithm will do a good job of merging when folder names are a good | 387 // This algorithm will do a good job of merging when folder names are a good |
| 388 // indicator of the two folders being the same. It will handle reordering and | 388 // indicator of the two folders being the same. It will handle reordering and |
| 389 // new node addition very well (without creating duplicates). | 389 // new node addition very well (without creating duplicates). |
| 390 // This algorithm will not do well if the folder name has changes but the | 390 // This algorithm will not do well if the folder name has changes but the |
| 391 // children under them are all the same. | 391 // children under them are all the same. |
| 392 | 392 |
| 393 SyncError error; | 393 csync::SyncError error; |
| 394 DCHECK(bookmark_model_->IsLoaded()); | 394 DCHECK(bookmark_model_->IsLoaded()); |
| 395 | 395 |
| 396 // To prime our association, we associate the top-level nodes, Bookmark Bar | 396 // To prime our association, we associate the top-level nodes, Bookmark Bar |
| 397 // and Other Bookmarks. | 397 // and Other Bookmarks. |
| 398 error = AssociateTaggedPermanentNode(bookmark_model_->other_node(), | 398 error = AssociateTaggedPermanentNode(bookmark_model_->other_node(), |
| 399 kOtherBookmarksTag); | 399 kOtherBookmarksTag); |
| 400 if (error.IsSet()) { | 400 if (error.IsSet()) { |
| 401 return error; | 401 return error; |
| 402 } | 402 } |
| 403 | 403 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 FROM_HERE, | 514 FROM_HERE, |
| 515 "Failed to create sync node.", | 515 "Failed to create sync node.", |
| 516 model_type()); | 516 model_type()); |
| 517 } | 517 } |
| 518 if (parent_node->GetChild(i)->is_folder()) | 518 if (parent_node->GetChild(i)->is_folder()) |
| 519 dfs_stack.push(sync_child_id); | 519 dfs_stack.push(sync_child_id); |
| 520 number_of_new_sync_nodes_created_at_association_++; | 520 number_of_new_sync_nodes_created_at_association_++; |
| 521 } | 521 } |
| 522 } | 522 } |
| 523 | 523 |
| 524 return SyncError(); | 524 return csync::SyncError(); |
| 525 } | 525 } |
| 526 | 526 |
| 527 void BookmarkModelAssociator::PostPersistAssociationsTask() { | 527 void BookmarkModelAssociator::PostPersistAssociationsTask() { |
| 528 // No need to post a task if a task is already pending. | 528 // No need to post a task if a task is already pending. |
| 529 if (weak_factory_.HasWeakPtrs()) | 529 if (weak_factory_.HasWeakPtrs()) |
| 530 return; | 530 return; |
| 531 MessageLoop::current()->PostTask( | 531 MessageLoop::current()->PostTask( |
| 532 FROM_HERE, | 532 FROM_HERE, |
| 533 base::Bind( | 533 base::Bind( |
| 534 &BookmarkModelAssociator::PersistAssociations, | 534 &BookmarkModelAssociator::PersistAssociations, |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 bool BookmarkModelAssociator::CryptoReadyIfNecessary() { | 663 bool BookmarkModelAssociator::CryptoReadyIfNecessary() { |
| 664 // We only access the cryptographer while holding a transaction. | 664 // We only access the cryptographer while holding a transaction. |
| 665 csync::ReadTransaction trans(FROM_HERE, user_share_); | 665 csync::ReadTransaction trans(FROM_HERE, user_share_); |
| 666 const syncable::ModelTypeSet encrypted_types = | 666 const syncable::ModelTypeSet encrypted_types = |
| 667 csync::GetEncryptedTypes(&trans); | 667 csync::GetEncryptedTypes(&trans); |
| 668 return !encrypted_types.Has(syncable::BOOKMARKS) || | 668 return !encrypted_types.Has(syncable::BOOKMARKS) || |
| 669 trans.GetCryptographer()->is_ready(); | 669 trans.GetCryptographer()->is_ready(); |
| 670 } | 670 } |
| 671 | 671 |
| 672 } // namespace browser_sync | 672 } // namespace browser_sync |
| OLD | NEW |