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 |