Index: chrome/browser/bookmarks/bookmark_codec.cc |
diff --git a/chrome/browser/bookmarks/bookmark_codec.cc b/chrome/browser/bookmarks/bookmark_codec.cc |
index dd145b39f49da5e4a53f1db36ac54c1a629fdc5b..56b0c2525e207845e684d6a5e432cb35d9c13905 100644 |
--- a/chrome/browser/bookmarks/bookmark_codec.cc |
+++ b/chrome/browser/bookmarks/bookmark_codec.cc |
@@ -19,6 +19,7 @@ using base::Time; |
const char* BookmarkCodec::kRootsKey = "roots"; |
const char* BookmarkCodec::kRootFolderNameKey = "bookmark_bar"; |
const char* BookmarkCodec::kOtherBookmarkFolderNameKey = "other"; |
+const char* BookmarkCodec::kSyncedBookmarkFolderNameKey = "synced"; |
const char* BookmarkCodec::kVersionKey = "version"; |
const char* BookmarkCodec::kChecksumKey = "checksum"; |
const char* BookmarkCodec::kIdKey = "id"; |
@@ -43,16 +44,19 @@ BookmarkCodec::BookmarkCodec() |
BookmarkCodec::~BookmarkCodec() {} |
Value* BookmarkCodec::Encode(BookmarkModel* model) { |
- return Encode(model->GetBookmarkBarNode(), model->other_node()); |
+ return Encode(model->GetBookmarkBarNode(), model->other_node(), |
+ model->synced_node()); |
} |
Value* BookmarkCodec::Encode(const BookmarkNode* bookmark_bar_node, |
- const BookmarkNode* other_folder_node) { |
+ const BookmarkNode* other_folder_node, |
+ const BookmarkNode* synced_folder_node) { |
ids_reassigned_ = false; |
InitializeChecksum(); |
DictionaryValue* roots = new DictionaryValue(); |
roots->Set(kRootFolderNameKey, EncodeNode(bookmark_bar_node)); |
roots->Set(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node)); |
+ roots->Set(kSyncedBookmarkFolderNameKey, EncodeNode(synced_folder_node)); |
DictionaryValue* main = new DictionaryValue(); |
main->SetInteger(kVersionKey, kCurrentVersion); |
@@ -67,6 +71,7 @@ Value* BookmarkCodec::Encode(const BookmarkNode* bookmark_bar_node, |
bool BookmarkCodec::Decode(BookmarkNode* bb_node, |
BookmarkNode* other_folder_node, |
+ BookmarkNode* synced_folder_node, |
int64* max_id, |
const Value& value) { |
ids_.clear(); |
@@ -75,12 +80,13 @@ bool BookmarkCodec::Decode(BookmarkNode* bb_node, |
maximum_id_ = 0; |
stored_checksum_.clear(); |
InitializeChecksum(); |
- bool success = DecodeHelper(bb_node, other_folder_node, value); |
+ bool success = DecodeHelper(bb_node, other_folder_node, synced_folder_node, |
+ value); |
FinalizeChecksum(); |
// If either the checksums differ or some IDs were missing/not unique, |
// reassign IDs. |
if (!ids_valid_ || computed_checksum() != stored_checksum()) |
- ReassignIDs(bb_node, other_folder_node); |
+ ReassignIDs(bb_node, other_folder_node, synced_folder_node); |
*max_id = maximum_id_ + 1; |
return success; |
} |
@@ -115,6 +121,7 @@ Value* BookmarkCodec::EncodeNode(const BookmarkNode* node) { |
bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node, |
BookmarkNode* other_folder_node, |
+ BookmarkNode* synced_folder_node, |
const Value& value) { |
if (value.GetType() != Value::TYPE_DICTIONARY) |
return false; // Unexpected type. |
@@ -147,21 +154,45 @@ bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node, |
if (!roots_d_value->Get(kRootFolderNameKey, &root_folder_value) || |
root_folder_value->GetType() != Value::TYPE_DICTIONARY || |
!roots_d_value->Get(kOtherBookmarkFolderNameKey, &other_folder_value) || |
- other_folder_value->GetType() != Value::TYPE_DICTIONARY) |
- return false; // Invalid type for root folder and/or other folder. |
- |
+ other_folder_value->GetType() != Value::TYPE_DICTIONARY) { |
+ return false; // Invalid type for root folder and/or other |
+ // folder. |
+ } |
DecodeNode(*static_cast<DictionaryValue*>(root_folder_value), NULL, |
bb_node); |
DecodeNode(*static_cast<DictionaryValue*>(other_folder_value), NULL, |
other_folder_node); |
+ |
+ // Fail silently if we can't deserialize synced bookmarks. We can't require |
+ // them to exist in order to be backwards-compatible with older versions of |
+ // chrome. |
+ Value* synced_folder_value; |
+ if (roots_d_value->Get(kSyncedBookmarkFolderNameKey, &synced_folder_value) && |
+ synced_folder_value->GetType() == Value::TYPE_DICTIONARY) { |
+ DecodeNode(*static_cast<DictionaryValue*>(synced_folder_value), NULL, |
+ synced_folder_node); |
+ } else { |
+ // If we didn't find the synced folder, we're almost guaranteed to have a |
+ // duplicate id when we add the synced folder. Consequently, if we don't |
+ // intend to reassign ids in the future (ids_valid_ is still true), then at |
+ // least reassign the synced bookmarks to avoid it colliding with anything |
+ // else. |
+ if (ids_valid_) { |
+ ReassignIDsHelper(synced_folder_node); |
+ } |
+ } |
+ |
// Need to reset the type as decoding resets the type to FOLDER. Similarly |
// we need to reset the title as the title is persisted and restored from |
// the file. |
bb_node->set_type(BookmarkNode::BOOKMARK_BAR); |
other_folder_node->set_type(BookmarkNode::OTHER_NODE); |
+ synced_folder_node->set_type(BookmarkNode::SYNCED); |
bb_node->set_title(l10n_util::GetStringUTF16(IDS_BOOMARK_BAR_FOLDER_NAME)); |
other_folder_node->set_title( |
l10n_util::GetStringUTF16(IDS_BOOMARK_BAR_OTHER_FOLDER_NAME)); |
+ synced_folder_node->set_title( |
+ l10n_util::GetStringUTF16(IDS_BOOMARK_BAR_SYNCED_FOLDER_NAME)); |
return true; |
} |
@@ -289,10 +320,12 @@ bool BookmarkCodec::DecodeNode(const DictionaryValue& value, |
} |
void BookmarkCodec::ReassignIDs(BookmarkNode* bb_node, |
- BookmarkNode* other_node) { |
+ BookmarkNode* other_node, |
+ BookmarkNode* synced_node) { |
maximum_id_ = 0; |
ReassignIDsHelper(bb_node); |
ReassignIDsHelper(other_node); |
+ ReassignIDsHelper(synced_node); |
ids_reassigned_ = true; |
} |