mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
feat: ses.enableExtension and ses.disableExtension
This commit is contained in:
@@ -1541,6 +1541,25 @@ Unloads an extension.
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
|
||||
#### `ses.enableExtension(extensionId)`
|
||||
|
||||
* `extensionId` string - ID of extension to enable
|
||||
|
||||
Enables the extension and activates it for use by starting any background
|
||||
workers. If the extension is disabled, marks it as enabled.
|
||||
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
|
||||
#### `ses.disableExtension(extensionId)`
|
||||
|
||||
* `extensionId` string - ID of extension to disable
|
||||
|
||||
Disables the extension and deactives it.
|
||||
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
|
||||
#### `ses.getExtension(extensionId)`
|
||||
|
||||
* `extensionId` string - ID of extension to query
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "shell/browser/extensions/electron_extension_info.h"
|
||||
#include "shell/browser/extensions/electron_extension_system.h"
|
||||
#include "shell/common/gin_converters/extension_converter.h"
|
||||
#endif
|
||||
@@ -1309,7 +1310,8 @@ v8::Local<v8::Promise> Session::GetSharedDictionaryUsageInfo() {
|
||||
v8::Local<v8::Promise> Session::LoadExtension(
|
||||
const base::FilePath& extension_path,
|
||||
gin::Arguments* args) {
|
||||
gin_helper::Promise<const extensions::Extension*> promise(isolate_);
|
||||
gin_helper::Promise<const extensions::ElectronExtensionInfo&> promise(
|
||||
isolate_);
|
||||
v8::Local<v8::Promise> handle = promise.GetHandle();
|
||||
|
||||
if (!extension_path.IsAbsolute()) {
|
||||
@@ -1338,27 +1340,37 @@ v8::Local<v8::Promise> Session::LoadExtension(
|
||||
extension_system->LoadExtension(
|
||||
extension_path, load_flags,
|
||||
base::BindOnce(
|
||||
[](gin_helper::Promise<const extensions::Extension*> promise,
|
||||
[](gin_helper::Promise<const extensions::ElectronExtensionInfo&>
|
||||
promise,
|
||||
base::WeakPtr<ElectronBrowserContext> browser_context,
|
||||
const extensions::Extension* extension,
|
||||
const std::string& error_msg) {
|
||||
if (extension) {
|
||||
if (extension && browser_context) {
|
||||
if (!error_msg.empty())
|
||||
util::EmitWarning(promise.isolate(), error_msg,
|
||||
"ExtensionLoadWarning");
|
||||
promise.Resolve(extension);
|
||||
const auto& extension_info = extensions::ElectronExtensionInfo(
|
||||
extension, browser_context.get());
|
||||
promise.Resolve(extension_info);
|
||||
} else {
|
||||
promise.RejectWithErrorMessage(error_msg);
|
||||
}
|
||||
},
|
||||
std::move(promise)));
|
||||
std::move(promise), browser_context()->GetWeakPtr()));
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Session::RemoveExtension(const std::string& extension_id) {
|
||||
auto* extension_system = static_cast<extensions::ElectronExtensionSystem*>(
|
||||
extensions::ExtensionSystem::Get(browser_context()));
|
||||
extension_system->RemoveExtension(extension_id);
|
||||
browser_context()->extension_system()->RemoveExtension(extension_id);
|
||||
}
|
||||
|
||||
void Session::EnableExtension(const std::string& extension_id) {
|
||||
browser_context()->extension_system()->EnableExtension(extension_id);
|
||||
}
|
||||
|
||||
void Session::DisableExtension(const std::string& extension_id) {
|
||||
browser_context()->extension_system()->DisableExtension(extension_id);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::GetExtension(const std::string& extension_id) {
|
||||
@@ -1366,7 +1378,9 @@ v8::Local<v8::Value> Session::GetExtension(const std::string& extension_id) {
|
||||
const extensions::Extension* extension =
|
||||
registry->GetInstalledExtension(extension_id);
|
||||
if (extension) {
|
||||
return gin::ConvertToV8(isolate_, extension);
|
||||
const auto& extension_info =
|
||||
extensions::ElectronExtensionInfo(extension, browser_context());
|
||||
return gin::ConvertToV8(isolate_, extension_info);
|
||||
} else {
|
||||
return v8::Null(isolate_);
|
||||
}
|
||||
@@ -1376,29 +1390,40 @@ v8::Local<v8::Value> Session::GetAllExtensions() {
|
||||
auto* registry = extensions::ExtensionRegistry::Get(browser_context());
|
||||
const extensions::ExtensionSet extensions =
|
||||
registry->GenerateInstalledExtensionsSet();
|
||||
std::vector<const extensions::Extension*> extensions_vector;
|
||||
std::vector<extensions::ElectronExtensionInfo> extensions_vector;
|
||||
for (const auto& extension : extensions) {
|
||||
if (extension->location() !=
|
||||
extensions::mojom::ManifestLocation::kComponent)
|
||||
extensions_vector.emplace_back(extension.get());
|
||||
extensions::mojom::ManifestLocation::kComponent) {
|
||||
const auto& extension_info =
|
||||
extensions::ElectronExtensionInfo(extension.get(), browser_context());
|
||||
extensions_vector.emplace_back(extension_info);
|
||||
}
|
||||
}
|
||||
return gin::ConvertToV8(isolate_, extensions_vector);
|
||||
}
|
||||
|
||||
void Session::OnExtensionLoaded(content::BrowserContext* browser_context,
|
||||
const extensions::Extension* extension) {
|
||||
Emit("extension-loaded", extension);
|
||||
void Session::OnExtensionLoaded(
|
||||
content::BrowserContext* content_browser_context,
|
||||
const extensions::Extension* extension) {
|
||||
const auto& extension_info =
|
||||
extensions::ElectronExtensionInfo(extension, browser_context());
|
||||
Emit("extension-loaded", extension_info);
|
||||
}
|
||||
|
||||
void Session::OnExtensionUnloaded(content::BrowserContext* browser_context,
|
||||
const extensions::Extension* extension,
|
||||
extensions::UnloadedExtensionReason reason) {
|
||||
Emit("extension-unloaded", extension);
|
||||
void Session::OnExtensionUnloaded(
|
||||
content::BrowserContext* content_browser_context,
|
||||
const extensions::Extension* extension,
|
||||
extensions::UnloadedExtensionReason reason) {
|
||||
const auto& extension_info =
|
||||
extensions::ElectronExtensionInfo(extension, browser_context());
|
||||
Emit("extension-unloaded", extension_info);
|
||||
}
|
||||
|
||||
void Session::OnExtensionReady(content::BrowserContext* browser_context,
|
||||
void Session::OnExtensionReady(content::BrowserContext* content_browser_context,
|
||||
const extensions::Extension* extension) {
|
||||
Emit("extension-ready", extension);
|
||||
const auto& extension_info =
|
||||
extensions::ElectronExtensionInfo(extension, browser_context());
|
||||
Emit("extension-ready", extension_info);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1875,6 +1900,8 @@ void Session::FillObjectTemplate(v8::Isolate* isolate,
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
.SetMethod("loadExtension", &Session::LoadExtension)
|
||||
.SetMethod("removeExtension", &Session::RemoveExtension)
|
||||
.SetMethod("enableExtension", &Session::EnableExtension)
|
||||
.SetMethod("disableExtension", &Session::DisableExtension)
|
||||
.SetMethod("getExtension", &Session::GetExtension)
|
||||
.SetMethod("getAllExtensions", &Session::GetAllExtensions)
|
||||
#endif
|
||||
|
||||
@@ -182,6 +182,8 @@ class Session final : public gin::Wrappable<Session>,
|
||||
v8::Local<v8::Promise> LoadExtension(const base::FilePath& extension_path,
|
||||
gin::Arguments* args);
|
||||
void RemoveExtension(const std::string& extension_id);
|
||||
void EnableExtension(const std::string& extension_id);
|
||||
void DisableExtension(const std::string& extension_id);
|
||||
v8::Local<v8::Value> GetExtension(const std::string& extension_id);
|
||||
v8::Local<v8::Value> GetAllExtensions();
|
||||
|
||||
|
||||
@@ -155,10 +155,7 @@ class ElectronBrowserContext : public content::BrowserContext {
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
extensions::ElectronExtensionSystem* extension_system() {
|
||||
// Guard usages of extension_system() with !IsOffTheRecord()
|
||||
// There is no extension system for in-memory sessions
|
||||
DCHECK(!IsOffTheRecord());
|
||||
extensions::ElectronExtensionSystem* extension_system() const {
|
||||
return extension_system_;
|
||||
}
|
||||
#endif
|
||||
|
||||
33
shell/browser/extensions/electron_extension_info.h
Normal file
33
shell/browser/extensions/electron_extension_info.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2018 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 ELECTRON_SHELL_BROWSER_EXTENSIONS_ELECTRON_EXTENSION_INFO_H_
|
||||
#define ELECTRON_SHELL_BROWSER_EXTENSIONS_ELECTRON_EXTENSION_INFO_H_
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
|
||||
namespace electron {
|
||||
class ElectronBrowserContext;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class Extension;
|
||||
|
||||
struct ElectronExtensionInfo {
|
||||
explicit ElectronExtensionInfo(
|
||||
const Extension* extension_in,
|
||||
const electron::ElectronBrowserContext* browser_context_in)
|
||||
: extension(extension_in), browser_context(browser_context_in) {
|
||||
DCHECK(extension_in);
|
||||
DCHECK(browser_context_in);
|
||||
}
|
||||
|
||||
raw_ptr<const Extension> extension;
|
||||
raw_ptr<const electron::ElectronBrowserContext> browser_context;
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_EXTENSIONS_ELECTRON_EXTENSION_INFO_H_
|
||||
@@ -81,6 +81,22 @@ void ElectronExtensionSystem::RemoveExtension(const ExtensionId& extension_id) {
|
||||
extension_id, extensions::UnloadedExtensionReason::UNINSTALL);
|
||||
}
|
||||
|
||||
void ElectronExtensionSystem::EnableExtension(const std::string& extension_id) {
|
||||
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
||||
extension_registrar_->EnableExtension(extension_id);
|
||||
}
|
||||
|
||||
void ElectronExtensionSystem::DisableExtension(
|
||||
const ExtensionId& extension_id) {
|
||||
extension_registrar_->DisableExtension(
|
||||
extension_id, disable_reason::DisableReason::DISABLE_USER_ACTION);
|
||||
}
|
||||
|
||||
bool ElectronExtensionSystem::IsExtensionEnabled(
|
||||
const ExtensionId& extension_id) const {
|
||||
return extension_registrar_->IsExtensionEnabled(extension_id);
|
||||
}
|
||||
|
||||
void ElectronExtensionSystem::Shutdown() {
|
||||
extension_loader_.reset();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "base/one_shot_event.h"
|
||||
#include "components/value_store/value_store_factory.h"
|
||||
#include "components/value_store/value_store_factory_impl.h"
|
||||
#include "extensions/browser/disable_reason.h"
|
||||
#include "extensions/browser/extension_registrar.h"
|
||||
#include "extensions/browser/extension_system.h"
|
||||
|
||||
@@ -61,6 +62,17 @@ class ElectronExtensionSystem : public ExtensionSystem {
|
||||
|
||||
void RemoveExtension(const ExtensionId& extension_id);
|
||||
|
||||
// Enables the extension. If the extension is already enabled, does
|
||||
// nothing.
|
||||
void EnableExtension(const ExtensionId& extension_id);
|
||||
|
||||
// Disables the extension. If the extension is already disabled, just adds
|
||||
// the incoming disable reason(s). If the extension cannot be disabled (due to
|
||||
// policy), does nothing.
|
||||
void DisableExtension(const ExtensionId& extension_id);
|
||||
|
||||
bool IsExtensionEnabled(const ExtensionId& extension_id) const;
|
||||
|
||||
// KeyedService implementation:
|
||||
void Shutdown() override;
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
#include "extensions/common/extension.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
#include "shell/browser/extensions/electron_extension_info.h"
|
||||
#include "shell/browser/extensions/electron_extension_system.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
@@ -13,16 +16,20 @@
|
||||
namespace gin {
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<const extensions::Extension*>::ToV8(
|
||||
v8::Local<v8::Value> Converter<extensions::ElectronExtensionInfo>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const extensions::Extension* extension) {
|
||||
const extensions::ElectronExtensionInfo& info) {
|
||||
auto extension_id = info.extension->id();
|
||||
auto dict = gin::Dictionary::CreateEmpty(isolate);
|
||||
dict.Set("id", extension->id());
|
||||
dict.Set("name", extension->name());
|
||||
dict.Set("path", extension->path());
|
||||
dict.Set("url", extension->url());
|
||||
dict.Set("version", extension->VersionString());
|
||||
dict.Set("manifest", *extension->manifest()->value());
|
||||
dict.Set("id", extension_id);
|
||||
dict.Set("name", info.extension->name());
|
||||
dict.Set("path", info.extension->path());
|
||||
dict.Set("url", info.extension->url());
|
||||
dict.Set("version", info.extension->VersionString());
|
||||
dict.Set("manifest", *info.extension->manifest()->value());
|
||||
|
||||
auto* ext_system = info.browser_context->extension_system();
|
||||
dict.Set("enabled", ext_system->IsExtensionEnabled(extension_id));
|
||||
|
||||
return gin::ConvertToV8(isolate, dict);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019 Slack Technologies, Inc.
|
||||
// Copyright (c) 2025 Salesforce, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@@ -8,15 +8,16 @@
|
||||
#include "gin/converter.h"
|
||||
|
||||
namespace extensions {
|
||||
class Extension;
|
||||
struct ElectronExtensionInfo;
|
||||
}
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <>
|
||||
struct Converter<const extensions::Extension*> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const extensions::Extension* val);
|
||||
struct Converter<extensions::ElectronExtensionInfo> {
|
||||
static v8::Local<v8::Value> ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const extensions::ElectronExtensionInfo& val);
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
|
||||
Reference in New Issue
Block a user