1// Copyright (c) 2012 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 CHROME_BROWSER_EXTENSIONS_API_BOOKMARKS_BOOKMARKS_API_H_
6#define CHROME_BROWSER_EXTENSIONS_API_BOOKMARKS_BOOKMARKS_API_H_
7
8#include <list>
9#include <string>
10#include <vector>
11
12#include "base/compiler_specific.h"
13#include "base/memory/ref_counted.h"
14#include "chrome/browser/extensions/chrome_extension_function.h"
15#include "components/bookmarks/browser/base_bookmark_model_observer.h"
16#include "components/bookmarks/browser/bookmark_node.h"
17#include "extensions/browser/browser_context_keyed_api_factory.h"
18#include "extensions/browser/event_router.h"
19#include "ui/shell_dialogs/select_file_dialog.h"
20
21class ChromeBookmarkClient;
22
23namespace base {
24class FilePath;
25class ListValue;
26}
27
28namespace content {
29class BrowserContext;
30}
31
32namespace extensions {
33
34namespace api {
35namespace bookmarks {
36struct CreateDetails;
37}
38}
39
40// Observes BookmarkModel and then routes the notifications as events to
41// the extension system.
42class BookmarkEventRouter : public BookmarkModelObserver {
43 public:
44  explicit BookmarkEventRouter(Profile* profile);
45  virtual ~BookmarkEventRouter();
46
47  // BookmarkModelObserver:
48  virtual void BookmarkModelLoaded(BookmarkModel* model,
49                                   bool ids_reassigned) OVERRIDE;
50  virtual void BookmarkModelBeingDeleted(BookmarkModel* model) OVERRIDE;
51  virtual void BookmarkNodeMoved(BookmarkModel* model,
52                                 const BookmarkNode* old_parent,
53                                 int old_index,
54                                 const BookmarkNode* new_parent,
55                                 int new_index) OVERRIDE;
56  virtual void BookmarkNodeAdded(BookmarkModel* model,
57                                 const BookmarkNode* parent,
58                                 int index) OVERRIDE;
59  virtual void BookmarkNodeRemoved(BookmarkModel* model,
60                                   const BookmarkNode* parent,
61                                   int old_index,
62                                   const BookmarkNode* node,
63                                   const std::set<GURL>& removed_urls) OVERRIDE;
64  virtual void BookmarkAllUserNodesRemoved(
65      BookmarkModel* model,
66      const std::set<GURL>& removed_urls) OVERRIDE;
67  virtual void BookmarkNodeChanged(BookmarkModel* model,
68                                   const BookmarkNode* node) OVERRIDE;
69  virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
70                                          const BookmarkNode* node) OVERRIDE;
71  virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
72                                             const BookmarkNode* node) OVERRIDE;
73  virtual void ExtensiveBookmarkChangesBeginning(BookmarkModel* model) OVERRIDE;
74  virtual void ExtensiveBookmarkChangesEnded(BookmarkModel* model) OVERRIDE;
75
76 private:
77  // Helper to actually dispatch an event to extension listeners.
78  void DispatchEvent(const std::string& event_name,
79                     scoped_ptr<base::ListValue> event_args);
80
81  content::BrowserContext* browser_context_;
82  BookmarkModel* model_;
83  ChromeBookmarkClient* client_;
84
85  DISALLOW_COPY_AND_ASSIGN(BookmarkEventRouter);
86};
87
88class BookmarksAPI : public BrowserContextKeyedAPI,
89                     public EventRouter::Observer {
90 public:
91  explicit BookmarksAPI(content::BrowserContext* context);
92  virtual ~BookmarksAPI();
93
94  // KeyedService implementation.
95  virtual void Shutdown() OVERRIDE;
96
97  // BrowserContextKeyedAPI implementation.
98  static BrowserContextKeyedAPIFactory<BookmarksAPI>* GetFactoryInstance();
99
100  // EventRouter::Observer implementation.
101  virtual void OnListenerAdded(
102      const EventListenerInfo& details) OVERRIDE;
103
104 private:
105  friend class BrowserContextKeyedAPIFactory<BookmarksAPI>;
106
107  content::BrowserContext* browser_context_;
108
109  // BrowserContextKeyedAPI implementation.
110  static const char* service_name() {
111    return "BookmarksAPI";
112  }
113  static const bool kServiceIsNULLWhileTesting = true;
114
115  // Created lazily upon OnListenerAdded.
116  scoped_ptr<BookmarkEventRouter> bookmark_event_router_;
117};
118
119class BookmarksFunction : public ChromeAsyncExtensionFunction,
120                          public BaseBookmarkModelObserver {
121 public:
122  // AsyncExtensionFunction:
123  virtual bool RunAsync() OVERRIDE;
124
125 protected:
126  virtual ~BookmarksFunction() {}
127
128  // RunAsync semantic equivalent called when the bookmarks are ready.
129  virtual bool RunOnReady() = 0;
130
131  // Helper to get the BookmarkModel.
132  BookmarkModel* GetBookmarkModel();
133
134  // Helper to get the ChromeBookmarkClient.
135  ChromeBookmarkClient* GetChromeBookmarkClient();
136
137  // Helper to get the bookmark id as int64 from the given string id.
138  // Sets error_ to an error string if the given id string can't be parsed
139  // as an int64. In case of error, doesn't change id and returns false.
140  bool GetBookmarkIdAsInt64(const std::string& id_string, int64* id);
141
142  // Helper to get the bookmark node from a given string id.
143  // If the given id can't be parsed or doesn't refer to a valid node, sets
144  // error_ and returns NULL.
145  const BookmarkNode* GetBookmarkNodeFromId(const std::string& id_string);
146
147  // Helper to create a bookmark node from a CreateDetails object. If a node
148  // can't be created based on the given details, sets error_ and returns NULL.
149  const BookmarkNode* CreateBookmarkNode(
150      BookmarkModel* model,
151      const api::bookmarks::CreateDetails& details,
152      const BookmarkNode::MetaInfoMap* meta_info);
153
154  // Helper that checks if bookmark editing is enabled. If it's not, this sets
155  // error_ to the appropriate error string.
156  bool EditBookmarksEnabled();
157
158  // Helper that checks if |node| can be modified. Returns false if |node|
159  // is NULL, or a managed node, or the root node. In these cases the node
160  // can't be edited, can't have new child nodes appended, and its direct
161  // children can't be moved or reordered.
162  bool CanBeModified(const BookmarkNode* node);
163
164 private:
165  // BaseBookmarkModelObserver:
166  virtual void BookmarkModelChanged() OVERRIDE;
167  virtual void BookmarkModelLoaded(BookmarkModel* model,
168                                   bool ids_reassigned) OVERRIDE;
169};
170
171class BookmarksGetFunction : public BookmarksFunction {
172 public:
173  DECLARE_EXTENSION_FUNCTION("bookmarks.get", BOOKMARKS_GET)
174
175 protected:
176  virtual ~BookmarksGetFunction() {}
177
178  // BookmarksFunction:
179  virtual bool RunOnReady() OVERRIDE;
180};
181
182class BookmarksGetChildrenFunction : public BookmarksFunction {
183 public:
184  DECLARE_EXTENSION_FUNCTION("bookmarks.getChildren", BOOKMARKS_GETCHILDREN)
185
186 protected:
187  virtual ~BookmarksGetChildrenFunction() {}
188
189  // BookmarksFunction:
190  virtual bool RunOnReady() OVERRIDE;
191};
192
193class BookmarksGetRecentFunction : public BookmarksFunction {
194 public:
195  DECLARE_EXTENSION_FUNCTION("bookmarks.getRecent", BOOKMARKS_GETRECENT)
196
197 protected:
198  virtual ~BookmarksGetRecentFunction() {}
199
200  // BookmarksFunction:
201  virtual bool RunOnReady() OVERRIDE;
202};
203
204class BookmarksGetTreeFunction : public BookmarksFunction {
205 public:
206  DECLARE_EXTENSION_FUNCTION("bookmarks.getTree", BOOKMARKS_GETTREE)
207
208 protected:
209  virtual ~BookmarksGetTreeFunction() {}
210
211  // BookmarksFunction:
212  virtual bool RunOnReady() OVERRIDE;
213};
214
215class BookmarksGetSubTreeFunction : public BookmarksFunction {
216 public:
217  DECLARE_EXTENSION_FUNCTION("bookmarks.getSubTree", BOOKMARKS_GETSUBTREE)
218
219 protected:
220  virtual ~BookmarksGetSubTreeFunction() {}
221
222  // BookmarksFunction:
223  virtual bool RunOnReady() OVERRIDE;
224};
225
226class BookmarksSearchFunction : public BookmarksFunction {
227 public:
228  DECLARE_EXTENSION_FUNCTION("bookmarks.search", BOOKMARKS_SEARCH)
229
230 protected:
231  virtual ~BookmarksSearchFunction() {}
232
233  // BookmarksFunction:
234  virtual bool RunOnReady() OVERRIDE;
235};
236
237class BookmarksRemoveFunction : public BookmarksFunction {
238 public:
239  DECLARE_EXTENSION_FUNCTION("bookmarks.remove", BOOKMARKS_REMOVE)
240
241  // Returns true on successful parse and sets invalid_id to true if conversion
242  // from id string to int64 failed.
243  static bool ExtractIds(const base::ListValue* args,
244                         std::list<int64>* ids,
245                         bool* invalid_id);
246
247 protected:
248  virtual ~BookmarksRemoveFunction() {}
249
250  // BookmarksFunction:
251  virtual bool RunOnReady() OVERRIDE;
252};
253
254class BookmarksRemoveTreeFunction : public BookmarksRemoveFunction {
255 public:
256  DECLARE_EXTENSION_FUNCTION("bookmarks.removeTree", BOOKMARKS_REMOVETREE)
257
258 protected:
259  virtual ~BookmarksRemoveTreeFunction() {}
260};
261
262class BookmarksCreateFunction : public BookmarksFunction {
263 public:
264  DECLARE_EXTENSION_FUNCTION("bookmarks.create", BOOKMARKS_CREATE)
265
266 protected:
267  virtual ~BookmarksCreateFunction() {}
268
269  // BookmarksFunction:
270  virtual bool RunOnReady() OVERRIDE;
271};
272
273class BookmarksMoveFunction : public BookmarksFunction {
274 public:
275  DECLARE_EXTENSION_FUNCTION("bookmarks.move", BOOKMARKS_MOVE)
276
277  static bool ExtractIds(const base::ListValue* args,
278                         std::list<int64>* ids,
279                         bool* invalid_id);
280
281 protected:
282  virtual ~BookmarksMoveFunction() {}
283
284  // BookmarksFunction:
285  virtual bool RunOnReady() OVERRIDE;
286};
287
288class BookmarksUpdateFunction : public BookmarksFunction {
289 public:
290  DECLARE_EXTENSION_FUNCTION("bookmarks.update", BOOKMARKS_UPDATE)
291
292  static bool ExtractIds(const base::ListValue* args,
293                         std::list<int64>* ids,
294                         bool* invalid_id);
295
296 protected:
297  virtual ~BookmarksUpdateFunction() {}
298
299  // BookmarksFunction:
300  virtual bool RunOnReady() OVERRIDE;
301};
302
303class BookmarksIOFunction : public BookmarksFunction,
304                            public ui::SelectFileDialog::Listener {
305 public:
306  BookmarksIOFunction();
307
308  virtual void FileSelected(const base::FilePath& path, int index, void* params) = 0;
309
310  // ui::SelectFileDialog::Listener:
311  virtual void MultiFilesSelected(const std::vector<base::FilePath>& files,
312                                  void* params) OVERRIDE;
313  virtual void FileSelectionCanceled(void* params) OVERRIDE;
314
315  void SelectFile(ui::SelectFileDialog::Type type);
316
317 protected:
318  virtual ~BookmarksIOFunction();
319
320 private:
321  void ShowSelectFileDialog(
322      ui::SelectFileDialog::Type type,
323      const base::FilePath& default_path);
324
325 protected:
326  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
327};
328
329class BookmarksImportFunction : public BookmarksIOFunction {
330 public:
331  DECLARE_EXTENSION_FUNCTION("bookmarks.import", BOOKMARKS_IMPORT)
332
333  // BookmarkManagerIOFunction:
334  virtual void FileSelected(const base::FilePath& path,
335                            int index,
336                            void* params) OVERRIDE;
337
338 private:
339  virtual ~BookmarksImportFunction() {}
340
341  // BookmarksFunction:
342  virtual bool RunOnReady() OVERRIDE;
343};
344
345class BookmarksExportFunction : public BookmarksIOFunction {
346 public:
347  DECLARE_EXTENSION_FUNCTION("bookmarks.export", BOOKMARKS_EXPORT)
348
349  // BookmarkManagerIOFunction:
350  virtual void FileSelected(const base::FilePath& path,
351                            int index,
352                            void* params) OVERRIDE;
353
354 private:
355  virtual ~BookmarksExportFunction() {}
356
357  // BookmarksFunction:
358  virtual bool RunOnReady() OVERRIDE;
359};
360
361}  // namespace extensions
362
363#endif  // CHROME_BROWSER_EXTENSIONS_API_BOOKMARKS_BOOKMARKS_API_H_
364