Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: components/enhanced_bookmarks/enhanced_bookmark_model.cc

Issue 563363002: Only set remote id during url node creation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: EnhancedBookmarkModelObserver Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/enhanced_bookmarks/enhanced_bookmark_model.h" 5 #include "components/enhanced_bookmarks/enhanced_bookmark_model.h"
6 6
7 #include <iomanip> 7 #include <iomanip>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/rand_util.h" 12 #include "base/rand_util.h"
13 #include "components/bookmarks/browser/bookmark_model.h" 13 #include "components/bookmarks/browser/bookmark_model.h"
14 #include "components/bookmarks/browser/bookmark_node.h" 14 #include "components/bookmarks/browser/bookmark_node.h"
15 #include "components/enhanced_bookmarks/enhanced_bookmark_model_observer.h"
15 #include "components/enhanced_bookmarks/proto/metadata.pb.h" 16 #include "components/enhanced_bookmarks/proto/metadata.pb.h"
17 #include "ui/base/models/tree_node_iterator.h"
16 #include "url/gurl.h" 18 #include "url/gurl.h"
17 19
18 namespace { 20 namespace {
19 const char* kBookmarkBarId = "f_bookmarks_bar"; 21 const char* kBookmarkBarId = "f_bookmarks_bar";
20 22
21 const char* kIdKey = "stars.id"; 23 const char* kIdKey = "stars.id";
22 const char* kImageDataKey = "stars.imageData"; 24 const char* kImageDataKey = "stars.imageData";
23 const char* kNoteKey = "stars.note"; 25 const char* kNoteKey = "stars.note";
26 const char* kOldIdKey = "stars.oldId";
24 const char* kPageDataKey = "stars.pageData"; 27 const char* kPageDataKey = "stars.pageData";
25 const char* kUserEditKey = "stars.userEdit";
26 const char* kVersionKey = "stars.version"; 28 const char* kVersionKey = "stars.version";
27 29
28 const char* kFolderPrefix = "ebf_";
29 const char* kBookmarkPrefix = "ebc_"; 30 const char* kBookmarkPrefix = "ebc_";
30 31
31 // Helper method for working with bookmark metainfo. 32 // Helper method for working with bookmark metainfo.
32 std::string DataForMetaInfoField(const BookmarkNode* node, 33 std::string DataForMetaInfoField(const BookmarkNode* node,
33 const std::string& field) { 34 const std::string& field) {
34 std::string value; 35 std::string value;
35 if (!node->GetMetaInfo(field, &value)) 36 if (!node->GetMetaInfo(field, &value))
36 return std::string(); 37 return std::string();
37 38
38 std::string decoded; 39 std::string decoded;
(...skipping 16 matching lines...) Expand all
55 return false; 56 return false;
56 57
57 *out_url = url; 58 *out_url = url;
58 *width = info.width(); 59 *width = info.width();
59 *height = info.height(); 60 *height = info.height();
60 return true; 61 return true;
61 } 62 }
62 63
63 // Generate a random remote id, with a prefix that depends on whether the node 64 // Generate a random remote id, with a prefix that depends on whether the node
64 // is a folder or a bookmark. 65 // is a folder or a bookmark.
65 std::string GenerateRemoteId(bool is_folder) { 66 std::string GenerateRemoteId() {
66 std::stringstream random_id; 67 std::stringstream random_id;
67 // Add prefix depending on whether the node is a folder or not. 68 random_id << kBookmarkPrefix;
68 if (is_folder)
69 random_id << kFolderPrefix;
70 else
71 random_id << kBookmarkPrefix;
72 69
73 // Generate 32 digit hex string random suffix. 70 // Generate 32 digit hex string random suffix.
74 random_id << std::hex << std::setfill('0') << std::setw(16); 71 random_id << std::hex << std::setfill('0') << std::setw(16);
75 random_id << base::RandUint64() << base::RandUint64(); 72 random_id << base::RandUint64() << base::RandUint64();
76 return random_id.str(); 73 return random_id.str();
77 } 74 }
78 } // namespace 75 } // namespace
79 76
80 namespace enhanced_bookmarks { 77 namespace enhanced_bookmarks {
81 78
82 EnhancedBookmarkModel::EnhancedBookmarkModel(BookmarkModel* bookmark_model, 79 EnhancedBookmarkModel::EnhancedBookmarkModel(BookmarkModel* bookmark_model,
83 const std::string& version) 80 const std::string& version)
84 : bookmark_model_(bookmark_model), version_(version) { 81 : bookmark_model_(bookmark_model), loaded_(false), version_(version) {
82 bookmark_model_->AddObserver(this);
83 if (bookmark_model_->loaded()) {
84 InitializeIdMap();
85 loaded_ = true;
86 }
85 } 87 }
86 88
87 EnhancedBookmarkModel::~EnhancedBookmarkModel() { 89 EnhancedBookmarkModel::~EnhancedBookmarkModel() {
88 } 90 }
89 91
92 void EnhancedBookmarkModel::ShutDown() {
93 FOR_EACH_OBSERVER(EnhancedBookmarkModelObserver,
94 observers_,
95 EnhancedBookmarkModelShuttingDown());
96 bookmark_model_->RemoveObserver(this);
97 bookmark_model_ = NULL;
98 }
99
100 void EnhancedBookmarkModel::AddObserver(
101 EnhancedBookmarkModelObserver* observer) {
102 observers_.AddObserver(observer);
103 }
104
105 void EnhancedBookmarkModel::RemoveObserver(
106 EnhancedBookmarkModelObserver* observer) {
107 observers_.RemoveObserver(observer);
108 }
109
90 // Moves |node| to |new_parent| and inserts it at the given |index|. 110 // Moves |node| to |new_parent| and inserts it at the given |index|.
91 void EnhancedBookmarkModel::Move(const BookmarkNode* node, 111 void EnhancedBookmarkModel::Move(const BookmarkNode* node,
92 const BookmarkNode* new_parent, 112 const BookmarkNode* new_parent,
93 int index) { 113 int index) {
94 // TODO(rfevang): Update meta info placement fields.
95 bookmark_model_->Move(node, new_parent, index); 114 bookmark_model_->Move(node, new_parent, index);
96 } 115 }
97 116
98 // Adds a new folder node at the specified position. 117 // Adds a new folder node at the specified position.
99 const BookmarkNode* EnhancedBookmarkModel::AddFolder( 118 const BookmarkNode* EnhancedBookmarkModel::AddFolder(
100 const BookmarkNode* parent, 119 const BookmarkNode* parent,
101 int index, 120 int index,
102 const base::string16& title) { 121 const base::string16& title) {
103 BookmarkNode::MetaInfoMap meta_info; 122 return bookmark_model_->AddFolder(parent, index, title);
104 meta_info[kIdKey] = GenerateRemoteId(true);
105
106 // TODO(rfevang): Set meta info placement fields.
107 return bookmark_model_->AddFolderWithMetaInfo(
108 parent, index, title, &meta_info);
109 } 123 }
110 124
111 // Adds a url at the specified position. 125 // Adds a url at the specified position.
112 const BookmarkNode* EnhancedBookmarkModel::AddURL( 126 const BookmarkNode* EnhancedBookmarkModel::AddURL(
113 const BookmarkNode* parent, 127 const BookmarkNode* parent,
114 int index, 128 int index,
115 const base::string16& title, 129 const base::string16& title,
116 const GURL& url, 130 const GURL& url,
117 const base::Time& creation_time) { 131 const base::Time& creation_time) {
118 BookmarkNode::MetaInfoMap meta_info; 132 BookmarkNode::MetaInfoMap meta_info;
119 meta_info[kIdKey] = GenerateRemoteId(false); 133 meta_info[kIdKey] = GenerateRemoteId();
120
121 // TODO(rfevang): Set meta info placement fields.
122 return bookmark_model_->AddURLWithCreationTimeAndMetaInfo( 134 return bookmark_model_->AddURLWithCreationTimeAndMetaInfo(
123 parent, index, title, url, creation_time, &meta_info); 135 parent, index, title, url, creation_time, &meta_info);
124 } 136 }
125 137
126 std::string EnhancedBookmarkModel::GetRemoteId(const BookmarkNode* node) { 138 std::string EnhancedBookmarkModel::GetRemoteId(const BookmarkNode* node) {
127 if (node == bookmark_model_->bookmark_bar_node()) 139 if (node == bookmark_model_->bookmark_bar_node())
128 return kBookmarkBarId; 140 return kBookmarkBarId;
129 141
130 // Permanent nodes other than the bookmarks bar don't have ids.
131 DCHECK(!bookmark_model_->is_permanent_node(node));
132
133 std::string id; 142 std::string id;
134 if (!node->GetMetaInfo(kIdKey, &id) || id.empty()) 143 if (!node->GetMetaInfo(kIdKey, &id))
135 return SetRemoteId(node); 144 return std::string();
136 return id; 145 return id;
137 } 146 }
138 147
139 std::string EnhancedBookmarkModel::SetRemoteId(const BookmarkNode* node) { 148 const BookmarkNode* EnhancedBookmarkModel::BookmarkForRemoteId(
140 std::string remote_id = GenerateRemoteId(node->is_folder()); 149 const std::string& remote_id) {
141 SetMetaInfo(node, kIdKey, remote_id, false); 150 IdToNodeMap::iterator it = id_map_.find(remote_id);
142 return remote_id; 151 if (it != id_map_.end())
152 return it->second;
153 return NULL;
143 } 154 }
144 155
145 void EnhancedBookmarkModel::SetDescription(const BookmarkNode* node, 156 void EnhancedBookmarkModel::SetDescription(const BookmarkNode* node,
146 const std::string& description) { 157 const std::string& description) {
147 SetMetaInfo(node, kNoteKey, description, true); 158 SetMetaInfo(node, kNoteKey, description);
148 } 159 }
149 160
150 std::string EnhancedBookmarkModel::GetDescription(const BookmarkNode* node) { 161 std::string EnhancedBookmarkModel::GetDescription(const BookmarkNode* node) {
151 // First, look for a custom note set by the user. 162 // First, look for a custom note set by the user.
152 std::string description; 163 std::string description;
153 if (node->GetMetaInfo(kNoteKey, &description) && !description.empty()) 164 if (node->GetMetaInfo(kNoteKey, &description) && !description.empty())
154 return description; 165 return description;
155 166
156 // If none are present, return the snippet. 167 // If none are present, return the snippet.
157 return GetSnippet(node); 168 return GetSnippet(node);
(...skipping 24 matching lines...) Expand all
182 info->set_height(height); 193 info->set_height(height);
183 data.set_allocated_original_info(info.release()); 194 data.set_allocated_original_info(info.release());
184 195
185 std::string output; 196 std::string output;
186 bool result = data.SerializePartialToString(&output); 197 bool result = data.SerializePartialToString(&output);
187 if (!result) 198 if (!result)
188 return false; 199 return false;
189 200
190 std::string encoded; 201 std::string encoded;
191 base::Base64Encode(output, &encoded); 202 base::Base64Encode(output, &encoded);
192 SetMetaInfo(node, kImageDataKey, encoded, true); 203 SetMetaInfo(node, kImageDataKey, encoded);
193 // Ensure that the bookmark has a stars.id, to trigger the server processing.
194 GetRemoteId(node);
195 return true; 204 return true;
196 } 205 }
197 206
198 bool EnhancedBookmarkModel::GetOriginalImage(const BookmarkNode* node, 207 bool EnhancedBookmarkModel::GetOriginalImage(const BookmarkNode* node,
199 GURL* url, 208 GURL* url,
200 int* width, 209 int* width,
201 int* height) { 210 int* height) {
202 std::string decoded(DataForMetaInfoField(node, kImageDataKey)); 211 std::string decoded(DataForMetaInfoField(node, kImageDataKey));
203 if (decoded == "") 212 if (decoded == "")
204 return false; 213 return false;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 return std::string(); 253 return std::string();
245 254
246 return data.snippet(); 255 return data.snippet();
247 } 256 }
248 257
249 void EnhancedBookmarkModel::SetVersionSuffix( 258 void EnhancedBookmarkModel::SetVersionSuffix(
250 const std::string& version_suffix) { 259 const std::string& version_suffix) {
251 version_suffix_ = version_suffix; 260 version_suffix_ = version_suffix;
252 } 261 }
253 262
263 void EnhancedBookmarkModel::BookmarkModelChanged() {
264 }
265
266 void EnhancedBookmarkModel::BookmarkModelLoaded(BookmarkModel* model,
267 bool ids_reassigned) {
268 InitializeIdMap();
269 FOR_EACH_OBSERVER(
270 EnhancedBookmarkModelObserver, observers_, EnhancedBookmarkModelLoaded());
271 }
272
273 void EnhancedBookmarkModel::BookmarkNodeAdded(BookmarkModel* model,
274 const BookmarkNode* parent,
275 int index) {
276 const BookmarkNode* node = parent->GetChild(index);
277 AddToIdMap(node);
278 ResetDuplicateRemoteIds();
279 FOR_EACH_OBSERVER(
280 EnhancedBookmarkModelObserver, observers_, EnhancedBookmarkAdded(node));
281 }
282
283 void EnhancedBookmarkModel::BookmarkNodeRemoved(
284 BookmarkModel* model,
285 const BookmarkNode* parent,
286 int old_index,
287 const BookmarkNode* node,
288 const std::set<GURL>& removed_urls) {
289 std::string remote_id = GetRemoteId(node);
290 id_map_.erase(remote_id);
291 FOR_EACH_OBSERVER(
292 EnhancedBookmarkModelObserver, observers_, EnhancedBookmarkRemoved(node));
293 }
294
295 void EnhancedBookmarkModel::OnWillChangeBookmarkMetaInfo(
296 BookmarkModel* model,
297 const BookmarkNode* node) {
298 prev_remote_id_ = GetRemoteId(node);
299 }
300
301 void EnhancedBookmarkModel::BookmarkMetaInfoChanged(BookmarkModel* model,
302 const BookmarkNode* node) {
303 std::string remote_id = GetRemoteId(node);
304 if (remote_id != prev_remote_id_) {
305 id_map_.erase(prev_remote_id_);
306 if (!remote_id.empty()) {
307 AddToIdMap(node);
308 ResetDuplicateRemoteIds();
309 }
310
311 // The remote id could have been changed again by the de-duping process, so
312 // get the current state of the id before notifying observers.
313 std::string new_remote_id = GetRemoteId(node);
314 if (prev_remote_id_ != new_remote_id) {
315 FOR_EACH_OBSERVER(EnhancedBookmarkModelObserver,
316 observers_,
317 EnhancedBookmarkRemoteIdChanged(
318 node, prev_remote_id_, new_remote_id));
319 }
320 }
321 }
322
323 void EnhancedBookmarkModel::BookmarkAllUserNodesRemoved(
324 BookmarkModel* model,
325 const std::set<GURL>& removed_urls) {
326 id_map_.clear();
327 // Re-initialize so non-user nodes with remote ids are present in the map.
328 InitializeIdMap();
329 FOR_EACH_OBSERVER(EnhancedBookmarkModelObserver,
330 observers_,
331 EnhancedBookmarkAllUserNodesRemoved());
332 }
333
334 void EnhancedBookmarkModel::InitializeIdMap() {
335 ui::TreeNodeIterator<const BookmarkNode> iterator(
336 bookmark_model_->root_node());
337 while (iterator.has_next()) {
338 AddToIdMap(iterator.Next());
339 }
340 ResetDuplicateRemoteIds();
341 }
342
343 void EnhancedBookmarkModel::AddToIdMap(const BookmarkNode* node) {
344 std::string remote_id = GetRemoteId(node);
345 if (remote_id.empty())
346 return;
347
348 // Try to insert the node.
349 std::pair<IdToNodeMap::iterator, bool> result =
350 id_map_.insert(make_pair(remote_id, node));
351 if (!result.second) {
352 // Some node already had the same remote id, so add both nodes to the
353 // to-be-reset set.
354 nodes_to_reset_[result.first->second] = remote_id;
355 nodes_to_reset_[node] = remote_id;
356 }
357 }
358
359 void EnhancedBookmarkModel::ResetDuplicateRemoteIds() {
360 for (NodeToIdMap::iterator it = nodes_to_reset_.begin();
Mark 2014/09/18 18:18:27 Just checking, are you able to get some sort of lo
Rune Fevang 2014/09/19 01:18:07 There's no sync API support for doing that, the bo
361 it != nodes_to_reset_.end();
362 ++it) {
363 BookmarkNode::MetaInfoMap meta_info;
364 meta_info[kIdKey] = "";
365 meta_info[kOldIdKey] = it->second;
366 SetMultipleMetaInfo(it->first, meta_info);
367 }
368 nodes_to_reset_.clear();
369 }
370
254 void EnhancedBookmarkModel::SetMetaInfo(const BookmarkNode* node, 371 void EnhancedBookmarkModel::SetMetaInfo(const BookmarkNode* node,
255 const std::string& field, 372 const std::string& field,
256 const std::string& value, 373 const std::string& value) {
257 bool user_edit) {
258 DCHECK(!bookmark_model_->is_permanent_node(node)); 374 DCHECK(!bookmark_model_->is_permanent_node(node));
259 375
260 BookmarkNode::MetaInfoMap meta_info; 376 BookmarkNode::MetaInfoMap meta_info;
261 const BookmarkNode::MetaInfoMap* old_meta_info = node->GetMetaInfoMap(); 377 const BookmarkNode::MetaInfoMap* old_meta_info = node->GetMetaInfoMap();
262 if (old_meta_info) 378 if (old_meta_info)
263 meta_info.insert(old_meta_info->begin(), old_meta_info->end()); 379 meta_info.insert(old_meta_info->begin(), old_meta_info->end());
264 380
265 // Don't update anything if the value to set is already there. 381 // Don't update anything if the value to set is already there.
266 BookmarkNode::MetaInfoMap::iterator it = meta_info.find(field); 382 BookmarkNode::MetaInfoMap::iterator it = meta_info.find(field);
267 if (it != meta_info.end() && it->second == value) 383 if (it != meta_info.end() && it->second == value)
268 return; 384 return;
269 385
270 meta_info[field] = value; 386 meta_info[field] = value;
271 meta_info[kVersionKey] = GetVersionString(); 387 meta_info[kVersionKey] = GetVersionString();
272 meta_info[kUserEditKey] = user_edit ? "true" : "false";
273 bookmark_model_->SetNodeMetaInfoMap(node, meta_info); 388 bookmark_model_->SetNodeMetaInfoMap(node, meta_info);
274 } 389 }
275 390
276 std::string EnhancedBookmarkModel::GetVersionString() { 391 std::string EnhancedBookmarkModel::GetVersionString() {
277 if (version_suffix_.empty()) 392 if (version_suffix_.empty())
278 return version_; 393 return version_;
279 return version_ + '/' + version_suffix_; 394 return version_ + '/' + version_suffix_;
280 } 395 }
281 396
397 void EnhancedBookmarkModel::SetMultipleMetaInfo(
398 const BookmarkNode* node,
399 BookmarkNode::MetaInfoMap meta_info) {
400 DCHECK(!bookmark_model_->is_permanent_node(node));
401
402 // Don't update anything if every value is already set correctly.
403 if (node->GetMetaInfoMap()) {
404 bool changed = false;
405 const BookmarkNode::MetaInfoMap* old_meta_info = node->GetMetaInfoMap();
406 for (BookmarkNode::MetaInfoMap::iterator it = meta_info.begin();
407 it != meta_info.end();
408 ++it) {
409 BookmarkNode::MetaInfoMap::const_iterator old_field =
410 old_meta_info->find(it->first);
411 if (old_field == old_meta_info->end() ||
412 old_field->second == it->second) {
Mark 2014/09/18 18:18:27 So is all this effort really necessary? What happ
Rune Fevang 2014/09/19 01:18:07 Necessary? Not really, it's more of a safeguard ag
413 changed = true;
414 break;
415 }
416 }
417 if (!changed)
418 return;
419
420 // Fill in the values that aren't changing
421 meta_info.insert(old_meta_info->begin(), old_meta_info->end());
422 }
423
424 meta_info[kVersionKey] = GetVersionString();
425 bookmark_model_->SetNodeMetaInfoMap(node, meta_info);
426 }
427
282 bool EnhancedBookmarkModel::SetAllImages(const BookmarkNode* node, 428 bool EnhancedBookmarkModel::SetAllImages(const BookmarkNode* node,
283 const GURL& image_url, 429 const GURL& image_url,
284 int image_width, 430 int image_width,
285 int image_height, 431 int image_height,
286 const GURL& thumbnail_url, 432 const GURL& thumbnail_url,
287 int thumbnail_width, 433 int thumbnail_width,
288 int thumbnail_height) { 434 int thumbnail_height) {
289 DCHECK(node->is_url()); 435 DCHECK(node->is_url());
290 DCHECK(image_url.is_valid() || image_url.is_empty()); 436 DCHECK(image_url.is_valid() || image_url.is_empty());
291 DCHECK(thumbnail_url.is_valid() || thumbnail_url.is_empty()); 437 DCHECK(thumbnail_url.is_valid() || thumbnail_url.is_empty());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 if (!result) 478 if (!result)
333 return false; 479 return false;
334 480
335 std::string encoded; 481 std::string encoded;
336 base::Base64Encode(output, &encoded); 482 base::Base64Encode(output, &encoded);
337 bookmark_model_->SetNodeMetaInfo(node, kImageDataKey, encoded); 483 bookmark_model_->SetNodeMetaInfo(node, kImageDataKey, encoded);
338 return true; 484 return true;
339 } 485 }
340 486
341 } // namespace enhanced_bookmarks 487 } // namespace enhanced_bookmarks
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698