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

Side by Side Diff: components/bookmarks/browser/bookmark_model.cc

Issue 2379863002: Fix object ownership in ui/base/models. (Closed)
Patch Set: chromeos/android Created 4 years, 2 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/bookmarks/browser/bookmark_model.h" 5 #include "components/bookmarks/browser/bookmark_model.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/i18n/string_compare.h" 13 #include "base/i18n/string_compare.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h"
16 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
17 #include "base/profiler/scoped_tracker.h" 18 #include "base/profiler/scoped_tracker.h"
18 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
19 #include "components/bookmarks/browser/bookmark_expanded_state_tracker.h" 20 #include "components/bookmarks/browser/bookmark_expanded_state_tracker.h"
20 #include "components/bookmarks/browser/bookmark_index.h" 21 #include "components/bookmarks/browser/bookmark_index.h"
21 #include "components/bookmarks/browser/bookmark_match.h" 22 #include "components/bookmarks/browser/bookmark_match.h"
22 #include "components/bookmarks/browser/bookmark_model_observer.h" 23 #include "components/bookmarks/browser/bookmark_model_observer.h"
23 #include "components/bookmarks/browser/bookmark_node_data.h" 24 #include "components/bookmarks/browser/bookmark_node_data.h"
24 #include "components/bookmarks/browser/bookmark_storage.h" 25 #include "components/bookmarks/browser/bookmark_storage.h"
25 #include "components/bookmarks/browser/bookmark_undo_delegate.h" 26 #include "components/bookmarks/browser/bookmark_undo_delegate.h"
(...skipping 18 matching lines...) Expand all
44 BookmarkPermanentNode* AsMutable(const BookmarkPermanentNode* node) { 45 BookmarkPermanentNode* AsMutable(const BookmarkPermanentNode* node) {
45 return const_cast<BookmarkPermanentNode*>(node); 46 return const_cast<BookmarkPermanentNode*>(node);
46 } 47 }
47 48
48 // Comparator used when sorting permanent nodes. Nodes that are initially 49 // Comparator used when sorting permanent nodes. Nodes that are initially
49 // visible are sorted before nodes that are initially hidden. 50 // visible are sorted before nodes that are initially hidden.
50 class VisibilityComparator { 51 class VisibilityComparator {
51 public: 52 public:
52 explicit VisibilityComparator(BookmarkClient* client) : client_(client) {} 53 explicit VisibilityComparator(BookmarkClient* client) : client_(client) {}
53 54
54 // Returns true if |n1| preceeds |n2|. 55 // Returns true if |n1| precedes |n2|.
55 bool operator()(const BookmarkPermanentNode* n1, 56 bool operator()(const std::unique_ptr<BookmarkPermanentNode>& n1,
56 const BookmarkPermanentNode* n2) { 57 const std::unique_ptr<BookmarkPermanentNode>& n2) {
57 bool n1_visible = client_->IsPermanentNodeVisible(n1); 58 bool n1_visible = client_->IsPermanentNodeVisible(n1.get());
58 bool n2_visible = client_->IsPermanentNodeVisible(n2); 59 bool n2_visible = client_->IsPermanentNodeVisible(n2.get());
59 return n1_visible != n2_visible && n1_visible; 60 return n1_visible != n2_visible && n1_visible;
60 } 61 }
61 62
62 private: 63 private:
63 BookmarkClient* client_; 64 BookmarkClient* client_;
64 }; 65 };
65 66
66 // Comparator used when sorting bookmarks. Folders are sorted first, then 67 // Comparator used when sorting bookmarks. Folders are sorted first, then
67 // bookmarks. 68 // bookmarks.
68 class SortComparator { 69 class SortComparator {
69 public: 70 public:
70 explicit SortComparator(icu::Collator* collator) : collator_(collator) {} 71 explicit SortComparator(icu::Collator* collator) : collator_(collator) {}
71 72
72 // Returns true if |n1| preceeds |n2|. 73 // Returns true if |n1| precedes |n2|.
73 bool operator()(const BookmarkNode* n1, const BookmarkNode* n2) { 74 bool operator()(const std::unique_ptr<BookmarkNode>& n1,
75 const std::unique_ptr<BookmarkNode>& n2) {
74 if (n1->type() == n2->type()) { 76 if (n1->type() == n2->type()) {
75 // Types are the same, compare the names. 77 // Types are the same, compare the names.
76 if (!collator_) 78 if (!collator_)
77 return n1->GetTitle() < n2->GetTitle(); 79 return n1->GetTitle() < n2->GetTitle();
78 return base::i18n::CompareString16WithCollator( 80 return base::i18n::CompareString16WithCollator(
79 *collator_, n1->GetTitle(), n2->GetTitle()) == UCOL_LESS; 81 *collator_, n1->GetTitle(), n2->GetTitle()) == UCOL_LESS;
80 } 82 }
81 // Types differ, sort such that folders come first. 83 // Types differ, sort such that folders come first.
82 return n1->is_folder(); 84 return n1->is_folder();
83 } 85 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 void BookmarkModel::Remove(const BookmarkNode* node) { 212 void BookmarkModel::Remove(const BookmarkNode* node) {
211 DCHECK(loaded_); 213 DCHECK(loaded_);
212 DCHECK(node); 214 DCHECK(node);
213 DCHECK(!is_root_node(node)); 215 DCHECK(!is_root_node(node));
214 RemoveAndDeleteNode(AsMutable(node)); 216 RemoveAndDeleteNode(AsMutable(node));
215 } 217 }
216 218
217 void BookmarkModel::RemoveAllUserBookmarks() { 219 void BookmarkModel::RemoveAllUserBookmarks() {
218 std::set<GURL> removed_urls; 220 std::set<GURL> removed_urls;
219 struct RemoveNodeData { 221 struct RemoveNodeData {
220 RemoveNodeData(const BookmarkNode* parent, int index, BookmarkNode* node)
221 : parent(parent), index(index), node(node) {}
222
223 const BookmarkNode* parent; 222 const BookmarkNode* parent;
224 int index; 223 int index;
225 BookmarkNode* node; 224 std::unique_ptr<BookmarkNode> node;
226 }; 225 };
227 std::vector<RemoveNodeData> removed_node_data_list; 226 std::vector<RemoveNodeData> removed_node_data_list;
228 227
229 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, 228 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
230 OnWillRemoveAllUserBookmarks(this)); 229 OnWillRemoveAllUserBookmarks(this));
231 230
232 BeginExtensiveChanges(); 231 BeginExtensiveChanges();
233 // Skip deleting permanent nodes. Permanent bookmark nodes are the root and 232 // Skip deleting permanent nodes. Permanent bookmark nodes are the root and
234 // its immediate children. For removing all non permanent nodes just remove 233 // its immediate children. For removing all non permanent nodes just remove
235 // all children of non-root permanent nodes. 234 // all children of non-root permanent nodes.
236 { 235 {
237 base::AutoLock url_lock(url_lock_); 236 base::AutoLock url_lock(url_lock_);
238 for (int i = 0; i < root_.child_count(); ++i) { 237 for (int i = 0; i < root_.child_count(); ++i) {
239 const BookmarkNode* permanent_node = root_.GetChild(i); 238 const BookmarkNode* permanent_node = root_.GetChild(i);
240 239
241 if (!client_->CanBeEditedByUser(permanent_node)) 240 if (!client_->CanBeEditedByUser(permanent_node))
242 continue; 241 continue;
243 242
244 for (int j = permanent_node->child_count() - 1; j >= 0; --j) { 243 for (int j = permanent_node->child_count() - 1; j >= 0; --j) {
245 BookmarkNode* child_node = AsMutable(permanent_node->GetChild(j)); 244 std::unique_ptr<BookmarkNode> node = RemoveNodeAndGetRemovedUrls(
246 RemoveNodeAndGetRemovedUrls(child_node, &removed_urls); 245 AsMutable(permanent_node->GetChild(j)), &removed_urls);
247 removed_node_data_list.push_back( 246 removed_node_data_list.push_back({permanent_node, j, std::move(node)});
248 RemoveNodeData(permanent_node, j, child_node));
249 } 247 }
250 } 248 }
251 } 249 }
252 EndExtensiveChanges(); 250 EndExtensiveChanges();
253 if (store_.get()) 251 if (store_.get())
254 store_->ScheduleSave(); 252 store_->ScheduleSave();
255 253
256 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, 254 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
257 BookmarkAllUserNodesRemoved(this, removed_urls)); 255 BookmarkAllUserNodesRemoved(this, removed_urls));
258 256
259 BeginGroupedChanges(); 257 BeginGroupedChanges();
260 for (const auto& removed_node_data : removed_node_data_list) { 258 for (auto& removed_node_data : removed_node_data_list) {
261 undo_delegate()->OnBookmarkNodeRemoved( 259 undo_delegate()->OnBookmarkNodeRemoved(this, removed_node_data.parent,
262 this, removed_node_data.parent, removed_node_data.index, 260 removed_node_data.index,
263 std::unique_ptr<BookmarkNode>(removed_node_data.node)); 261 std::move(removed_node_data.node));
264 } 262 }
265 EndGroupedChanges(); 263 EndGroupedChanges();
266 } 264 }
267 265
268 void BookmarkModel::Move(const BookmarkNode* node, 266 void BookmarkModel::Move(const BookmarkNode* node,
269 const BookmarkNode* new_parent, 267 const BookmarkNode* new_parent,
270 int index) { 268 int index) {
271 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || 269 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) ||
272 is_root_node(new_parent) || is_permanent_node(node)) { 270 is_root_node(new_parent) || is_permanent_node(node)) {
273 NOTREACHED(); 271 NOTREACHED();
(...skipping 12 matching lines...) Expand all
286 if (old_parent == new_parent && 284 if (old_parent == new_parent &&
287 (index == old_index || index == old_index + 1)) { 285 (index == old_index || index == old_index + 1)) {
288 // Node is already in this position, nothing to do. 286 // Node is already in this position, nothing to do.
289 return; 287 return;
290 } 288 }
291 289
292 SetDateFolderModified(new_parent, Time::Now()); 290 SetDateFolderModified(new_parent, Time::Now());
293 291
294 if (old_parent == new_parent && index > old_index) 292 if (old_parent == new_parent && index > old_index)
295 index--; 293 index--;
294
295 BookmarkNode* mutable_old_parent = AsMutable(old_parent);
296 std::unique_ptr<BookmarkNode> owned_node =
297 mutable_old_parent->Remove(AsMutable(node));
296 BookmarkNode* mutable_new_parent = AsMutable(new_parent); 298 BookmarkNode* mutable_new_parent = AsMutable(new_parent);
297 mutable_new_parent->Add(AsMutable(node), index); 299 mutable_new_parent->Add(std::move(owned_node), index);
298 300
299 if (store_.get()) 301 if (store_.get())
300 store_->ScheduleSave(); 302 store_->ScheduleSave();
301 303
302 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, 304 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
303 BookmarkNodeMoved(this, old_parent, old_index, 305 BookmarkNodeMoved(this, old_parent, old_index,
304 new_parent, index)); 306 new_parent, index));
305 } 307 }
306 308
307 void BookmarkModel::Copy(const BookmarkNode* node, 309 void BookmarkModel::Copy(const BookmarkNode* node,
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 const BookmarkNode* parent, 589 const BookmarkNode* parent,
588 int index, 590 int index,
589 const base::string16& title, 591 const base::string16& title,
590 const BookmarkNode::MetaInfoMap* meta_info) { 592 const BookmarkNode::MetaInfoMap* meta_info) {
591 if (!loaded_ || is_root_node(parent) || !IsValidIndex(parent, index, true)) { 593 if (!loaded_ || is_root_node(parent) || !IsValidIndex(parent, index, true)) {
592 // Can't add to the root. 594 // Can't add to the root.
593 NOTREACHED(); 595 NOTREACHED();
594 return NULL; 596 return NULL;
595 } 597 }
596 598
597 BookmarkNode* new_node = new BookmarkNode(generate_next_node_id(), GURL()); 599 std::unique_ptr<BookmarkNode> new_node =
600 base::MakeUnique<BookmarkNode>(generate_next_node_id(), GURL());
598 new_node->set_date_folder_modified(Time::Now()); 601 new_node->set_date_folder_modified(Time::Now());
599 // Folders shouldn't have line breaks in their titles. 602 // Folders shouldn't have line breaks in their titles.
600 new_node->SetTitle(title); 603 new_node->SetTitle(title);
601 new_node->set_type(BookmarkNode::FOLDER); 604 new_node->set_type(BookmarkNode::FOLDER);
602 if (meta_info) 605 if (meta_info)
603 new_node->SetMetaInfoMap(*meta_info); 606 new_node->SetMetaInfoMap(*meta_info);
604 607
605 return AddNode(AsMutable(parent), index, new_node); 608 return AddNode(AsMutable(parent), index, std::move(new_node));
606 } 609 }
607 610
608 const BookmarkNode* BookmarkModel::AddURL(const BookmarkNode* parent, 611 const BookmarkNode* BookmarkModel::AddURL(const BookmarkNode* parent,
609 int index, 612 int index,
610 const base::string16& title, 613 const base::string16& title,
611 const GURL& url) { 614 const GURL& url) {
612 return AddURLWithCreationTimeAndMetaInfo( 615 return AddURLWithCreationTimeAndMetaInfo(
613 parent, 616 parent,
614 index, 617 index,
615 title, 618 title,
(...skipping 12 matching lines...) Expand all
628 if (!loaded_ || !url.is_valid() || is_root_node(parent) || 631 if (!loaded_ || !url.is_valid() || is_root_node(parent) ||
629 !IsValidIndex(parent, index, true)) { 632 !IsValidIndex(parent, index, true)) {
630 NOTREACHED(); 633 NOTREACHED();
631 return NULL; 634 return NULL;
632 } 635 }
633 636
634 // Syncing may result in dates newer than the last modified date. 637 // Syncing may result in dates newer than the last modified date.
635 if (creation_time > parent->date_folder_modified()) 638 if (creation_time > parent->date_folder_modified())
636 SetDateFolderModified(parent, creation_time); 639 SetDateFolderModified(parent, creation_time);
637 640
638 BookmarkNode* new_node = new BookmarkNode(generate_next_node_id(), url); 641 std::unique_ptr<BookmarkNode> new_node =
642 base::MakeUnique<BookmarkNode>(generate_next_node_id(), url);
639 new_node->SetTitle(title); 643 new_node->SetTitle(title);
640 new_node->set_date_added(creation_time); 644 new_node->set_date_added(creation_time);
641 new_node->set_type(BookmarkNode::URL); 645 new_node->set_type(BookmarkNode::URL);
642 if (meta_info) 646 if (meta_info)
643 new_node->SetMetaInfoMap(*meta_info); 647 new_node->SetMetaInfoMap(*meta_info);
644 648
645 return AddNode(AsMutable(parent), index, new_node); 649 return AddNode(AsMutable(parent), index, std::move(new_node));
646 } 650 }
647 651
648 void BookmarkModel::SortChildren(const BookmarkNode* parent) { 652 void BookmarkModel::SortChildren(const BookmarkNode* parent) {
649 DCHECK(client_->CanBeEditedByUser(parent)); 653 DCHECK(client_->CanBeEditedByUser(parent));
650 654
651 if (!parent || !parent->is_folder() || is_root_node(parent) || 655 if (!parent || !parent->is_folder() || is_root_node(parent) ||
652 parent->child_count() <= 1) { 656 parent->child_count() <= 1) {
653 return; 657 return;
654 } 658 }
655 659
(...skipping 16 matching lines...) Expand all
672 BookmarkNodeChildrenReordered(this, parent)); 676 BookmarkNodeChildrenReordered(this, parent));
673 } 677 }
674 678
675 void BookmarkModel::ReorderChildren( 679 void BookmarkModel::ReorderChildren(
676 const BookmarkNode* parent, 680 const BookmarkNode* parent,
677 const std::vector<const BookmarkNode*>& ordered_nodes) { 681 const std::vector<const BookmarkNode*>& ordered_nodes) {
678 DCHECK(client_->CanBeEditedByUser(parent)); 682 DCHECK(client_->CanBeEditedByUser(parent));
679 683
680 // Ensure that all children in |parent| are in |ordered_nodes|. 684 // Ensure that all children in |parent| are in |ordered_nodes|.
681 DCHECK_EQ(static_cast<size_t>(parent->child_count()), ordered_nodes.size()); 685 DCHECK_EQ(static_cast<size_t>(parent->child_count()), ordered_nodes.size());
682 for (size_t i = 0; i < ordered_nodes.size(); ++i) 686 for (const BookmarkNode* node : ordered_nodes)
683 DCHECK_EQ(parent, ordered_nodes[i]->parent()); 687 DCHECK_EQ(parent, node->parent());
684 688
685 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, 689 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
686 OnWillReorderBookmarkNode(this, parent)); 690 OnWillReorderBookmarkNode(this, parent));
687 691
688 AsMutable(parent)->SetChildren( 692 BookmarkNode* mutable_parent = AsMutable(parent);
689 *(reinterpret_cast<const std::vector<BookmarkNode*>*>(&ordered_nodes))); 693 for (size_t i = 0; i < ordered_nodes.size() - 1; ++i) {
sky 2016/09/29 22:06:48 if ordered_nodes is empty this code is problematic
Avi (use Gerrit) 2016/09/29 22:59:58 Done.
694 std::unique_ptr<BookmarkNode> node =
695 mutable_parent->Remove(AsMutable(ordered_nodes[i]));
sky 2016/09/29 22:06:48 This implementation is way more expensive than the
Avi (use Gerrit) 2016/09/29 22:59:58 Yes. The only thought I have on how to do better i
Avi (use Gerrit) 2016/09/30 00:16:48 Actually I have an idea.
696 mutable_parent->Add(std::move(node), i);
697 }
690 698
691 if (store_.get()) 699 if (store_.get())
692 store_->ScheduleSave(); 700 store_->ScheduleSave();
693 701
694 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, 702 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
695 BookmarkNodeChildrenReordered(this, parent)); 703 BookmarkNodeChildrenReordered(this, parent));
696 } 704 }
697 705
698 void BookmarkModel::SetDateFolderModified(const BookmarkNode* parent, 706 void BookmarkModel::SetDateFolderModified(const BookmarkNode* parent,
699 const Time time) { 707 const Time time) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 case BookmarkNode::OTHER_NODE: 753 case BookmarkNode::OTHER_NODE:
746 return other_node_; 754 return other_node_;
747 case BookmarkNode::MOBILE: 755 case BookmarkNode::MOBILE:
748 return mobile_node_; 756 return mobile_node_;
749 default: 757 default:
750 NOTREACHED(); 758 NOTREACHED();
751 return NULL; 759 return NULL;
752 } 760 }
753 } 761 }
754 762
755 void BookmarkModel::RestoreRemovedNode( 763 void BookmarkModel::RestoreRemovedNode(const BookmarkNode* parent,
756 const BookmarkNode* parent, 764 int index,
757 int index, 765 std::unique_ptr<BookmarkNode> node) {
758 std::unique_ptr<BookmarkNode> scoped_node) { 766 BookmarkNode* node_ptr = node.get();
759 BookmarkNode* node = scoped_node.release(); 767 AddNode(AsMutable(parent), index, std::move(node));
760 AddNode(AsMutable(parent), index, node);
761 768
762 // We might be restoring a folder node that have already contained a set of 769 // We might be restoring a folder node that have already contained a set of
763 // child nodes. We need to notify all of them. 770 // child nodes. We need to notify all of them.
764 NotifyNodeAddedForAllDescendents(node); 771 NotifyNodeAddedForAllDescendents(node_ptr);
765 } 772 }
766 773
767 void BookmarkModel::NotifyNodeAddedForAllDescendents(const BookmarkNode* node) { 774 void BookmarkModel::NotifyNodeAddedForAllDescendents(const BookmarkNode* node) {
768 for (int i = 0; i < node->child_count(); ++i) { 775 for (int i = 0; i < node->child_count(); ++i) {
769 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, 776 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
770 BookmarkNodeAdded(this, node, i)); 777 BookmarkNodeAdded(this, node, i));
771 NotifyNodeAddedForAllDescendents(node->GetChild(i)); 778 NotifyNodeAddedForAllDescendents(node->GetChild(i));
772 } 779 }
773 } 780 }
774 781
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 tracked_objects::ScopedTracker tracking_profile2( 826 tracked_objects::ScopedTracker tracking_profile2(
820 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading2")); 827 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading2"));
821 828
822 // If bookmarks file changed externally, the IDs may have changed 829 // If bookmarks file changed externally, the IDs may have changed
823 // externally. In that case, the decoder may have reassigned IDs to make 830 // externally. In that case, the decoder may have reassigned IDs to make
824 // them unique. So when the file has changed externally, we should save the 831 // them unique. So when the file has changed externally, we should save the
825 // bookmarks file to persist new IDs. 832 // bookmarks file to persist new IDs.
826 if (store_.get()) 833 if (store_.get())
827 store_->ScheduleSave(); 834 store_->ScheduleSave();
828 } 835 }
829 bookmark_bar_node_ = details->release_bb_node(); 836 std::unique_ptr<BookmarkPermanentNode> owned_bb_node =
830 other_node_ = details->release_other_folder_node(); 837 details->owned_bb_node();
831 mobile_node_ = details->release_mobile_folder_node(); 838 std::unique_ptr<BookmarkPermanentNode> owned_other_folder_node =
832 index_.reset(details->release_index()); 839 details->owned_other_folder_node();
840 std::unique_ptr<BookmarkPermanentNode> owned_mobile_folder_node =
841 details->owned_mobile_folder_node();
842 index_ = details->owned_index();
843
844 bookmark_bar_node_ = owned_bb_node.get();
sky 2016/09/29 22:06:48 Can you set these members when you add them below?
Avi (use Gerrit) 2016/09/29 22:59:58 Not sure what you mean. Have something like roo
sky 2016/09/30 03:07:05 My mistake. What you have is fine.
845 other_node_ = owned_other_folder_node.get();
846 mobile_node_ = owned_mobile_folder_node.get();
833 847
834 // Get any extra nodes and take ownership of them at the |root_|. 848 // Get any extra nodes and take ownership of them at the |root_|.
835 std::vector<BookmarkPermanentNode*> extra_nodes; 849 std::vector<std::unique_ptr<BookmarkPermanentNode>> extra_nodes =
836 details->release_extra_nodes(&extra_nodes); 850 details->owned_extra_nodes();
837 851
838 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 852 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179
839 // is fixed. 853 // is fixed.
840 tracked_objects::ScopedTracker tracking_profile3( 854 tracked_objects::ScopedTracker tracking_profile3(
841 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading3")); 855 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading3"));
842 856
843 // WARNING: order is important here, various places assume the order is 857 // WARNING: order is important here, various places assume the order is
844 // constant (but can vary between embedders with the initial visibility 858 // constant (but can vary between embedders with the initial visibility
845 // of permanent nodes). 859 // of permanent nodes).
846 std::vector<BookmarkPermanentNode*> root_children; 860 std::vector<std::unique_ptr<BookmarkPermanentNode>> root_children;
847 root_children.push_back(bookmark_bar_node_); 861 root_children.push_back(std::move(owned_bb_node));
848 root_children.push_back(other_node_); 862 root_children.push_back(std::move(owned_other_folder_node));
849 root_children.push_back(mobile_node_); 863 root_children.push_back(std::move(owned_mobile_folder_node));
850 for (size_t i = 0; i < extra_nodes.size(); ++i) 864 std::move(extra_nodes.begin(), extra_nodes.end(),
851 root_children.push_back(extra_nodes[i]); 865 std::back_inserter(root_children));
852 866
853 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 867 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179
854 // is fixed. 868 // is fixed.
855 tracked_objects::ScopedTracker tracking_profile4( 869 tracked_objects::ScopedTracker tracking_profile4(
856 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading4")); 870 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading4"));
857 871
858 std::stable_sort(root_children.begin(), 872 std::stable_sort(root_children.begin(),
859 root_children.end(), 873 root_children.end(),
860 VisibilityComparator(client_.get())); 874 VisibilityComparator(client_.get()));
861 for (size_t i = 0; i < root_children.size(); ++i) 875 for (size_t i = 0; i < root_children.size(); ++i)
862 root_.Add(root_children[i], static_cast<int>(i)); 876 root_.Add(std::move(root_children[i]), static_cast<int>(i));
863 877
864 root_.SetMetaInfoMap(details->model_meta_info_map()); 878 root_.SetMetaInfoMap(details->model_meta_info_map());
865 root_.set_sync_transaction_version(details->model_sync_transaction_version()); 879 root_.set_sync_transaction_version(details->model_sync_transaction_version());
866 880
867 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 881 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179
868 // is fixed. 882 // is fixed.
869 tracked_objects::ScopedTracker tracking_profile5( 883 tracked_objects::ScopedTracker tracking_profile5(
870 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading5")); 884 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading5"));
871 885
872 { 886 {
873 base::AutoLock url_lock(url_lock_); 887 base::AutoLock url_lock(url_lock_);
874 // Update nodes_ordered_by_url_set_ from the nodes. 888 // Update nodes_ordered_by_url_set_ from the nodes.
875 PopulateNodesByURL(&root_); 889 PopulateNodesByURL(&root_);
876 } 890 }
877 891
878 loaded_ = true; 892 loaded_ = true;
879 893
880 loaded_signal_.Signal(); 894 loaded_signal_.Signal();
881 895
882 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179 896 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/467179
883 // is fixed. 897 // is fixed.
884 tracked_objects::ScopedTracker tracking_profile6( 898 tracked_objects::ScopedTracker tracking_profile6(
885 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading6")); 899 FROM_HERE_WITH_EXPLICIT_FUNCTION("467179 BookmarkModel::DoneLoading6"));
886 900
887 // Notify our direct observers. 901 // Notify our direct observers.
888 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, 902 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
889 BookmarkModelLoaded(this, details->ids_reassigned())); 903 BookmarkModelLoaded(this, details->ids_reassigned()));
890 } 904 }
891 905
892 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) { 906 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* node_ptr) {
893 std::unique_ptr<BookmarkNode> node(delete_me); 907 std::unique_ptr<BookmarkNode> node;
894 908
895 const BookmarkNode* parent = node->parent(); 909 const BookmarkNode* parent = node_ptr->parent();
896 DCHECK(parent); 910 DCHECK(parent);
897 int index = parent->GetIndexOf(node.get()); 911 int index = parent->GetIndexOf(node_ptr);
898 DCHECK_NE(-1, index); 912 DCHECK_NE(-1, index);
899 913
900 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, 914 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
901 OnWillRemoveBookmarks(this, parent, index, node.get())); 915 OnWillRemoveBookmarks(this, parent, index, node_ptr));
902 916
903 std::set<GURL> removed_urls; 917 std::set<GURL> removed_urls;
904 { 918 {
905 base::AutoLock url_lock(url_lock_); 919 base::AutoLock url_lock(url_lock_);
906 RemoveNodeAndGetRemovedUrls(node.get(), &removed_urls); 920 node = RemoveNodeAndGetRemovedUrls(node_ptr, &removed_urls);
907 } 921 }
908 922
909 if (store_.get()) 923 if (store_.get())
910 store_->ScheduleSave(); 924 store_->ScheduleSave();
911 925
912 FOR_EACH_OBSERVER( 926 FOR_EACH_OBSERVER(
913 BookmarkModelObserver, 927 BookmarkModelObserver,
914 observers_, 928 observers_,
915 BookmarkNodeRemoved(this, parent, index, node.get(), removed_urls)); 929 BookmarkNodeRemoved(this, parent, index, node.get(), removed_urls));
916 930
917 undo_delegate()->OnBookmarkNodeRemoved(this, parent, index, std::move(node)); 931 undo_delegate()->OnBookmarkNodeRemoved(this, parent, index, std::move(node));
918 } 932 }
919 933
920 void BookmarkModel::RemoveNodeFromInternalMaps(BookmarkNode* node) { 934 void BookmarkModel::RemoveNodeFromInternalMaps(BookmarkNode* node) {
921 index_->Remove(node); 935 index_->Remove(node);
922 // NOTE: this is called in such a way that url_lock_ is already held. As 936 // NOTE: this is called in such a way that url_lock_ is already held. As
923 // such, this doesn't explicitly grab the lock. 937 // such, this doesn't explicitly grab the lock.
924 url_lock_.AssertAcquired(); 938 url_lock_.AssertAcquired();
925 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); 939 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node);
926 DCHECK(i != nodes_ordered_by_url_set_.end()); 940 DCHECK(i != nodes_ordered_by_url_set_.end());
927 // i points to the first node with the URL, advance until we find the 941 // i points to the first node with the URL, advance until we find the
928 // node we're removing. 942 // node we're removing.
929 while (*i != node) 943 while (*i != node)
930 ++i; 944 ++i;
931 nodes_ordered_by_url_set_.erase(i); 945 nodes_ordered_by_url_set_.erase(i);
932 } 946 }
933 947
934 void BookmarkModel::RemoveNodeAndGetRemovedUrls(BookmarkNode* node, 948 std::unique_ptr<BookmarkNode> BookmarkModel::RemoveNodeAndGetRemovedUrls(
935 std::set<GURL>* removed_urls) { 949 BookmarkNode* node_ptr,
950 std::set<GURL>* removed_urls) {
936 // NOTE: this method should be always called with |url_lock_| held. 951 // NOTE: this method should be always called with |url_lock_| held.
937 // This method does not explicitly acquires a lock. 952 // This method does not explicitly acquires a lock.
938 url_lock_.AssertAcquired(); 953 url_lock_.AssertAcquired();
939 DCHECK(removed_urls); 954 DCHECK(removed_urls);
940 BookmarkNode* parent = node->parent(); 955 BookmarkNode* parent = node_ptr->parent();
941 DCHECK(parent); 956 DCHECK(parent);
942 parent->Remove(node); 957 std::unique_ptr<BookmarkNode> node = parent->Remove(node_ptr);
943 RemoveNode(node, removed_urls); 958 RemoveNode(node_ptr, removed_urls);
944 // RemoveNode adds an entry to removed_urls for each node of type URL. As we 959 // RemoveNode adds an entry to removed_urls for each node of type URL. As we
945 // allow duplicates we need to remove any entries that are still bookmarked. 960 // allow duplicates we need to remove any entries that are still bookmarked.
946 for (std::set<GURL>::iterator i = removed_urls->begin(); 961 for (std::set<GURL>::iterator i = removed_urls->begin();
947 i != removed_urls->end();) { 962 i != removed_urls->end();) {
948 if (IsBookmarkedNoLock(*i)) { 963 if (IsBookmarkedNoLock(*i)) {
949 // When we erase the iterator pointing at the erasee is 964 // When we erase the iterator pointing at the erasee is
950 // invalidated, so using i++ here within the "erase" call is 965 // invalidated, so using i++ here within the "erase" call is
951 // important as it advances the iterator before passing the 966 // important as it advances the iterator before passing the
952 // old value through to erase. 967 // old value through to erase.
953 removed_urls->erase(i++); 968 removed_urls->erase(i++);
954 } else { 969 } else {
955 ++i; 970 ++i;
956 } 971 }
957 } 972 }
973
974 return node;
958 } 975 }
959 976
960 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, 977 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent,
961 int index, 978 int index,
962 BookmarkNode* node) { 979 std::unique_ptr<BookmarkNode> node) {
963 parent->Add(node, index); 980 BookmarkNode* node_ptr = node.get();
981 parent->Add(std::move(node), index);
964 982
965 if (store_.get()) 983 if (store_.get())
966 store_->ScheduleSave(); 984 store_->ScheduleSave();
967 985
968 { 986 {
969 base::AutoLock url_lock(url_lock_); 987 base::AutoLock url_lock(url_lock_);
970 AddNodeToInternalMaps(node); 988 AddNodeToInternalMaps(node_ptr);
971 } 989 }
972 990
973 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, 991 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
974 BookmarkNodeAdded(this, parent, index)); 992 BookmarkNodeAdded(this, parent, index));
975 993
976 return node; 994 return node_ptr;
977 } 995 }
978 996
979 void BookmarkModel::AddNodeToInternalMaps(BookmarkNode* node) { 997 void BookmarkModel::AddNodeToInternalMaps(BookmarkNode* node) {
980 url_lock_.AssertAcquired(); 998 url_lock_.AssertAcquired();
981 if (node->is_url()) { 999 if (node->is_url()) {
982 index_->Add(node); 1000 index_->Add(node);
983 nodes_ordered_by_url_set_.insert(node); 1001 nodes_ordered_by_url_set_.insert(node);
984 } 1002 }
985 for (int i = 0; i < node->child_count(); ++i) 1003 for (int i = 0; i < node->child_count(); ++i)
986 AddNodeToInternalMaps(node->GetChild(i)); 1004 AddNodeToInternalMaps(node->GetChild(i));
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 undo_delegate_ = undo_delegate; 1123 undo_delegate_ = undo_delegate;
1106 if (undo_delegate_) 1124 if (undo_delegate_)
1107 undo_delegate_->SetUndoProvider(this); 1125 undo_delegate_->SetUndoProvider(this);
1108 } 1126 }
1109 1127
1110 BookmarkUndoDelegate* BookmarkModel::undo_delegate() const { 1128 BookmarkUndoDelegate* BookmarkModel::undo_delegate() const {
1111 return undo_delegate_ ? undo_delegate_ : empty_undo_delegate_.get(); 1129 return undo_delegate_ ? undo_delegate_ : empty_undo_delegate_.get();
1112 } 1130 }
1113 1131
1114 } // namespace bookmarks 1132 } // namespace bookmarks
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698