OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/hash_tables.h" | 10 #include "base/hash_tables.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 // | 40 // |
41 // It is the responsibility of something upstream (at time of writing, | 41 // It is the responsibility of something upstream (at time of writing, |
42 // the sync server) to create these tagged nodes when initializing sync | 42 // the sync server) to create these tagged nodes when initializing sync |
43 // for the first time for a user. Thus, once the backend finishes | 43 // for the first time for a user. Thus, once the backend finishes |
44 // initializing, the ProfileSyncService can rely on the presence of tagged | 44 // initializing, the ProfileSyncService can rely on the presence of tagged |
45 // nodes. | 45 // nodes. |
46 // | 46 // |
47 // TODO(ncarter): Pull these tags from an external protocol specification | 47 // TODO(ncarter): Pull these tags from an external protocol specification |
48 // rather than hardcoding them here. | 48 // rather than hardcoding them here. |
49 static const char kBookmarkBarTag[] = "bookmark_bar"; | 49 static const char kBookmarkBarTag[] = "bookmark_bar"; |
50 static const char kSyncedBookmarksTag[] = "synced_bookmarks"; | 50 static const char kMobileBookmarksTag[] = "synced_bookmarks"; |
51 static const char kOtherBookmarksTag[] = "other_bookmarks"; | 51 static const char kOtherBookmarksTag[] = "other_bookmarks"; |
52 static const char kServerError[] = | 52 static const char kServerError[] = |
53 "Server did not create top-level nodes. Possibly we are running against " | 53 "Server did not create top-level nodes. Possibly we are running against " |
54 "an out-of-date server?"; | 54 "an out-of-date server?"; |
55 | 55 |
56 // Bookmark comparer for map of bookmark nodes. | 56 // Bookmark comparer for map of bookmark nodes. |
57 class BookmarkComparer { | 57 class BookmarkComparer { |
58 public: | 58 public: |
59 // Compares the two given nodes and returns whether node1 should appear | 59 // Compares the two given nodes and returns whether node1 should appear |
60 // before node2 in strict weak ordering. | 60 // before node2 in strict weak ordering. |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 if (iter == id_map_inverse_.end()) | 236 if (iter == id_map_inverse_.end()) |
237 return; | 237 return; |
238 id_map_.erase(iter->second->id()); | 238 id_map_.erase(iter->second->id()); |
239 id_map_inverse_.erase(iter); | 239 id_map_inverse_.erase(iter); |
240 dirty_associations_sync_ids_.erase(sync_id); | 240 dirty_associations_sync_ids_.erase(sync_id); |
241 } | 241 } |
242 | 242 |
243 bool BookmarkModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) { | 243 bool BookmarkModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) { |
244 DCHECK(has_nodes); | 244 DCHECK(has_nodes); |
245 *has_nodes = false; | 245 *has_nodes = false; |
246 bool has_synced_folder = true; | 246 bool has_mobile_folder = true; |
247 int64 bookmark_bar_sync_id; | 247 int64 bookmark_bar_sync_id; |
248 if (!GetSyncIdForTaggedNode(kBookmarkBarTag, &bookmark_bar_sync_id)) { | 248 if (!GetSyncIdForTaggedNode(kBookmarkBarTag, &bookmark_bar_sync_id)) { |
249 return false; | 249 return false; |
250 } | 250 } |
251 int64 other_bookmarks_sync_id; | 251 int64 other_bookmarks_sync_id; |
252 if (!GetSyncIdForTaggedNode(kOtherBookmarksTag, &other_bookmarks_sync_id)) { | 252 if (!GetSyncIdForTaggedNode(kOtherBookmarksTag, &other_bookmarks_sync_id)) { |
253 return false; | 253 return false; |
254 } | 254 } |
255 int64 synced_bookmarks_sync_id; | 255 int64 mobile_bookmarks_sync_id; |
256 if (!GetSyncIdForTaggedNode(kSyncedBookmarksTag, &synced_bookmarks_sync_id)) { | 256 if (!GetSyncIdForTaggedNode(kMobileBookmarksTag, &mobile_bookmarks_sync_id)) { |
257 has_synced_folder = false; | 257 has_mobile_folder = false; |
258 } | 258 } |
259 | 259 |
260 sync_api::ReadTransaction trans(FROM_HERE, user_share_); | 260 sync_api::ReadTransaction trans(FROM_HERE, user_share_); |
261 | 261 |
262 sync_api::ReadNode bookmark_bar_node(&trans); | 262 sync_api::ReadNode bookmark_bar_node(&trans); |
263 if (!bookmark_bar_node.InitByIdLookup(bookmark_bar_sync_id)) { | 263 if (!bookmark_bar_node.InitByIdLookup(bookmark_bar_sync_id)) { |
264 return false; | 264 return false; |
265 } | 265 } |
266 | 266 |
267 sync_api::ReadNode other_bookmarks_node(&trans); | 267 sync_api::ReadNode other_bookmarks_node(&trans); |
268 if (!other_bookmarks_node.InitByIdLookup(other_bookmarks_sync_id)) { | 268 if (!other_bookmarks_node.InitByIdLookup(other_bookmarks_sync_id)) { |
269 return false; | 269 return false; |
270 } | 270 } |
271 | 271 |
272 sync_api::ReadNode synced_bookmarks_node(&trans); | 272 sync_api::ReadNode mobile_bookmarks_node(&trans); |
273 if (has_synced_folder && | 273 if (has_mobile_folder && |
274 !synced_bookmarks_node.InitByIdLookup(synced_bookmarks_sync_id)) { | 274 !mobile_bookmarks_node.InitByIdLookup(mobile_bookmarks_sync_id)) { |
275 return false; | 275 return false; |
276 } | 276 } |
277 | 277 |
278 // Sync model has user created nodes if either one of the permanent nodes | 278 // Sync model has user created nodes if any of the permanent nodes has |
279 // has children. | 279 // children. |
280 *has_nodes = bookmark_bar_node.HasChildren() || | 280 *has_nodes = bookmark_bar_node.HasChildren() || |
281 other_bookmarks_node.HasChildren() || | 281 other_bookmarks_node.HasChildren() || |
282 (has_synced_folder && synced_bookmarks_node.HasChildren()); | 282 (has_mobile_folder && mobile_bookmarks_node.HasChildren()); |
283 return true; | 283 return true; |
284 } | 284 } |
285 | 285 |
286 bool BookmarkModelAssociator::NodesMatch( | 286 bool BookmarkModelAssociator::NodesMatch( |
287 const BookmarkNode* bookmark, | 287 const BookmarkNode* bookmark, |
288 const sync_api::BaseNode* sync_node) const { | 288 const sync_api::BaseNode* sync_node) const { |
289 if (bookmark->GetTitle() != UTF8ToUTF16(sync_node->GetTitle())) | 289 if (bookmark->GetTitle() != UTF8ToUTF16(sync_node->GetTitle())) |
290 return false; | 290 return false; |
291 if (bookmark->is_folder() != sync_node->GetIsFolder()) | 291 if (bookmark->is_folder() != sync_node->GetIsFolder()) |
292 return false; | 292 return false; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 if (!AssociateTaggedPermanentNode(bookmark_model_->other_node(), | 361 if (!AssociateTaggedPermanentNode(bookmark_model_->other_node(), |
362 kOtherBookmarksTag)) { | 362 kOtherBookmarksTag)) { |
363 error->Reset(FROM_HERE, kServerError, model_type()); | 363 error->Reset(FROM_HERE, kServerError, model_type()); |
364 return false; | 364 return false; |
365 } | 365 } |
366 if (!AssociateTaggedPermanentNode(bookmark_model_->bookmark_bar_node(), | 366 if (!AssociateTaggedPermanentNode(bookmark_model_->bookmark_bar_node(), |
367 kBookmarkBarTag)) { | 367 kBookmarkBarTag)) { |
368 error->Reset(FROM_HERE, kServerError, model_type()); | 368 error->Reset(FROM_HERE, kServerError, model_type()); |
369 return false; | 369 return false; |
370 } | 370 } |
371 if (!AssociateTaggedPermanentNode(bookmark_model_->synced_node(), | 371 if (!AssociateTaggedPermanentNode(bookmark_model_->mobile_node(), |
372 kSyncedBookmarksTag) && | 372 kMobileBookmarksTag)) { |
373 // We only need to ensure that the "synced bookmarks" folder exists on the | |
374 // server if the command line flag is set. | |
375 CommandLine::ForCurrentProcess()->HasSwitch( | |
376 switches::kEnableSyncedBookmarksFolder)) { | |
377 error->Reset(FROM_HERE, kServerError, model_type()); | 373 error->Reset(FROM_HERE, kServerError, model_type()); |
378 return false; | 374 return false; |
379 } | 375 } |
380 int64 bookmark_bar_sync_id = GetSyncIdFromChromeId( | 376 int64 bookmark_bar_sync_id = GetSyncIdFromChromeId( |
381 bookmark_model_->bookmark_bar_node()->id()); | 377 bookmark_model_->bookmark_bar_node()->id()); |
382 DCHECK_NE(bookmark_bar_sync_id, sync_api::kInvalidId); | 378 DCHECK_NE(bookmark_bar_sync_id, sync_api::kInvalidId); |
383 int64 other_bookmarks_sync_id = GetSyncIdFromChromeId( | 379 int64 other_bookmarks_sync_id = GetSyncIdFromChromeId( |
384 bookmark_model_->other_node()->id()); | 380 bookmark_model_->other_node()->id()); |
385 DCHECK_NE(other_bookmarks_sync_id, sync_api::kInvalidId); | 381 DCHECK_NE(other_bookmarks_sync_id, sync_api::kInvalidId); |
386 int64 synced_bookmarks_sync_id = GetSyncIdFromChromeId( | 382 int64 mobile_bookmarks_sync_id = GetSyncIdFromChromeId( |
387 bookmark_model_->synced_node()->id()); | 383 bookmark_model_->mobile_node()->id()); |
388 if (CommandLine::ForCurrentProcess()->HasSwitch( | 384 DCHECK_NE(mobile_bookmarks_sync_id, sync_api::kInvalidId); |
389 switches::kEnableSyncedBookmarksFolder)) { | |
390 DCHECK_NE(synced_bookmarks_sync_id, sync_api::kInvalidId); | |
391 } | |
392 | 385 |
393 std::stack<int64> dfs_stack; | 386 std::stack<int64> dfs_stack; |
394 if (synced_bookmarks_sync_id != sync_api::kInvalidId) | 387 if (mobile_bookmarks_sync_id != sync_api::kInvalidId) |
395 dfs_stack.push(synced_bookmarks_sync_id); | 388 dfs_stack.push(mobile_bookmarks_sync_id); |
396 dfs_stack.push(other_bookmarks_sync_id); | 389 dfs_stack.push(other_bookmarks_sync_id); |
397 dfs_stack.push(bookmark_bar_sync_id); | 390 dfs_stack.push(bookmark_bar_sync_id); |
398 | 391 |
399 sync_api::WriteTransaction trans(FROM_HERE, user_share_); | 392 sync_api::WriteTransaction trans(FROM_HERE, user_share_); |
400 | 393 |
401 while (!dfs_stack.empty()) { | 394 while (!dfs_stack.empty()) { |
402 int64 sync_parent_id = dfs_stack.top(); | 395 int64 sync_parent_id = dfs_stack.top(); |
403 dfs_stack.pop(); | 396 dfs_stack.pop(); |
404 | 397 |
405 sync_api::ReadNode sync_parent(&trans); | 398 sync_api::ReadNode sync_parent(&trans); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 int64 bookmark_bar_id; | 517 int64 bookmark_bar_id; |
525 if (!GetSyncIdForTaggedNode(kBookmarkBarTag, &bookmark_bar_id)) { | 518 if (!GetSyncIdForTaggedNode(kBookmarkBarTag, &bookmark_bar_id)) { |
526 // We should always be able to find the permanent nodes. | 519 // We should always be able to find the permanent nodes. |
527 return false; | 520 return false; |
528 } | 521 } |
529 int64 other_bookmarks_id; | 522 int64 other_bookmarks_id; |
530 if (!GetSyncIdForTaggedNode(kOtherBookmarksTag, &other_bookmarks_id)) { | 523 if (!GetSyncIdForTaggedNode(kOtherBookmarksTag, &other_bookmarks_id)) { |
531 // We should always be able to find the permanent nodes. | 524 // We should always be able to find the permanent nodes. |
532 return false; | 525 return false; |
533 } | 526 } |
534 int64 synced_bookmarks_id = -1; | 527 int64 mobile_bookmarks_id = -1; |
535 if (!GetSyncIdForTaggedNode(kSyncedBookmarksTag, &synced_bookmarks_id) && | 528 if (!GetSyncIdForTaggedNode(kMobileBookmarksTag, &mobile_bookmarks_id)) { |
536 CommandLine::ForCurrentProcess()->HasSwitch( | |
537 switches::kEnableSyncedBookmarksFolder)) { | |
538 | |
539 // We should always be able to find the permanent nodes. | 529 // We should always be able to find the permanent nodes. |
540 return false; | 530 return false; |
541 } | 531 } |
542 | 532 |
543 // Build a bookmark node ID index since we are going to repeatedly search for | 533 // Build a bookmark node ID index since we are going to repeatedly search for |
544 // bookmark nodes by their IDs. | 534 // bookmark nodes by their IDs. |
545 BookmarkNodeIdIndex id_index; | 535 BookmarkNodeIdIndex id_index; |
546 id_index.AddAll(bookmark_model_->bookmark_bar_node()); | 536 id_index.AddAll(bookmark_model_->bookmark_bar_node()); |
547 id_index.AddAll(bookmark_model_->other_node()); | 537 id_index.AddAll(bookmark_model_->other_node()); |
548 id_index.AddAll(bookmark_model_->synced_node()); | 538 id_index.AddAll(bookmark_model_->mobile_node()); |
549 | 539 |
550 std::stack<int64> dfs_stack; | 540 std::stack<int64> dfs_stack; |
551 if (synced_bookmarks_id != -1) | 541 dfs_stack.push(mobile_bookmarks_id); |
552 dfs_stack.push(synced_bookmarks_id); | |
553 dfs_stack.push(other_bookmarks_id); | 542 dfs_stack.push(other_bookmarks_id); |
554 dfs_stack.push(bookmark_bar_id); | 543 dfs_stack.push(bookmark_bar_id); |
555 | 544 |
556 sync_api::ReadTransaction trans(FROM_HERE, user_share_); | 545 sync_api::ReadTransaction trans(FROM_HERE, user_share_); |
557 | 546 |
558 // Count total number of nodes in sync model so that we can compare that | 547 // Count total number of nodes in sync model so that we can compare that |
559 // with the total number of nodes in the bookmark model. | 548 // with the total number of nodes in the bookmark model. |
560 size_t sync_node_count = 0; | 549 size_t sync_node_count = 0; |
561 while (!dfs_stack.empty()) { | 550 while (!dfs_stack.empty()) { |
562 int64 parent_id = dfs_stack.top(); | 551 int64 parent_id = dfs_stack.top(); |
563 dfs_stack.pop(); | 552 dfs_stack.pop(); |
564 ++sync_node_count; | 553 ++sync_node_count; |
565 sync_api::ReadNode sync_parent(&trans); | 554 sync_api::ReadNode sync_parent(&trans); |
566 if (!sync_parent.InitByIdLookup(parent_id)) { | 555 if (!sync_parent.InitByIdLookup(parent_id)) { |
567 return false; | 556 return false; |
568 } | 557 } |
569 | 558 |
570 int64 external_id = sync_parent.GetExternalId(); | 559 int64 external_id = sync_parent.GetExternalId(); |
571 if (external_id == 0) | 560 if (external_id == 0) |
572 return false; | 561 return false; |
573 | 562 |
574 const BookmarkNode* node = id_index.Find(external_id); | 563 const BookmarkNode* node = id_index.Find(external_id); |
575 if (!node) | 564 if (!node) |
576 return false; | 565 return false; |
577 | 566 |
578 // Don't try to call NodesMatch on permanent nodes like bookmark bar and | 567 // Don't try to call NodesMatch on permanent nodes like bookmark bar and |
579 // other bookmarks. They are not expected to match. | 568 // other bookmarks. They are not expected to match. |
580 if (node != bookmark_model_->bookmark_bar_node() && | 569 if (node != bookmark_model_->bookmark_bar_node() && |
581 node != bookmark_model_->synced_node() && | 570 node != bookmark_model_->mobile_node() && |
582 node != bookmark_model_->other_node() && | 571 node != bookmark_model_->other_node() && |
583 !NodesMatch(node, &sync_parent)) | 572 !NodesMatch(node, &sync_parent)) |
584 return false; | 573 return false; |
585 | 574 |
586 Associate(node, sync_parent.GetId()); | 575 Associate(node, sync_parent.GetId()); |
587 | 576 |
588 // Add all children of the current node to the stack. | 577 // Add all children of the current node to the stack. |
589 int64 child_id = sync_parent.GetFirstChildId(); | 578 int64 child_id = sync_parent.GetFirstChildId(); |
590 while (child_id != sync_api::kInvalidId) { | 579 while (child_id != sync_api::kInvalidId) { |
591 dfs_stack.push(child_id); | 580 dfs_stack.push(child_id); |
(...skipping 17 matching lines...) Expand all Loading... |
609 bool BookmarkModelAssociator::CryptoReadyIfNecessary() { | 598 bool BookmarkModelAssociator::CryptoReadyIfNecessary() { |
610 // We only access the cryptographer while holding a transaction. | 599 // We only access the cryptographer while holding a transaction. |
611 sync_api::ReadTransaction trans(FROM_HERE, user_share_); | 600 sync_api::ReadTransaction trans(FROM_HERE, user_share_); |
612 const syncable::ModelTypeSet& encrypted_types = | 601 const syncable::ModelTypeSet& encrypted_types = |
613 sync_api::GetEncryptedTypes(&trans); | 602 sync_api::GetEncryptedTypes(&trans); |
614 return encrypted_types.count(syncable::BOOKMARKS) == 0 || | 603 return encrypted_types.count(syncable::BOOKMARKS) == 0 || |
615 trans.GetCryptographer()->is_ready(); | 604 trans.GetCryptographer()->is_ready(); |
616 } | 605 } |
617 | 606 |
618 } // namespace browser_sync | 607 } // namespace browser_sync |
OLD | NEW |