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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_
10 #include "base/files/file.h"
11 #include "base/scoped_observer.h"
12 #include "chrome/browser/extensions/api/developer_private/entry_picker.h"
13 #include "chrome/browser/extensions/api/file_system/file_system_api.h"
14 #include "chrome/browser/extensions/chrome_extension_function.h"
15 #include "chrome/browser/extensions/error_console/error_console.h"
16 #include "chrome/browser/extensions/extension_install_prompt.h"
17 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
18 #include "chrome/browser/extensions/pack_extension_job.h"
19 #include "chrome/browser/extensions/requirements_checker.h"
20 #include "content/public/browser/notification_observer.h"
21 #include "content/public/browser/notification_registrar.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "extensions/browser/browser_context_keyed_api_factory.h"
24 #include "extensions/browser/event_router.h"
25 #include "extensions/browser/extension_registry_observer.h"
26 #include "storage/browser/fileapi/file_system_context.h"
27 #include "storage/browser/fileapi/file_system_operation.h"
28 #include "ui/shell_dialogs/select_file_dialog.h"
32 namespace extensions {
35 class ExtensionRegistry;
36 class ExtensionSystem;
37 class ManagementPolicy;
42 class EntryPickerClient;
44 namespace developer_private {
47 struct ItemInspectView;
50 } // namespace developer_private
54 namespace developer = api::developer_private;
56 typedef std::vector<linked_ptr<developer::ItemInfo> > ItemInfoList;
57 typedef std::vector<linked_ptr<developer::ProjectInfo> > ProjectInfoList;
58 typedef std::vector<linked_ptr<developer::ItemInspectView> >
61 class DeveloperPrivateEventRouter : public content::NotificationObserver,
62 public ExtensionRegistryObserver,
63 public ErrorConsole::Observer {
65 explicit DeveloperPrivateEventRouter(Profile* profile);
66 virtual ~DeveloperPrivateEventRouter();
68 // Add or remove an ID to the list of extensions subscribed to events.
69 void AddExtensionId(const std::string& extension_id);
70 void RemoveExtensionId(const std::string& extension_id);
73 // content::NotificationObserver implementation.
74 virtual void Observe(int type,
75 const content::NotificationSource& source,
76 const content::NotificationDetails& details) OVERRIDE;
78 // ExtensionRegistryObserver implementation.
79 virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
80 const Extension* extension) OVERRIDE;
81 virtual void OnExtensionUnloaded(
82 content::BrowserContext* browser_context,
83 const Extension* extension,
84 UnloadedExtensionInfo::Reason reason) OVERRIDE;
85 virtual void OnExtensionWillBeInstalled(
86 content::BrowserContext* browser_context,
87 const Extension* extension,
90 const std::string& old_name) OVERRIDE;
91 virtual void OnExtensionUninstalled(
92 content::BrowserContext* browser_context,
93 const Extension* extension,
94 extensions::UninstallReason reason) OVERRIDE;
96 // ErrorConsole::Observer implementation.
97 virtual void OnErrorAdded(const ExtensionError* error) OVERRIDE;
99 content::NotificationRegistrar registrar_;
101 ScopedObserver<extensions::ExtensionRegistry,
102 extensions::ExtensionRegistryObserver>
103 extension_registry_observer_;
107 // The set of IDs of the Extensions that have subscribed to DeveloperPrivate
108 // events. Since the only consumer of the DeveloperPrivate API is currently
109 // the Apps Developer Tool (which replaces the chrome://extensions page), we
110 // don't want to send information about the subscribing extension in an
111 // update. In particular, we want to avoid entering a loop, which could happen
112 // when, e.g., the Apps Developer Tool throws an error.
113 std::set<std::string> extension_ids_;
115 DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateEventRouter);
118 // The profile-keyed service that manages the DeveloperPrivate API.
119 class DeveloperPrivateAPI : public BrowserContextKeyedAPI,
120 public EventRouter::Observer {
122 static BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>*
123 GetFactoryInstance();
125 // Convenience method to get the DeveloperPrivateAPI for a profile.
126 static DeveloperPrivateAPI* Get(content::BrowserContext* context);
128 explicit DeveloperPrivateAPI(content::BrowserContext* context);
129 virtual ~DeveloperPrivateAPI();
131 void SetLastUnpackedDirectory(const base::FilePath& path);
133 base::FilePath& GetLastUnpackedDirectory() {
134 return last_unpacked_directory_;
137 // KeyedService implementation
138 virtual void Shutdown() OVERRIDE;
140 // EventRouter::Observer implementation.
141 virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE;
142 virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
145 friend class BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>;
147 // BrowserContextKeyedAPI implementation.
148 static const char* service_name() { return "DeveloperPrivateAPI"; }
149 static const bool kServiceRedirectedInIncognito = true;
150 static const bool kServiceIsNULLWhileTesting = true;
152 void RegisterNotifications();
156 // Used to start the load |load_extension_dialog_| in the last directory that
158 base::FilePath last_unpacked_directory_;
160 // Created lazily upon OnListenerAdded.
161 scoped_ptr<DeveloperPrivateEventRouter> developer_private_event_router_;
163 DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateAPI);
168 class DeveloperPrivateAutoUpdateFunction : public ChromeSyncExtensionFunction {
170 DECLARE_EXTENSION_FUNCTION("developerPrivate.autoUpdate",
171 DEVELOPERPRIVATE_AUTOUPDATE)
174 virtual ~DeveloperPrivateAutoUpdateFunction();
176 // ExtensionFunction:
177 virtual bool RunSync() OVERRIDE;
180 class DeveloperPrivateGetItemsInfoFunction
181 : public ChromeAsyncExtensionFunction {
183 DECLARE_EXTENSION_FUNCTION("developerPrivate.getItemsInfo",
184 DEVELOPERPRIVATE_GETITEMSINFO)
187 virtual ~DeveloperPrivateGetItemsInfoFunction();
189 // ExtensionFunction:
190 virtual bool RunAsync() OVERRIDE;
193 scoped_ptr<developer::ItemInfo> CreateItemInfo(const Extension& item,
194 bool item_is_enabled);
196 void GetIconsOnFileThread(
197 ItemInfoList item_list,
198 std::map<std::string, ExtensionResource> itemIdToIconResourceMap);
200 // Helper that lists the current inspectable html pages for the extension.
201 void GetInspectablePagesForExtensionProcess(
202 const Extension* extension,
203 const std::set<content::RenderViewHost*>& views,
204 ItemInspectViewList* result);
206 ItemInspectViewList GetInspectablePagesForExtension(
207 const Extension* extension,
208 bool extension_is_enabled);
210 void GetAppWindowPagesForExtensionProfile(const Extension* extension,
211 ItemInspectViewList* result);
213 linked_ptr<developer::ItemInspectView> constructInspectView(
215 int render_process_id,
218 bool generated_background_page);
221 class DeveloperPrivateInspectFunction : public ChromeSyncExtensionFunction {
223 DECLARE_EXTENSION_FUNCTION("developerPrivate.inspect",
224 DEVELOPERPRIVATE_INSPECT)
227 virtual ~DeveloperPrivateInspectFunction();
229 // ExtensionFunction:
230 virtual bool RunSync() OVERRIDE;
233 class DeveloperPrivateAllowFileAccessFunction
234 : public ChromeSyncExtensionFunction {
236 DECLARE_EXTENSION_FUNCTION("developerPrivate.allowFileAccess",
237 DEVELOPERPRIVATE_ALLOWFILEACCESS);
240 virtual ~DeveloperPrivateAllowFileAccessFunction();
242 // ExtensionFunction:
243 virtual bool RunSync() OVERRIDE;
246 class DeveloperPrivateAllowIncognitoFunction
247 : public ChromeSyncExtensionFunction {
249 DECLARE_EXTENSION_FUNCTION("developerPrivate.allowIncognito",
250 DEVELOPERPRIVATE_ALLOWINCOGNITO);
253 virtual ~DeveloperPrivateAllowIncognitoFunction();
255 // ExtensionFunction:
256 virtual bool RunSync() OVERRIDE;
259 class DeveloperPrivateReloadFunction : public ChromeSyncExtensionFunction {
261 DECLARE_EXTENSION_FUNCTION("developerPrivate.reload",
262 DEVELOPERPRIVATE_RELOAD);
265 virtual ~DeveloperPrivateReloadFunction();
267 // ExtensionFunction:
268 virtual bool RunSync() OVERRIDE;
271 class DeveloperPrivateShowPermissionsDialogFunction
272 : public ChromeSyncExtensionFunction,
273 public ExtensionInstallPrompt::Delegate {
275 DECLARE_EXTENSION_FUNCTION("developerPrivate.showPermissionsDialog",
276 DEVELOPERPRIVATE_PERMISSIONS);
278 DeveloperPrivateShowPermissionsDialogFunction();
280 virtual ~DeveloperPrivateShowPermissionsDialogFunction();
282 // ExtensionFunction:
283 virtual bool RunSync() OVERRIDE;
285 // Overridden from ExtensionInstallPrompt::Delegate
286 virtual void InstallUIProceed() OVERRIDE;
287 virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
289 scoped_ptr<ExtensionInstallPrompt> prompt_;
290 std::string extension_id_;
293 class DeveloperPrivateEnableFunction
294 : public ChromeSyncExtensionFunction,
295 public base::SupportsWeakPtr<DeveloperPrivateEnableFunction> {
297 DECLARE_EXTENSION_FUNCTION("developerPrivate.enable",
298 DEVELOPERPRIVATE_ENABLE);
300 DeveloperPrivateEnableFunction();
303 virtual ~DeveloperPrivateEnableFunction();
305 // Callback for requirements checker.
306 void OnRequirementsChecked(const std::string& extension_id,
307 std::vector<std::string> requirements_errors);
308 // ExtensionFunction:
309 virtual bool RunSync() OVERRIDE;
312 scoped_ptr<RequirementsChecker> requirements_checker_;
315 class DeveloperPrivateChooseEntryFunction : public ChromeAsyncExtensionFunction,
316 public EntryPickerClient {
318 virtual ~DeveloperPrivateChooseEntryFunction();
319 virtual bool RunAsync() OVERRIDE;
320 bool ShowPicker(ui::SelectFileDialog::Type picker_type,
321 const base::FilePath& last_directory,
322 const base::string16& select_title,
323 const ui::SelectFileDialog::FileTypeInfo& info,
324 int file_type_index);
326 // EntryPickerClient functions.
327 virtual void FileSelected(const base::FilePath& path) = 0;
328 virtual void FileSelectionCanceled() = 0;
332 class DeveloperPrivateLoadUnpackedFunction
333 : public DeveloperPrivateChooseEntryFunction {
335 DECLARE_EXTENSION_FUNCTION("developerPrivate.loadUnpacked",
336 DEVELOPERPRIVATE_LOADUNPACKED);
339 virtual ~DeveloperPrivateLoadUnpackedFunction();
340 virtual bool RunAsync() OVERRIDE;
342 // EntryPickerCLient implementation.
343 virtual void FileSelected(const base::FilePath& path) OVERRIDE;
344 virtual void FileSelectionCanceled() OVERRIDE;
347 class DeveloperPrivateChoosePathFunction
348 : public DeveloperPrivateChooseEntryFunction {
350 DECLARE_EXTENSION_FUNCTION("developerPrivate.choosePath",
351 DEVELOPERPRIVATE_CHOOSEPATH);
354 virtual ~DeveloperPrivateChoosePathFunction();
355 virtual bool RunAsync() OVERRIDE;
357 // EntryPickerClient functions.
358 virtual void FileSelected(const base::FilePath& path) OVERRIDE;
359 virtual void FileSelectionCanceled() OVERRIDE;
362 class DeveloperPrivatePackDirectoryFunction
363 : public ChromeAsyncExtensionFunction,
364 public PackExtensionJob::Client {
367 DECLARE_EXTENSION_FUNCTION("developerPrivate.packDirectory",
368 DEVELOPERPRIVATE_PACKDIRECTORY);
370 DeveloperPrivatePackDirectoryFunction();
372 // ExtensionPackJob::Client implementation.
373 virtual void OnPackSuccess(const base::FilePath& crx_file,
374 const base::FilePath& key_file) OVERRIDE;
375 virtual void OnPackFailure(const std::string& error,
376 ExtensionCreator::ErrorType error_type) OVERRIDE;
379 virtual ~DeveloperPrivatePackDirectoryFunction();
380 virtual bool RunAsync() OVERRIDE;
383 scoped_refptr<PackExtensionJob> pack_job_;
384 std::string item_path_str_;
385 std::string key_path_str_;
388 class DeveloperPrivateIsProfileManagedFunction
389 : public ChromeSyncExtensionFunction {
391 DECLARE_EXTENSION_FUNCTION("developerPrivate.isProfileManaged",
392 DEVELOPERPRIVATE_ISPROFILEMANAGED);
395 virtual ~DeveloperPrivateIsProfileManagedFunction();
397 // ExtensionFunction:
398 virtual bool RunSync() OVERRIDE;
401 class DeveloperPrivateLoadDirectoryFunction
402 : public ChromeAsyncExtensionFunction {
404 DECLARE_EXTENSION_FUNCTION("developerPrivate.loadDirectory",
405 DEVELOPERPRIVATE_LOADUNPACKEDCROS);
407 DeveloperPrivateLoadDirectoryFunction();
410 virtual ~DeveloperPrivateLoadDirectoryFunction();
412 // ExtensionFunction:
413 virtual bool RunAsync() OVERRIDE;
415 bool LoadByFileSystemAPI(const storage::FileSystemURL& directory_url);
417 void ClearExistingDirectoryContent(const base::FilePath& project_path);
419 void ReadDirectoryByFileSystemAPI(const base::FilePath& project_path,
420 const base::FilePath& destination_path);
422 void ReadDirectoryByFileSystemAPICb(
423 const base::FilePath& project_path,
424 const base::FilePath& destination_path,
425 base::File::Error result,
426 const storage::FileSystemOperation::FileEntryList& file_list,
429 void SnapshotFileCallback(
430 const base::FilePath& target_path,
431 base::File::Error result,
432 const base::File::Info& file_info,
433 const base::FilePath& platform_path,
434 const scoped_refptr<storage::ShareableFileReference>& file_ref);
436 void CopyFile(const base::FilePath& src_path,
437 const base::FilePath& dest_path);
441 scoped_refptr<storage::FileSystemContext> context_;
443 // syncfs url representing the root of the folder to be copied.
444 std::string project_base_url_;
446 // physical path on disc of the folder to be copied.
447 base::FilePath project_base_path_;
450 int pending_copy_operations_count_;
452 // This is set to false if any of the copyFile operations fail on
453 // call of the API. It is returned as a response of the API call.
457 class DeveloperPrivateRequestFileSourceFunction
458 : public ChromeAsyncExtensionFunction {
460 DECLARE_EXTENSION_FUNCTION("developerPrivate.requestFileSource",
461 DEVELOPERPRIVATE_REQUESTFILESOURCE);
463 DeveloperPrivateRequestFileSourceFunction();
466 virtual ~DeveloperPrivateRequestFileSourceFunction();
468 // ExtensionFunction:
469 virtual bool RunAsync() OVERRIDE;
472 void LaunchCallback(const base::DictionaryValue& results);
475 class DeveloperPrivateOpenDevToolsFunction
476 : public ChromeAsyncExtensionFunction {
478 DECLARE_EXTENSION_FUNCTION("developerPrivate.openDevTools",
479 DEVELOPERPRIVATE_OPENDEVTOOLS);
481 DeveloperPrivateOpenDevToolsFunction();
484 virtual ~DeveloperPrivateOpenDevToolsFunction();
486 // ExtensionFunction:
487 virtual bool RunAsync() OVERRIDE;
492 } // namespace extensions
494 #endif // CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_