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 21 class ChromeBookmarkClient; 22 23 namespace base { 24 class FilePath; 25 class ListValue; 26 } 27 28 namespace content { 29 class BrowserContext; 30 } 31 32 namespace extensions { 33 34 namespace api { 35 namespace bookmarks { 36 struct CreateDetails; 37 } 38 } 39 40 // Observes BookmarkModel and then routes the notifications as events to 41 // the extension system. 42 class 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 88 class 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 119 class 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 171 class 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 182 class 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 193 class 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 204 class 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 215 class 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 226 class 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 237 class 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 254 class BookmarksRemoveTreeFunction : public BookmarksRemoveFunction { 255 public: 256 DECLARE_EXTENSION_FUNCTION("bookmarks.removeTree", BOOKMARKS_REMOVETREE) 257 258 protected: 259 virtual ~BookmarksRemoveTreeFunction() {} 260 }; 261 262 class 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 273 class 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 288 class 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 303 class 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 329 class 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 345 class 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