| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef COMPONENTS_BOOKMARKS_CORE_BROWSER_BOOKMARK_MODEL_H_ | |
| 6 #define COMPONENTS_BOOKMARKS_CORE_BROWSER_BOOKMARK_MODEL_H_ | |
| 7 | |
| 8 #include <map> | |
| 9 #include <set> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/basictypes.h" | |
| 13 #include "base/compiler_specific.h" | |
| 14 #include "base/memory/ref_counted.h" | |
| 15 #include "base/memory/scoped_ptr.h" | |
| 16 #include "base/observer_list.h" | |
| 17 #include "base/strings/string16.h" | |
| 18 #include "base/synchronization/lock.h" | |
| 19 #include "base/synchronization/waitable_event.h" | |
| 20 #include "components/bookmarks/core/browser/bookmark_client.h" | |
| 21 #include "components/bookmarks/core/browser/bookmark_node.h" | |
| 22 #include "components/bookmarks/core/browser/bookmark_service.h" | |
| 23 #include "ui/gfx/image/image.h" | |
| 24 #include "url/gurl.h" | |
| 25 | |
| 26 class BookmarkExpandedStateTracker; | |
| 27 class BookmarkIndex; | |
| 28 class BookmarkLoadDetails; | |
| 29 class BookmarkModelObserver; | |
| 30 class BookmarkStorage; | |
| 31 struct BookmarkMatch; | |
| 32 class PrefService; | |
| 33 class ScopedGroupBookmarkActions; | |
| 34 | |
| 35 namespace base { | |
| 36 class FilePath; | |
| 37 class SequencedTaskRunner; | |
| 38 } | |
| 39 | |
| 40 namespace favicon_base { | |
| 41 struct FaviconImageResult; | |
| 42 } | |
| 43 | |
| 44 namespace test { | |
| 45 class TestBookmarkClient; | |
| 46 } | |
| 47 | |
| 48 // BookmarkModel -------------------------------------------------------------- | |
| 49 | |
| 50 // BookmarkModel provides a directed acyclic graph of URLs and folders. | |
| 51 // Three graphs are provided for the three entry points: those on the 'bookmarks | |
| 52 // bar', those in the 'other bookmarks' folder and those in the 'mobile' folder. | |
| 53 // | |
| 54 // An observer may be attached to observe relevant events. | |
| 55 // | |
| 56 // You should NOT directly create a BookmarkModel, instead go through the | |
| 57 // BookmarkModelFactory. | |
| 58 class BookmarkModel : public BookmarkService { | |
| 59 public: | |
| 60 // |index_urls| says whether URLs should be stored in the BookmarkIndex | |
| 61 // in addition to bookmark titles. | |
| 62 BookmarkModel(BookmarkClient* client, bool index_urls); | |
| 63 virtual ~BookmarkModel(); | |
| 64 | |
| 65 // Invoked prior to destruction to release any necessary resources. | |
| 66 void Shutdown(); | |
| 67 | |
| 68 // Loads the bookmarks. This is called upon creation of the | |
| 69 // BookmarkModel. You need not invoke this directly. | |
| 70 // All load operations will be executed on |io_task_runner| and the completion | |
| 71 // callback will be called from |ui_task_runner|. | |
| 72 void Load(PrefService* pref_service, | |
| 73 const std::string& accept_languages, | |
| 74 const base::FilePath& profile_path, | |
| 75 const scoped_refptr<base::SequencedTaskRunner>& io_task_runner, | |
| 76 const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner); | |
| 77 | |
| 78 // Returns true if the model finished loading. | |
| 79 bool loaded() const { return loaded_; } | |
| 80 | |
| 81 // Returns the root node. The 'bookmark bar' node and 'other' node are | |
| 82 // children of the root node. | |
| 83 const BookmarkNode* root_node() const { return &root_; } | |
| 84 | |
| 85 // Returns the 'bookmark bar' node. This is NULL until loaded. | |
| 86 const BookmarkNode* bookmark_bar_node() const { return bookmark_bar_node_; } | |
| 87 | |
| 88 // Returns the 'other' node. This is NULL until loaded. | |
| 89 const BookmarkNode* other_node() const { return other_node_; } | |
| 90 | |
| 91 // Returns the 'mobile' node. This is NULL until loaded. | |
| 92 const BookmarkNode* mobile_node() const { return mobile_node_; } | |
| 93 | |
| 94 bool is_root_node(const BookmarkNode* node) const { return node == &root_; } | |
| 95 | |
| 96 // Returns whether the given |node| is one of the permanent nodes - root node, | |
| 97 // 'bookmark bar' node, 'other' node or 'mobile' node. | |
| 98 bool is_permanent_node(const BookmarkNode* node) const { | |
| 99 return node == &root_ || | |
| 100 node == bookmark_bar_node_ || | |
| 101 node == other_node_ || | |
| 102 node == mobile_node_; | |
| 103 } | |
| 104 | |
| 105 // Returns the parent the last node was added to. This never returns NULL | |
| 106 // (as long as the model is loaded). | |
| 107 const BookmarkNode* GetParentForNewNodes(); | |
| 108 | |
| 109 void AddObserver(BookmarkModelObserver* observer); | |
| 110 void RemoveObserver(BookmarkModelObserver* observer); | |
| 111 | |
| 112 // Notifies the observers that an extensive set of changes is about to happen, | |
| 113 // such as during import or sync, so they can delay any expensive UI updates | |
| 114 // until it's finished. | |
| 115 void BeginExtensiveChanges(); | |
| 116 void EndExtensiveChanges(); | |
| 117 | |
| 118 // Returns true if this bookmark model is currently in a mode where extensive | |
| 119 // changes might happen, such as for import and sync. This is helpful for | |
| 120 // observers that are created after the mode has started, and want to check | |
| 121 // state during their own initializer, such as the NTP. | |
| 122 bool IsDoingExtensiveChanges() const { return extensive_changes_ > 0; } | |
| 123 | |
| 124 // Removes the node at the given |index| from |parent|. Removing a folder node | |
| 125 // recursively removes all nodes. Observers are notified immediately. | |
| 126 void Remove(const BookmarkNode* parent, int index); | |
| 127 | |
| 128 // Removes all the non-permanent bookmark nodes. Observers are only notified | |
| 129 // when all nodes have been removed. There is no notification for individual | |
| 130 // node removals. | |
| 131 void RemoveAll(); | |
| 132 | |
| 133 // Moves |node| to |new_parent| and inserts it at the given |index|. | |
| 134 void Move(const BookmarkNode* node, | |
| 135 const BookmarkNode* new_parent, | |
| 136 int index); | |
| 137 | |
| 138 // Inserts a copy of |node| into |new_parent| at |index|. | |
| 139 void Copy(const BookmarkNode* node, | |
| 140 const BookmarkNode* new_parent, | |
| 141 int index); | |
| 142 | |
| 143 // Returns the favicon for |node|. If the favicon has not yet been | |
| 144 // loaded it is loaded and the observer of the model notified when done. | |
| 145 const gfx::Image& GetFavicon(const BookmarkNode* node); | |
| 146 | |
| 147 // Returns the type of the favicon for |node|. If the favicon has not yet | |
| 148 // been loaded, it returns |favicon_base::INVALID_ICON|. | |
| 149 favicon_base::IconType GetFaviconType(const BookmarkNode* node); | |
| 150 | |
| 151 // Sets the title of |node|. | |
| 152 void SetTitle(const BookmarkNode* node, const base::string16& title); | |
| 153 | |
| 154 // Sets the URL of |node|. | |
| 155 void SetURL(const BookmarkNode* node, const GURL& url); | |
| 156 | |
| 157 // Sets the date added time of |node|. | |
| 158 void SetDateAdded(const BookmarkNode* node, base::Time date_added); | |
| 159 | |
| 160 // Returns the set of nodes with the |url|. | |
| 161 void GetNodesByURL(const GURL& url, std::vector<const BookmarkNode*>* nodes); | |
| 162 | |
| 163 // Returns the most recently added node for the |url|. Returns NULL if |url| | |
| 164 // is not bookmarked. | |
| 165 const BookmarkNode* GetMostRecentlyAddedNodeForURL(const GURL& url); | |
| 166 | |
| 167 // Returns true if there are bookmarks, otherwise returns false. | |
| 168 // This method is thread safe. | |
| 169 bool HasBookmarks(); | |
| 170 | |
| 171 // Returns true if there is a bookmark with the |url|. | |
| 172 // This method is thread safe. | |
| 173 // See BookmarkService for more details on this. | |
| 174 virtual bool IsBookmarked(const GURL& url) OVERRIDE; | |
| 175 | |
| 176 // Returns all the bookmarked urls and their titles. | |
| 177 // This method is thread safe. | |
| 178 // See BookmarkService for more details on this. | |
| 179 virtual void GetBookmarks( | |
| 180 std::vector<BookmarkService::URLAndTitle>* urls) OVERRIDE; | |
| 181 | |
| 182 // Blocks until loaded; this is NOT invoked on the main thread. | |
| 183 // See BookmarkService for more details on this. | |
| 184 virtual void BlockTillLoaded() OVERRIDE; | |
| 185 | |
| 186 // Adds a new folder node at the specified position. | |
| 187 const BookmarkNode* AddFolder(const BookmarkNode* parent, | |
| 188 int index, | |
| 189 const base::string16& title); | |
| 190 | |
| 191 // Adds a new folder with meta info. | |
| 192 const BookmarkNode* AddFolderWithMetaInfo( | |
| 193 const BookmarkNode* parent, | |
| 194 int index, | |
| 195 const base::string16& title, | |
| 196 const BookmarkNode::MetaInfoMap* meta_info); | |
| 197 | |
| 198 // Adds a url at the specified position. | |
| 199 const BookmarkNode* AddURL(const BookmarkNode* parent, | |
| 200 int index, | |
| 201 const base::string16& title, | |
| 202 const GURL& url); | |
| 203 | |
| 204 // Adds a url with a specific creation date and meta info. | |
| 205 const BookmarkNode* AddURLWithCreationTimeAndMetaInfo( | |
| 206 const BookmarkNode* parent, | |
| 207 int index, | |
| 208 const base::string16& title, | |
| 209 const GURL& url, | |
| 210 const base::Time& creation_time, | |
| 211 const BookmarkNode::MetaInfoMap* meta_info); | |
| 212 | |
| 213 // Sorts the children of |parent|, notifying observers by way of the | |
| 214 // BookmarkNodeChildrenReordered method. | |
| 215 void SortChildren(const BookmarkNode* parent); | |
| 216 | |
| 217 // Order the children of |parent| as specified in |ordered_nodes|. This | |
| 218 // function should only be used to reorder the child nodes of |parent| and | |
| 219 // is not meant to move nodes between different parent. Notifies observers | |
| 220 // using the BookmarkNodeChildrenReordered method. | |
| 221 void ReorderChildren(const BookmarkNode* parent, | |
| 222 const std::vector<const BookmarkNode*>& ordered_nodes); | |
| 223 | |
| 224 // Sets the date when the folder was modified. | |
| 225 void SetDateFolderModified(const BookmarkNode* node, const base::Time time); | |
| 226 | |
| 227 // Resets the 'date modified' time of the node to 0. This is used during | |
| 228 // importing to exclude the newly created folders from showing up in the | |
| 229 // combobox of most recently modified folders. | |
| 230 void ResetDateFolderModified(const BookmarkNode* node); | |
| 231 | |
| 232 // Returns up to |max_count| of bookmarks containing each term from |text| | |
| 233 // in either the title or the URL. | |
| 234 void GetBookmarksMatching( | |
| 235 const base::string16& text, | |
| 236 size_t max_count, | |
| 237 std::vector<BookmarkMatch>* matches); | |
| 238 | |
| 239 // Sets the store to NULL, making it so the BookmarkModel does not persist | |
| 240 // any changes to disk. This is only useful during testing to speed up | |
| 241 // testing. | |
| 242 void ClearStore(); | |
| 243 | |
| 244 // Returns the next node ID. | |
| 245 int64 next_node_id() const { return next_node_id_; } | |
| 246 | |
| 247 // Returns the object responsible for tracking the set of expanded nodes in | |
| 248 // the bookmark editor. | |
| 249 BookmarkExpandedStateTracker* expanded_state_tracker() { | |
| 250 return expanded_state_tracker_.get(); | |
| 251 } | |
| 252 | |
| 253 // Sets the visibility of one of the permanent nodes (unless the node must | |
| 254 // always be visible, see |BookmarkClient::IsPermanentNodeVisible| for more | |
| 255 // details). This is set by sync. | |
| 256 void SetPermanentNodeVisible(BookmarkNode::Type type, bool value); | |
| 257 | |
| 258 // Returns the permanent node of type |type|. | |
| 259 const BookmarkPermanentNode* PermanentNode(BookmarkNode::Type type); | |
| 260 | |
| 261 // Sets/deletes meta info of |node|. | |
| 262 void SetNodeMetaInfo(const BookmarkNode* node, | |
| 263 const std::string& key, | |
| 264 const std::string& value); | |
| 265 void SetNodeMetaInfoMap(const BookmarkNode* node, | |
| 266 const BookmarkNode::MetaInfoMap& meta_info_map); | |
| 267 void DeleteNodeMetaInfo(const BookmarkNode* node, | |
| 268 const std::string& key); | |
| 269 | |
| 270 // Sets the sync transaction version of |node|. | |
| 271 void SetNodeSyncTransactionVersion(const BookmarkNode* node, | |
| 272 int64 sync_transaction_version); | |
| 273 | |
| 274 // Notify BookmarkModel that the favicons for |urls| have changed and have to | |
| 275 // be refetched. This notification is sent by BookmarkClient. | |
| 276 void OnFaviconChanged(const std::set<GURL>& urls); | |
| 277 | |
| 278 // Returns the client used by this BookmarkModel. | |
| 279 BookmarkClient* client() const { return client_; } | |
| 280 | |
| 281 private: | |
| 282 friend class BookmarkCodecTest; | |
| 283 friend class BookmarkModelTest; | |
| 284 friend class BookmarkStorage; | |
| 285 friend class ScopedGroupBookmarkActions; | |
| 286 friend class test::TestBookmarkClient; | |
| 287 | |
| 288 // Used to order BookmarkNodes by URL. | |
| 289 class NodeURLComparator { | |
| 290 public: | |
| 291 bool operator()(const BookmarkNode* n1, const BookmarkNode* n2) const { | |
| 292 return n1->url() < n2->url(); | |
| 293 } | |
| 294 }; | |
| 295 | |
| 296 // Implementation of IsBookmarked. Before calling this the caller must obtain | |
| 297 // a lock on |url_lock_|. | |
| 298 bool IsBookmarkedNoLock(const GURL& url); | |
| 299 | |
| 300 // Removes the node from internal maps and recurses through all children. If | |
| 301 // the node is a url, its url is added to removed_urls. | |
| 302 // | |
| 303 // This does NOT delete the node. | |
| 304 void RemoveNode(BookmarkNode* node, std::set<GURL>* removed_urls); | |
| 305 | |
| 306 // Invoked when loading is finished. Sets |loaded_| and notifies observers. | |
| 307 // BookmarkModel takes ownership of |details|. | |
| 308 void DoneLoading(scoped_ptr<BookmarkLoadDetails> details); | |
| 309 | |
| 310 // Populates |nodes_ordered_by_url_set_| from root. | |
| 311 void PopulateNodesByURL(BookmarkNode* node); | |
| 312 | |
| 313 // Removes the node from its parent, but does not delete it. No notifications | |
| 314 // are sent. |removed_urls| is populated with the urls which no longer have | |
| 315 // any bookmarks associated with them. | |
| 316 // This method should be called after acquiring |url_lock_|. | |
| 317 void RemoveNodeAndGetRemovedUrls(BookmarkNode* node, | |
| 318 std::set<GURL>* removed_urls); | |
| 319 | |
| 320 // Removes the node from its parent, sends notification, and deletes it. | |
| 321 // type specifies how the node should be removed. | |
| 322 void RemoveAndDeleteNode(BookmarkNode* delete_me); | |
| 323 | |
| 324 // Remove |node| from |nodes_ordered_by_url_set_|. | |
| 325 void RemoveNodeFromURLSet(BookmarkNode* node); | |
| 326 | |
| 327 // Adds the |node| at |parent| in the specified |index| and notifies its | |
| 328 // observers. | |
| 329 BookmarkNode* AddNode(BookmarkNode* parent, | |
| 330 int index, | |
| 331 BookmarkNode* node); | |
| 332 | |
| 333 // Returns true if the parent and index are valid. | |
| 334 bool IsValidIndex(const BookmarkNode* parent, int index, bool allow_end); | |
| 335 | |
| 336 // Creates one of the possible permanent nodes (bookmark bar node, other node | |
| 337 // and mobile node) from |type|. | |
| 338 BookmarkPermanentNode* CreatePermanentNode(BookmarkNode::Type type); | |
| 339 | |
| 340 // Notification that a favicon has finished loading. If we can decode the | |
| 341 // favicon, FaviconLoaded is invoked. | |
| 342 void OnFaviconDataAvailable( | |
| 343 BookmarkNode* node, | |
| 344 favicon_base::IconType icon_type, | |
| 345 const favicon_base::FaviconImageResult& image_result); | |
| 346 | |
| 347 // Invoked from the node to load the favicon. Requests the favicon from the | |
| 348 // favicon service. | |
| 349 void LoadFavicon(BookmarkNode* node, favicon_base::IconType icon_type); | |
| 350 | |
| 351 // Called to notify the observers that the favicon has been loaded. | |
| 352 void FaviconLoaded(const BookmarkNode* node); | |
| 353 | |
| 354 // If we're waiting on a favicon for node, the load request is canceled. | |
| 355 void CancelPendingFaviconLoadRequests(BookmarkNode* node); | |
| 356 | |
| 357 // Notifies the observers that a set of changes initiated by a single user | |
| 358 // action is about to happen and has completed. | |
| 359 void BeginGroupedChanges(); | |
| 360 void EndGroupedChanges(); | |
| 361 | |
| 362 // Generates and returns the next node ID. | |
| 363 int64 generate_next_node_id(); | |
| 364 | |
| 365 // Sets the maximum node ID to the given value. | |
| 366 // This is used by BookmarkCodec to report the maximum ID after it's done | |
| 367 // decoding since during decoding codec assigns node IDs. | |
| 368 void set_next_node_id(int64 id) { next_node_id_ = id; } | |
| 369 | |
| 370 // Creates and returns a new BookmarkLoadDetails. It's up to the caller to | |
| 371 // delete the returned object. | |
| 372 scoped_ptr<BookmarkLoadDetails> CreateLoadDetails( | |
| 373 const std::string& accept_languages); | |
| 374 | |
| 375 BookmarkClient* const client_; | |
| 376 | |
| 377 // Whether the initial set of data has been loaded. | |
| 378 bool loaded_; | |
| 379 | |
| 380 // The root node. This contains the bookmark bar node, the 'other' node and | |
| 381 // the mobile node as children. | |
| 382 BookmarkNode root_; | |
| 383 | |
| 384 BookmarkPermanentNode* bookmark_bar_node_; | |
| 385 BookmarkPermanentNode* other_node_; | |
| 386 BookmarkPermanentNode* mobile_node_; | |
| 387 | |
| 388 // The maximum ID assigned to the bookmark nodes in the model. | |
| 389 int64 next_node_id_; | |
| 390 | |
| 391 // The observers. | |
| 392 ObserverList<BookmarkModelObserver> observers_; | |
| 393 | |
| 394 // Set of nodes ordered by URL. This is not a map to avoid copying the | |
| 395 // urls. | |
| 396 // WARNING: |nodes_ordered_by_url_set_| is accessed on multiple threads. As | |
| 397 // such, be sure and wrap all usage of it around |url_lock_|. | |
| 398 typedef std::multiset<BookmarkNode*, NodeURLComparator> NodesOrderedByURLSet; | |
| 399 NodesOrderedByURLSet nodes_ordered_by_url_set_; | |
| 400 base::Lock url_lock_; | |
| 401 | |
| 402 // Used for loading favicons. | |
| 403 base::CancelableTaskTracker cancelable_task_tracker_; | |
| 404 | |
| 405 // Reads/writes bookmarks to disk. | |
| 406 scoped_refptr<BookmarkStorage> store_; | |
| 407 | |
| 408 scoped_ptr<BookmarkIndex> index_; | |
| 409 | |
| 410 // True if URLs are stored in the BookmarkIndex in addition to bookmark | |
| 411 // titles. | |
| 412 const bool index_urls_; | |
| 413 | |
| 414 base::WaitableEvent loaded_signal_; | |
| 415 | |
| 416 // See description of IsDoingExtensiveChanges above. | |
| 417 int extensive_changes_; | |
| 418 | |
| 419 scoped_ptr<BookmarkExpandedStateTracker> expanded_state_tracker_; | |
| 420 | |
| 421 DISALLOW_COPY_AND_ASSIGN(BookmarkModel); | |
| 422 }; | |
| 423 | |
| 424 #endif // COMPONENTS_BOOKMARKS_CORE_BROWSER_BOOKMARK_MODEL_H_ | |
| OLD | NEW |