123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_MODEL_H_
- #define COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_MODEL_H_
- #include <stddef.h>
- #include <stdint.h>
- #include <map>
- #include <memory>
- #include <set>
- #include <string>
- #include <vector>
- #include "base/check_op.h"
- #include "base/compiler_specific.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/memory/weak_ptr.h"
- #include "base/observer_list.h"
- #include "base/sequence_checker.h"
- #include "components/bookmarks/browser/bookmark_client.h"
- #include "components/bookmarks/browser/bookmark_node.h"
- #include "components/bookmarks/browser/bookmark_undo_provider.h"
- #include "components/keyed_service/core/keyed_service.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "ui/gfx/image/image.h"
- #include "url/gurl.h"
- class PrefService;
- namespace base {
- class FilePath;
- class GUID;
- }
- namespace favicon_base {
- struct FaviconImageResult;
- }
- namespace query_parser {
- enum class MatchingAlgorithm;
- }
- namespace bookmarks {
- class BookmarkCodecTest;
- class BookmarkExpandedStateTracker;
- class BookmarkLoadDetails;
- class BookmarkModelObserver;
- class BookmarkStorage;
- class BookmarkUndoDelegate;
- class ModelLoader;
- class ScopedGroupBookmarkActions;
- class TestBookmarkClient;
- class TitledUrlIndex;
- class UrlIndex;
- struct UrlAndTitle;
- struct TitledUrlMatch;
- // BookmarkModel --------------------------------------------------------------
- // BookmarkModel provides a directed acyclic graph of URLs and folders.
- // Three graphs are provided for the three entry points: those on the 'bookmarks
- // bar', those in the 'other bookmarks' folder and those in the 'mobile' folder.
- //
- // An observer may be attached to observe relevant events.
- //
- // You should NOT directly create a BookmarkModel, instead go through the
- // BookmarkModelFactory.
- class BookmarkModel : public BookmarkUndoProvider,
- public KeyedService {
- public:
- explicit BookmarkModel(std::unique_ptr<BookmarkClient> client);
- BookmarkModel(const BookmarkModel&) = delete;
- BookmarkModel& operator=(const BookmarkModel&) = delete;
- ~BookmarkModel() override;
- // Triggers the loading of bookmarks, which is an asynchronous operation with
- // most heavy-lifting taking place in a background sequence. Upon completion,
- // loaded() will return true and observers will be notified via
- // BookmarkModelLoaded().
- void Load(PrefService* pref_service, const base::FilePath& profile_path);
- // Returns true if the model finished loading.
- bool loaded() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return loaded_;
- }
- // Returns the object responsible for tracking loading.
- scoped_refptr<ModelLoader> model_loader();
- // Returns the root node. The 'bookmark bar' node and 'other' node are
- // children of the root node.
- const BookmarkNode* root_node() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return root_;
- }
- // Returns the 'bookmark bar' node. This is NULL until loaded.
- const BookmarkNode* bookmark_bar_node() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return bookmark_bar_node_;
- }
- // Returns the 'other' node. This is NULL until loaded.
- const BookmarkNode* other_node() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return other_node_;
- }
- // Returns the 'mobile' node. This is NULL until loaded.
- const BookmarkNode* mobile_node() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return mobile_node_;
- }
- bool is_root_node(const BookmarkNode* node) const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return node == root_;
- }
- // Returns whether the given |node| is one of the permanent nodes - root node,
- // 'bookmark bar' node, 'other' node or 'mobile' node, or one of the root
- // nodes supplied by the |client_|.
- bool is_permanent_node(const BookmarkNode* node) const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return node && (node == root_ || node->parent() == root_);
- }
- void AddObserver(BookmarkModelObserver* observer);
- void RemoveObserver(BookmarkModelObserver* observer);
- // Notifies the observers that an extensive set of changes is about to happen,
- // such as during import or sync, so they can delay any expensive UI updates
- // until it's finished.
- void BeginExtensiveChanges();
- void EndExtensiveChanges();
- // Returns true if this bookmark model is currently in a mode where extensive
- // changes might happen, such as for import and sync. This is helpful for
- // observers that are created after the mode has started, and want to check
- // state during their own initializer, such as the NTP.
- bool IsDoingExtensiveChanges() const { return extensive_changes_ > 0; }
- // Removes |node| from the model and deletes it. Removing a folder node
- // recursively removes all nodes. Observers are notified immediately. |node|
- // must not be a permanent node.
- void Remove(const BookmarkNode* node);
- // Removes all the non-permanent bookmark nodes that are editable by the user.
- // Observers are only notified when all nodes have been removed. There is no
- // notification for individual node removals.
- void RemoveAllUserBookmarks();
- // Moves |node| to |new_parent| and inserts it at the given |index|.
- void Move(const BookmarkNode* node,
- const BookmarkNode* new_parent,
- size_t index);
- // Inserts a copy of |node| into |new_parent| at |index|.
- void Copy(const BookmarkNode* node,
- const BookmarkNode* new_parent,
- size_t index);
- // Returns the favicon for |node|. If the favicon has not yet been loaded,
- // a load will be triggered and the observer of the model notified when done.
- // This also means that, on return, the node's state is guaranteed to be
- // either LOADED_FAVICON (if it was already loaded prior to the call) or
- // LOADING_FAVICON (with the exception of folders, where the call is a no-op).
- const gfx::Image& GetFavicon(const BookmarkNode* node);
- // Sets the title of |node|.
- void SetTitle(const BookmarkNode* node, const std::u16string& title);
- // Sets the URL of |node|.
- void SetURL(const BookmarkNode* node, const GURL& url);
- // Sets the date added time of |node|.
- void SetDateAdded(const BookmarkNode* node, base::Time date_added);
- // Returns the set of nodes with the |url|.
- void GetNodesByURL(const GURL& url, std::vector<const BookmarkNode*>* nodes);
- // Returns the most recently added user node for the |url|; urls from any
- // nodes that are not editable by the user are never returned by this call.
- // Returns NULL if |url| is not bookmarked.
- const BookmarkNode* GetMostRecentlyAddedUserNodeForURL(const GURL& url);
- // Returns true if there are bookmarks, otherwise returns false.
- bool HasBookmarks();
- // Returns true is there is no user created bookmarks or folders.
- bool HasNoUserCreatedBookmarksOrFolders();
- // Returns true if the specified URL is bookmarked.
- bool IsBookmarked(const GURL& url);
- // Returns, by reference in |bookmarks|, the set of bookmarked urls and their
- // titles. This returns the unique set of URLs. For example, if two bookmarks
- // reference the same URL only one entry is added not matter the titles are
- // same or not.
- void GetBookmarks(std::vector<UrlAndTitle>* urls);
- // Adds a new folder node at the specified position with the given
- // |creation_time|, |guid| and |meta_info|. If no GUID is provided (i.e.
- // nullopt), then a random one will be generated. If a GUID is provided, it
- // must be valid.
- const BookmarkNode* AddFolder(
- const BookmarkNode* parent,
- size_t index,
- const std::u16string& title,
- const BookmarkNode::MetaInfoMap* meta_info = nullptr,
- absl::optional<base::Time> creation_time = absl::nullopt,
- absl::optional<base::GUID> guid = absl::nullopt);
- // Adds a new bookmark for the given `url` at the specified position with the
- // given `meta_info`. Used for bookmarks being added through some direct user
- // action (e.g. the bookmark star).
- const BookmarkNode* AddNewURL(
- const BookmarkNode* parent,
- size_t index,
- const std::u16string& title,
- const GURL& url,
- const BookmarkNode::MetaInfoMap* meta_info = nullptr);
- // Adds a url at the specified position with the given `creation_time`,
- // `meta_info`, `guid`, and `last_used_time`. If no GUID is provided
- // (i.e. nullopt), then a random one will be generated. If a GUID is
- // provided, it must be valid. Used for bookmarks not being added from
- // direct user actions (e.g. created via sync, locally modified bookmark
- // or pre-existing bookmark).
- const BookmarkNode* AddURL(
- const BookmarkNode* parent,
- size_t index,
- const std::u16string& title,
- const GURL& url,
- const BookmarkNode::MetaInfoMap* meta_info = nullptr,
- absl::optional<base::Time> creation_time = absl::nullopt,
- absl::optional<base::GUID> guid = absl::nullopt);
- // Sorts the children of |parent|, notifying observers by way of the
- // BookmarkNodeChildrenReordered method.
- void SortChildren(const BookmarkNode* parent);
- // Order the children of |parent| as specified in |ordered_nodes|. This
- // function should only be used to reorder the child nodes of |parent| and
- // is not meant to move nodes between different parent. Notifies observers
- // using the BookmarkNodeChildrenReordered method.
- void ReorderChildren(const BookmarkNode* parent,
- const std::vector<const BookmarkNode*>& ordered_nodes);
- // Sets the date when the folder was modified.
- void SetDateFolderModified(const BookmarkNode* node, const base::Time time);
- // Resets the 'date modified' time of the node to 0. This is used during
- // importing to exclude the newly created folders from showing up in the
- // combobox of most recently modified folders.
- void ResetDateFolderModified(const BookmarkNode* node);
- // Updates the last used `time` for the given `id` / `url`.
- void UpdateLastUsedTime(const BookmarkNode* node, const base::Time time);
- // Clears the last used time for the given time range. Called when the user
- // clears their history. Time() and Time::Max() are used for min/max values.
- void ClearLastUsedTimeInRange(const base::Time delete_begin,
- const base::Time delete_end);
- // Returns up to |max_count| bookmarks containing each term from |query| in
- // either the title, URL, or, if |match_ancestor_titles| is true, the titles
- // of ancestors. |matching_algorithm| determines the algorithm used by
- // QueryParser internally to parse |query|.
- std::vector<TitledUrlMatch> GetBookmarksMatching(
- const std::u16string& query,
- size_t max_count,
- query_parser::MatchingAlgorithm matching_algorithm,
- bool match_ancestor_titles = false);
- // Sets the store to NULL, making it so the BookmarkModel does not persist
- // any changes to disk. This is only useful during testing to speed up
- // testing.
- void ClearStore();
- // Returns the next node ID.
- int64_t next_node_id() const { return next_node_id_; }
- // Returns the object responsible for tracking the set of expanded nodes in
- // the bookmark editor.
- BookmarkExpandedStateTracker* expanded_state_tracker() {
- return expanded_state_tracker_.get();
- }
- // Sets/deletes meta info of |node|.
- void SetNodeMetaInfo(const BookmarkNode* node,
- const std::string& key,
- const std::string& value);
- void SetNodeMetaInfoMap(const BookmarkNode* node,
- const BookmarkNode::MetaInfoMap& meta_info_map);
- void DeleteNodeMetaInfo(const BookmarkNode* node,
- const std::string& key);
- // Adds |key| to the set of meta info keys that are not copied when a node is
- // cloned.
- void AddNonClonedKey(const std::string& key);
- // Returns the set of meta info keys that should not be copied when a node is
- // cloned.
- const std::set<std::string>& non_cloned_keys() const {
- return non_cloned_keys_;
- }
- // Notify BookmarkModel that the favicons for the given page URLs (e.g.
- // http://www.google.com) and the given icon URL (e.g.
- // http://www.google.com/favicon.ico) have changed. It is valid to call
- // OnFaviconsChanged() with non-empty |page_urls| and an empty |icon_url| and
- // vice versa.
- void OnFaviconsChanged(const std::set<GURL>& page_urls,
- const GURL& icon_url);
- // Returns the client used by this BookmarkModel.
- BookmarkClient* client() const { return client_.get(); }
- void SetUndoDelegate(BookmarkUndoDelegate* undo_delegate);
- base::WeakPtr<BookmarkModel> AsWeakPtr() {
- return weak_factory_.GetWeakPtr();
- }
- private:
- friend class BookmarkCodecTest;
- friend class BookmarkModelFaviconTest;
- friend class BookmarkStorage;
- friend class ScopedGroupBookmarkActions;
- friend class TestBookmarkClient;
- // BookmarkUndoProvider:
- void RestoreRemovedNode(const BookmarkNode* parent,
- size_t index,
- std::unique_ptr<BookmarkNode> node) override;
- // Notifies the observers for adding every descendant of |node|.
- void NotifyNodeAddedForAllDescendants(const BookmarkNode* node);
- // Removes the node from internal maps and recurses through all children. If
- // the node is a url, its url is added to removed_urls.
- //
- // This does NOT delete the node.
- void RemoveNodeFromIndexRecursive(BookmarkNode* node);
- // Called when done loading. Updates internal state and notifies observers.
- void DoneLoading(std::unique_ptr<BookmarkLoadDetails> details);
- // Adds the |node| at |parent| in the specified |index| and notifies its
- // observers.
- BookmarkNode* AddNode(BookmarkNode* parent,
- size_t index,
- std::unique_ptr<BookmarkNode> node);
- // Adds |node| to |index_| and recursively invokes this for all children.
- void AddNodeToIndexRecursive(const BookmarkNode* node);
- // Returns true if the parent and index are valid.
- bool IsValidIndex(const BookmarkNode* parent, size_t index, bool allow_end);
- // Notification that a favicon has finished loading. If we can decode the
- // favicon, FaviconLoaded is invoked.
- void OnFaviconDataAvailable(
- BookmarkNode* node,
- const favicon_base::FaviconImageResult& image_result);
- // Invoked from the node to load the favicon. Requests the favicon from the
- // favicon service.
- void LoadFavicon(BookmarkNode* node);
- // Called to notify the observers that the favicon has been loaded.
- void FaviconLoaded(const BookmarkNode* node);
- // If we're waiting on a favicon for node, the load request is canceled.
- void CancelPendingFaviconLoadRequests(BookmarkNode* node);
- // Notifies the observers that a set of changes initiated by a single user
- // action is about to happen and has completed.
- void BeginGroupedChanges();
- void EndGroupedChanges();
- // Generates and returns the next node ID.
- int64_t generate_next_node_id();
- // Sets the maximum node ID to the given value.
- // This is used by BookmarkCodec to report the maximum ID after it's done
- // decoding since during decoding codec assigns node IDs.
- void set_next_node_id(int64_t id) { next_node_id_ = id; }
- BookmarkUndoDelegate* undo_delegate() const;
- // Implementation of `UpdateLastUsedTime` which gives the option to skip
- // saving the change to `BookmarkStorage. Used to efficiently make changes
- // to multiple bookmarks.
- void UpdateLastUsedTimeImpl(const BookmarkNode* node, base::Time time);
- void ClearLastUsedTimeInRangeRecursive(BookmarkNode* node,
- const base::Time delete_begin,
- const base::Time delete_end);
- std::unique_ptr<BookmarkClient> client_;
- // Whether the initial set of data has been loaded.
- bool loaded_ = false;
- // See |root_| for details.
- std::unique_ptr<BookmarkNode> owned_root_;
- // The root node. This contains the bookmark bar node, the 'other' node and
- // the mobile node as children. The value of |root_| is initially that of
- // |owned_root_|. Once loading has completed, |owned_root_| is destroyed and
- // this is set to url_index_->root(). |owned_root_| is done as lots of
- // existing code assumes the root is non-null while loading.
- raw_ptr<BookmarkNode> root_ = nullptr;
- raw_ptr<BookmarkPermanentNode> bookmark_bar_node_ = nullptr;
- raw_ptr<BookmarkPermanentNode> other_node_ = nullptr;
- raw_ptr<BookmarkPermanentNode> mobile_node_ = nullptr;
- // The maximum ID assigned to the bookmark nodes in the model.
- int64_t next_node_id_ = 1;
- // The observers.
- base::ObserverList<BookmarkModelObserver>::Unchecked observers_;
- // Used for loading favicons.
- base::CancelableTaskTracker cancelable_task_tracker_;
- // Writes bookmarks to disk.
- std::unique_ptr<BookmarkStorage> store_;
- std::unique_ptr<TitledUrlIndex> titled_url_index_;
- // Owned by |model_loader_|.
- // WARNING: in some tests this does *not* refer to
- // |ModelLoader::history_bookmark_model_|. This is because some tests
- // directly call DoneLoading().
- // TODO: this is confusing, fix tests not to circumvent ModelLoader.
- scoped_refptr<UrlIndex> url_index_;
- // See description of IsDoingExtensiveChanges above.
- int extensive_changes_ = 0;
- std::unique_ptr<BookmarkExpandedStateTracker> expanded_state_tracker_;
- std::set<std::string> non_cloned_keys_;
- raw_ptr<BookmarkUndoDelegate> undo_delegate_ = nullptr;
- std::unique_ptr<BookmarkUndoDelegate> empty_undo_delegate_;
- scoped_refptr<ModelLoader> model_loader_;
- SEQUENCE_CHECKER(sequence_checker_);
- base::WeakPtrFactory<BookmarkModel> weak_factory_{this};
- };
- } // namespace bookmarks
- #endif // COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_MODEL_H_
|