| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_ |
| #define CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_ |
| |
| #include <set> |
| |
| #include "base/files/file.h" |
| #include "base/scoped_observer.h" |
| #include "chrome/browser/extensions/api/developer_private/entry_picker.h" |
| #include "chrome/browser/extensions/api/file_system/file_system_api.h" |
| #include "chrome/browser/extensions/chrome_extension_function.h" |
| #include "chrome/browser/extensions/error_console/error_console.h" |
| #include "chrome/browser/extensions/extension_uninstall_dialog.h" |
| #include "chrome/browser/extensions/pack_extension_job.h" |
| #include "extensions/browser/browser_context_keyed_api_factory.h" |
| #include "extensions/browser/event_router.h" |
| #include "extensions/browser/extension_registry_observer.h" |
| #include "extensions/browser/process_manager_observer.h" |
| #include "storage/browser/fileapi/file_system_context.h" |
| #include "storage/browser/fileapi/file_system_operation.h" |
| #include "ui/shell_dialogs/select_file_dialog.h" |
| |
| class Profile; |
| |
| namespace extensions { |
| |
| class ExtensionError; |
| class ExtensionRegistry; |
| class ExtensionSystem; |
| class ManagementPolicy; |
| class ProcessManager; |
| class RequirementsChecker; |
| |
| namespace api { |
| |
| class EntryPicker; |
| class EntryPickerClient; |
| |
| namespace developer_private { |
| |
| struct ItemInfo; |
| struct ItemInspectView; |
| struct ProjectInfo; |
| |
| namespace RequestFileSource { |
| struct Params; |
| } |
| |
| } // namespace developer_private |
| |
| } // namespace api |
| |
| namespace developer = api::developer_private; |
| |
| typedef std::vector<linked_ptr<developer::ItemInfo> > ItemInfoList; |
| typedef std::vector<linked_ptr<developer::ProjectInfo> > ProjectInfoList; |
| typedef std::vector<linked_ptr<developer::ItemInspectView> > |
| ItemInspectViewList; |
| |
| class DeveloperPrivateEventRouter : public ExtensionRegistryObserver, |
| public ErrorConsole::Observer, |
| public ProcessManagerObserver { |
| public: |
| explicit DeveloperPrivateEventRouter(Profile* profile); |
| ~DeveloperPrivateEventRouter() override; |
| |
| // Add or remove an ID to the list of extensions subscribed to events. |
| void AddExtensionId(const std::string& extension_id); |
| void RemoveExtensionId(const std::string& extension_id); |
| |
| private: |
| // ExtensionRegistryObserver: |
| void OnExtensionLoaded(content::BrowserContext* browser_context, |
| const Extension* extension) override; |
| void OnExtensionUnloaded(content::BrowserContext* browser_context, |
| const Extension* extension, |
| UnloadedExtensionInfo::Reason reason) override; |
| void OnExtensionWillBeInstalled(content::BrowserContext* browser_context, |
| const Extension* extension, |
| bool is_update, |
| bool from_ephemeral, |
| const std::string& old_name) override; |
| void OnExtensionUninstalled(content::BrowserContext* browser_context, |
| const Extension* extension, |
| extensions::UninstallReason reason) override; |
| |
| // ErrorConsole::Observer: |
| void OnErrorAdded(const ExtensionError* error) override; |
| |
| // ProcessManagerObserver: |
| void OnExtensionFrameRegistered( |
| const std::string& extension_id, |
| content::RenderFrameHost* render_frame_host) override; |
| void OnExtensionFrameUnregistered( |
| const std::string& extension_id, |
| content::RenderFrameHost* render_frame_host) override; |
| |
| ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> |
| extension_registry_observer_; |
| ScopedObserver<ErrorConsole, ErrorConsole::Observer> error_console_observer_; |
| ScopedObserver<ProcessManager, ProcessManagerObserver> |
| process_manager_observer_; |
| |
| Profile* profile_; |
| |
| // The set of IDs of the Extensions that have subscribed to DeveloperPrivate |
| // events. Since the only consumer of the DeveloperPrivate API is currently |
| // the Apps Developer Tool (which replaces the chrome://extensions page), we |
| // don't want to send information about the subscribing extension in an |
| // update. In particular, we want to avoid entering a loop, which could happen |
| // when, e.g., the Apps Developer Tool throws an error. |
| std::set<std::string> extension_ids_; |
| |
| DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateEventRouter); |
| }; |
| |
| // The profile-keyed service that manages the DeveloperPrivate API. |
| class DeveloperPrivateAPI : public BrowserContextKeyedAPI, |
| public EventRouter::Observer { |
| public: |
| static BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>* |
| GetFactoryInstance(); |
| |
| // Convenience method to get the DeveloperPrivateAPI for a profile. |
| static DeveloperPrivateAPI* Get(content::BrowserContext* context); |
| |
| explicit DeveloperPrivateAPI(content::BrowserContext* context); |
| ~DeveloperPrivateAPI() override; |
| |
| void SetLastUnpackedDirectory(const base::FilePath& path); |
| |
| base::FilePath& GetLastUnpackedDirectory() { |
| return last_unpacked_directory_; |
| } |
| |
| // KeyedService implementation |
| void Shutdown() override; |
| |
| // EventRouter::Observer implementation. |
| void OnListenerAdded(const EventListenerInfo& details) override; |
| void OnListenerRemoved(const EventListenerInfo& details) override; |
| |
| private: |
| friend class BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>; |
| |
| // BrowserContextKeyedAPI implementation. |
| static const char* service_name() { return "DeveloperPrivateAPI"; } |
| static const bool kServiceRedirectedInIncognito = true; |
| static const bool kServiceIsNULLWhileTesting = true; |
| |
| void RegisterNotifications(); |
| |
| Profile* profile_; |
| |
| // Used to start the load |load_extension_dialog_| in the last directory that |
| // was loaded. |
| base::FilePath last_unpacked_directory_; |
| |
| // Created lazily upon OnListenerAdded. |
| scoped_ptr<DeveloperPrivateEventRouter> developer_private_event_router_; |
| |
| DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateAPI); |
| }; |
| |
| namespace api { |
| |
| class DeveloperPrivateAPIFunction : public UIThreadExtensionFunction { |
| protected: |
| ~DeveloperPrivateAPIFunction() override; |
| |
| // Returns the extension with the given |id| from the registry, including |
| // all possible extensions (enabled, disabled, terminated, etc). |
| const Extension* GetExtensionById(const std::string& id); |
| }; |
| |
| class DeveloperPrivateAutoUpdateFunction : public ChromeSyncExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.autoUpdate", |
| DEVELOPERPRIVATE_AUTOUPDATE) |
| |
| protected: |
| ~DeveloperPrivateAutoUpdateFunction() override; |
| |
| // ExtensionFunction: |
| bool RunSync() override; |
| }; |
| |
| class DeveloperPrivateGetItemsInfoFunction |
| : public DeveloperPrivateAPIFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.getItemsInfo", |
| DEVELOPERPRIVATE_GETITEMSINFO) |
| DeveloperPrivateGetItemsInfoFunction(); |
| |
| private: |
| ~DeveloperPrivateGetItemsInfoFunction() override; |
| ResponseAction Run() override; |
| |
| void GetIconsOnFileThread( |
| std::map<std::string, ExtensionResource> resource_map); |
| void Finish(); |
| |
| ItemInfoList item_list_; |
| }; |
| |
| class DeveloperPrivateGetExtensionsInfoFunction |
| : public DeveloperPrivateAPIFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.getExtensionsInfo", |
| DEVELOPERPRIVATE_GETEXTENSIONSINFO); |
| |
| private: |
| ~DeveloperPrivateGetExtensionsInfoFunction() override; |
| ResponseAction Run() override; |
| }; |
| |
| class DeveloperPrivateGetExtensionInfoFunction |
| : public DeveloperPrivateAPIFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.getExtensionInfo", |
| DEVELOPERPRIVATE_GETEXTENSIONINFO); |
| |
| private: |
| ~DeveloperPrivateGetExtensionInfoFunction() override; |
| ResponseAction Run() override; |
| }; |
| |
| class DeveloperPrivateUpdateExtensionConfigurationFunction |
| : public DeveloperPrivateAPIFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.updateExtensionConfiguration", |
| DEVELOPERPRIVATE_UPDATEEXTENSIONCONFIGURATION); |
| |
| protected: |
| ~DeveloperPrivateUpdateExtensionConfigurationFunction() override; |
| ResponseAction Run() override; |
| }; |
| |
| class DeveloperPrivateReloadFunction : public DeveloperPrivateAPIFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.reload", |
| DEVELOPERPRIVATE_RELOAD); |
| |
| protected: |
| ~DeveloperPrivateReloadFunction() override; |
| |
| // ExtensionFunction: |
| ResponseAction Run() override; |
| }; |
| |
| class DeveloperPrivateShowPermissionsDialogFunction |
| : public DeveloperPrivateAPIFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.showPermissionsDialog", |
| DEVELOPERPRIVATE_PERMISSIONS); |
| DeveloperPrivateShowPermissionsDialogFunction(); |
| |
| protected: |
| // DeveloperPrivateAPIFunction: |
| ~DeveloperPrivateShowPermissionsDialogFunction() override; |
| ResponseAction Run() override; |
| |
| void Finish(); |
| |
| DISALLOW_COPY_AND_ASSIGN(DeveloperPrivateShowPermissionsDialogFunction); |
| }; |
| |
| class DeveloperPrivateChooseEntryFunction : public UIThreadExtensionFunction, |
| public EntryPickerClient { |
| protected: |
| ~DeveloperPrivateChooseEntryFunction() override; |
| bool ShowPicker(ui::SelectFileDialog::Type picker_type, |
| const base::string16& select_title, |
| const ui::SelectFileDialog::FileTypeInfo& info, |
| int file_type_index); |
| }; |
| |
| |
| class DeveloperPrivateLoadUnpackedFunction |
| : public DeveloperPrivateChooseEntryFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.loadUnpacked", |
| DEVELOPERPRIVATE_LOADUNPACKED); |
| DeveloperPrivateLoadUnpackedFunction(); |
| |
| protected: |
| ~DeveloperPrivateLoadUnpackedFunction() override; |
| ResponseAction Run() override; |
| |
| // EntryPickerClient: |
| void FileSelected(const base::FilePath& path) override; |
| void FileSelectionCanceled() override; |
| |
| // Callback for the UnpackedLoader. |
| void OnLoadComplete(const Extension* extension, |
| const base::FilePath& file_path, |
| const std::string& error); |
| |
| private: |
| // Whether or not we should fail quietly in the event of a load error. |
| bool fail_quietly_; |
| }; |
| |
| class DeveloperPrivateChoosePathFunction |
| : public DeveloperPrivateChooseEntryFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.choosePath", |
| DEVELOPERPRIVATE_CHOOSEPATH); |
| |
| protected: |
| ~DeveloperPrivateChoosePathFunction() override; |
| ResponseAction Run() override; |
| |
| // EntryPickerClient: |
| void FileSelected(const base::FilePath& path) override; |
| void FileSelectionCanceled() override; |
| }; |
| |
| class DeveloperPrivatePackDirectoryFunction |
| : public DeveloperPrivateAPIFunction, |
| public PackExtensionJob::Client { |
| |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.packDirectory", |
| DEVELOPERPRIVATE_PACKDIRECTORY); |
| |
| DeveloperPrivatePackDirectoryFunction(); |
| |
| // ExtensionPackJob::Client implementation. |
| void OnPackSuccess(const base::FilePath& crx_file, |
| const base::FilePath& key_file) override; |
| void OnPackFailure(const std::string& error, |
| ExtensionCreator::ErrorType error_type) override; |
| |
| protected: |
| ~DeveloperPrivatePackDirectoryFunction() override; |
| ResponseAction Run() override; |
| |
| private: |
| scoped_refptr<PackExtensionJob> pack_job_; |
| std::string item_path_str_; |
| std::string key_path_str_; |
| }; |
| |
| class DeveloperPrivateIsProfileManagedFunction |
| : public ChromeSyncExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.isProfileManaged", |
| DEVELOPERPRIVATE_ISPROFILEMANAGED); |
| |
| protected: |
| ~DeveloperPrivateIsProfileManagedFunction() override; |
| |
| // ExtensionFunction: |
| bool RunSync() override; |
| }; |
| |
| class DeveloperPrivateLoadDirectoryFunction |
| : public ChromeAsyncExtensionFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.loadDirectory", |
| DEVELOPERPRIVATE_LOADUNPACKEDCROS); |
| |
| DeveloperPrivateLoadDirectoryFunction(); |
| |
| protected: |
| ~DeveloperPrivateLoadDirectoryFunction() override; |
| |
| // ExtensionFunction: |
| bool RunAsync() override; |
| |
| bool LoadByFileSystemAPI(const storage::FileSystemURL& directory_url); |
| |
| void ClearExistingDirectoryContent(const base::FilePath& project_path); |
| |
| void ReadDirectoryByFileSystemAPI(const base::FilePath& project_path, |
| const base::FilePath& destination_path); |
| |
| void ReadDirectoryByFileSystemAPICb( |
| const base::FilePath& project_path, |
| const base::FilePath& destination_path, |
| base::File::Error result, |
| const storage::FileSystemOperation::FileEntryList& file_list, |
| bool has_more); |
| |
| void SnapshotFileCallback( |
| const base::FilePath& target_path, |
| base::File::Error result, |
| const base::File::Info& file_info, |
| const base::FilePath& platform_path, |
| const scoped_refptr<storage::ShareableFileReference>& file_ref); |
| |
| void CopyFile(const base::FilePath& src_path, |
| const base::FilePath& dest_path); |
| |
| void Load(); |
| |
| scoped_refptr<storage::FileSystemContext> context_; |
| |
| // syncfs url representing the root of the folder to be copied. |
| std::string project_base_url_; |
| |
| // physical path on disc of the folder to be copied. |
| base::FilePath project_base_path_; |
| |
| private: |
| int pending_copy_operations_count_; |
| |
| // This is set to false if any of the copyFile operations fail on |
| // call of the API. It is returned as a response of the API call. |
| bool success_; |
| }; |
| |
| class DeveloperPrivateRequestFileSourceFunction |
| : public DeveloperPrivateAPIFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.requestFileSource", |
| DEVELOPERPRIVATE_REQUESTFILESOURCE); |
| DeveloperPrivateRequestFileSourceFunction(); |
| |
| protected: |
| ~DeveloperPrivateRequestFileSourceFunction() override; |
| ResponseAction Run() override; |
| |
| private: |
| void Finish(const std::string& file_contents); |
| |
| scoped_ptr<api::developer_private::RequestFileSource::Params> params_; |
| }; |
| |
| class DeveloperPrivateOpenDevToolsFunction |
| : public DeveloperPrivateAPIFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.openDevTools", |
| DEVELOPERPRIVATE_OPENDEVTOOLS); |
| DeveloperPrivateOpenDevToolsFunction(); |
| |
| protected: |
| ~DeveloperPrivateOpenDevToolsFunction() override; |
| ResponseAction Run() override; |
| }; |
| |
| class DeveloperPrivateDeleteExtensionErrorsFunction |
| : public DeveloperPrivateAPIFunction { |
| public: |
| DECLARE_EXTENSION_FUNCTION("developerPrivate.deleteExtensionErrors", |
| DEVELOPERPRIVATE_DELETEEXTENSIONERRORS); |
| |
| protected: |
| ~DeveloperPrivateDeleteExtensionErrorsFunction() override; |
| ResponseAction Run() override; |
| }; |
| |
| } // namespace api |
| |
| } // namespace extensions |
| |
| #endif // CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_ |