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 "content/public/browser/notification_observer.h"
20 #include "content/public/browser/notification_registrar.h"
21 #include "content/public/browser/render_view_host.h"
22 #include "extensions/browser/browser_context_keyed_api_factory.h"
23 #include "extensions/browser/event_router.h"
24 #include "extensions/browser/extension_registry_observer.h"
25 #include "storage/browser/fileapi/file_system_context.h"
26 #include "storage/browser/fileapi/file_system_operation.h"
27 #include "ui/shell_dialogs/select_file_dialog.h"
31 namespace extensions
{
34 class ExtensionRegistry
;
35 class ExtensionSystem
;
36 class ManagementPolicy
;
37 class RequirementsChecker
;
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 ~DeveloperPrivateEventRouter() override
;
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 void Observe(int type
,
75 const content::NotificationSource
& source
,
76 const content::NotificationDetails
& details
) override
;
78 // ExtensionRegistryObserver implementation.
79 void OnExtensionLoaded(content::BrowserContext
* browser_context
,
80 const Extension
* extension
) override
;
81 void OnExtensionUnloaded(content::BrowserContext
* browser_context
,
82 const Extension
* extension
,
83 UnloadedExtensionInfo::Reason reason
) override
;
84 void OnExtensionWillBeInstalled(content::BrowserContext
* browser_context
,
85 const Extension
* extension
,
88 const std::string
& old_name
) override
;
89 void OnExtensionUninstalled(content::BrowserContext
* browser_context
,
90 const Extension
* extension
,
91 extensions::UninstallReason reason
) override
;
93 // ErrorConsole::Observer implementation.
94 void OnErrorAdded(const ExtensionError
* error
) override
;
96 content::NotificationRegistrar registrar_
;
98 ScopedObserver
<extensions::ExtensionRegistry
,
99 extensions::ExtensionRegistryObserver
>
100 extension_registry_observer_
;
104 // The set of IDs of the Extensions that have subscribed to DeveloperPrivate
105 // events. Since the only consumer of the DeveloperPrivate API is currently
106 // the Apps Developer Tool (which replaces the chrome://extensions page), we
107 // don't want to send information about the subscribing extension in an
108 // update. In particular, we want to avoid entering a loop, which could happen
109 // when, e.g., the Apps Developer Tool throws an error.
110 std::set
<std::string
> extension_ids_
;
112 DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateEventRouter
);
115 // The profile-keyed service that manages the DeveloperPrivate API.
116 class DeveloperPrivateAPI
: public BrowserContextKeyedAPI
,
117 public EventRouter::Observer
{
119 static BrowserContextKeyedAPIFactory
<DeveloperPrivateAPI
>*
120 GetFactoryInstance();
122 // Convenience method to get the DeveloperPrivateAPI for a profile.
123 static DeveloperPrivateAPI
* Get(content::BrowserContext
* context
);
125 explicit DeveloperPrivateAPI(content::BrowserContext
* context
);
126 ~DeveloperPrivateAPI() override
;
128 void SetLastUnpackedDirectory(const base::FilePath
& path
);
130 base::FilePath
& GetLastUnpackedDirectory() {
131 return last_unpacked_directory_
;
134 // KeyedService implementation
135 void Shutdown() override
;
137 // EventRouter::Observer implementation.
138 void OnListenerAdded(const EventListenerInfo
& details
) override
;
139 void OnListenerRemoved(const EventListenerInfo
& details
) override
;
142 friend class BrowserContextKeyedAPIFactory
<DeveloperPrivateAPI
>;
144 // BrowserContextKeyedAPI implementation.
145 static const char* service_name() { return "DeveloperPrivateAPI"; }
146 static const bool kServiceRedirectedInIncognito
= true;
147 static const bool kServiceIsNULLWhileTesting
= true;
149 void RegisterNotifications();
153 // Used to start the load |load_extension_dialog_| in the last directory that
155 base::FilePath last_unpacked_directory_
;
157 // Created lazily upon OnListenerAdded.
158 scoped_ptr
<DeveloperPrivateEventRouter
> developer_private_event_router_
;
160 DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateAPI
);
165 class DeveloperPrivateAPIFunction
: public UIThreadExtensionFunction
{
167 ~DeveloperPrivateAPIFunction() override
;
169 // Returns the extension with the given |id| from the registry, including
170 // all possible extensions (enabled, disabled, terminated, etc).
171 const Extension
* GetExtensionById(const std::string
& id
);
174 class DeveloperPrivateAutoUpdateFunction
: public ChromeSyncExtensionFunction
{
176 DECLARE_EXTENSION_FUNCTION("developerPrivate.autoUpdate",
177 DEVELOPERPRIVATE_AUTOUPDATE
)
180 ~DeveloperPrivateAutoUpdateFunction() override
;
182 // ExtensionFunction:
183 bool RunSync() override
;
186 class DeveloperPrivateGetItemsInfoFunction
187 : public ChromeAsyncExtensionFunction
{
189 DECLARE_EXTENSION_FUNCTION("developerPrivate.getItemsInfo",
190 DEVELOPERPRIVATE_GETITEMSINFO
)
193 ~DeveloperPrivateGetItemsInfoFunction() override
;
195 // ExtensionFunction:
196 bool RunAsync() override
;
199 scoped_ptr
<developer::ItemInfo
> CreateItemInfo(const Extension
& item
,
200 bool item_is_enabled
);
202 void GetIconsOnFileThread(
203 ItemInfoList item_list
,
204 std::map
<std::string
, ExtensionResource
> itemIdToIconResourceMap
);
206 // Helper that lists the current inspectable html pages for the extension.
207 void GetInspectablePagesForExtensionProcess(
208 const Extension
* extension
,
209 const std::set
<content::RenderViewHost
*>& views
,
210 ItemInspectViewList
* result
);
212 ItemInspectViewList
GetInspectablePagesForExtension(
213 const Extension
* extension
,
214 bool extension_is_enabled
);
216 void GetAppWindowPagesForExtensionProfile(const Extension
* extension
,
217 ItemInspectViewList
* result
);
219 linked_ptr
<developer::ItemInspectView
> constructInspectView(
221 int render_process_id
,
224 bool generated_background_page
);
227 class DeveloperPrivateInspectFunction
: public ChromeSyncExtensionFunction
{
229 DECLARE_EXTENSION_FUNCTION("developerPrivate.inspect",
230 DEVELOPERPRIVATE_INSPECT
)
233 ~DeveloperPrivateInspectFunction() override
;
235 // ExtensionFunction:
236 bool RunSync() override
;
239 class DeveloperPrivateAllowFileAccessFunction
240 : public DeveloperPrivateAPIFunction
{
242 DECLARE_EXTENSION_FUNCTION("developerPrivate.allowFileAccess",
243 DEVELOPERPRIVATE_ALLOWFILEACCESS
);
246 ~DeveloperPrivateAllowFileAccessFunction() override
;
248 // ExtensionFunction:
249 ResponseAction
Run() override
;
252 class DeveloperPrivateAllowIncognitoFunction
253 : public DeveloperPrivateAPIFunction
{
255 DECLARE_EXTENSION_FUNCTION("developerPrivate.allowIncognito",
256 DEVELOPERPRIVATE_ALLOWINCOGNITO
);
259 ~DeveloperPrivateAllowIncognitoFunction() override
;
261 // UIThreadExtensionFunction:
262 ResponseAction
Run() override
;
265 class DeveloperPrivateReloadFunction
: public DeveloperPrivateAPIFunction
{
267 DECLARE_EXTENSION_FUNCTION("developerPrivate.reload",
268 DEVELOPERPRIVATE_RELOAD
);
271 ~DeveloperPrivateReloadFunction() override
;
273 // ExtensionFunction:
274 ResponseAction
Run() override
;
277 class DeveloperPrivateShowPermissionsDialogFunction
278 : public ChromeSyncExtensionFunction
,
279 public ExtensionInstallPrompt::Delegate
{
281 DECLARE_EXTENSION_FUNCTION("developerPrivate.showPermissionsDialog",
282 DEVELOPERPRIVATE_PERMISSIONS
);
284 DeveloperPrivateShowPermissionsDialogFunction();
286 ~DeveloperPrivateShowPermissionsDialogFunction() override
;
288 // ExtensionFunction:
289 bool RunSync() override
;
291 // Overridden from ExtensionInstallPrompt::Delegate
292 void InstallUIProceed() override
;
293 void InstallUIAbort(bool user_initiated
) override
;
295 scoped_ptr
<ExtensionInstallPrompt
> prompt_
;
296 std::string extension_id_
;
299 class DeveloperPrivateChooseEntryFunction
: public UIThreadExtensionFunction
,
300 public EntryPickerClient
{
302 ~DeveloperPrivateChooseEntryFunction() override
;
303 bool ShowPicker(ui::SelectFileDialog::Type picker_type
,
304 const base::string16
& select_title
,
305 const ui::SelectFileDialog::FileTypeInfo
& info
,
306 int file_type_index
);
310 class DeveloperPrivateLoadUnpackedFunction
311 : public DeveloperPrivateChooseEntryFunction
{
313 DECLARE_EXTENSION_FUNCTION("developerPrivate.loadUnpacked",
314 DEVELOPERPRIVATE_LOADUNPACKED
);
315 DeveloperPrivateLoadUnpackedFunction();
318 ~DeveloperPrivateLoadUnpackedFunction() override
;
319 ResponseAction
Run() override
;
321 // EntryPickerClient:
322 void FileSelected(const base::FilePath
& path
) override
;
323 void FileSelectionCanceled() override
;
325 // Callback for the UnpackedLoader.
326 void OnLoadComplete(const Extension
* extension
,
327 const base::FilePath
& file_path
,
328 const std::string
& error
);
331 // Whether or not we should fail quietly in the event of a load error.
335 class DeveloperPrivateChoosePathFunction
336 : public DeveloperPrivateChooseEntryFunction
{
338 DECLARE_EXTENSION_FUNCTION("developerPrivate.choosePath",
339 DEVELOPERPRIVATE_CHOOSEPATH
);
342 ~DeveloperPrivateChoosePathFunction() override
;
343 ResponseAction
Run() override
;
345 // EntryPickerClient:
346 void FileSelected(const base::FilePath
& path
) override
;
347 void FileSelectionCanceled() override
;
350 class DeveloperPrivatePackDirectoryFunction
351 : public DeveloperPrivateAPIFunction
,
352 public PackExtensionJob::Client
{
355 DECLARE_EXTENSION_FUNCTION("developerPrivate.packDirectory",
356 DEVELOPERPRIVATE_PACKDIRECTORY
);
358 DeveloperPrivatePackDirectoryFunction();
360 // ExtensionPackJob::Client implementation.
361 void OnPackSuccess(const base::FilePath
& crx_file
,
362 const base::FilePath
& key_file
) override
;
363 void OnPackFailure(const std::string
& error
,
364 ExtensionCreator::ErrorType error_type
) override
;
367 ~DeveloperPrivatePackDirectoryFunction() override
;
368 ResponseAction
Run() override
;
371 scoped_refptr
<PackExtensionJob
> pack_job_
;
372 std::string item_path_str_
;
373 std::string key_path_str_
;
376 class DeveloperPrivateIsProfileManagedFunction
377 : public ChromeSyncExtensionFunction
{
379 DECLARE_EXTENSION_FUNCTION("developerPrivate.isProfileManaged",
380 DEVELOPERPRIVATE_ISPROFILEMANAGED
);
383 ~DeveloperPrivateIsProfileManagedFunction() override
;
385 // ExtensionFunction:
386 bool RunSync() override
;
389 class DeveloperPrivateLoadDirectoryFunction
390 : public ChromeAsyncExtensionFunction
{
392 DECLARE_EXTENSION_FUNCTION("developerPrivate.loadDirectory",
393 DEVELOPERPRIVATE_LOADUNPACKEDCROS
);
395 DeveloperPrivateLoadDirectoryFunction();
398 ~DeveloperPrivateLoadDirectoryFunction() override
;
400 // ExtensionFunction:
401 bool RunAsync() override
;
403 bool LoadByFileSystemAPI(const storage::FileSystemURL
& directory_url
);
405 void ClearExistingDirectoryContent(const base::FilePath
& project_path
);
407 void ReadDirectoryByFileSystemAPI(const base::FilePath
& project_path
,
408 const base::FilePath
& destination_path
);
410 void ReadDirectoryByFileSystemAPICb(
411 const base::FilePath
& project_path
,
412 const base::FilePath
& destination_path
,
413 base::File::Error result
,
414 const storage::FileSystemOperation::FileEntryList
& file_list
,
417 void SnapshotFileCallback(
418 const base::FilePath
& target_path
,
419 base::File::Error result
,
420 const base::File::Info
& file_info
,
421 const base::FilePath
& platform_path
,
422 const scoped_refptr
<storage::ShareableFileReference
>& file_ref
);
424 void CopyFile(const base::FilePath
& src_path
,
425 const base::FilePath
& dest_path
);
429 scoped_refptr
<storage::FileSystemContext
> context_
;
431 // syncfs url representing the root of the folder to be copied.
432 std::string project_base_url_
;
434 // physical path on disc of the folder to be copied.
435 base::FilePath project_base_path_
;
438 int pending_copy_operations_count_
;
440 // This is set to false if any of the copyFile operations fail on
441 // call of the API. It is returned as a response of the API call.
445 class DeveloperPrivateRequestFileSourceFunction
446 : public ChromeAsyncExtensionFunction
{
448 DECLARE_EXTENSION_FUNCTION("developerPrivate.requestFileSource",
449 DEVELOPERPRIVATE_REQUESTFILESOURCE
);
451 DeveloperPrivateRequestFileSourceFunction();
454 ~DeveloperPrivateRequestFileSourceFunction() override
;
456 // ExtensionFunction:
457 bool RunAsync() override
;
460 void LaunchCallback(const base::DictionaryValue
& results
);
463 class DeveloperPrivateOpenDevToolsFunction
464 : public ChromeAsyncExtensionFunction
{
466 DECLARE_EXTENSION_FUNCTION("developerPrivate.openDevTools",
467 DEVELOPERPRIVATE_OPENDEVTOOLS
);
469 DeveloperPrivateOpenDevToolsFunction();
472 ~DeveloperPrivateOpenDevToolsFunction() override
;
474 // ExtensionFunction:
475 bool RunAsync() override
;
480 } // namespace extensions
482 #endif // CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_