Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / bookmarks / core / browser / bookmark_model.h
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. This is set by sync.
254   void SetPermanentNodeVisible(BookmarkNode::Type type, bool value);
255
256   // Sets/deletes meta info of |node|.
257   void SetNodeMetaInfo(const BookmarkNode* node,
258                        const std::string& key,
259                        const std::string& value);
260   void SetNodeMetaInfoMap(const BookmarkNode* node,
261                           const BookmarkNode::MetaInfoMap& meta_info_map);
262   void DeleteNodeMetaInfo(const BookmarkNode* node,
263                           const std::string& key);
264
265   // Sets the sync transaction version of |node|.
266   void SetNodeSyncTransactionVersion(const BookmarkNode* node,
267                                      int64 sync_transaction_version);
268
269   // Notify BookmarkModel that the favicons for |urls| have changed and have to
270   // be refetched. This notification is sent by BookmarkClient.
271   void OnFaviconChanged(const std::set<GURL>& urls);
272
273   // Returns the client used by this BookmarkModel.
274   BookmarkClient* client() const { return client_; }
275
276  private:
277   friend class BookmarkCodecTest;
278   friend class BookmarkModelTest;
279   friend class BookmarkStorage;
280   friend class ScopedGroupBookmarkActions;
281   friend class test::TestBookmarkClient;
282
283   // Used to order BookmarkNodes by URL.
284   class NodeURLComparator {
285    public:
286     bool operator()(const BookmarkNode* n1, const BookmarkNode* n2) const {
287       return n1->url() < n2->url();
288     }
289   };
290
291   // Implementation of IsBookmarked. Before calling this the caller must obtain
292   // a lock on |url_lock_|.
293   bool IsBookmarkedNoLock(const GURL& url);
294
295   // Removes the node from internal maps and recurses through all children. If
296   // the node is a url, its url is added to removed_urls.
297   //
298   // This does NOT delete the node.
299   void RemoveNode(BookmarkNode* node, std::set<GURL>* removed_urls);
300
301   // Invoked when loading is finished. Sets |loaded_| and notifies observers.
302   // BookmarkModel takes ownership of |details|.
303   void DoneLoading(scoped_ptr<BookmarkLoadDetails> details);
304
305   // Populates |nodes_ordered_by_url_set_| from root.
306   void PopulateNodesByURL(BookmarkNode* node);
307
308   // Removes the node from its parent, but does not delete it. No notifications
309   // are sent. |removed_urls| is populated with the urls which no longer have
310   // any bookmarks associated with them.
311   // This method should be called after acquiring |url_lock_|.
312   void RemoveNodeAndGetRemovedUrls(BookmarkNode* node,
313                                    std::set<GURL>* removed_urls);
314
315   // Removes the node from its parent, sends notification, and deletes it.
316   // type specifies how the node should be removed.
317   void RemoveAndDeleteNode(BookmarkNode* delete_me);
318
319   // Remove |node| from |nodes_ordered_by_url_set_|.
320   void RemoveNodeFromURLSet(BookmarkNode* node);
321
322   // Adds the |node| at |parent| in the specified |index| and notifies its
323   // observers.
324   BookmarkNode* AddNode(BookmarkNode* parent,
325                         int index,
326                         BookmarkNode* node);
327
328   // Returns true if the parent and index are valid.
329   bool IsValidIndex(const BookmarkNode* parent, int index, bool allow_end);
330
331   // Creates one of the possible permanent nodes (bookmark bar node, other node
332   // and mobile node) from |type|.
333   BookmarkPermanentNode* CreatePermanentNode(BookmarkNode::Type type);
334
335   // Notification that a favicon has finished loading. If we can decode the
336   // favicon, FaviconLoaded is invoked.
337   void OnFaviconDataAvailable(
338       BookmarkNode* node,
339       favicon_base::IconType icon_type,
340       const favicon_base::FaviconImageResult& image_result);
341
342   // Invoked from the node to load the favicon. Requests the favicon from the
343   // favicon service.
344   void LoadFavicon(BookmarkNode* node, favicon_base::IconType icon_type);
345
346   // Called to notify the observers that the favicon has been loaded.
347   void FaviconLoaded(const BookmarkNode* node);
348
349   // If we're waiting on a favicon for node, the load request is canceled.
350   void CancelPendingFaviconLoadRequests(BookmarkNode* node);
351
352   // Notifies the observers that a set of changes initiated by a single user
353   // action is about to happen and has completed.
354   void BeginGroupedChanges();
355   void EndGroupedChanges();
356
357   // Generates and returns the next node ID.
358   int64 generate_next_node_id();
359
360   // Sets the maximum node ID to the given value.
361   // This is used by BookmarkCodec to report the maximum ID after it's done
362   // decoding since during decoding codec assigns node IDs.
363   void set_next_node_id(int64 id) { next_node_id_ = id; }
364
365   // Creates and returns a new BookmarkLoadDetails. It's up to the caller to
366   // delete the returned object.
367   scoped_ptr<BookmarkLoadDetails> CreateLoadDetails(
368       const std::string& accept_languages);
369
370   BookmarkClient* const client_;
371
372   // Whether the initial set of data has been loaded.
373   bool loaded_;
374
375   // The root node. This contains the bookmark bar node and the 'other' node as
376   // children.
377   BookmarkNode root_;
378
379   BookmarkPermanentNode* bookmark_bar_node_;
380   BookmarkPermanentNode* other_node_;
381   BookmarkPermanentNode* mobile_node_;
382
383   // The maximum ID assigned to the bookmark nodes in the model.
384   int64 next_node_id_;
385
386   // The observers.
387   ObserverList<BookmarkModelObserver> observers_;
388
389   // Set of nodes ordered by URL. This is not a map to avoid copying the
390   // urls.
391   // WARNING: |nodes_ordered_by_url_set_| is accessed on multiple threads. As
392   // such, be sure and wrap all usage of it around |url_lock_|.
393   typedef std::multiset<BookmarkNode*, NodeURLComparator> NodesOrderedByURLSet;
394   NodesOrderedByURLSet nodes_ordered_by_url_set_;
395   base::Lock url_lock_;
396
397   // Used for loading favicons.
398   base::CancelableTaskTracker cancelable_task_tracker_;
399
400   // Reads/writes bookmarks to disk.
401   scoped_refptr<BookmarkStorage> store_;
402
403   scoped_ptr<BookmarkIndex> index_;
404
405   // True if URLs are stored in the BookmarkIndex in addition to bookmark
406   // titles.
407   const bool index_urls_;
408
409   base::WaitableEvent loaded_signal_;
410
411   // See description of IsDoingExtensiveChanges above.
412   int extensive_changes_;
413
414   scoped_ptr<BookmarkExpandedStateTracker> expanded_state_tracker_;
415
416   DISALLOW_COPY_AND_ASSIGN(BookmarkModel);
417 };
418
419 #endif  // COMPONENTS_BOOKMARKS_CORE_BROWSER_BOOKMARK_MODEL_H_