From a9e738bb0e1f99d68c8b8f04f244bf6a5b07dff9 Mon Sep 17 00:00:00 2001 From: sentialx Date: Wed, 19 Aug 2020 14:17:50 +0200 Subject: [PATCH 01/10] fix: initialize management policy --- shell/browser/extensions/electron_extension_system.cc | 5 ++++- shell/browser/extensions/electron_extension_system.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/shell/browser/extensions/electron_extension_system.cc b/shell/browser/extensions/electron_extension_system.cc index 035a267feae34..5efedc00e23be 100644 --- a/shell/browser/extensions/electron_extension_system.cc +++ b/shell/browser/extensions/electron_extension_system.cc @@ -25,6 +25,7 @@ #include "extensions/browser/api/app_runtime/app_runtime_api.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/info_map.h" +#include "extensions/browser/management_policy.h" #include "extensions/browser/notification_types.h" #include "extensions/browser/null_app_sorting.h" #include "extensions/browser/quota_service.h" @@ -91,6 +92,8 @@ void ElectronExtensionSystem::InitForRegularProfile(bool extensions_enabled) { if (!browser_context_->IsOffTheRecord()) LoadComponentExtensions(); + + management_policy_.reset(new ManagementPolicy); } std::unique_ptr ParseManifest( @@ -130,7 +133,7 @@ RuntimeData* ElectronExtensionSystem::runtime_data() { } ManagementPolicy* ElectronExtensionSystem::management_policy() { - return nullptr; + return management_policy_.get(); } ServiceWorkerManager* ElectronExtensionSystem::service_worker_manager() { diff --git a/shell/browser/extensions/electron_extension_system.h b/shell/browser/extensions/electron_extension_system.h index ea5e07b84330b..e1f0d767be191 100644 --- a/shell/browser/extensions/electron_extension_system.h +++ b/shell/browser/extensions/electron_extension_system.h @@ -104,6 +104,7 @@ class ElectronExtensionSystem : public ExtensionSystem { std::unique_ptr quota_service_; std::unique_ptr shared_user_script_manager_; std::unique_ptr app_sorting_; + std::unique_ptr management_policy_; std::unique_ptr extension_loader_; From 84ede16f5594575a62089fbec31a2a61d0908304 Mon Sep 17 00:00:00 2001 From: sentialx Date: Sun, 23 Aug 2020 20:38:14 +0200 Subject: [PATCH 02/10] fix(extensions): crash when using chrome.management --- filenames.gni | 2 + .../electron_management_api_delegate.cc | 235 ++++++++++++++++++ .../electron_management_api_delegate.h | 83 +++++++ .../electron_extensions_api_client.cc | 6 + .../electron_extensions_api_client.h | 1 + 5 files changed, 327 insertions(+) create mode 100644 shell/browser/extensions/api/management/electron_management_api_delegate.cc create mode 100644 shell/browser/extensions/api/management/electron_management_api_delegate.h diff --git a/filenames.gni b/filenames.gni index 26de2d06009e7..2c1d506c25b0f 100644 --- a/filenames.gni +++ b/filenames.gni @@ -624,6 +624,8 @@ filenames = { "shell/browser/extensions/api/resources_private/resources_private_api.h", "shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc", "shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h", + "shell/browser/extensions/api/management/electron_management_api_delegate.cc", + "shell/browser/extensions/api/management/electron_management_api_delegate.h", "shell/browser/extensions/api/tabs/tabs_api.cc", "shell/browser/extensions/api/tabs/tabs_api.h", "shell/browser/extensions/api/streams_private/streams_private_api.cc", diff --git a/shell/browser/extensions/api/management/electron_management_api_delegate.cc b/shell/browser/extensions/api/management/electron_management_api_delegate.cc new file mode 100644 index 0000000000000..4a612f399c39e --- /dev/null +++ b/shell/browser/extensions/api/management/electron_management_api_delegate.cc @@ -0,0 +1,235 @@ +// Copyright 2014 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. + +// TODO(sentialx): emit relevant events in Electron's session? +#include "shell/browser/extensions/api/management/electron_management_api_delegate.h" + +#include +#include + +#include "base/bind.h" +#include "base/macros.h" +#include "base/strings/strcat.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task/post_task.h" +#include "chrome/common/extensions/extension_metrics.h" +#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" +#include "chrome/common/web_application_info.h" +#include "chrome/common/webui_url_constants.cc" +#include "components/favicon/core/favicon_service.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/web_contents.h" +#include "extensions/browser/api/management/management_api.h" +#include "extensions/browser/api/management/management_api_constants.h" +#include "extensions/browser/disable_reason.h" +#include "extensions/browser/extension_prefs.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_system.h" +#include "extensions/common/api/management.h" +#include "extensions/common/extension.h" +#include "services/data_decoder/public/cpp/data_decoder.h" +#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h" + +namespace { +class ManagementSetEnabledFunctionInstallPromptDelegate + : public extensions::InstallPromptDelegate { + public: + ManagementSetEnabledFunctionInstallPromptDelegate( + content::WebContents* web_contents, + content::BrowserContext* browser_context, + const extensions::Extension* extension, + const base::Callback& callback) { + // TODO(sentialx): emit event + } + ~ManagementSetEnabledFunctionInstallPromptDelegate() override {} + + private: + base::WeakPtrFactory + weak_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(ManagementSetEnabledFunctionInstallPromptDelegate); +}; + +class ManagementUninstallFunctionUninstallDialogDelegate + : public extensions::UninstallDialogDelegate { + public: + ManagementUninstallFunctionUninstallDialogDelegate( + extensions::ManagementUninstallFunctionBase* function, + const extensions::Extension* target_extension, + bool show_programmatic_uninstall_ui) { + // TODO(sentialx): emit event + } + + ~ManagementUninstallFunctionUninstallDialogDelegate() override {} + + private: + DISALLOW_COPY_AND_ASSIGN(ManagementUninstallFunctionUninstallDialogDelegate); +}; + +} // namespace + +ElectronManagementAPIDelegate::ElectronManagementAPIDelegate() {} + +ElectronManagementAPIDelegate::~ElectronManagementAPIDelegate() {} + +void ElectronManagementAPIDelegate::LaunchAppFunctionDelegate( + const extensions::Extension* extension, + content::BrowserContext* context) const { + // TODO(sentialx): emit event + extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_EXTENSION_API, + extension->GetType()); +} + +GURL ElectronManagementAPIDelegate::GetFullLaunchURL( + const extensions::Extension* extension) const { + return extensions::AppLaunchInfo::GetFullLaunchURL(extension); +} + +extensions::LaunchType ElectronManagementAPIDelegate::GetLaunchType( + const extensions::ExtensionPrefs* prefs, + const extensions::Extension* extension) const { + // TODO(sentialx) + return extensions::LAUNCH_TYPE_DEFAULT; +} + +void ElectronManagementAPIDelegate:: + GetPermissionWarningsByManifestFunctionDelegate( + extensions::ManagementGetPermissionWarningsByManifestFunction* function, + const std::string& manifest_str) const { + data_decoder::DataDecoder::ParseJsonIsolated( + manifest_str, + base::BindOnce( + &extensions::ManagementGetPermissionWarningsByManifestFunction:: + OnParse, + function)); +} + +std::unique_ptr +ElectronManagementAPIDelegate::SetEnabledFunctionDelegate( + content::WebContents* web_contents, + content::BrowserContext* browser_context, + const extensions::Extension* extension, + const base::Callback& callback) const { + return std::unique_ptr( + new ManagementSetEnabledFunctionInstallPromptDelegate( + web_contents, browser_context, extension, callback)); +} + +std::unique_ptr +ElectronManagementAPIDelegate::UninstallFunctionDelegate( + extensions::ManagementUninstallFunctionBase* function, + const extensions::Extension* target_extension, + bool show_programmatic_uninstall_ui) const { + return std::unique_ptr( + new ManagementUninstallFunctionUninstallDialogDelegate( + function, target_extension, show_programmatic_uninstall_ui)); +} + +bool ElectronManagementAPIDelegate::CreateAppShortcutFunctionDelegate( + extensions::ManagementCreateAppShortcutFunction* function, + const extensions::Extension* extension, + std::string* error) const { + return false; // TODO(sentialx): route event and return true +} + +std::unique_ptr +ElectronManagementAPIDelegate::GenerateAppForLinkFunctionDelegate( + extensions::ManagementGenerateAppForLinkFunction* function, + content::BrowserContext* context, + const std::string& title, + const GURL& launch_url) const { + // TODO(sentialx) + return nullptr; +} + +bool ElectronManagementAPIDelegate::CanContextInstallWebApps( + content::BrowserContext* context) const { + // TODO(sentialx) + return false; +} + +void ElectronManagementAPIDelegate::InstallOrLaunchReplacementWebApp( + content::BrowserContext* context, + const GURL& web_app_url, + InstallOrLaunchWebAppCallback callback) const { + // TODO(sentialx) +} + +bool ElectronManagementAPIDelegate::CanContextInstallAndroidApps( + content::BrowserContext* context) const { + return false; +} + +void ElectronManagementAPIDelegate::CheckAndroidAppInstallStatus( + const std::string& package_name, + AndroidAppInstallStatusCallback callback) const { + std::move(callback).Run(false); +} + +void ElectronManagementAPIDelegate::InstallReplacementAndroidApp( + const std::string& package_name, + InstallAndroidAppCallback callback) const { + std::move(callback).Run(false); +} + +void ElectronManagementAPIDelegate::EnableExtension( + content::BrowserContext* context, + const std::string& extension_id) const { + // const extensions::Extension* extension = + // extensions::ExtensionRegistry::Get(context)->GetExtensionById( + // extension_id, extensions::ExtensionRegistry::EVERYTHING); + + // TODO(sentialx): we don't have ExtensionService + // If the extension was disabled for a permissions increase, the Management + // API will have displayed a re-enable prompt to the user, so we know it's + // safe to grant permissions here. + // extensions::ExtensionSystem::Get(context) + // ->extension_service() + // ->GrantPermissionsAndEnableExtension(extension); +} + +void ElectronManagementAPIDelegate::DisableExtension( + content::BrowserContext* context, + const extensions::Extension* source_extension, + const std::string& extension_id, + extensions::disable_reason::DisableReason disable_reason) const { + // TODO(sentialx): we don't have ExtensionService + // extensions::ExtensionSystem::Get(context) + // ->extension_service() + // ->DisableExtensionWithSource(source_extension, extension_id, + // disable_reason); +} + +bool ElectronManagementAPIDelegate::UninstallExtension( + content::BrowserContext* context, + const std::string& transient_extension_id, + extensions::UninstallReason reason, + base::string16* error) const { + // TODO(sentialx): we don't have ExtensionService + // return extensions::ExtensionSystem::Get(context) + // ->extension_service() + // ->UninstallExtension(transient_extension_id, reason, error); + return false; +} + +void ElectronManagementAPIDelegate::SetLaunchType( + content::BrowserContext* context, + const std::string& extension_id, + extensions::LaunchType launch_type) const { + // TODO(sentialx) + // extensions::SetLaunchType(context, extension_id, launch_type); +} + +GURL ElectronManagementAPIDelegate::GetIconURL( + const extensions::Extension* extension, + int icon_size, + ExtensionIconSet::MatchType match, + bool grayscale) const { + GURL icon_url(base::StringPrintf("%s%s/%d/%d%s", + chrome::kChromeUIExtensionIconURL, + extension->id().c_str(), icon_size, match, + grayscale ? "?grayscale=true" : "")); + CHECK(icon_url.is_valid()); + return icon_url; +} \ No newline at end of file diff --git a/shell/browser/extensions/api/management/electron_management_api_delegate.h b/shell/browser/extensions/api/management/electron_management_api_delegate.h new file mode 100644 index 0000000000000..b916920757683 --- /dev/null +++ b/shell/browser/extensions/api/management/electron_management_api_delegate.h @@ -0,0 +1,83 @@ +// Copyright 2014 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 SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_SHELL_MANAGEMENT_API_DELEGATE_H_ +#define SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_SHELL_MANAGEMENT_API_DELEGATE_H_ + +#include "base/task/cancelable_task_tracker.h" +#include "extensions/browser/api/management/management_api_delegate.h" + +class ElectronManagementAPIDelegate : public extensions::ManagementAPIDelegate { + public: + ElectronManagementAPIDelegate(); + ~ElectronManagementAPIDelegate() override; + + // ManagementAPIDelegate. + void LaunchAppFunctionDelegate( + const extensions::Extension* extension, + content::BrowserContext* context) const override; + GURL GetFullLaunchURL(const extensions::Extension* extension) const override; + extensions::LaunchType GetLaunchType( + const extensions::ExtensionPrefs* prefs, + const extensions::Extension* extension) const override; + void GetPermissionWarningsByManifestFunctionDelegate( + extensions::ManagementGetPermissionWarningsByManifestFunction* function, + const std::string& manifest_str) const override; + std::unique_ptr SetEnabledFunctionDelegate( + content::WebContents* web_contents, + content::BrowserContext* browser_context, + const extensions::Extension* extension, + const base::Callback& callback) const override; + std::unique_ptr + UninstallFunctionDelegate( + extensions::ManagementUninstallFunctionBase* function, + const extensions::Extension* target_extension, + bool show_programmatic_uninstall_ui) const override; + bool CreateAppShortcutFunctionDelegate( + extensions::ManagementCreateAppShortcutFunction* function, + const extensions::Extension* extension, + std::string* error) const override; + std::unique_ptr + GenerateAppForLinkFunctionDelegate( + extensions::ManagementGenerateAppForLinkFunction* function, + content::BrowserContext* context, + const std::string& title, + const GURL& launch_url) const override; + bool CanContextInstallWebApps( + content::BrowserContext* context) const override; + void InstallOrLaunchReplacementWebApp( + content::BrowserContext* context, + const GURL& web_app_url, + ManagementAPIDelegate::InstallOrLaunchWebAppCallback callback) + const override; + bool CanContextInstallAndroidApps( + content::BrowserContext* context) const override; + void CheckAndroidAppInstallStatus( + const std::string& package_name, + ManagementAPIDelegate::AndroidAppInstallStatusCallback callback) + const override; + void InstallReplacementAndroidApp( + const std::string& package_name, + ManagementAPIDelegate::InstallAndroidAppCallback callback) const override; + void EnableExtension(content::BrowserContext* context, + const std::string& extension_id) const override; + void DisableExtension( + content::BrowserContext* context, + const extensions::Extension* source_extension, + const std::string& extension_id, + extensions::disable_reason::DisableReason disable_reason) const override; + bool UninstallExtension(content::BrowserContext* context, + const std::string& transient_extension_id, + extensions::UninstallReason reason, + base::string16* error) const override; + void SetLaunchType(content::BrowserContext* context, + const std::string& extension_id, + extensions::LaunchType launch_type) const override; + GURL GetIconURL(const extensions::Extension* extension, + int icon_size, + ExtensionIconSet::MatchType match, + bool grayscale) const override; +}; + +#endif // SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_SHELL_MANAGEMENT_API_DELEGATE_H_ \ No newline at end of file diff --git a/shell/browser/extensions/electron_extensions_api_client.cc b/shell/browser/extensions/electron_extensions_api_client.cc index 5da08766e7e99..f79d8281059f4 100644 --- a/shell/browser/extensions/electron_extensions_api_client.cc +++ b/shell/browser/extensions/electron_extensions_api_client.cc @@ -9,6 +9,7 @@ #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h" #include "printing/buildflags/buildflags.h" +#include "shell/browser/extensions/api/management/electron_management_api_delegate.h" #include "shell/browser/extensions/electron_extension_web_contents_observer.h" #include "shell/browser/extensions/electron_messaging_delegate.h" @@ -59,6 +60,11 @@ void ElectronExtensionsAPIClient::AttachWebContentsHelpers( #endif } +ManagementAPIDelegate* +ElectronExtensionsAPIClient::CreateManagementAPIDelegate() const { + return new ElectronManagementAPIDelegate; +} + std::unique_ptr ElectronExtensionsAPIClient::CreateMimeHandlerViewGuestDelegate( MimeHandlerViewGuest* guest) const { diff --git a/shell/browser/extensions/electron_extensions_api_client.h b/shell/browser/extensions/electron_extensions_api_client.h index 1747d7e982668..03d07d8453bb0 100644 --- a/shell/browser/extensions/electron_extensions_api_client.h +++ b/shell/browser/extensions/electron_extensions_api_client.h @@ -25,6 +25,7 @@ class ElectronExtensionsAPIClient : public ExtensionsAPIClient { std::unique_ptr CreateMimeHandlerViewGuestDelegate( MimeHandlerViewGuest* guest) const override; + ManagementAPIDelegate* CreateManagementAPIDelegate() const override; private: std::unique_ptr messaging_delegate_; From 1d908820aa001fcbf9b77a45c40bd1b674078c10 Mon Sep 17 00:00:00 2001 From: sentialx Date: Sun, 23 Aug 2020 20:55:03 +0200 Subject: [PATCH 03/10] test: add tests --- spec-main/extensions-spec.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/spec-main/extensions-spec.ts b/spec-main/extensions-spec.ts index 812cde9ba0ca0..113ddddde993e 100644 --- a/spec-main/extensions-spec.ts +++ b/spec-main/extensions-spec.ts @@ -37,6 +37,26 @@ describe('chrome extensions', () => { }); }); + it('does not crash when using chrome.management', async () => { + const customSession = session.fromPartition(`persist:${require('uuid').v4()}`); + const w = new BrowserWindow({ show: false, webPreferences: { session: customSession, sandbox: true } }); + w.loadURL('about:blank'); + + await emittedOnce(w.webContents, 'dom-ready'); + await customSession.loadExtension(path.join(fixtures, 'extensions', 'persistent-background-page')); + const args: any = await emittedOnce(app, 'web-contents-created'); + const wc: Electron.WebContents = args[1]; + await expect(wc.executeJavaScript(` + (() => { + return new Promise((resolve) => { + chrome.management.getSelf((info) => { + resolve(info); + }); + }) + })(); + `)).to.eventually.have.property('id'); + }); + it('can open WebSQLDatabase in a background page', async () => { const customSession = session.fromPartition(`persist:${require('uuid').v4()}`); const w = new BrowserWindow({ show: false, webPreferences: { session: customSession, sandbox: true } }); From 8dfcd7d65853c732b42bb3f3346f97fa1ec9e511 Mon Sep 17 00:00:00 2001 From: sentialx Date: Sun, 23 Aug 2020 21:10:50 +0200 Subject: [PATCH 04/10] docs: add a note about chrome.management --- docs/api/extensions.md | 216 +++++++++++++++++++++-------------------- 1 file changed, 112 insertions(+), 104 deletions(-) diff --git a/docs/api/extensions.md b/docs/api/extensions.md index 4a93951024921..c430d2b944e59 100644 --- a/docs/api/extensions.md +++ b/docs/api/extensions.md @@ -1,104 +1,112 @@ -# Chrome Extension Support - -Electron supports a subset of the [Chrome Extensions -API][chrome-extensions-api-index], primarily to support DevTools extensions and -Chromium-internal extensions, but it also happens to support some other -extension capabilities. - -[chrome-extensions-api-index]: https://developer.chrome.com/extensions/api_index - -> **Note:** Electron does not support arbitrary Chrome extensions from the -> store, and it is a **non-goal** of the Electron project to be perfectly -> compatible with Chrome's implementation of Extensions. - -## Loading extensions - -Electron only supports loading unpacked extensions (i.e., `.crx` files do not -work). Extensions are installed per-`session`. To load an extension, call -[`ses.loadExtension`](session.md#sesloadextensionpath): - -```js -const { session } = require('electron') - -session.loadExtension('path/to/unpacked/extension').then(({ id }) => { - // ... -}) -``` - -Loaded extensions will not be automatically remembered across exits; if you do -not call `loadExtension` when the app runs, the extension will not be loaded. - -Note that loading extensions is only supported in persistent sessions. -Attempting to load an extension into an in-memory session will throw an error. - -See the [`session`](session.md) documentation for more information about -loading, unloading, and querying active extensions. - -## Supported Extensions APIs - -We support the following extensions APIs, with some caveats. Other APIs may -additionally be supported, but support for any APIs not listed here is -provisional and may be removed. - -### `chrome.devtools.inspectedWindow` - -All features of this API are supported. - -### `chrome.devtools.network` - -All features of this API are supported. - -### `chrome.devtools.panels` - -All features of this API are supported. - -### `chrome.extension` - -The following properties of `chrome.extension` are supported: - -- `chrome.extension.lastError` - -The following methods of `chrome.extension` are supported: - -- `chrome.extension.getURL` -- `chrome.extension.getBackgroundPage` - -### `chrome.runtime` - -The following properties of `chrome.runtime` are supported: - -- `chrome.runtime.lastError` -- `chrome.runtime.id` - -The following methods of `chrome.runtime` are supported: - -- `chrome.runtime.getBackgroundPage` -- `chrome.runtime.getManifest` -- `chrome.runtime.getURL` -- `chrome.runtime.connect` -- `chrome.runtime.sendMessage` - -The following events of `chrome.runtime` are supported: - -- `chrome.runtime.onStartup` -- `chrome.runtime.onInstalled` -- `chrome.runtime.onSuspend` -- `chrome.runtime.onSuspendCanceled` -- `chrome.runtime.onConnect` -- `chrome.runtime.onMessage` - -### `chrome.storage` - -Only `chrome.storage.local` is supported; `chrome.storage.sync` and -`chrome.storage.managed` are not. - -### `chrome.tabs` - -The following methods of `chrome.tabs` are supported: - -- `chrome.tabs.sendMessage` -- `chrome.tabs.executeScript` - -> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active -> tab". Since Electron has no such concept, passing `-1` as a tab ID is not -> supported and will raise an error. +# Chrome Extension Support + +Electron supports a subset of the [Chrome Extensions +API][chrome-extensions-api-index], primarily to support DevTools extensions and +Chromium-internal extensions, but it also happens to support some other +extension capabilities. + +[chrome-extensions-api-index]: https://developer.chrome.com/extensions/api_index + +> **Note:** Electron does not support arbitrary Chrome extensions from the +> store, and it is a **non-goal** of the Electron project to be perfectly +> compatible with Chrome's implementation of Extensions. + +## Loading extensions + +Electron only supports loading unpacked extensions (i.e., `.crx` files do not +work). Extensions are installed per-`session`. To load an extension, call +[`ses.loadExtension`](session.md#sesloadextensionpath): + +```js +const { session } = require('electron') + +session.loadExtension('path/to/unpacked/extension').then(({ id }) => { + // ... +}) +``` + +Loaded extensions will not be automatically remembered across exits; if you do +not call `loadExtension` when the app runs, the extension will not be loaded. + +Note that loading extensions is only supported in persistent sessions. +Attempting to load an extension into an in-memory session will throw an error. + +See the [`session`](session.md) documentation for more information about +loading, unloading, and querying active extensions. + +## Supported Extensions APIs + +We support the following extensions APIs, with some caveats. Other APIs may +additionally be supported, but support for any APIs not listed here is +provisional and may be removed. + +### `chrome.devtools.inspectedWindow` + +All features of this API are supported. + +### `chrome.devtools.network` + +All features of this API are supported. + +### `chrome.devtools.panels` + +All features of this API are supported. + +### `chrome.extension` + +The following properties of `chrome.extension` are supported: + +- `chrome.extension.lastError` + +The following methods of `chrome.extension` are supported: + +- `chrome.extension.getURL` +- `chrome.extension.getBackgroundPage` + +### `chrome.runtime` + +The following properties of `chrome.runtime` are supported: + +- `chrome.runtime.lastError` +- `chrome.runtime.id` + +The following methods of `chrome.runtime` are supported: + +- `chrome.runtime.getBackgroundPage` +- `chrome.runtime.getManifest` +- `chrome.runtime.getURL` +- `chrome.runtime.connect` +- `chrome.runtime.sendMessage` + +The following events of `chrome.runtime` are supported: + +- `chrome.runtime.onStartup` +- `chrome.runtime.onInstalled` +- `chrome.runtime.onSuspend` +- `chrome.runtime.onSuspendCanceled` +- `chrome.runtime.onConnect` +- `chrome.runtime.onMessage` + +### `chrome.storage` + +Only `chrome.storage.local` is supported; `chrome.storage.sync` and +`chrome.storage.managed` are not. + +### `chrome.tabs` + +The following methods of `chrome.tabs` are supported: + +- `chrome.tabs.sendMessage` +- `chrome.tabs.executeScript` + +> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active +> tab". Since Electron has no such concept, passing `-1` as a tab ID is not +> supported and will raise an error. + +### `chrome.management` + +The following methods of `chrome.management` are supported: + +- `chrome.management.getAll` +- `chrome.management.get` +- `chrome.management.getSelf` From 8601ea35b125848b4731064cd599a2dd0e998f58 Mon Sep 17 00:00:00 2001 From: sentialx Date: Sun, 23 Aug 2020 21:14:54 +0200 Subject: [PATCH 05/10] fix: lint errors --- .../api/management/electron_management_api_delegate.cc | 5 +++-- .../api/management/electron_management_api_delegate.h | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/shell/browser/extensions/api/management/electron_management_api_delegate.cc b/shell/browser/extensions/api/management/electron_management_api_delegate.cc index 4a612f399c39e..7a58941a89fca 100644 --- a/shell/browser/extensions/api/management/electron_management_api_delegate.cc +++ b/shell/browser/extensions/api/management/electron_management_api_delegate.cc @@ -6,6 +6,7 @@ #include "shell/browser/extensions/api/management/electron_management_api_delegate.h" #include +#include #include #include "base/bind.h" @@ -16,7 +17,7 @@ #include "chrome/common/extensions/extension_metrics.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/web_application_info.h" -#include "chrome/common/webui_url_constants.cc" +#include "chrome/common/webui_url_constants.h" #include "components/favicon/core/favicon_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" @@ -232,4 +233,4 @@ GURL ElectronManagementAPIDelegate::GetIconURL( grayscale ? "?grayscale=true" : "")); CHECK(icon_url.is_valid()); return icon_url; -} \ No newline at end of file +} diff --git a/shell/browser/extensions/api/management/electron_management_api_delegate.h b/shell/browser/extensions/api/management/electron_management_api_delegate.h index b916920757683..462417a39f02e 100644 --- a/shell/browser/extensions/api/management/electron_management_api_delegate.h +++ b/shell/browser/extensions/api/management/electron_management_api_delegate.h @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_SHELL_MANAGEMENT_API_DELEGATE_H_ -#define SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_SHELL_MANAGEMENT_API_DELEGATE_H_ +#ifndef SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_ELECTRON_MANAGEMENT_API_DELEGATE_H_ +#define SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_ELECTRON_MANAGEMENT_API_DELEGATE_H_ + +#include #include "base/task/cancelable_task_tracker.h" #include "extensions/browser/api/management/management_api_delegate.h" @@ -80,4 +82,5 @@ class ElectronManagementAPIDelegate : public extensions::ManagementAPIDelegate { bool grayscale) const override; }; -#endif // SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_SHELL_MANAGEMENT_API_DELEGATE_H_ \ No newline at end of file +#endif +// SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_ELECTRON_MANAGEMENT_API_DELEGATE_H_ From d2cb217d267edd277af914338d61fc6c2cae1104 Mon Sep 17 00:00:00 2001 From: sentialx Date: Sun, 23 Aug 2020 21:18:36 +0200 Subject: [PATCH 06/10] fix: lint errors --- .../api/management/electron_management_api_delegate.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/browser/extensions/api/management/electron_management_api_delegate.h b/shell/browser/extensions/api/management/electron_management_api_delegate.h index 462417a39f02e..4c985debeed83 100644 --- a/shell/browser/extensions/api/management/electron_management_api_delegate.h +++ b/shell/browser/extensions/api/management/electron_management_api_delegate.h @@ -6,6 +6,7 @@ #define SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_ELECTRON_MANAGEMENT_API_DELEGATE_H_ #include +#include #include "base/task/cancelable_task_tracker.h" #include "extensions/browser/api/management/management_api_delegate.h" @@ -82,5 +83,4 @@ class ElectronManagementAPIDelegate : public extensions::ManagementAPIDelegate { bool grayscale) const override; }; -#endif -// SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_ELECTRON_MANAGEMENT_API_DELEGATE_H_ +#endif // SHELL_BROWSER_EXTENSIONS_API_MANAGEMENT_ELECTRON_MANAGEMENT_API_DELEGATE_H_ From 4af32f85349b954650acac9f7ed47f46648dbc3f Mon Sep 17 00:00:00 2001 From: sentialx Date: Sun, 23 Aug 2020 22:25:26 +0200 Subject: [PATCH 07/10] fix: remove favicon_service include --- .../api/management/electron_management_api_delegate.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/browser/extensions/api/management/electron_management_api_delegate.cc b/shell/browser/extensions/api/management/electron_management_api_delegate.cc index 7a58941a89fca..19e0cd9c84c8d 100644 --- a/shell/browser/extensions/api/management/electron_management_api_delegate.cc +++ b/shell/browser/extensions/api/management/electron_management_api_delegate.cc @@ -18,7 +18,6 @@ #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/web_application_info.h" #include "chrome/common/webui_url_constants.h" -#include "components/favicon/core/favicon_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/api/management/management_api.h" From a82da8adf34d7bc968c03a0cfb1413d00449e59b Mon Sep 17 00:00:00 2001 From: sentialx Date: Tue, 25 Aug 2020 15:56:35 +0200 Subject: [PATCH 08/10] fix: add missing management permission --- .../extensions/api/_permission_features.json | 64 ++++++++++++++++++- .../electron_extensions_api_provider.cc | 1 + 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/shell/common/extensions/api/_permission_features.json b/shell/common/extensions/api/_permission_features.json index 6f0aacd586037..44d71cc852ef8 100644 --- a/shell/common/extensions/api/_permission_features.json +++ b/shell/common/extensions/api/_permission_features.json @@ -5,5 +5,65 @@ "extension" ], "location": "component" - } -} + }, + "management": [ + { + "channel": "stable", + "extension_types": [ + "extension", + "legacy_packaged_app" + ] + }, + { + "channel": "stable", + "extension_types": [ + "platform_app" + ], + "whitelist": [ + "AE27D69DBE571F4B1694F05C89B710C646792231", // Published ADT + // TODO(grv): clean up once Apps developer tool is published. + "5107DE9024C329EEA9C9A72D94C16723790C6422", // Apps Developer Tool. + "8C0B1873FFFB65E4D0F4D772879F7304CEF125C2", // Apps Editor old. + "FA0501B579070BB9CBD4FCAEC8CB0EDF22BA2F04", // Apps Editor published. + "EE17C698905F7F2E6DDC87C9C30F11E164C829F4", // Watchdog (Activity Log) + "90113DA9516526D24DAF156C629CC41C049E8882", // Watchdog Test Version + "4A4EA121622FCA3D78ED2AB534197F43D7189EE0", // Spark nightly build. + "9FDE6E7F06FCFA11D9A05041C7FF6D8AE662F5D1", // Spark release. + "50B4A905D522C06E27CA6D099E3E54BDA1F152C5", // Spark Beta channel. + "BA0C8BB92084C9741312D90D3EA882526853455F", // Spark dev channel. + "5F57A9AE8DFF5D6BB09DF8606270402612E871E5", // http://crbug.com/422624 + "46578A13607D38F1DC8E280C4F499FB0A2F9565C", // http://crbug.com/819404 + "898FB5A39687D210766B8998BA4530B99C9E6586", // http://crbug.com/819404 + "82F30B65397BC3E4ADE627BBD857AB8A58210648", // http://crbug.com/819404 + "C74B2AF138F9EDECD04D0965AB36CA66C8290466" // http://crbug.com/957772 + ] + }, + { + "channel": "stable", + "extension_types": [ + "hosted_app" + ], + "whitelist": [ + "B44D08FD98F1523ED5837D78D0A606EA9D6206E5" // Web Store + ] + }, + { + "channel": "stable", + "extension_types": [ + "platform_app" + ], + "session_types": [ + "kiosk" + ] + }, + { + "channel": "stable", + "dependencies": [ + "behavior:imprivata_login_screen_extension" + ], + "extension_types": [ + "login_screen_extension" + ] + } + ] +} \ No newline at end of file diff --git a/shell/common/extensions/electron_extensions_api_provider.cc b/shell/common/extensions/electron_extensions_api_provider.cc index e02aee3f2df07..8acf2c3875dab 100644 --- a/shell/common/extensions/electron_extensions_api_provider.cc +++ b/shell/common/extensions/electron_extensions_api_provider.cc @@ -38,6 +38,7 @@ constexpr APIPermissionInfo::InitInfo permissions_to_register[] = { APIPermissionInfo::kFlagInternal}, {APIPermission::kResourcesPrivate, "resourcesPrivate", APIPermissionInfo::kFlagCannotBeOptional}, + {APIPermission::kManagement, "management"}, }; base::span GetPermissionInfos() { return base::make_span(permissions_to_register); From 8fca85d4940978765966417d9b3d66cde3909ac8 Mon Sep 17 00:00:00 2001 From: sentialx Date: Tue, 25 Aug 2020 16:00:03 +0200 Subject: [PATCH 09/10] docs: more supported apis --- docs/api/extensions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api/extensions.md b/docs/api/extensions.md index c430d2b944e59..5aba21ff4fdbf 100644 --- a/docs/api/extensions.md +++ b/docs/api/extensions.md @@ -110,3 +110,7 @@ The following methods of `chrome.management` are supported: - `chrome.management.getAll` - `chrome.management.get` - `chrome.management.getSelf` +- `chrome.management.getPermissionWarningsById` +- `chrome.management.getPermissionWarningsByManifest` +- `chrome.management.onEnabled` +- `chrome.management.onDisabled` From 53262bd175554d7ac33a86b21095e9c6dfd3aacc Mon Sep 17 00:00:00 2001 From: sentialx Date: Thu, 27 Aug 2020 13:35:50 +0200 Subject: [PATCH 10/10] fix: extensions.md line endings --- docs/api/extensions.md | 232 ++++++++++++++++++++--------------------- 1 file changed, 116 insertions(+), 116 deletions(-) diff --git a/docs/api/extensions.md b/docs/api/extensions.md index 5aba21ff4fdbf..f483d6318b056 100644 --- a/docs/api/extensions.md +++ b/docs/api/extensions.md @@ -1,116 +1,116 @@ -# Chrome Extension Support - -Electron supports a subset of the [Chrome Extensions -API][chrome-extensions-api-index], primarily to support DevTools extensions and -Chromium-internal extensions, but it also happens to support some other -extension capabilities. - -[chrome-extensions-api-index]: https://developer.chrome.com/extensions/api_index - -> **Note:** Electron does not support arbitrary Chrome extensions from the -> store, and it is a **non-goal** of the Electron project to be perfectly -> compatible with Chrome's implementation of Extensions. - -## Loading extensions - -Electron only supports loading unpacked extensions (i.e., `.crx` files do not -work). Extensions are installed per-`session`. To load an extension, call -[`ses.loadExtension`](session.md#sesloadextensionpath): - -```js -const { session } = require('electron') - -session.loadExtension('path/to/unpacked/extension').then(({ id }) => { - // ... -}) -``` - -Loaded extensions will not be automatically remembered across exits; if you do -not call `loadExtension` when the app runs, the extension will not be loaded. - -Note that loading extensions is only supported in persistent sessions. -Attempting to load an extension into an in-memory session will throw an error. - -See the [`session`](session.md) documentation for more information about -loading, unloading, and querying active extensions. - -## Supported Extensions APIs - -We support the following extensions APIs, with some caveats. Other APIs may -additionally be supported, but support for any APIs not listed here is -provisional and may be removed. - -### `chrome.devtools.inspectedWindow` - -All features of this API are supported. - -### `chrome.devtools.network` - -All features of this API are supported. - -### `chrome.devtools.panels` - -All features of this API are supported. - -### `chrome.extension` - -The following properties of `chrome.extension` are supported: - -- `chrome.extension.lastError` - -The following methods of `chrome.extension` are supported: - -- `chrome.extension.getURL` -- `chrome.extension.getBackgroundPage` - -### `chrome.runtime` - -The following properties of `chrome.runtime` are supported: - -- `chrome.runtime.lastError` -- `chrome.runtime.id` - -The following methods of `chrome.runtime` are supported: - -- `chrome.runtime.getBackgroundPage` -- `chrome.runtime.getManifest` -- `chrome.runtime.getURL` -- `chrome.runtime.connect` -- `chrome.runtime.sendMessage` - -The following events of `chrome.runtime` are supported: - -- `chrome.runtime.onStartup` -- `chrome.runtime.onInstalled` -- `chrome.runtime.onSuspend` -- `chrome.runtime.onSuspendCanceled` -- `chrome.runtime.onConnect` -- `chrome.runtime.onMessage` - -### `chrome.storage` - -Only `chrome.storage.local` is supported; `chrome.storage.sync` and -`chrome.storage.managed` are not. - -### `chrome.tabs` - -The following methods of `chrome.tabs` are supported: - -- `chrome.tabs.sendMessage` -- `chrome.tabs.executeScript` - -> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active -> tab". Since Electron has no such concept, passing `-1` as a tab ID is not -> supported and will raise an error. - -### `chrome.management` - -The following methods of `chrome.management` are supported: - -- `chrome.management.getAll` -- `chrome.management.get` -- `chrome.management.getSelf` -- `chrome.management.getPermissionWarningsById` -- `chrome.management.getPermissionWarningsByManifest` -- `chrome.management.onEnabled` -- `chrome.management.onDisabled` +# Chrome Extension Support + +Electron supports a subset of the [Chrome Extensions +API][chrome-extensions-api-index], primarily to support DevTools extensions and +Chromium-internal extensions, but it also happens to support some other +extension capabilities. + +[chrome-extensions-api-index]: https://developer.chrome.com/extensions/api_index + +> **Note:** Electron does not support arbitrary Chrome extensions from the +> store, and it is a **non-goal** of the Electron project to be perfectly +> compatible with Chrome's implementation of Extensions. + +## Loading extensions + +Electron only supports loading unpacked extensions (i.e., `.crx` files do not +work). Extensions are installed per-`session`. To load an extension, call +[`ses.loadExtension`](session.md#sesloadextensionpath): + +```js +const { session } = require('electron') + +session.loadExtension('path/to/unpacked/extension').then(({ id }) => { + // ... +}) +``` + +Loaded extensions will not be automatically remembered across exits; if you do +not call `loadExtension` when the app runs, the extension will not be loaded. + +Note that loading extensions is only supported in persistent sessions. +Attempting to load an extension into an in-memory session will throw an error. + +See the [`session`](session.md) documentation for more information about +loading, unloading, and querying active extensions. + +## Supported Extensions APIs + +We support the following extensions APIs, with some caveats. Other APIs may +additionally be supported, but support for any APIs not listed here is +provisional and may be removed. + +### `chrome.devtools.inspectedWindow` + +All features of this API are supported. + +### `chrome.devtools.network` + +All features of this API are supported. + +### `chrome.devtools.panels` + +All features of this API are supported. + +### `chrome.extension` + +The following properties of `chrome.extension` are supported: + +- `chrome.extension.lastError` + +The following methods of `chrome.extension` are supported: + +- `chrome.extension.getURL` +- `chrome.extension.getBackgroundPage` + +### `chrome.runtime` + +The following properties of `chrome.runtime` are supported: + +- `chrome.runtime.lastError` +- `chrome.runtime.id` + +The following methods of `chrome.runtime` are supported: + +- `chrome.runtime.getBackgroundPage` +- `chrome.runtime.getManifest` +- `chrome.runtime.getURL` +- `chrome.runtime.connect` +- `chrome.runtime.sendMessage` + +The following events of `chrome.runtime` are supported: + +- `chrome.runtime.onStartup` +- `chrome.runtime.onInstalled` +- `chrome.runtime.onSuspend` +- `chrome.runtime.onSuspendCanceled` +- `chrome.runtime.onConnect` +- `chrome.runtime.onMessage` + +### `chrome.storage` + +Only `chrome.storage.local` is supported; `chrome.storage.sync` and +`chrome.storage.managed` are not. + +### `chrome.tabs` + +The following methods of `chrome.tabs` are supported: + +- `chrome.tabs.sendMessage` +- `chrome.tabs.executeScript` + +> **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active +> tab". Since Electron has no such concept, passing `-1` as a tab ID is not +> supported and will raise an error. + +### `chrome.management` + +The following methods of `chrome.management` are supported: + +- `chrome.management.getAll` +- `chrome.management.get` +- `chrome.management.getSelf` +- `chrome.management.getPermissionWarningsById` +- `chrome.management.getPermissionWarningsByManifest` +- `chrome.management.onEnabled` +- `chrome.management.onDisabled`