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/bookmarks/bookmark_codec.h" | 5 #include "chrome/browser/bookmarks/bookmark_codec.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "base/values.h" | 11 #include "base/values.h" |
12 #include "chrome/browser/bookmarks/bookmark_model.h" | 12 #include "chrome/browser/bookmarks/bookmark_model.h" |
13 #include "googleurl/src/gurl.h" | 13 #include "googleurl/src/gurl.h" |
14 #include "grit/generated_resources.h" | 14 #include "grit/generated_resources.h" |
15 #include "ui/base/l10n/l10n_util.h" | 15 #include "ui/base/l10n/l10n_util.h" |
16 | 16 |
17 using base::Time; | 17 using base::Time; |
18 | 18 |
19 const char* BookmarkCodec::kRootsKey = "roots"; | 19 const char* BookmarkCodec::kRootsKey = "roots"; |
20 const char* BookmarkCodec::kRootFolderNameKey = "bookmark_bar"; | 20 const char* BookmarkCodec::kRootFolderNameKey = "bookmark_bar"; |
21 const char* BookmarkCodec::kOtherBookmarkFolderNameKey = "other"; | 21 const char* BookmarkCodec::kOtherBookmarkFolderNameKey = "other"; |
22 const char* BookmarkCodec::kSyncedBookmarkFolderNameKey = "synced"; | 22 // The value is left as 'synced' for historical reasons. |
| 23 const char* BookmarkCodec::kMobileBookmarkFolderNameKey = "synced"; |
23 const char* BookmarkCodec::kVersionKey = "version"; | 24 const char* BookmarkCodec::kVersionKey = "version"; |
24 const char* BookmarkCodec::kChecksumKey = "checksum"; | 25 const char* BookmarkCodec::kChecksumKey = "checksum"; |
25 const char* BookmarkCodec::kIdKey = "id"; | 26 const char* BookmarkCodec::kIdKey = "id"; |
26 const char* BookmarkCodec::kTypeKey = "type"; | 27 const char* BookmarkCodec::kTypeKey = "type"; |
27 const char* BookmarkCodec::kNameKey = "name"; | 28 const char* BookmarkCodec::kNameKey = "name"; |
28 const char* BookmarkCodec::kDateAddedKey = "date_added"; | 29 const char* BookmarkCodec::kDateAddedKey = "date_added"; |
29 const char* BookmarkCodec::kURLKey = "url"; | 30 const char* BookmarkCodec::kURLKey = "url"; |
30 const char* BookmarkCodec::kDateModifiedKey = "date_modified"; | 31 const char* BookmarkCodec::kDateModifiedKey = "date_modified"; |
31 const char* BookmarkCodec::kChildrenKey = "children"; | 32 const char* BookmarkCodec::kChildrenKey = "children"; |
32 const char* BookmarkCodec::kTypeURL = "url"; | 33 const char* BookmarkCodec::kTypeURL = "url"; |
33 const char* BookmarkCodec::kTypeFolder = "folder"; | 34 const char* BookmarkCodec::kTypeFolder = "folder"; |
34 | 35 |
35 // Current version of the file. | 36 // Current version of the file. |
36 static const int kCurrentVersion = 1; | 37 static const int kCurrentVersion = 1; |
37 | 38 |
38 BookmarkCodec::BookmarkCodec() | 39 BookmarkCodec::BookmarkCodec() |
39 : ids_reassigned_(false), | 40 : ids_reassigned_(false), |
40 ids_valid_(true), | 41 ids_valid_(true), |
41 maximum_id_(0) { | 42 maximum_id_(0) { |
42 } | 43 } |
43 | 44 |
44 BookmarkCodec::~BookmarkCodec() {} | 45 BookmarkCodec::~BookmarkCodec() {} |
45 | 46 |
46 Value* BookmarkCodec::Encode(BookmarkModel* model) { | 47 Value* BookmarkCodec::Encode(BookmarkModel* model) { |
47 return Encode(model->bookmark_bar_node(), | 48 return Encode(model->bookmark_bar_node(), |
48 model->other_node(), | 49 model->other_node(), |
49 model->synced_node()); | 50 model->mobile_node()); |
50 } | 51 } |
51 | 52 |
52 Value* BookmarkCodec::Encode(const BookmarkNode* bookmark_bar_node, | 53 Value* BookmarkCodec::Encode(const BookmarkNode* bookmark_bar_node, |
53 const BookmarkNode* other_folder_node, | 54 const BookmarkNode* other_folder_node, |
54 const BookmarkNode* synced_folder_node) { | 55 const BookmarkNode* mobile_folder_node) { |
55 ids_reassigned_ = false; | 56 ids_reassigned_ = false; |
56 InitializeChecksum(); | 57 InitializeChecksum(); |
57 DictionaryValue* roots = new DictionaryValue(); | 58 DictionaryValue* roots = new DictionaryValue(); |
58 roots->Set(kRootFolderNameKey, EncodeNode(bookmark_bar_node)); | 59 roots->Set(kRootFolderNameKey, EncodeNode(bookmark_bar_node)); |
59 roots->Set(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node)); | 60 roots->Set(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node)); |
60 roots->Set(kSyncedBookmarkFolderNameKey, EncodeNode(synced_folder_node)); | 61 roots->Set(kMobileBookmarkFolderNameKey, EncodeNode(mobile_folder_node)); |
61 | 62 |
62 DictionaryValue* main = new DictionaryValue(); | 63 DictionaryValue* main = new DictionaryValue(); |
63 main->SetInteger(kVersionKey, kCurrentVersion); | 64 main->SetInteger(kVersionKey, kCurrentVersion); |
64 FinalizeChecksum(); | 65 FinalizeChecksum(); |
65 // We are going to store the computed checksum. So set stored checksum to be | 66 // We are going to store the computed checksum. So set stored checksum to be |
66 // the same as computed checksum. | 67 // the same as computed checksum. |
67 stored_checksum_ = computed_checksum_; | 68 stored_checksum_ = computed_checksum_; |
68 main->Set(kChecksumKey, Value::CreateStringValue(computed_checksum_)); | 69 main->Set(kChecksumKey, Value::CreateStringValue(computed_checksum_)); |
69 main->Set(kRootsKey, roots); | 70 main->Set(kRootsKey, roots); |
70 return main; | 71 return main; |
71 } | 72 } |
72 | 73 |
73 bool BookmarkCodec::Decode(BookmarkNode* bb_node, | 74 bool BookmarkCodec::Decode(BookmarkNode* bb_node, |
74 BookmarkNode* other_folder_node, | 75 BookmarkNode* other_folder_node, |
75 BookmarkNode* synced_folder_node, | 76 BookmarkNode* mobile_folder_node, |
76 int64* max_id, | 77 int64* max_id, |
77 const Value& value) { | 78 const Value& value) { |
78 ids_.clear(); | 79 ids_.clear(); |
79 ids_reassigned_ = false; | 80 ids_reassigned_ = false; |
80 ids_valid_ = true; | 81 ids_valid_ = true; |
81 maximum_id_ = 0; | 82 maximum_id_ = 0; |
82 stored_checksum_.clear(); | 83 stored_checksum_.clear(); |
83 InitializeChecksum(); | 84 InitializeChecksum(); |
84 bool success = DecodeHelper(bb_node, other_folder_node, synced_folder_node, | 85 bool success = DecodeHelper(bb_node, other_folder_node, mobile_folder_node, |
85 value); | 86 value); |
86 FinalizeChecksum(); | 87 FinalizeChecksum(); |
87 // If either the checksums differ or some IDs were missing/not unique, | 88 // If either the checksums differ or some IDs were missing/not unique, |
88 // reassign IDs. | 89 // reassign IDs. |
89 if (!ids_valid_ || computed_checksum() != stored_checksum()) | 90 if (!ids_valid_ || computed_checksum() != stored_checksum()) |
90 ReassignIDs(bb_node, other_folder_node, synced_folder_node); | 91 ReassignIDs(bb_node, other_folder_node, mobile_folder_node); |
91 *max_id = maximum_id_ + 1; | 92 *max_id = maximum_id_ + 1; |
92 return success; | 93 return success; |
93 } | 94 } |
94 | 95 |
95 Value* BookmarkCodec::EncodeNode(const BookmarkNode* node) { | 96 Value* BookmarkCodec::EncodeNode(const BookmarkNode* node) { |
96 DictionaryValue* value = new DictionaryValue(); | 97 DictionaryValue* value = new DictionaryValue(); |
97 std::string id = base::Int64ToString(node->id()); | 98 std::string id = base::Int64ToString(node->id()); |
98 value->SetString(kIdKey, id); | 99 value->SetString(kIdKey, id); |
99 const string16& title = node->GetTitle(); | 100 const string16& title = node->GetTitle(); |
100 value->SetString(kNameKey, title); | 101 value->SetString(kNameKey, title); |
(...skipping 14 matching lines...) Expand all Loading... |
115 ListValue* child_values = new ListValue(); | 116 ListValue* child_values = new ListValue(); |
116 value->Set(kChildrenKey, child_values); | 117 value->Set(kChildrenKey, child_values); |
117 for (int i = 0; i < node->child_count(); ++i) | 118 for (int i = 0; i < node->child_count(); ++i) |
118 child_values->Append(EncodeNode(node->GetChild(i))); | 119 child_values->Append(EncodeNode(node->GetChild(i))); |
119 } | 120 } |
120 return value; | 121 return value; |
121 } | 122 } |
122 | 123 |
123 bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node, | 124 bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node, |
124 BookmarkNode* other_folder_node, | 125 BookmarkNode* other_folder_node, |
125 BookmarkNode* synced_folder_node, | 126 BookmarkNode* mobile_folder_node, |
126 const Value& value) { | 127 const Value& value) { |
127 if (value.GetType() != Value::TYPE_DICTIONARY) | 128 if (value.GetType() != Value::TYPE_DICTIONARY) |
128 return false; // Unexpected type. | 129 return false; // Unexpected type. |
129 | 130 |
130 const DictionaryValue& d_value = static_cast<const DictionaryValue&>(value); | 131 const DictionaryValue& d_value = static_cast<const DictionaryValue&>(value); |
131 | 132 |
132 int version; | 133 int version; |
133 if (!d_value.GetInteger(kVersionKey, &version) || version != kCurrentVersion) | 134 if (!d_value.GetInteger(kVersionKey, &version) || version != kCurrentVersion) |
134 return false; // Unknown version. | 135 return false; // Unknown version. |
135 | 136 |
(...skipping 21 matching lines...) Expand all Loading... |
157 !roots_d_value->Get(kOtherBookmarkFolderNameKey, &other_folder_value) || | 158 !roots_d_value->Get(kOtherBookmarkFolderNameKey, &other_folder_value) || |
158 other_folder_value->GetType() != Value::TYPE_DICTIONARY) { | 159 other_folder_value->GetType() != Value::TYPE_DICTIONARY) { |
159 return false; // Invalid type for root folder and/or other | 160 return false; // Invalid type for root folder and/or other |
160 // folder. | 161 // folder. |
161 } | 162 } |
162 DecodeNode(*static_cast<DictionaryValue*>(root_folder_value), NULL, | 163 DecodeNode(*static_cast<DictionaryValue*>(root_folder_value), NULL, |
163 bb_node); | 164 bb_node); |
164 DecodeNode(*static_cast<DictionaryValue*>(other_folder_value), NULL, | 165 DecodeNode(*static_cast<DictionaryValue*>(other_folder_value), NULL, |
165 other_folder_node); | 166 other_folder_node); |
166 | 167 |
167 // Fail silently if we can't deserialize synced bookmarks. We can't require | 168 // Fail silently if we can't deserialize mobile bookmarks. We can't require |
168 // them to exist in order to be backwards-compatible with older versions of | 169 // them to exist in order to be backwards-compatible with older versions of |
169 // chrome. | 170 // chrome. |
170 Value* synced_folder_value; | 171 Value* mobile_folder_value; |
171 if (roots_d_value->Get(kSyncedBookmarkFolderNameKey, &synced_folder_value) && | 172 if (roots_d_value->Get(kMobileBookmarkFolderNameKey, &mobile_folder_value) && |
172 synced_folder_value->GetType() == Value::TYPE_DICTIONARY) { | 173 mobile_folder_value->GetType() == Value::TYPE_DICTIONARY) { |
173 DecodeNode(*static_cast<DictionaryValue*>(synced_folder_value), NULL, | 174 DecodeNode(*static_cast<DictionaryValue*>(mobile_folder_value), NULL, |
174 synced_folder_node); | 175 mobile_folder_node); |
175 } else { | 176 } else { |
176 // If we didn't find the synced folder, we're almost guaranteed to have a | 177 // If we didn't find the mobile folder, we're almost guaranteed to have a |
177 // duplicate id when we add the synced folder. Consequently, if we don't | 178 // duplicate id when we add the mobile folder. Consequently, if we don't |
178 // intend to reassign ids in the future (ids_valid_ is still true), then at | 179 // intend to reassign ids in the future (ids_valid_ is still true), then at |
179 // least reassign the synced bookmarks to avoid it colliding with anything | 180 // least reassign the mobile bookmarks to avoid it colliding with anything |
180 // else. | 181 // else. |
181 if (ids_valid_) { | 182 if (ids_valid_) |
182 ReassignIDsHelper(synced_folder_node); | 183 ReassignIDsHelper(mobile_folder_node); |
183 } | |
184 } | 184 } |
185 | 185 |
186 // Need to reset the type as decoding resets the type to FOLDER. Similarly | 186 // Need to reset the type as decoding resets the type to FOLDER. Similarly |
187 // we need to reset the title as the title is persisted and restored from | 187 // we need to reset the title as the title is persisted and restored from |
188 // the file. | 188 // the file. |
189 bb_node->set_type(BookmarkNode::BOOKMARK_BAR); | 189 bb_node->set_type(BookmarkNode::BOOKMARK_BAR); |
190 other_folder_node->set_type(BookmarkNode::OTHER_NODE); | 190 other_folder_node->set_type(BookmarkNode::OTHER_NODE); |
191 synced_folder_node->set_type(BookmarkNode::SYNCED); | 191 mobile_folder_node->set_type(BookmarkNode::MOBILE); |
192 bb_node->set_title(l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_FOLDER_NAME)); | 192 bb_node->set_title(l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_FOLDER_NAME)); |
193 other_folder_node->set_title( | 193 other_folder_node->set_title( |
194 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME)); | 194 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME)); |
195 synced_folder_node->set_title( | 195 mobile_folder_node->set_title( |
196 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_SYNCED_FOLDER_NAME)); | 196 l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_MOBILE_FOLDER_NAME)); |
197 | 197 |
198 return true; | 198 return true; |
199 } | 199 } |
200 | 200 |
201 bool BookmarkCodec::DecodeChildren(const ListValue& child_value_list, | 201 bool BookmarkCodec::DecodeChildren(const ListValue& child_value_list, |
202 BookmarkNode* parent) { | 202 BookmarkNode* parent) { |
203 for (size_t i = 0; i < child_value_list.GetSize(); ++i) { | 203 for (size_t i = 0; i < child_value_list.GetSize(); ++i) { |
204 Value* child_value; | 204 Value* child_value; |
205 if (!child_value_list.Get(i, &child_value)) | 205 if (!child_value_list.Get(i, &child_value)) |
206 return false; | 206 return false; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 return false; | 315 return false; |
316 } | 316 } |
317 | 317 |
318 node->set_title(title); | 318 node->set_title(title); |
319 node->set_date_added(date_added); | 319 node->set_date_added(date_added); |
320 return true; | 320 return true; |
321 } | 321 } |
322 | 322 |
323 void BookmarkCodec::ReassignIDs(BookmarkNode* bb_node, | 323 void BookmarkCodec::ReassignIDs(BookmarkNode* bb_node, |
324 BookmarkNode* other_node, | 324 BookmarkNode* other_node, |
325 BookmarkNode* synced_node) { | 325 BookmarkNode* mobile_node) { |
326 maximum_id_ = 0; | 326 maximum_id_ = 0; |
327 ReassignIDsHelper(bb_node); | 327 ReassignIDsHelper(bb_node); |
328 ReassignIDsHelper(other_node); | 328 ReassignIDsHelper(other_node); |
329 ReassignIDsHelper(synced_node); | 329 ReassignIDsHelper(mobile_node); |
330 ids_reassigned_ = true; | 330 ids_reassigned_ = true; |
331 } | 331 } |
332 | 332 |
333 void BookmarkCodec::ReassignIDsHelper(BookmarkNode* node) { | 333 void BookmarkCodec::ReassignIDsHelper(BookmarkNode* node) { |
334 DCHECK(node); | 334 DCHECK(node); |
335 node->set_id(++maximum_id_); | 335 node->set_id(++maximum_id_); |
336 for (int i = 0; i < node->child_count(); ++i) | 336 for (int i = 0; i < node->child_count(); ++i) |
337 ReassignIDsHelper(node->GetChild(i)); | 337 ReassignIDsHelper(node->GetChild(i)); |
338 } | 338 } |
339 | 339 |
(...skipping 27 matching lines...) Expand all Loading... |
367 | 367 |
368 void BookmarkCodec::InitializeChecksum() { | 368 void BookmarkCodec::InitializeChecksum() { |
369 base::MD5Init(&md5_context_); | 369 base::MD5Init(&md5_context_); |
370 } | 370 } |
371 | 371 |
372 void BookmarkCodec::FinalizeChecksum() { | 372 void BookmarkCodec::FinalizeChecksum() { |
373 base::MD5Digest digest; | 373 base::MD5Digest digest; |
374 base::MD5Final(&digest, &md5_context_); | 374 base::MD5Final(&digest, &md5_context_); |
375 computed_checksum_ = base::MD5DigestToBase16(digest); | 375 computed_checksum_ = base::MD5DigestToBase16(digest); |
376 } | 376 } |
OLD | NEW |