File: permanent_folder_ordering_tracker.h

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (186 lines) | stat: -rw-r--r-- 8,231 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_BOOKMARKS_PERMANENT_FOLDER_ORDERING_TRACKER_H_
#define CHROME_BROWSER_BOOKMARKS_PERMANENT_FOLDER_ORDERING_TRACKER_H_

#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "components/bookmarks/browser/bookmark_model_observer.h"
#include "components/bookmarks/browser/bookmark_node.h"
#include "components/bookmarks/browser/bookmark_node_data.h"

namespace bookmarks {
class BookmarkModel;
class BookmarkNode;
}  // namespace bookmarks

// Tracks any custom order across child nodes of a particular local and account
// permanent bookmark node of a certain type `bookmarks::BookmarkNode::Type`
// (bookmark bar, other, mobile). Manages operations across children of local
// and account equivalent permanent node e.g. add, move, remove bookmark node.
// It also allows querying their direct children while respecting the custom
// order between the children of the two permanent nodes.
// If only local or syncable node exists, this class just forwards operations to
// the `BookmarkModel`.
class PermanentFolderOrderingTracker : public bookmarks::BookmarkModelObserver {
 public:
  class Delegate {
   public:
    // Called every time the ordering of the nodes in
    // `PermanentFolderOrderingTracker` changes.
    virtual void TrackedOrderingChanged() = 0;

    virtual ~Delegate() = default;
  };

  // `tracked_type` must reflect the type of the permanent node, it must be
  // one of the following: BOOKMARK_BAR, OTHER_NODE, MOBILE. Other node types
  // are invalid.
  // `delegate` must not be null and must outlive this class.
  PermanentFolderOrderingTracker(bookmarks::BookmarkModel* model,
                                 bookmarks::BookmarkNode::Type tracked_type,
                                 Delegate* delegate);

  ~PermanentFolderOrderingTracker() override;

  PermanentFolderOrderingTracker(const PermanentFolderOrderingTracker&) =
      delete;
  PermanentFolderOrderingTracker& operator=(
      const PermanentFolderOrderingTracker&) = delete;

  // This function must be invoked, and ordering will only be tracked
  // afterwards.
  void Init(std::vector<int64_t> in_order_node_ids);

  // Returns underlying permanent nodes.
  // If the bookmark model is not loaded, it returns empty.
  std::vector<const bookmarks::BookmarkNode*> GetUnderlyingPermanentNodes()
      const;

  // Returns default parent node for new nodes created as a child of
  // `tracked_type_`.
  // This will return the account node if one exists, otherwise it returns the
  // local/syncable node.
  // `BookmarkModel` must be loaded.
  const bookmarks::BookmarkNode* GetDefaultParentForNewNodes() const;

  // Returns index of `node`.
  // `node` must be a direct child of one of the tracked permanent
  // nodes in `this`.
  size_t GetIndexOf(const bookmarks::BookmarkNode* node) const;

  // Returns node at `index`.
  const bookmarks::BookmarkNode* GetNodeAtIndex(size_t index) const;

  // Returns children count for nodes tracked in this tracker.
  size_t GetChildrenCount() const;

  // Moves node from an arbitrary parent to become a child of the permanent
  // folder tracked by this at `index`.
  // If `node` is local or account bookmark, it will remain local/account after
  // the move.
  // Note that if node is already being tracked by this, there are two possible
  // target indices (index) that result in a no-op. This is similar to what
  // `BookmarkModel::Move()` does
  // Returns the new index or `std::nullopt` if `MoveToIndex` is no-op.
  std::optional<size_t> MoveToIndex(const bookmarks::BookmarkNode* node,
                                    size_t index);

  // Copies nodes in `elements` to be new child nodes of the permanent
  // folder tracked by this starting at `index`.
  // The new nodes will be child nodes of `GetDefaultParentForNewNodes()`.
  void AddNodesAsCopiesOfNodeData(
      const std::vector<bookmarks::BookmarkNodeData::Element>& elements,
      size_t index);

  // Helper function for optimization purposes, it returns the same value as
  // `GetIndexOf()`.
  // Returns `in_storage_index` if ordering is not tracked
  // `ShouldTrackOrdering()` is false. Otherwise, returns `GetIndexOf()`
  size_t GetIndexAcrossStorage(const bookmarks::BookmarkNode* node,
                               size_t in_storage_index) const;

  // Returns true if `ordering` is not empty and has non-default order.
  // Default order is all account child nodes then local child nodes.
  bool IsNonDefaultOrderingTracked() const;

  // bookmarks::BookmarkModelObserver:
  void BookmarkModelLoaded(bool ids_reassigned) override;
  void BookmarkNodeMoved(const bookmarks::BookmarkNode* old_parent,
                         size_t old_index,
                         const bookmarks::BookmarkNode* new_parent,
                         size_t new_index) override;
  void BookmarkNodeAdded(const bookmarks::BookmarkNode* parent,
                         size_t index,
                         bool added_by_user) override;
  void BookmarkNodeRemoved(const bookmarks::BookmarkNode* parent,
                           size_t old_index,
                           const bookmarks::BookmarkNode* node,
                           const std::set<GURL>& removed_urls,
                           const base::Location& location) override;
  void OnWillRemoveAllUserBookmarks(const base::Location& location) override;
  void BookmarkAllUserNodesRemoved(const std::set<GURL>& removed_urls,
                                   const base::Location& location) override;
  void BookmarkNodeChanged(const bookmarks::BookmarkNode* node) override {}
  void BookmarkNodeFaviconChanged(
      const bookmarks::BookmarkNode* node) override {}
  void BookmarkNodeChildrenReordered(
      const bookmarks::BookmarkNode* node) override;

 private:
  void NotifyTrackedOrderingChanged();
  void SetTrackedPermanentNodes();
  bool IsTrackedPermanentNode(const bookmarks::BookmarkNode* node) const;
  void ResetOrderingToDefault();
  bool ShouldTrackOrdering() const;
  size_t GetExpectedOrderingSize() const;
  std::vector<raw_ptr<const bookmarks::BookmarkNode>> GetDefaultOrderIfTracked()
      const;

  void RemoveBookmarkNodeIfTracked(const bookmarks::BookmarkNode* parent,
                                   size_t old_index,
                                   const bookmarks::BookmarkNode* node);

  void AddBookmarkNodeIfTracked(const bookmarks::BookmarkNode* parent,
                                size_t index);

  // This function counts bookmarks within the permanent bookmarks folder
  // tracked by this. If account_storage is true, it counts bookmarks whose
  // parent is account_node_. Otherwise, it counts bookmarks with a parent of
  // local_or_syncable_node_, considering only children indexed from 0 to index
  // - 1.
  size_t GetInStorageBookmarkCountBeforeIndex(bool account_storage,
                                              size_t index) const;

  void ReconcileLoadedNodeIds();

  const raw_ptr<bookmarks::BookmarkModel> model_;
  const bookmarks::BookmarkNode::Type tracked_type_;
  const raw_ptr<Delegate> delegate_;

  bool initialized_ = false;

  raw_ptr<const bookmarks::BookmarkNode> local_or_syncable_node_ = nullptr;
  raw_ptr<const bookmarks::BookmarkNode> account_node_ = nullptr;

  // Loaded node Ids from disk.
  // Only needed while the bookmark model is being loaded.
  std::vector<int64_t> loaded_node_ids_during_model_load_;

  // Non-empty if both `local_or_syncable_node_` and
  // `account_node_` have children (`ShouldTrackOrdering()` returns true).
  // If ordering is tracked, the size of the vector is the sum of direct
  // children of the `local_or_syncable_node_` and `account_node_` (as returned
  // by `GetExpectedOrderingSize()`).
  std::vector<raw_ptr<const bookmarks::BookmarkNode>> ordering_;

  bool all_user_bookmarks_remove_in_progress_ = false;

  base::ScopedObservation<bookmarks::BookmarkModel,
                          bookmarks::BookmarkModelObserver>
      model_observation_{this};
};

#endif  // CHROME_BROWSER_BOOKMARKS_PERMANENT_FOLDER_ORDERING_TRACKER_H_