feat: preliminary support for //extensions (#17440)
This commit is contained in:
Родитель
bd526f97a5
Коммит
95977291f7
14
BUILD.gn
14
BUILD.gn
|
@ -627,6 +627,20 @@ source_set("electron_lib") {
|
|||
if (enable_pepper_flash) {
|
||||
deps += [ "components/pepper_flash" ]
|
||||
}
|
||||
|
||||
public_deps += [ "shell/common/extensions/api:extensions_features" ]
|
||||
deps += [
|
||||
"//components/pref_registry",
|
||||
"//components/user_prefs",
|
||||
"//extensions/browser",
|
||||
"//extensions/browser:core_api_provider",
|
||||
"//extensions/common",
|
||||
"//extensions/common:core_api_provider",
|
||||
"//extensions/renderer",
|
||||
]
|
||||
if (enable_electron_extensions) {
|
||||
sources += filenames.lib_sources_extensions
|
||||
}
|
||||
}
|
||||
|
||||
electron_paks("packed_resources") {
|
||||
|
|
|
@ -17,6 +17,7 @@ buildflag_header("buildflags") {
|
|||
"ENABLE_PDF_VIEWER=$enable_pdf_viewer",
|
||||
"ENABLE_TTS=$enable_tts",
|
||||
"ENABLE_COLOR_CHOOSER=$enable_color_chooser",
|
||||
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
|
||||
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -26,4 +26,7 @@ declare_args() {
|
|||
|
||||
# Enable flash plugin support.
|
||||
enable_pepper_flash = true
|
||||
|
||||
# Enable Chrome extensions support.
|
||||
enable_electron_extensions = false
|
||||
}
|
||||
|
|
|
@ -604,6 +604,35 @@ filenames = {
|
|||
"chromium_src/chrome/browser/certificate_manager_model.h",
|
||||
]
|
||||
|
||||
lib_sources_extensions = [
|
||||
"shell/browser/extensions/api/runtime/atom_runtime_api_delegate.cc",
|
||||
"shell/browser/extensions/api/runtime/atom_runtime_api_delegate.h",
|
||||
"shell/browser/extensions/atom_extensions_browser_client.cc",
|
||||
"shell/browser/extensions/atom_extensions_browser_client.h",
|
||||
"shell/browser/extensions/atom_browser_context_keyed_service_factories.cc",
|
||||
"shell/browser/extensions/atom_browser_context_keyed_service_factories.h",
|
||||
"shell/browser/extensions/atom_display_info_provider.cc",
|
||||
"shell/browser/extensions/atom_display_info_provider.h",
|
||||
"shell/browser/extensions/atom_extension_host_delegate.cc",
|
||||
"shell/browser/extensions/atom_extension_host_delegate.h",
|
||||
"shell/browser/extensions/atom_extension_loader.cc",
|
||||
"shell/browser/extensions/atom_extension_loader.h",
|
||||
"shell/browser/extensions/atom_extension_system.cc",
|
||||
"shell/browser/extensions/atom_extension_system.h",
|
||||
"shell/browser/extensions/atom_extension_system_factory.cc",
|
||||
"shell/browser/extensions/atom_extension_system_factory.h",
|
||||
"shell/browser/extensions/atom_extension_web_contents_observer.cc",
|
||||
"shell/browser/extensions/atom_extension_web_contents_observer.h",
|
||||
"shell/browser/extensions/atom_navigation_ui_data.cc",
|
||||
"shell/browser/extensions/atom_navigation_ui_data.h",
|
||||
"shell/common/extensions/atom_extensions_api_provider.cc",
|
||||
"shell/common/extensions/atom_extensions_api_provider.h",
|
||||
"shell/common/extensions/atom_extensions_client.cc",
|
||||
"shell/common/extensions/atom_extensions_client.h",
|
||||
"shell/renderer/extensions/atom_extensions_renderer_client.cc",
|
||||
"shell/renderer/extensions/atom_extensions_renderer_client.h",
|
||||
]
|
||||
|
||||
app_sources = [
|
||||
"shell/app/atom_main.cc",
|
||||
"shell/app/atom_main.h",
|
||||
|
|
|
@ -67,6 +67,10 @@
|
|||
#include "shell/common/options_switches.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "shell/browser/extensions/atom_extension_system.h"
|
||||
#endif
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::StoragePartition;
|
||||
|
||||
|
@ -638,6 +642,14 @@ std::vector<base::FilePath::StringType> Session::GetPreloads() const {
|
|||
return prefs->preloads();
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
void Session::LoadChromeExtension(const base::FilePath extension_path) {
|
||||
auto* extension_system = static_cast<extensions::AtomExtensionSystem*>(
|
||||
extensions::ExtensionSystem::Get(browser_context()));
|
||||
extension_system->LoadExtension(extension_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = Cookies::Create(isolate, browser_context());
|
||||
|
@ -745,6 +757,9 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
|||
&Session::CreateInterruptedDownload)
|
||||
.SetMethod("setPreloads", &Session::SetPreloads)
|
||||
.SetMethod("getPreloads", &Session::GetPreloads)
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
.SetMethod("loadChromeExtension", &Session::LoadChromeExtension)
|
||||
#endif
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
.SetProperty("netLog", &Session::NetLog)
|
||||
.SetProperty("protocol", &Session::Protocol)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "shell/browser/api/trackable_object.h"
|
||||
#include "shell/browser/atom_blob_reader.h"
|
||||
|
@ -86,6 +87,10 @@ class Session : public mate::TrackableObject<Session>,
|
|||
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> NetLog(v8::Isolate* isolate);
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
void LoadChromeExtension(const base::FilePath extension_path);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Session() override;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/context_menu_params.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "electron/shell/common/api/api.mojom.h"
|
||||
#include "mojo/public/cpp/system/platform_handle.h"
|
||||
#include "native_mate/converter.h"
|
||||
|
@ -112,6 +113,10 @@
|
|||
#include "components/printing/common/print_messages.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "shell/browser/extensions/atom_extension_web_contents_observer.h"
|
||||
#endif
|
||||
|
||||
namespace mate {
|
||||
|
||||
#if BUILDFLAG(ENABLE_PRINTING)
|
||||
|
@ -456,12 +461,13 @@ void WebContents::InitWithSessionAndOptions(
|
|||
// Save the preferences in C++.
|
||||
new WebContentsPreferences(web_contents(), options);
|
||||
|
||||
// Initialize permission helper.
|
||||
WebContentsPermissionHelper::CreateForWebContents(web_contents());
|
||||
// Initialize security state client.
|
||||
SecurityStateTabHelper::CreateForWebContents(web_contents());
|
||||
// Initialize zoom controller.
|
||||
InitZoomController(web_contents(), options);
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
extensions::AtomExtensionWebContentsObserver::CreateForWebContents(
|
||||
web_contents());
|
||||
#endif
|
||||
|
||||
registry_.AddInterface(base::BindRepeating(&WebContents::BindElectronBrowser,
|
||||
base::Unretained(this)));
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "base/threading/sequenced_task_runner_handle.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
|
@ -43,6 +44,22 @@
|
|||
#include "shell/common/application_info.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "components/pref_registry/pref_registry_syncable.h"
|
||||
#include "components/user_prefs/user_prefs.h"
|
||||
#include "extensions/browser/browser_context_keyed_service_factories.h"
|
||||
#include "extensions/browser/extension_pref_store.h"
|
||||
#include "extensions/browser/extension_pref_value_map_factory.h"
|
||||
#include "extensions/browser/extension_prefs.h"
|
||||
#include "extensions/browser/pref_names.h"
|
||||
#include "extensions/common/extension_api.h"
|
||||
#include "shell/browser/extensions/atom_browser_context_keyed_service_factories.h"
|
||||
#include "shell/browser/extensions/atom_extension_system.h"
|
||||
#include "shell/browser/extensions/atom_extension_system_factory.h"
|
||||
#include "shell/browser/extensions/atom_extensions_browser_client.h"
|
||||
#include "shell/common/extensions/atom_extensions_client.h"
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace electron {
|
||||
|
@ -91,6 +108,8 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
|||
|
||||
content::BrowserContext::Initialize(this, path_);
|
||||
|
||||
BrowserContextDependencyManager::GetInstance()->MarkBrowserContextLive(this);
|
||||
|
||||
// Initialize Pref Registry.
|
||||
InitPrefs();
|
||||
|
||||
|
@ -102,7 +121,15 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
|||
|
||||
cookie_change_notifier_ = std::make_unique<CookieChangeNotifier>(this);
|
||||
|
||||
BrowserContextDependencyManager::GetInstance()->MarkBrowserContextLive(this);
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
|
||||
this);
|
||||
|
||||
extension_system_ = static_cast<extensions::AtomExtensionSystem*>(
|
||||
extensions::ExtensionSystem::Get(this));
|
||||
extension_system_->InitForRegularProfile(true /* extensions_enabled */);
|
||||
extension_system_->FinishInitialization();
|
||||
#endif
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
|
@ -131,7 +158,16 @@ void AtomBrowserContext::InitPrefs() {
|
|||
pref_store->ReadPrefs(); // Synchronous.
|
||||
prefs_factory.set_user_prefs(pref_store);
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto* ext_pref_store = new ExtensionPrefStore(
|
||||
ExtensionPrefValueMapFactory::GetForBrowserContext(this),
|
||||
IsOffTheRecord());
|
||||
prefs_factory.set_extension_prefs(ext_pref_store);
|
||||
|
||||
auto registry = WrapRefCounted(new user_prefs::PrefRegistrySyncable);
|
||||
#else
|
||||
auto registry = WrapRefCounted(new PrefRegistrySimple);
|
||||
#endif
|
||||
|
||||
registry->RegisterFilePathPref(prefs::kSelectFileLastDirectory,
|
||||
base::FilePath());
|
||||
|
@ -144,11 +180,17 @@ void AtomBrowserContext::InitPrefs() {
|
|||
MediaDeviceIDSalt::RegisterPrefs(registry.get());
|
||||
ZoomLevelDelegate::RegisterPrefs(registry.get());
|
||||
PrefProxyConfigTrackerImpl::RegisterPrefs(registry.get());
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
extensions::ExtensionPrefs::RegisterProfilePrefs(registry.get());
|
||||
#endif
|
||||
|
||||
prefs_ = prefs_factory.Create(
|
||||
registry.get(),
|
||||
std::make_unique<PrefStoreDelegate>(weak_factory_.GetWeakPtr()));
|
||||
prefs_->UpdateCommandLinePrefStore(new ValueMapPrefStore);
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
user_prefs::UserPrefs::Set(this, prefs_.get());
|
||||
#endif
|
||||
}
|
||||
|
||||
void AtomBrowserContext::SetUserAgent(const std::string& user_agent) {
|
||||
|
@ -305,6 +347,16 @@ AtomBrowserContext::GetClientHintsControllerDelegate() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void AtomBrowserContext::SetCorsOriginAccessListForOrigin(
|
||||
const url::Origin& source_origin,
|
||||
std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
|
||||
std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
|
||||
base::OnceClosure closure) {
|
||||
// TODO(nornagon): actually set the CORS access lists. This is called from
|
||||
// extensions/browser/renderer_startup_helper.cc.
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(closure));
|
||||
}
|
||||
|
||||
ResolveProxyHelper* AtomBrowserContext::GetResolveProxyHelper() {
|
||||
if (!resolve_proxy_helper_) {
|
||||
resolve_proxy_helper_ = base::MakeRefCounted<ResolveProxyHelper>(this);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "chrome/browser/net/proxy_config_monitor.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/resource_context.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "shell/browser/media/media_device_id_salt.h"
|
||||
#include "shell/browser/net/url_request_context_getter.h"
|
||||
|
||||
|
@ -26,6 +27,12 @@ namespace storage {
|
|||
class SpecialStoragePolicy;
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
namespace extensions {
|
||||
class AtomExtensionSystem;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
||||
class AtomBlobReader;
|
||||
|
@ -41,6 +48,27 @@ class AtomBrowserContext
|
|||
: public base::RefCountedDeleteOnSequence<AtomBrowserContext>,
|
||||
public content::BrowserContext {
|
||||
public:
|
||||
// partition_id => browser_context
|
||||
struct PartitionKey {
|
||||
std::string partition;
|
||||
bool in_memory;
|
||||
|
||||
PartitionKey(const std::string& partition, bool in_memory)
|
||||
: partition(partition), in_memory(in_memory) {}
|
||||
|
||||
bool operator<(const PartitionKey& other) const {
|
||||
if (partition == other.partition)
|
||||
return in_memory < other.in_memory;
|
||||
return partition < other.partition;
|
||||
}
|
||||
|
||||
bool operator==(const PartitionKey& other) const {
|
||||
return (partition == other.partition) && (in_memory == other.in_memory);
|
||||
}
|
||||
};
|
||||
using BrowserContextMap =
|
||||
std::map<PartitionKey, base::WeakPtr<AtomBrowserContext>>;
|
||||
|
||||
// Get or create the BrowserContext according to its |partition| and
|
||||
// |in_memory|. The |options| will be passed to constructor when there is no
|
||||
// existing BrowserContext.
|
||||
|
@ -49,6 +77,10 @@ class AtomBrowserContext
|
|||
bool in_memory,
|
||||
const base::DictionaryValue& options = base::DictionaryValue());
|
||||
|
||||
static BrowserContextMap browser_context_map() {
|
||||
return browser_context_map_;
|
||||
}
|
||||
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
std::string GetUserAgent() const;
|
||||
bool CanUseHttpCache() const;
|
||||
|
@ -84,6 +116,13 @@ class AtomBrowserContext
|
|||
content::ClientHintsControllerDelegate* GetClientHintsControllerDelegate()
|
||||
override;
|
||||
|
||||
// extensions deps
|
||||
void SetCorsOriginAccessListForOrigin(
|
||||
const url::Origin& source_origin,
|
||||
std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
|
||||
std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
|
||||
base::OnceClosure closure) override;
|
||||
|
||||
CookieChangeNotifier* cookie_change_notifier() const {
|
||||
return cookie_change_notifier_.get();
|
||||
}
|
||||
|
@ -114,26 +153,6 @@ class AtomBrowserContext
|
|||
// Initialize pref registry.
|
||||
void InitPrefs();
|
||||
|
||||
// partition_id => browser_context
|
||||
struct PartitionKey {
|
||||
std::string partition;
|
||||
bool in_memory;
|
||||
|
||||
PartitionKey(const std::string& partition, bool in_memory)
|
||||
: partition(partition), in_memory(in_memory) {}
|
||||
|
||||
bool operator<(const PartitionKey& other) const {
|
||||
if (partition == other.partition)
|
||||
return in_memory < other.in_memory;
|
||||
return partition < other.partition;
|
||||
}
|
||||
|
||||
bool operator==(const PartitionKey& other) const {
|
||||
return (partition == other.partition) && (in_memory == other.in_memory);
|
||||
}
|
||||
};
|
||||
using BrowserContextMap =
|
||||
std::map<PartitionKey, base::WeakPtr<AtomBrowserContext>>;
|
||||
static BrowserContextMap browser_context_map_;
|
||||
|
||||
// Self-destructing class responsible for creating URLRequestContextGetter
|
||||
|
@ -162,6 +181,11 @@ class AtomBrowserContext
|
|||
bool use_cache_ = true;
|
||||
int max_cache_size_ = 0;
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
// Owned by the KeyedService system.
|
||||
extensions::AtomExtensionSystem* extension_system_;
|
||||
#endif
|
||||
|
||||
base::WeakPtrFactory<AtomBrowserContext> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||
|
|
|
@ -92,6 +92,15 @@
|
|||
#include "device/bluetooth/dbus/dbus_bluez_manager_wrapper_linux.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
||||
#include "extensions/browser/browser_context_keyed_service_factories.h"
|
||||
#include "extensions/common/extension_api.h"
|
||||
#include "shell/browser/extensions/atom_browser_context_keyed_service_factories.h"
|
||||
#include "shell/browser/extensions/atom_extensions_browser_client.h"
|
||||
#include "shell/common/extensions/atom_extensions_client.h"
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
@ -375,6 +384,10 @@ int AtomBrowserMainParts::PreCreateThreads() {
|
|||
}
|
||||
|
||||
void AtomBrowserMainParts::PostDestroyThreads() {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
extensions_browser_client_.reset();
|
||||
extensions::ExtensionsBrowserClient::Set(nullptr);
|
||||
#endif
|
||||
#if defined(OS_LINUX)
|
||||
device::BluetoothAdapterFactory::Shutdown();
|
||||
bluez::DBusBluezManagerWrapperLinux::Shutdown();
|
||||
|
@ -415,6 +428,18 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
|||
node_bindings_->PrepareMessageLoop();
|
||||
node_bindings_->RunMessageLoop();
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
extensions_client_ = std::make_unique<AtomExtensionsClient>();
|
||||
extensions::ExtensionsClient::Set(extensions_client_.get());
|
||||
|
||||
// BrowserContextKeyedAPIServiceFactories require an ExtensionsBrowserClient.
|
||||
extensions_browser_client_ = std::make_unique<AtomExtensionsBrowserClient>();
|
||||
extensions::ExtensionsBrowserClient::Set(extensions_browser_client_.get());
|
||||
|
||||
extensions::EnsureBrowserContextKeyedServiceFactoriesBuilt();
|
||||
extensions::electron::EnsureBrowserContextKeyedServiceFactoriesBuilt();
|
||||
#endif
|
||||
|
||||
// url::Add*Scheme are not threadsafe, this helps prevent data races.
|
||||
url::LockSchemeRegistries();
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_main_parts.h"
|
||||
#include "content/public/common/main_function_params.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "services/device/public/mojom/geolocation_control.mojom.h"
|
||||
#include "ui/views/layout/layout_provider.h"
|
||||
|
||||
|
@ -29,14 +30,20 @@ class WMState;
|
|||
|
||||
namespace electron {
|
||||
|
||||
class ElectronBindings;
|
||||
class AtomBrowserContext;
|
||||
class Browser;
|
||||
class ElectronBindings;
|
||||
class JavascriptEnvironment;
|
||||
class NodeBindings;
|
||||
class NodeDebugger;
|
||||
class NodeEnvironment;
|
||||
class BridgeTaskRunner;
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
class AtomExtensionsClient;
|
||||
class AtomExtensionsBrowserClient;
|
||||
#endif
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
class ViewsDelegate;
|
||||
#endif
|
||||
|
@ -128,6 +135,11 @@ class AtomBrowserMainParts : public content::BrowserMainParts {
|
|||
std::unique_ptr<IconManager> icon_manager_;
|
||||
std::unique_ptr<base::FieldTrialList> field_trial_list_;
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
std::unique_ptr<AtomExtensionsClient> extensions_client_;
|
||||
std::unique_ptr<AtomExtensionsBrowserClient> extensions_browser_client_;
|
||||
#endif
|
||||
|
||||
base::RepeatingTimer gc_timer_;
|
||||
|
||||
// List of callbacks should be executed before destroying JS env.
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/browser/extensions/api/runtime/atom_runtime_api_delegate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "extensions/common/api/runtime.h"
|
||||
#include "shell/browser/extensions/atom_extension_system.h"
|
||||
|
||||
using extensions::api::runtime::PlatformInfo;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
AtomRuntimeAPIDelegate::AtomRuntimeAPIDelegate(
|
||||
content::BrowserContext* browser_context)
|
||||
: browser_context_(browser_context) {
|
||||
DCHECK(browser_context_);
|
||||
}
|
||||
|
||||
AtomRuntimeAPIDelegate::~AtomRuntimeAPIDelegate() = default;
|
||||
|
||||
void AtomRuntimeAPIDelegate::AddUpdateObserver(UpdateObserver* observer) {}
|
||||
|
||||
void AtomRuntimeAPIDelegate::RemoveUpdateObserver(UpdateObserver* observer) {}
|
||||
|
||||
void AtomRuntimeAPIDelegate::ReloadExtension(const std::string& extension_id) {
|
||||
static_cast<AtomExtensionSystem*>(ExtensionSystem::Get(browser_context_))
|
||||
->ReloadExtension(extension_id);
|
||||
}
|
||||
|
||||
bool AtomRuntimeAPIDelegate::CheckForUpdates(
|
||||
const std::string& extension_id,
|
||||
const UpdateCheckCallback& callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AtomRuntimeAPIDelegate::OpenURL(const GURL& uninstall_url) {}
|
||||
|
||||
bool AtomRuntimeAPIDelegate::GetPlatformInfo(PlatformInfo* info) {
|
||||
// TODO(nornagon): put useful information here.
|
||||
#if defined(OS_LINUX)
|
||||
info->os = api::runtime::PLATFORM_OS_LINUX;
|
||||
#endif
|
||||
return true;
|
||||
} // namespace extensions
|
||||
|
||||
bool AtomRuntimeAPIDelegate::RestartDevice(std::string* error_message) {
|
||||
*error_message = "Restart is not supported in Electron";
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,42 @@
|
|||
// 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_RUNTIME_ATOM_RUNTIME_API_DELEGATE_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_API_RUNTIME_ATOM_RUNTIME_API_DELEGATE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "extensions/browser/api/runtime/runtime_api_delegate.h"
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
} // namespace content
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class AtomRuntimeAPIDelegate : public RuntimeAPIDelegate {
|
||||
public:
|
||||
explicit AtomRuntimeAPIDelegate(content::BrowserContext* browser_context);
|
||||
~AtomRuntimeAPIDelegate() override;
|
||||
|
||||
// RuntimeAPIDelegate implementation.
|
||||
void AddUpdateObserver(UpdateObserver* observer) override;
|
||||
void RemoveUpdateObserver(UpdateObserver* observer) override;
|
||||
void ReloadExtension(const std::string& extension_id) override;
|
||||
bool CheckForUpdates(const std::string& extension_id,
|
||||
const UpdateCheckCallback& callback) override;
|
||||
void OpenURL(const GURL& uninstall_url) override;
|
||||
bool GetPlatformInfo(api::runtime::PlatformInfo* info) override;
|
||||
bool RestartDevice(std::string* error_message) override;
|
||||
|
||||
private:
|
||||
content::BrowserContext* browser_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomRuntimeAPIDelegate);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_API_RUNTIME_ATOM_RUNTIME_API_DELEGATE_H_
|
|
@ -0,0 +1,25 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/browser/extensions/atom_browser_context_keyed_service_factories.h"
|
||||
|
||||
#include "extensions/browser/updater/update_service_factory.h"
|
||||
// #include "extensions/shell/browser/api/identity/identity_api.h"
|
||||
#include "shell/browser/extensions/atom_extension_system_factory.h"
|
||||
|
||||
namespace extensions {
|
||||
namespace electron {
|
||||
|
||||
void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
|
||||
// IdentityAPI::GetFactoryInstance();
|
||||
|
||||
// TODO(rockot): Remove this once UpdateService is supported across all
|
||||
// extensions embedders (and namely chrome.)
|
||||
UpdateServiceFactory::GetInstance();
|
||||
|
||||
AtomExtensionSystemFactory::GetInstance();
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
} // namespace extensions
|
|
@ -0,0 +1,18 @@
|
|||
// 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_ATOM_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ATOM_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
|
||||
|
||||
namespace extensions {
|
||||
namespace electron {
|
||||
|
||||
// Ensures the existence of any BrowserContextKeyedServiceFactory provided by
|
||||
// the core extensions code.
|
||||
void EnsureBrowserContextKeyedServiceFactoriesBuilt();
|
||||
|
||||
} // namespace electron
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ATOM_BROWSER_CONTEXT_KEYED_SERVICE_FACTORIES_H_
|
|
@ -0,0 +1,11 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/browser/extensions/atom_display_info_provider.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
AtomDisplayInfoProvider::AtomDisplayInfoProvider() = default;
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,23 @@
|
|||
// 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_ATOM_DISPLAY_INFO_PROVIDER_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ATOM_DISPLAY_INFO_PROVIDER_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "extensions/browser/api/system_display/display_info_provider.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class AtomDisplayInfoProvider : public DisplayInfoProvider {
|
||||
public:
|
||||
AtomDisplayInfoProvider();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomDisplayInfoProvider);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ATOM_DISPLAY_INFO_PROVIDER_H_
|
|
@ -0,0 +1,88 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/browser/extensions/atom_extension_host_delegate.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/logging.h"
|
||||
#include "extensions/browser/media_capture_util.h"
|
||||
#include "extensions/browser/serial_extension_host_queue.h"
|
||||
#include "shell/browser/extensions/atom_extension_web_contents_observer.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
AtomExtensionHostDelegate::AtomExtensionHostDelegate() {}
|
||||
|
||||
AtomExtensionHostDelegate::~AtomExtensionHostDelegate() {}
|
||||
|
||||
void AtomExtensionHostDelegate::OnExtensionHostCreated(
|
||||
content::WebContents* web_contents) {
|
||||
AtomExtensionWebContentsObserver::CreateForWebContents(web_contents);
|
||||
}
|
||||
|
||||
void AtomExtensionHostDelegate::OnRenderViewCreatedForBackgroundPage(
|
||||
ExtensionHost* host) {}
|
||||
|
||||
content::JavaScriptDialogManager*
|
||||
AtomExtensionHostDelegate::GetJavaScriptDialogManager() {
|
||||
// TODO(jamescook): Create a JavaScriptDialogManager or reuse the one from
|
||||
// content_shell.
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AtomExtensionHostDelegate::CreateTab(
|
||||
std::unique_ptr<content::WebContents> web_contents,
|
||||
const std::string& extension_id,
|
||||
WindowOpenDisposition disposition,
|
||||
const gfx::Rect& initial_rect,
|
||||
bool user_gesture) {
|
||||
// TODO(jamescook): Should app_shell support opening popup windows?
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
void AtomExtensionHostDelegate::ProcessMediaAccessRequest(
|
||||
content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback,
|
||||
const Extension* extension) {
|
||||
// Allow access to the microphone and/or camera.
|
||||
media_capture_util::GrantMediaStreamRequest(web_contents, request,
|
||||
std::move(callback), extension);
|
||||
}
|
||||
|
||||
bool AtomExtensionHostDelegate::CheckMediaAccessPermission(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& security_origin,
|
||||
blink::mojom::MediaStreamType type,
|
||||
const Extension* extension) {
|
||||
media_capture_util::VerifyMediaAccessPermission(type, extension);
|
||||
return true;
|
||||
}
|
||||
|
||||
static base::LazyInstance<SerialExtensionHostQueue>::DestructorAtExit g_queue =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
ExtensionHostQueue* AtomExtensionHostDelegate::GetExtensionHostQueue() const {
|
||||
return g_queue.Pointer();
|
||||
}
|
||||
|
||||
content::PictureInPictureResult
|
||||
AtomExtensionHostDelegate::EnterPictureInPicture(
|
||||
content::WebContents* web_contents,
|
||||
const viz::SurfaceId& surface_id,
|
||||
const gfx::Size& natural_size) {
|
||||
NOTREACHED();
|
||||
return content::PictureInPictureResult();
|
||||
}
|
||||
|
||||
void AtomExtensionHostDelegate::ExitPictureInPicture() {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,52 @@
|
|||
// 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_ATOM_EXTENSION_HOST_DELEGATE_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_HOST_DELEGATE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "extensions/browser/extension_host_delegate.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// A minimal ExtensionHostDelegate.
|
||||
class AtomExtensionHostDelegate : public ExtensionHostDelegate {
|
||||
public:
|
||||
AtomExtensionHostDelegate();
|
||||
~AtomExtensionHostDelegate() override;
|
||||
|
||||
// ExtensionHostDelegate implementation.
|
||||
void OnExtensionHostCreated(content::WebContents* web_contents) override;
|
||||
void OnRenderViewCreatedForBackgroundPage(ExtensionHost* host) override;
|
||||
content::JavaScriptDialogManager* GetJavaScriptDialogManager() override;
|
||||
void CreateTab(std::unique_ptr<content::WebContents> web_contents,
|
||||
const std::string& extension_id,
|
||||
WindowOpenDisposition disposition,
|
||||
const gfx::Rect& initial_rect,
|
||||
bool user_gesture) override;
|
||||
void ProcessMediaAccessRequest(content::WebContents* web_contents,
|
||||
const content::MediaStreamRequest& request,
|
||||
content::MediaResponseCallback callback,
|
||||
const Extension* extension) override;
|
||||
bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& security_origin,
|
||||
blink::mojom::MediaStreamType type,
|
||||
const Extension* extension) override;
|
||||
ExtensionHostQueue* GetExtensionHostQueue() const override;
|
||||
content::PictureInPictureResult EnterPictureInPicture(
|
||||
content::WebContents* web_contents,
|
||||
const viz::SurfaceId& surface_id,
|
||||
const gfx::Size& natural_size) override;
|
||||
void ExitPictureInPicture() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomExtensionHostDelegate);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_HOST_DELEGATE_H_
|
|
@ -0,0 +1,158 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/browser/extensions/atom_extension_loader.h"
|
||||
|
||||
#include "base/auto_reset.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/sequenced_task_runner.h"
|
||||
#include "base/task_runner_util.h"
|
||||
#include "base/threading/thread_restrictions.h"
|
||||
#include "extensions/browser/extension_file_task_runner.h"
|
||||
#include "extensions/browser/extension_prefs.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/common/file_util.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
using LoadErrorBehavior = ExtensionRegistrar::LoadErrorBehavior;
|
||||
|
||||
namespace {
|
||||
|
||||
scoped_refptr<const Extension> LoadUnpacked(
|
||||
const base::FilePath& extension_dir) {
|
||||
// app_shell only supports unpacked extensions.
|
||||
// NOTE: If you add packed extension support consider removing the flag
|
||||
// FOLLOW_SYMLINKS_ANYWHERE below. Packed extensions should not have symlinks.
|
||||
if (!base::DirectoryExists(extension_dir)) {
|
||||
LOG(ERROR) << "Extension directory not found: "
|
||||
<< extension_dir.AsUTF8Unsafe();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int load_flags = Extension::FOLLOW_SYMLINKS_ANYWHERE;
|
||||
std::string load_error;
|
||||
scoped_refptr<Extension> extension = file_util::LoadExtension(
|
||||
extension_dir, Manifest::COMMAND_LINE, load_flags, &load_error);
|
||||
if (!extension.get()) {
|
||||
LOG(ERROR) << "Loading extension at " << extension_dir.value()
|
||||
<< " failed with: " << load_error;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Log warnings.
|
||||
if (extension->install_warnings().size()) {
|
||||
LOG(WARNING) << "Warnings loading extension at " << extension_dir.value()
|
||||
<< ":";
|
||||
for (const auto& warning : extension->install_warnings())
|
||||
LOG(WARNING) << warning.message;
|
||||
}
|
||||
|
||||
return extension;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomExtensionLoader::AtomExtensionLoader(
|
||||
content::BrowserContext* browser_context)
|
||||
: browser_context_(browser_context),
|
||||
extension_registrar_(browser_context, this),
|
||||
weak_factory_(this) {}
|
||||
|
||||
AtomExtensionLoader::~AtomExtensionLoader() = default;
|
||||
|
||||
const Extension* AtomExtensionLoader::LoadExtension(
|
||||
const base::FilePath& extension_dir) {
|
||||
// TODO(nornagon): load extensions asynchronously on
|
||||
// GetExtensionFileTaskRunner()
|
||||
base::ScopedAllowBlockingForTesting allow_blocking;
|
||||
scoped_refptr<const Extension> extension = LoadUnpacked(extension_dir);
|
||||
if (extension)
|
||||
extension_registrar_.AddExtension(extension);
|
||||
|
||||
return extension.get();
|
||||
}
|
||||
|
||||
void AtomExtensionLoader::ReloadExtension(ExtensionId extension_id) {
|
||||
const Extension* extension = ExtensionRegistry::Get(browser_context_)
|
||||
->GetInstalledExtension(extension_id);
|
||||
// We shouldn't be trying to reload extensions that haven't been added.
|
||||
DCHECK(extension);
|
||||
|
||||
// This should always start false since it's only set here, or in
|
||||
// LoadExtensionForReload() as a result of the call below.
|
||||
DCHECK_EQ(false, did_schedule_reload_);
|
||||
base::AutoReset<bool> reset_did_schedule_reload(&did_schedule_reload_, false);
|
||||
|
||||
extension_registrar_.ReloadExtension(extension_id, LoadErrorBehavior::kQuiet);
|
||||
if (did_schedule_reload_)
|
||||
return;
|
||||
}
|
||||
|
||||
void AtomExtensionLoader::FinishExtensionReload(
|
||||
const ExtensionId old_extension_id,
|
||||
scoped_refptr<const Extension> extension) {
|
||||
if (extension) {
|
||||
extension_registrar_.AddExtension(extension);
|
||||
}
|
||||
}
|
||||
|
||||
void AtomExtensionLoader::PreAddExtension(const Extension* extension,
|
||||
const Extension* old_extension) {
|
||||
if (old_extension)
|
||||
return;
|
||||
|
||||
// The extension might be disabled if a previous reload attempt failed. In
|
||||
// that case, we want to remove that disable reason.
|
||||
ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser_context_);
|
||||
if (extension_prefs->IsExtensionDisabled(extension->id()) &&
|
||||
extension_prefs->HasDisableReason(extension->id(),
|
||||
disable_reason::DISABLE_RELOAD)) {
|
||||
extension_prefs->RemoveDisableReason(extension->id(),
|
||||
disable_reason::DISABLE_RELOAD);
|
||||
// Only re-enable the extension if there are no other disable reasons.
|
||||
if (extension_prefs->GetDisableReasons(extension->id()) ==
|
||||
disable_reason::DISABLE_NONE) {
|
||||
extension_prefs->SetExtensionEnabled(extension->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AtomExtensionLoader::PostActivateExtension(
|
||||
scoped_refptr<const Extension> extension) {}
|
||||
|
||||
void AtomExtensionLoader::PostDeactivateExtension(
|
||||
scoped_refptr<const Extension> extension) {}
|
||||
|
||||
void AtomExtensionLoader::LoadExtensionForReload(
|
||||
const ExtensionId& extension_id,
|
||||
const base::FilePath& path,
|
||||
LoadErrorBehavior load_error_behavior) {
|
||||
CHECK(!path.empty());
|
||||
|
||||
base::PostTaskAndReplyWithResult(
|
||||
GetExtensionFileTaskRunner().get(), FROM_HERE,
|
||||
base::BindOnce(&LoadUnpacked, path),
|
||||
base::BindOnce(&AtomExtensionLoader::FinishExtensionReload,
|
||||
weak_factory_.GetWeakPtr(), extension_id));
|
||||
did_schedule_reload_ = true;
|
||||
}
|
||||
|
||||
bool AtomExtensionLoader::CanEnableExtension(const Extension* extension) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomExtensionLoader::CanDisableExtension(const Extension* extension) {
|
||||
// Extensions cannot be disabled by the user.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomExtensionLoader::ShouldBlockExtension(const Extension* extension) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,86 @@
|
|||
// 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 SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_LOADER_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_LOADER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "extensions/browser/extension_registrar.h"
|
||||
#include "extensions/common/extension_id.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
} // namespace base
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
} // namespace content
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class Extension;
|
||||
|
||||
// Handles extension loading and reloading using ExtensionRegistrar.
|
||||
class AtomExtensionLoader : public ExtensionRegistrar::Delegate {
|
||||
public:
|
||||
explicit AtomExtensionLoader(content::BrowserContext* browser_context);
|
||||
~AtomExtensionLoader() override;
|
||||
|
||||
// Loads an unpacked extension from a directory synchronously. Returns the
|
||||
// extension on success, or nullptr otherwise.
|
||||
const Extension* LoadExtension(const base::FilePath& extension_dir);
|
||||
|
||||
// Starts reloading the extension. A keep-alive is maintained until the
|
||||
// reload succeeds/fails. If the extension is an app, it will be launched upon
|
||||
// reloading.
|
||||
// This may invalidate references to the old Extension object, so it takes the
|
||||
// ID by value.
|
||||
void ReloadExtension(ExtensionId extension_id);
|
||||
|
||||
private:
|
||||
// If the extension loaded successfully, enables it. If it's an app, launches
|
||||
// it. If the load failed, updates ShellKeepAliveRequester.
|
||||
void FinishExtensionReload(const ExtensionId old_extension_id,
|
||||
scoped_refptr<const Extension> extension);
|
||||
|
||||
// ExtensionRegistrar::Delegate:
|
||||
void PreAddExtension(const Extension* extension,
|
||||
const Extension* old_extension) override;
|
||||
void PostActivateExtension(scoped_refptr<const Extension> extension) override;
|
||||
void PostDeactivateExtension(
|
||||
scoped_refptr<const Extension> extension) override;
|
||||
void LoadExtensionForReload(
|
||||
const ExtensionId& extension_id,
|
||||
const base::FilePath& path,
|
||||
ExtensionRegistrar::LoadErrorBehavior load_error_behavior) override;
|
||||
bool CanEnableExtension(const Extension* extension) override;
|
||||
bool CanDisableExtension(const Extension* extension) override;
|
||||
bool ShouldBlockExtension(const Extension* extension) override;
|
||||
|
||||
content::BrowserContext* browser_context_; // Not owned.
|
||||
|
||||
// Registers and unregisters extensions.
|
||||
ExtensionRegistrar extension_registrar_;
|
||||
|
||||
// Holds keep-alives for relaunching apps.
|
||||
// ShellKeepAliveRequester keep_alive_requester_;
|
||||
|
||||
// Indicates that we posted the (asynchronous) task to start reloading.
|
||||
// Used by ReloadExtension() to check whether ExtensionRegistrar calls
|
||||
// LoadExtensionForReload().
|
||||
bool did_schedule_reload_ = false;
|
||||
|
||||
base::WeakPtrFactory<AtomExtensionLoader> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomExtensionLoader);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_LOADER_H_
|
|
@ -0,0 +1,186 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/browser/extensions/atom_extension_system.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/notification_details.h"
|
||||
#include "content/public/browser/notification_service.h"
|
||||
#include "content/public/browser/notification_source.h"
|
||||
#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/notification_types.h"
|
||||
#include "extensions/browser/null_app_sorting.h"
|
||||
#include "extensions/browser/quota_service.h"
|
||||
#include "extensions/browser/runtime_data.h"
|
||||
#include "extensions/browser/service_worker_manager.h"
|
||||
#include "extensions/browser/shared_user_script_master.h"
|
||||
#include "extensions/browser/value_store/value_store_factory_impl.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/file_util.h"
|
||||
#include "shell/browser/extensions/atom_extension_loader.h"
|
||||
|
||||
using content::BrowserContext;
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
AtomExtensionSystem::AtomExtensionSystem(BrowserContext* browser_context)
|
||||
: browser_context_(browser_context),
|
||||
store_factory_(new ValueStoreFactoryImpl(browser_context->GetPath())),
|
||||
weak_factory_(this) {}
|
||||
|
||||
AtomExtensionSystem::~AtomExtensionSystem() = default;
|
||||
|
||||
const Extension* AtomExtensionSystem::LoadExtension(
|
||||
const base::FilePath& extension_dir) {
|
||||
return extension_loader_->LoadExtension(extension_dir);
|
||||
}
|
||||
|
||||
const Extension* AtomExtensionSystem::LoadApp(const base::FilePath& app_dir) {
|
||||
CHECK(false); // Should never call LoadApp
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AtomExtensionSystem::FinishInitialization() {
|
||||
// Inform the rest of the extensions system to start.
|
||||
ready_.Signal();
|
||||
content::NotificationService::current()->Notify(
|
||||
NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
|
||||
content::Source<BrowserContext>(browser_context_),
|
||||
content::NotificationService::NoDetails());
|
||||
}
|
||||
|
||||
void AtomExtensionSystem::ReloadExtension(const ExtensionId& extension_id) {
|
||||
extension_loader_->ReloadExtension(extension_id);
|
||||
}
|
||||
|
||||
void AtomExtensionSystem::Shutdown() {
|
||||
extension_loader_.reset();
|
||||
}
|
||||
|
||||
void AtomExtensionSystem::InitForRegularProfile(bool extensions_enabled) {
|
||||
service_worker_manager_ =
|
||||
std::make_unique<ServiceWorkerManager>(browser_context_);
|
||||
runtime_data_ =
|
||||
std::make_unique<RuntimeData>(ExtensionRegistry::Get(browser_context_));
|
||||
quota_service_ = std::make_unique<QuotaService>();
|
||||
shared_user_script_master_ =
|
||||
std::make_unique<SharedUserScriptMaster>(browser_context_);
|
||||
app_sorting_ = std::make_unique<NullAppSorting>();
|
||||
extension_loader_ = std::make_unique<AtomExtensionLoader>(browser_context_);
|
||||
}
|
||||
|
||||
void AtomExtensionSystem::InitForIncognitoProfile() {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
ExtensionService* AtomExtensionSystem::extension_service() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RuntimeData* AtomExtensionSystem::runtime_data() {
|
||||
return runtime_data_.get();
|
||||
}
|
||||
|
||||
ManagementPolicy* AtomExtensionSystem::management_policy() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ServiceWorkerManager* AtomExtensionSystem::service_worker_manager() {
|
||||
return service_worker_manager_.get();
|
||||
}
|
||||
|
||||
SharedUserScriptMaster* AtomExtensionSystem::shared_user_script_master() {
|
||||
return new SharedUserScriptMaster(browser_context_);
|
||||
}
|
||||
|
||||
StateStore* AtomExtensionSystem::state_store() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StateStore* AtomExtensionSystem::rules_store() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
scoped_refptr<ValueStoreFactory> AtomExtensionSystem::store_factory() {
|
||||
return store_factory_;
|
||||
}
|
||||
|
||||
InfoMap* AtomExtensionSystem::info_map() {
|
||||
if (!info_map_.get())
|
||||
info_map_ = new InfoMap;
|
||||
return info_map_.get();
|
||||
}
|
||||
|
||||
QuotaService* AtomExtensionSystem::quota_service() {
|
||||
return quota_service_.get();
|
||||
}
|
||||
|
||||
AppSorting* AtomExtensionSystem::app_sorting() {
|
||||
return app_sorting_.get();
|
||||
}
|
||||
|
||||
void AtomExtensionSystem::RegisterExtensionWithRequestContexts(
|
||||
const Extension* extension,
|
||||
const base::Closure& callback) {
|
||||
base::PostTaskWithTraitsAndReply(
|
||||
FROM_HERE, {BrowserThread::IO},
|
||||
base::Bind(&InfoMap::AddExtension, info_map(),
|
||||
base::RetainedRef(extension), base::Time::Now(), false, false),
|
||||
callback);
|
||||
}
|
||||
|
||||
void AtomExtensionSystem::UnregisterExtensionWithRequestContexts(
|
||||
const std::string& extension_id,
|
||||
const UnloadedExtensionReason reason) {}
|
||||
|
||||
const base::OneShotEvent& AtomExtensionSystem::ready() const {
|
||||
return ready_;
|
||||
}
|
||||
|
||||
ContentVerifier* AtomExtensionSystem::content_verifier() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<ExtensionSet> AtomExtensionSystem::GetDependentExtensions(
|
||||
const Extension* extension) {
|
||||
return std::make_unique<ExtensionSet>();
|
||||
}
|
||||
|
||||
void AtomExtensionSystem::InstallUpdate(
|
||||
const std::string& extension_id,
|
||||
const std::string& public_key,
|
||||
const base::FilePath& temp_dir,
|
||||
bool install_immediately,
|
||||
InstallUpdateCallback install_update_callback) {
|
||||
NOTREACHED();
|
||||
base::DeleteFile(temp_dir, true /* recursive */);
|
||||
}
|
||||
|
||||
bool AtomExtensionSystem::FinishDelayedInstallationIfReady(
|
||||
const std::string& extension_id,
|
||||
bool install_immediately) {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
void AtomExtensionSystem::OnExtensionRegisteredWithRequestContexts(
|
||||
scoped_refptr<Extension> extension) {
|
||||
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
|
||||
registry->AddReady(extension);
|
||||
registry->TriggerOnReady(extension.get());
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,119 @@
|
|||
// 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_ATOM_EXTENSION_SYSTEM_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_SYSTEM_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/one_shot_event.h"
|
||||
#include "extensions/browser/extension_system.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class BrowserContext;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class AtomExtensionLoader;
|
||||
class ValueStoreFactory;
|
||||
|
||||
// A simplified version of ExtensionSystem for app_shell. Allows
|
||||
// app_shell to skip initialization of services it doesn't need.
|
||||
class AtomExtensionSystem : public ExtensionSystem {
|
||||
public:
|
||||
using InstallUpdateCallback = ExtensionSystem::InstallUpdateCallback;
|
||||
explicit AtomExtensionSystem(content::BrowserContext* browser_context);
|
||||
~AtomExtensionSystem() override;
|
||||
|
||||
// Loads an unpacked extension from a directory. Returns the extension on
|
||||
// success, or nullptr otherwise.
|
||||
const Extension* LoadExtension(const base::FilePath& extension_dir);
|
||||
|
||||
// Loads an unpacked platform app from a directory. Returns the extension on
|
||||
// success, or nullptr otherwise.
|
||||
// Currently this just calls LoadExtension, as apps are not loaded differently
|
||||
// than other extensions. Use LaunchApp() to actually launch the loaded app.
|
||||
const Extension* LoadApp(const base::FilePath& app_dir);
|
||||
|
||||
// Finish initialization for the shell extension system.
|
||||
void FinishInitialization();
|
||||
|
||||
// Reloads the extension with id |extension_id|.
|
||||
void ReloadExtension(const ExtensionId& extension_id);
|
||||
|
||||
// KeyedService implementation:
|
||||
void Shutdown() override;
|
||||
|
||||
// ExtensionSystem implementation:
|
||||
void InitForRegularProfile(bool extensions_enabled) override;
|
||||
void InitForIncognitoProfile() override;
|
||||
ExtensionService* extension_service() override;
|
||||
RuntimeData* runtime_data() override;
|
||||
ManagementPolicy* management_policy() override;
|
||||
ServiceWorkerManager* service_worker_manager() override;
|
||||
SharedUserScriptMaster* shared_user_script_master() override;
|
||||
StateStore* state_store() override;
|
||||
StateStore* rules_store() override;
|
||||
scoped_refptr<ValueStoreFactory> store_factory() override;
|
||||
InfoMap* info_map() override;
|
||||
QuotaService* quota_service() override;
|
||||
AppSorting* app_sorting() override;
|
||||
void RegisterExtensionWithRequestContexts(
|
||||
const Extension* extension,
|
||||
const base::Closure& callback) override;
|
||||
void UnregisterExtensionWithRequestContexts(
|
||||
const std::string& extension_id,
|
||||
const UnloadedExtensionReason reason) override;
|
||||
const base::OneShotEvent& ready() const override;
|
||||
ContentVerifier* content_verifier() override;
|
||||
std::unique_ptr<ExtensionSet> GetDependentExtensions(
|
||||
const Extension* extension) override;
|
||||
void InstallUpdate(const std::string& extension_id,
|
||||
const std::string& public_key,
|
||||
const base::FilePath& temp_dir,
|
||||
bool install_immediately,
|
||||
InstallUpdateCallback install_update_callback) override;
|
||||
bool FinishDelayedInstallationIfReady(const std::string& extension_id,
|
||||
bool install_immediately) override;
|
||||
|
||||
private:
|
||||
void OnExtensionRegisteredWithRequestContexts(
|
||||
scoped_refptr<Extension> extension);
|
||||
content::BrowserContext* browser_context_; // Not owned.
|
||||
|
||||
// Data to be accessed on the IO thread. Must outlive process_manager_.
|
||||
scoped_refptr<InfoMap> info_map_;
|
||||
|
||||
std::unique_ptr<ServiceWorkerManager> service_worker_manager_;
|
||||
std::unique_ptr<RuntimeData> runtime_data_;
|
||||
std::unique_ptr<QuotaService> quota_service_;
|
||||
std::unique_ptr<SharedUserScriptMaster> shared_user_script_master_;
|
||||
std::unique_ptr<AppSorting> app_sorting_;
|
||||
|
||||
std::unique_ptr<AtomExtensionLoader> extension_loader_;
|
||||
|
||||
scoped_refptr<ValueStoreFactory> store_factory_;
|
||||
|
||||
// Signaled when the extension system has completed its startup tasks.
|
||||
base::OneShotEvent ready_;
|
||||
|
||||
base::WeakPtrFactory<AtomExtensionSystem> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomExtensionSystem);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_SYSTEM_H_
|
|
@ -0,0 +1,51 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/browser/extensions/atom_extension_system_factory.h"
|
||||
|
||||
#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
||||
#include "extensions/browser/extension_prefs_factory.h"
|
||||
#include "extensions/browser/extension_registry_factory.h"
|
||||
#include "shell/browser/extensions/atom_extension_system.h"
|
||||
|
||||
using content::BrowserContext;
|
||||
|
||||
namespace extensions {
|
||||
|
||||
ExtensionSystem* AtomExtensionSystemFactory::GetForBrowserContext(
|
||||
BrowserContext* context) {
|
||||
return static_cast<AtomExtensionSystem*>(
|
||||
GetInstance()->GetServiceForBrowserContext(context, true));
|
||||
}
|
||||
|
||||
// static
|
||||
AtomExtensionSystemFactory* AtomExtensionSystemFactory::GetInstance() {
|
||||
return base::Singleton<AtomExtensionSystemFactory>::get();
|
||||
}
|
||||
|
||||
AtomExtensionSystemFactory::AtomExtensionSystemFactory()
|
||||
: ExtensionSystemProvider("AtomExtensionSystem",
|
||||
BrowserContextDependencyManager::GetInstance()) {
|
||||
DependsOn(ExtensionPrefsFactory::GetInstance());
|
||||
DependsOn(ExtensionRegistryFactory::GetInstance());
|
||||
}
|
||||
|
||||
AtomExtensionSystemFactory::~AtomExtensionSystemFactory() {}
|
||||
|
||||
KeyedService* AtomExtensionSystemFactory::BuildServiceInstanceFor(
|
||||
BrowserContext* context) const {
|
||||
return new AtomExtensionSystem(context);
|
||||
}
|
||||
|
||||
BrowserContext* AtomExtensionSystemFactory::GetBrowserContextToUse(
|
||||
BrowserContext* context) const {
|
||||
// Use a separate instance for incognito.
|
||||
return context;
|
||||
}
|
||||
|
||||
bool AtomExtensionSystemFactory::ServiceIsCreatedWithBrowserContext() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,41 @@
|
|||
// 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_ATOM_EXTENSION_SYSTEM_FACTORY_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_SYSTEM_FACTORY_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/singleton.h"
|
||||
#include "extensions/browser/extension_system_provider.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// A factory that provides AtomExtensionSystem.
|
||||
class AtomExtensionSystemFactory : public ExtensionSystemProvider {
|
||||
public:
|
||||
// ExtensionSystemProvider implementation:
|
||||
ExtensionSystem* GetForBrowserContext(
|
||||
content::BrowserContext* context) override;
|
||||
|
||||
static AtomExtensionSystemFactory* GetInstance();
|
||||
|
||||
private:
|
||||
friend struct base::DefaultSingletonTraits<AtomExtensionSystemFactory>;
|
||||
|
||||
AtomExtensionSystemFactory();
|
||||
~AtomExtensionSystemFactory() override;
|
||||
|
||||
// BrowserContextKeyedServiceFactory implementation:
|
||||
KeyedService* BuildServiceInstanceFor(
|
||||
content::BrowserContext* context) const override;
|
||||
content::BrowserContext* GetBrowserContextToUse(
|
||||
content::BrowserContext* context) const override;
|
||||
bool ServiceIsCreatedWithBrowserContext() const override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomExtensionSystemFactory);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_SYSTEM_FACTORY_H_
|
|
@ -0,0 +1,26 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/browser/extensions/atom_extension_web_contents_observer.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
AtomExtensionWebContentsObserver::AtomExtensionWebContentsObserver(
|
||||
content::WebContents* web_contents)
|
||||
: ExtensionWebContentsObserver(web_contents) {}
|
||||
|
||||
AtomExtensionWebContentsObserver::~AtomExtensionWebContentsObserver() {}
|
||||
|
||||
void AtomExtensionWebContentsObserver::CreateForWebContents(
|
||||
content::WebContents* web_contents) {
|
||||
content::WebContentsUserData<
|
||||
AtomExtensionWebContentsObserver>::CreateForWebContents(web_contents);
|
||||
|
||||
// Initialize this instance if necessary.
|
||||
FromWebContents(web_contents)->Initialize();
|
||||
}
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_IMPL(AtomExtensionWebContentsObserver)
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,37 @@
|
|||
// 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_ATOM_EXTENSION_WEB_CONTENTS_OBSERVER_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_WEB_CONTENTS_OBSERVER_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "content/public/browser/web_contents_user_data.h"
|
||||
#include "extensions/browser/extension_web_contents_observer.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// The app_shell version of ExtensionWebContentsObserver.
|
||||
class AtomExtensionWebContentsObserver
|
||||
: public ExtensionWebContentsObserver,
|
||||
public content::WebContentsUserData<AtomExtensionWebContentsObserver> {
|
||||
public:
|
||||
~AtomExtensionWebContentsObserver() override;
|
||||
|
||||
// Creates and initializes an instance of this class for the given
|
||||
// |web_contents|, if it doesn't already exist.
|
||||
static void CreateForWebContents(content::WebContents* web_contents);
|
||||
|
||||
private:
|
||||
friend class content::WebContentsUserData<AtomExtensionWebContentsObserver>;
|
||||
|
||||
explicit AtomExtensionWebContentsObserver(content::WebContents* web_contents);
|
||||
|
||||
WEB_CONTENTS_USER_DATA_KEY_DECL();
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomExtensionWebContentsObserver);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSION_WEB_CONTENTS_OBSERVER_H_
|
|
@ -0,0 +1,300 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/browser/extensions/atom_extensions_browser_client.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/task/post_task.h"
|
||||
#include "build/build_config.h"
|
||||
#include "components/version_info/version_info.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/resource_request_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "extensions/browser/api/extensions_api_client.h"
|
||||
#include "extensions/browser/component_extension_resource_manager.h"
|
||||
#include "extensions/browser/core_extensions_browser_api_provider.h"
|
||||
#include "extensions/browser/event_router.h"
|
||||
#include "extensions/browser/mojo/interface_registration.h"
|
||||
#include "extensions/browser/null_app_sorting.h"
|
||||
#include "extensions/browser/updater/null_extension_cache.h"
|
||||
#include "extensions/browser/url_request_util.h"
|
||||
#include "extensions/common/features/feature_channel.h"
|
||||
#include "shell/browser/atom_browser_client.h"
|
||||
#include "shell/browser/atom_browser_context.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/extensions/api/runtime/atom_runtime_api_delegate.h"
|
||||
#include "shell/browser/extensions/atom_extension_host_delegate.h"
|
||||
#include "shell/browser/extensions/atom_extension_system_factory.h"
|
||||
#include "shell/browser/extensions/atom_extension_web_contents_observer.h"
|
||||
// #include "shell/browser/extensions/atom_extensions_api_client.h"
|
||||
// #include "shell/browser/extensions/atom_extensions_browser_api_provider.h"
|
||||
#include "services/network/public/mojom/url_loader.mojom.h"
|
||||
#include "shell/browser/extensions/atom_navigation_ui_data.h"
|
||||
|
||||
using content::BrowserContext;
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace electron {
|
||||
|
||||
AtomExtensionsBrowserClient::AtomExtensionsBrowserClient()
|
||||
: api_client_(new extensions::ExtensionsAPIClient),
|
||||
// : api_client_(new extensions::AtomExtensionsAPIClient),
|
||||
extension_cache_(new extensions::NullExtensionCache()) {
|
||||
// app_shell does not have a concept of channel yet, so leave UNKNOWN to
|
||||
// enable all channel-dependent extension APIs.
|
||||
extensions::SetCurrentChannel(version_info::Channel::UNKNOWN);
|
||||
|
||||
AddAPIProvider(
|
||||
std::make_unique<extensions::CoreExtensionsBrowserAPIProvider>());
|
||||
// AddAPIProvider(std::make_unique<AtomExtensionsBrowserAPIProvider>());
|
||||
}
|
||||
|
||||
AtomExtensionsBrowserClient::~AtomExtensionsBrowserClient() {}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsShuttingDown() {
|
||||
return electron::Browser::Get()->is_shutting_down();
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::AreExtensionsDisabled(
|
||||
const base::CommandLine& command_line,
|
||||
BrowserContext* context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsValidContext(BrowserContext* context) {
|
||||
auto context_map = AtomBrowserContext::browser_context_map();
|
||||
for (auto const& entry : context_map) {
|
||||
if (entry.second && entry.second.get() == context)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsSameContext(BrowserContext* first,
|
||||
BrowserContext* second) {
|
||||
return first == second;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::HasOffTheRecordContext(
|
||||
BrowserContext* context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BrowserContext* AtomExtensionsBrowserClient::GetOffTheRecordContext(
|
||||
BrowserContext* context) {
|
||||
// app_shell only supports a single context.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BrowserContext* AtomExtensionsBrowserClient::GetOriginalContext(
|
||||
BrowserContext* context) {
|
||||
DCHECK(context);
|
||||
if (context->IsOffTheRecord()) {
|
||||
return AtomBrowserContext::From("", false).get();
|
||||
} else {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsGuestSession(
|
||||
BrowserContext* context) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsExtensionIncognitoEnabled(
|
||||
const std::string& extension_id,
|
||||
content::BrowserContext* context) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::CanExtensionCrossIncognito(
|
||||
const extensions::Extension* extension,
|
||||
content::BrowserContext* context) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
base::FilePath AtomExtensionsBrowserClient::GetBundleResourcePath(
|
||||
const network::ResourceRequest& request,
|
||||
const base::FilePath& extension_resources_path,
|
||||
int* resource_id) const {
|
||||
*resource_id = 0;
|
||||
return base::FilePath();
|
||||
}
|
||||
|
||||
void AtomExtensionsBrowserClient::LoadResourceFromResourceBundle(
|
||||
const network::ResourceRequest& request,
|
||||
network::mojom::URLLoaderRequest loader,
|
||||
const base::FilePath& resource_relative_path,
|
||||
int resource_id,
|
||||
const std::string& content_security_policy,
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
bool send_cors_header) {
|
||||
NOTREACHED() << "Load resources from bundles not supported.";
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::AllowCrossRendererResourceLoad(
|
||||
const GURL& url,
|
||||
content::ResourceType resource_type,
|
||||
ui::PageTransition page_transition,
|
||||
int child_id,
|
||||
bool is_incognito,
|
||||
const extensions::Extension* extension,
|
||||
const extensions::ExtensionSet& extensions,
|
||||
const extensions::ProcessMap& process_map) {
|
||||
bool allowed = false;
|
||||
if (extensions::url_request_util::AllowCrossRendererResourceLoad(
|
||||
url, resource_type, page_transition, child_id, is_incognito,
|
||||
extension, extensions, process_map, &allowed)) {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
// Couldn't determine if resource is allowed. Block the load.
|
||||
return false;
|
||||
}
|
||||
|
||||
PrefService* AtomExtensionsBrowserClient::GetPrefServiceForContext(
|
||||
BrowserContext* context) {
|
||||
return static_cast<AtomBrowserContext*>(context)->prefs();
|
||||
}
|
||||
|
||||
void AtomExtensionsBrowserClient::GetEarlyExtensionPrefsObservers(
|
||||
content::BrowserContext* context,
|
||||
std::vector<extensions::EarlyExtensionPrefsObserver*>* observers) const {}
|
||||
|
||||
extensions::ProcessManagerDelegate*
|
||||
AtomExtensionsBrowserClient::GetProcessManagerDelegate() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::unique_ptr<extensions::ExtensionHostDelegate> AtomExtensionsBrowserClient::
|
||||
CreateExtensionHostDelegate() { // TODO(samuelmaddock):
|
||||
return base::WrapUnique(new extensions::AtomExtensionHostDelegate);
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::DidVersionUpdate(BrowserContext* context) {
|
||||
// TODO(jamescook): We might want to tell extensions when app_shell updates.
|
||||
return false;
|
||||
}
|
||||
|
||||
void AtomExtensionsBrowserClient::PermitExternalProtocolHandler() {}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsInDemoMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsScreensaverInDemoMode(
|
||||
const std::string& app_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsRunningInForcedAppMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsAppModeForcedForApp(
|
||||
const extensions::ExtensionId& extension_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsLoggedInAsPublicAccount() {
|
||||
return false;
|
||||
}
|
||||
|
||||
extensions::ExtensionSystemProvider*
|
||||
AtomExtensionsBrowserClient::GetExtensionSystemFactory() {
|
||||
return extensions::AtomExtensionSystemFactory::GetInstance();
|
||||
}
|
||||
|
||||
void AtomExtensionsBrowserClient::RegisterExtensionInterfaces(
|
||||
service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>*
|
||||
registry,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const extensions::Extension* extension) const {
|
||||
RegisterInterfacesForExtension(registry, render_frame_host, extension);
|
||||
}
|
||||
|
||||
std::unique_ptr<extensions::RuntimeAPIDelegate>
|
||||
AtomExtensionsBrowserClient::CreateRuntimeAPIDelegate(
|
||||
content::BrowserContext* context) const {
|
||||
return std::make_unique<extensions::AtomRuntimeAPIDelegate>(context);
|
||||
}
|
||||
|
||||
const extensions::ComponentExtensionResourceManager*
|
||||
AtomExtensionsBrowserClient::GetComponentExtensionResourceManager() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AtomExtensionsBrowserClient::BroadcastEventToRenderers(
|
||||
extensions::events::HistogramValue histogram_value,
|
||||
const std::string& event_name,
|
||||
std::unique_ptr<base::ListValue> args) {
|
||||
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
||||
base::PostTaskWithTraits(
|
||||
FROM_HERE, {BrowserThread::UI},
|
||||
base::BindOnce(&AtomExtensionsBrowserClient::BroadcastEventToRenderers,
|
||||
base::Unretained(this), histogram_value, event_name,
|
||||
std::move(args)));
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<extensions::Event> event(
|
||||
new extensions::Event(histogram_value, event_name, std::move(args)));
|
||||
auto context_map = AtomBrowserContext::browser_context_map();
|
||||
for (auto const& entry : context_map) {
|
||||
if (entry.second) {
|
||||
extensions::EventRouter::Get(entry.second.get())
|
||||
->BroadcastEvent(std::move(event));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extensions::ExtensionCache* AtomExtensionsBrowserClient::GetExtensionCache() {
|
||||
return extension_cache_.get();
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsBackgroundUpdateAllowed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsMinBrowserVersionSupported(
|
||||
const std::string& min_version) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AtomExtensionsBrowserClient::SetAPIClientForTest(
|
||||
extensions::ExtensionsAPIClient* api_client) {
|
||||
api_client_.reset(api_client);
|
||||
}
|
||||
|
||||
extensions::ExtensionWebContentsObserver*
|
||||
AtomExtensionsBrowserClient::GetExtensionWebContentsObserver(
|
||||
content::WebContents* web_contents) {
|
||||
return extensions::AtomExtensionWebContentsObserver::FromWebContents(
|
||||
web_contents);
|
||||
}
|
||||
|
||||
extensions::KioskDelegate* AtomExtensionsBrowserClient::GetKioskDelegate() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool AtomExtensionsBrowserClient::IsLockScreenContext(
|
||||
content::BrowserContext* context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string AtomExtensionsBrowserClient::GetApplicationLocale() {
|
||||
return AtomBrowserClient::Get()->GetApplicationLocale();
|
||||
}
|
||||
|
||||
std::string AtomExtensionsBrowserClient::GetUserAgent() const {
|
||||
return AtomBrowserClient::Get()->GetUserAgent();
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -0,0 +1,139 @@
|
|||
// 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_ATOM_EXTENSIONS_BROWSER_CLIENT_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSIONS_BROWSER_CLIENT_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "build/build_config.h"
|
||||
#include "extensions/browser/extensions_browser_client.h"
|
||||
|
||||
class PrefService;
|
||||
|
||||
namespace extensions {
|
||||
class ExtensionsAPIClient;
|
||||
class KioskDelegate;
|
||||
class ProcessManagerDelegate;
|
||||
class ProcessMap;
|
||||
} // namespace extensions
|
||||
|
||||
namespace electron {
|
||||
|
||||
// An ExtensionsBrowserClient that supports a single content::BrowserContext
|
||||
// with no related incognito context.
|
||||
// Must be initialized via InitWithBrowserContext() once the BrowserContext is
|
||||
// created.
|
||||
class AtomExtensionsBrowserClient : public extensions::ExtensionsBrowserClient {
|
||||
public:
|
||||
AtomExtensionsBrowserClient();
|
||||
~AtomExtensionsBrowserClient() override;
|
||||
|
||||
// ExtensionsBrowserClient overrides:
|
||||
bool IsShuttingDown() override;
|
||||
bool AreExtensionsDisabled(const base::CommandLine& command_line,
|
||||
content::BrowserContext* context) override;
|
||||
bool IsValidContext(content::BrowserContext* context) override;
|
||||
bool IsSameContext(content::BrowserContext* first,
|
||||
content::BrowserContext* second) override;
|
||||
bool HasOffTheRecordContext(content::BrowserContext* context) override;
|
||||
content::BrowserContext* GetOffTheRecordContext(
|
||||
content::BrowserContext* context) override;
|
||||
content::BrowserContext* GetOriginalContext(
|
||||
content::BrowserContext* context) override;
|
||||
bool IsGuestSession(content::BrowserContext* context) const override;
|
||||
bool IsExtensionIncognitoEnabled(
|
||||
const std::string& extension_id,
|
||||
content::BrowserContext* context) const override;
|
||||
bool CanExtensionCrossIncognito(
|
||||
const extensions::Extension* extension,
|
||||
content::BrowserContext* context) const override;
|
||||
base::FilePath GetBundleResourcePath(
|
||||
const network::ResourceRequest& request,
|
||||
const base::FilePath& extension_resources_path,
|
||||
int* resource_id) const override;
|
||||
void LoadResourceFromResourceBundle(
|
||||
const network::ResourceRequest& request,
|
||||
network::mojom::URLLoaderRequest loader,
|
||||
const base::FilePath& resource_relative_path,
|
||||
int resource_id,
|
||||
const std::string& content_security_policy,
|
||||
network::mojom::URLLoaderClientPtr client,
|
||||
bool send_cors_header) override;
|
||||
bool AllowCrossRendererResourceLoad(
|
||||
const GURL& url,
|
||||
content::ResourceType resource_type,
|
||||
ui::PageTransition page_transition,
|
||||
int child_id,
|
||||
bool is_incognito,
|
||||
const extensions::Extension* extension,
|
||||
const extensions::ExtensionSet& extensions,
|
||||
const extensions::ProcessMap& process_map) override;
|
||||
PrefService* GetPrefServiceForContext(
|
||||
content::BrowserContext* context) override;
|
||||
void GetEarlyExtensionPrefsObservers(
|
||||
content::BrowserContext* context,
|
||||
std::vector<extensions::EarlyExtensionPrefsObserver*>* observers)
|
||||
const override;
|
||||
extensions::ProcessManagerDelegate* GetProcessManagerDelegate()
|
||||
const override;
|
||||
std::unique_ptr<extensions::ExtensionHostDelegate>
|
||||
CreateExtensionHostDelegate() override;
|
||||
bool DidVersionUpdate(content::BrowserContext* context) override;
|
||||
void PermitExternalProtocolHandler() override;
|
||||
bool IsInDemoMode() override;
|
||||
bool IsScreensaverInDemoMode(const std::string& app_id) override;
|
||||
bool IsRunningInForcedAppMode() override;
|
||||
bool IsAppModeForcedForApp(
|
||||
const extensions::ExtensionId& extension_id) override;
|
||||
bool IsLoggedInAsPublicAccount() override;
|
||||
extensions::ExtensionSystemProvider* GetExtensionSystemFactory() override;
|
||||
void RegisterExtensionInterfaces(
|
||||
service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>*
|
||||
registry,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const extensions::Extension* extension) const override;
|
||||
std::unique_ptr<extensions::RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
|
||||
content::BrowserContext* context) const override;
|
||||
const extensions::ComponentExtensionResourceManager*
|
||||
GetComponentExtensionResourceManager() override;
|
||||
void BroadcastEventToRenderers(
|
||||
extensions::events::HistogramValue histogram_value,
|
||||
const std::string& event_name,
|
||||
std::unique_ptr<base::ListValue> args) override;
|
||||
extensions::ExtensionCache* GetExtensionCache() override;
|
||||
bool IsBackgroundUpdateAllowed() override;
|
||||
bool IsMinBrowserVersionSupported(const std::string& min_version) override;
|
||||
extensions::ExtensionWebContentsObserver* GetExtensionWebContentsObserver(
|
||||
content::WebContents* web_contents) override;
|
||||
extensions::KioskDelegate* GetKioskDelegate() override;
|
||||
bool IsLockScreenContext(content::BrowserContext* context) override;
|
||||
std::string GetApplicationLocale() override;
|
||||
std::string GetUserAgent() const override;
|
||||
|
||||
// |context| is the single BrowserContext used for IsValidContext().
|
||||
// |pref_service| is used for GetPrefServiceForContext().
|
||||
void InitWithBrowserContext(content::BrowserContext* context,
|
||||
PrefService* pref_service);
|
||||
|
||||
// Sets the API client.
|
||||
void SetAPIClientForTest(extensions::ExtensionsAPIClient* api_client);
|
||||
|
||||
private:
|
||||
// Support for extension APIs.
|
||||
std::unique_ptr<extensions::ExtensionsAPIClient> api_client_;
|
||||
|
||||
// The extension cache used for download and installation.
|
||||
std::unique_ptr<extensions::ExtensionCache> extension_cache_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomExtensionsBrowserClient);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ATOM_EXTENSIONS_BROWSER_CLIENT_H_
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
#include "shell/browser/extensions/atom_navigation_ui_data.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "content/public/browser/navigation_handle.h"
|
||||
#include "extensions/common/constants.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
AtomNavigationUIData::AtomNavigationUIData() {}
|
||||
|
||||
AtomNavigationUIData::AtomNavigationUIData(
|
||||
content::NavigationHandle* navigation_handle) {
|
||||
extension_data_ = std::make_unique<ExtensionNavigationUIData>(
|
||||
navigation_handle, extension_misc::kUnknownTabId,
|
||||
extension_misc::kUnknownWindowId);
|
||||
}
|
||||
|
||||
AtomNavigationUIData::~AtomNavigationUIData() {}
|
||||
|
||||
std::unique_ptr<content::NavigationUIData> AtomNavigationUIData::Clone() {
|
||||
std::unique_ptr<AtomNavigationUIData> copy =
|
||||
std::make_unique<AtomNavigationUIData>();
|
||||
|
||||
if (extension_data_)
|
||||
copy->SetExtensionNavigationUIData(extension_data_->DeepCopy());
|
||||
|
||||
return std::move(copy);
|
||||
}
|
||||
|
||||
void AtomNavigationUIData::SetExtensionNavigationUIData(
|
||||
std::unique_ptr<ExtensionNavigationUIData> extension_data) {
|
||||
extension_data_ = std::move(extension_data);
|
||||
}
|
||||
|
||||
} // namespace extensions
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2016 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_ATOM_NAVIGATION_UI_DATA_H_
|
||||
#define SHELL_BROWSER_EXTENSIONS_ATOM_NAVIGATION_UI_DATA_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "content/public/browser/navigation_ui_data.h"
|
||||
#include "extensions/browser/extension_navigation_ui_data.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
// PlzNavigate
|
||||
// Contains data that is passed from the UI thread to the IO thread at the
|
||||
// beginning of each navigation. The class is instantiated on the UI thread,
|
||||
// then a copy created using Clone is passed to the content::ResourceRequestInfo
|
||||
// on the IO thread.
|
||||
class AtomNavigationUIData : public content::NavigationUIData {
|
||||
public:
|
||||
AtomNavigationUIData();
|
||||
explicit AtomNavigationUIData(content::NavigationHandle* navigation_handle);
|
||||
~AtomNavigationUIData() override;
|
||||
|
||||
// Creates a new ChromeNavigationUIData that is a deep copy of the original.
|
||||
// Any changes to the original after the clone is created will not be
|
||||
// reflected in the clone. |extension_data_| is deep copied.
|
||||
std::unique_ptr<content::NavigationUIData> Clone() override;
|
||||
|
||||
void SetExtensionNavigationUIData(
|
||||
std::unique_ptr<ExtensionNavigationUIData> extension_data);
|
||||
|
||||
ExtensionNavigationUIData* GetExtensionNavigationUIData() const {
|
||||
return extension_data_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
// Manages the lifetime of optional ExtensionNavigationUIData information.
|
||||
std::unique_ptr<ExtensionNavigationUIData> extension_data_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomNavigationUIData);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // SHELL_BROWSER_EXTENSIONS_ATOM_NAVIGATION_UI_DATA_H_
|
|
@ -41,6 +41,10 @@ bool IsPrintingEnabled() {
|
|||
return BUILDFLAG(ENABLE_PRINTING);
|
||||
}
|
||||
|
||||
bool IsExtensionsEnabled() {
|
||||
return BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS);
|
||||
}
|
||||
|
||||
bool IsComponentBuild() {
|
||||
#if defined(COMPONENT_BUILD)
|
||||
return true;
|
||||
|
@ -64,6 +68,7 @@ void Initialize(v8::Local<v8::Object> exports,
|
|||
dict.SetMethod("isTtsEnabled", &IsTtsEnabled);
|
||||
dict.SetMethod("isPrintingEnabled", &IsPrintingEnabled);
|
||||
dict.SetMethod("isComponentBuild", &IsComponentBuild);
|
||||
dict.SetMethod("isExtensionsEnabled", &IsExtensionsEnabled);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Copyright 2015 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.
|
||||
|
||||
import("//extensions/buildflags/buildflags.gni")
|
||||
import("//tools/json_schema_compiler/json_features.gni")
|
||||
import("//tools/json_schema_compiler/json_schema_api.gni")
|
||||
|
||||
assert(enable_extensions)
|
||||
|
||||
################################################################################
|
||||
# Public Targets
|
||||
|
||||
group("extensions_features") {
|
||||
public_deps = [
|
||||
":manifest_features",
|
||||
|
||||
# TODO(devlin): It would be nicer to have this dependency hoisted up to
|
||||
# //extensions/common (since that's where it's consumed), but there's some
|
||||
# cycles to be resolved first.
|
||||
"//extensions/common/api:extensions_features",
|
||||
]
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Private Targets
|
||||
|
||||
json_features("manifest_features") {
|
||||
feature_type = "ManifestFeature"
|
||||
method_name = "AddAtomManifestFeatures"
|
||||
sources = [
|
||||
"_manifest_features.json",
|
||||
]
|
||||
visibility = [ ":extensions_features" ]
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// 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.
|
||||
|
||||
// This features file defines manifest keys implemented under src/chrome.
|
||||
// See chrome/common/extensions/api/_features.md to understand this file, as
|
||||
// well as feature.h, simple_feature.h, and feature_provider.h.
|
||||
|
||||
{
|
||||
"content_scripts": {
|
||||
"channel": "stable",
|
||||
"extension_types": ["extension", "legacy_packaged_app"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/common/extensions/atom_extensions_api_provider.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "extensions/common/features/json_feature_provider_source.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "shell/common/extensions/api/manifest_features.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
||||
AtomExtensionsAPIProvider::AtomExtensionsAPIProvider() = default;
|
||||
AtomExtensionsAPIProvider::~AtomExtensionsAPIProvider() = default;
|
||||
|
||||
// TODO(samuelmaddock): generate API features?
|
||||
|
||||
void AtomExtensionsAPIProvider::AddAPIFeatures(
|
||||
extensions::FeatureProvider* provider) {
|
||||
// AddShellAPIFeatures(provider);
|
||||
}
|
||||
|
||||
void AtomExtensionsAPIProvider::AddManifestFeatures(
|
||||
extensions::FeatureProvider* provider) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
// TODO(samuelmaddock): why is the extensions namespace generated?
|
||||
extensions::AddAtomManifestFeatures(provider);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AtomExtensionsAPIProvider::AddPermissionFeatures(
|
||||
extensions::FeatureProvider* provider) {
|
||||
// No shell-specific permission features.
|
||||
}
|
||||
|
||||
void AtomExtensionsAPIProvider::AddBehaviorFeatures(
|
||||
extensions::FeatureProvider* provider) {
|
||||
// No shell-specific behavior features.
|
||||
}
|
||||
|
||||
void AtomExtensionsAPIProvider::AddAPIJSONSources(
|
||||
extensions::JSONFeatureProviderSource* json_source) {
|
||||
// json_source->LoadJSON(IDR_SHELL_EXTENSION_API_FEATURES);
|
||||
}
|
||||
|
||||
bool AtomExtensionsAPIProvider::IsAPISchemaGenerated(const std::string& name) {
|
||||
// return shell::api::ShellGeneratedSchemas::IsGenerated(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
base::StringPiece AtomExtensionsAPIProvider::GetAPISchema(
|
||||
const std::string& name) {
|
||||
// return shell::api::ShellGeneratedSchemas::Get(name);
|
||||
return "";
|
||||
}
|
||||
|
||||
void AtomExtensionsAPIProvider::RegisterPermissions(
|
||||
extensions::PermissionsInfo* permissions_info) {}
|
||||
|
||||
void AtomExtensionsAPIProvider::RegisterManifestHandlers() {}
|
||||
|
||||
} // namespace electron
|
|
@ -0,0 +1,39 @@
|
|||
// 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 SHELL_COMMON_EXTENSIONS_ATOM_EXTENSIONS_API_PROVIDER_H_
|
||||
#define SHELL_COMMON_EXTENSIONS_ATOM_EXTENSIONS_API_PROVIDER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "extensions/common/extensions_api_provider.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class AtomExtensionsAPIProvider : public extensions::ExtensionsAPIProvider {
|
||||
public:
|
||||
AtomExtensionsAPIProvider();
|
||||
~AtomExtensionsAPIProvider() override;
|
||||
|
||||
// ExtensionsAPIProvider:
|
||||
void AddAPIFeatures(extensions::FeatureProvider* provider) override;
|
||||
void AddManifestFeatures(extensions::FeatureProvider* provider) override;
|
||||
void AddPermissionFeatures(extensions::FeatureProvider* provider) override;
|
||||
void AddBehaviorFeatures(extensions::FeatureProvider* provider) override;
|
||||
void AddAPIJSONSources(
|
||||
extensions::JSONFeatureProviderSource* json_source) override;
|
||||
bool IsAPISchemaGenerated(const std::string& name) override;
|
||||
base::StringPiece GetAPISchema(const std::string& name) override;
|
||||
void RegisterPermissions(
|
||||
extensions::PermissionsInfo* permissions_info) override;
|
||||
void RegisterManifestHandlers() override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomExtensionsAPIProvider);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_COMMON_EXTENSIONS_ATOM_EXTENSIONS_API_PROVIDER_H_
|
|
@ -0,0 +1,143 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/common/extensions/atom_extensions_client.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/macros.h"
|
||||
#include "components/version_info/version_info.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "extensions/common/core_extensions_api_provider.h"
|
||||
#include "extensions/common/extension_urls.h"
|
||||
#include "extensions/common/features/simple_feature.h"
|
||||
#include "extensions/common/permissions/permission_message_provider.h"
|
||||
#include "extensions/common/url_pattern_set.h"
|
||||
#include "shell/common/extensions/atom_extensions_api_provider.h"
|
||||
|
||||
using extensions::ExtensionsClient;
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO(jamescook): Refactor ChromePermissionsMessageProvider so we can share
|
||||
// code. For now, this implementation does nothing.
|
||||
class AtomPermissionMessageProvider
|
||||
: public extensions::PermissionMessageProvider {
|
||||
public:
|
||||
AtomPermissionMessageProvider() {}
|
||||
~AtomPermissionMessageProvider() override {}
|
||||
|
||||
// PermissionMessageProvider implementation.
|
||||
extensions::PermissionMessages GetPermissionMessages(
|
||||
const extensions::PermissionIDSet& permissions) const override {
|
||||
return extensions::PermissionMessages();
|
||||
}
|
||||
|
||||
extensions::PermissionMessages GetPowerfulPermissionMessages(
|
||||
const extensions::PermissionIDSet& permissions) const override {
|
||||
return extensions::PermissionMessages();
|
||||
}
|
||||
|
||||
bool IsPrivilegeIncrease(
|
||||
const extensions::PermissionSet& granted_permissions,
|
||||
const extensions::PermissionSet& requested_permissions,
|
||||
extensions::Manifest::Type extension_type) const override {
|
||||
// Ensure we implement this before shipping.
|
||||
CHECK(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
extensions::PermissionIDSet GetAllPermissionIDs(
|
||||
const extensions::PermissionSet& permissions,
|
||||
extensions::Manifest::Type extension_type) const override {
|
||||
return extensions::PermissionIDSet();
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomPermissionMessageProvider);
|
||||
};
|
||||
|
||||
base::LazyInstance<AtomPermissionMessageProvider>::DestructorAtExit
|
||||
g_permission_message_provider = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomExtensionsClient::AtomExtensionsClient()
|
||||
: webstore_base_url_(extension_urls::kChromeWebstoreBaseURL),
|
||||
webstore_update_url_(extension_urls::kChromeWebstoreUpdateURL) {
|
||||
AddAPIProvider(std::make_unique<extensions::CoreExtensionsAPIProvider>());
|
||||
AddAPIProvider(std::make_unique<AtomExtensionsAPIProvider>());
|
||||
}
|
||||
|
||||
AtomExtensionsClient::~AtomExtensionsClient() {}
|
||||
|
||||
void AtomExtensionsClient::Initialize() {
|
||||
// TODO(jamescook): Do we need to whitelist any extensions?
|
||||
}
|
||||
|
||||
void AtomExtensionsClient::InitializeWebStoreUrls(
|
||||
base::CommandLine* command_line) {}
|
||||
|
||||
const extensions::PermissionMessageProvider&
|
||||
AtomExtensionsClient::GetPermissionMessageProvider() const {
|
||||
NOTIMPLEMENTED();
|
||||
return g_permission_message_provider.Get();
|
||||
}
|
||||
|
||||
const std::string AtomExtensionsClient::GetProductName() {
|
||||
// TODO(samuelmaddock):
|
||||
return "app_shell";
|
||||
}
|
||||
|
||||
void AtomExtensionsClient::FilterHostPermissions(
|
||||
const extensions::URLPatternSet& hosts,
|
||||
extensions::URLPatternSet* new_hosts,
|
||||
extensions::PermissionIDSet* permissions) const {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void AtomExtensionsClient::SetScriptingWhitelist(
|
||||
const ExtensionsClient::ScriptingWhitelist& whitelist) {
|
||||
scripting_whitelist_ = whitelist;
|
||||
}
|
||||
|
||||
const ExtensionsClient::ScriptingWhitelist&
|
||||
AtomExtensionsClient::GetScriptingWhitelist() const {
|
||||
// TODO(jamescook): Real whitelist.
|
||||
return scripting_whitelist_;
|
||||
}
|
||||
|
||||
extensions::URLPatternSet AtomExtensionsClient::GetPermittedChromeSchemeHosts(
|
||||
const extensions::Extension* extension,
|
||||
const extensions::APIPermissionSet& api_permissions) const {
|
||||
NOTIMPLEMENTED();
|
||||
return extensions::URLPatternSet();
|
||||
}
|
||||
|
||||
bool AtomExtensionsClient::IsScriptableURL(const GURL& url,
|
||||
std::string* error) const {
|
||||
// No restrictions on URLs.
|
||||
return true;
|
||||
}
|
||||
|
||||
const GURL& AtomExtensionsClient::GetWebstoreBaseURL() const {
|
||||
return webstore_base_url_;
|
||||
}
|
||||
|
||||
const GURL& AtomExtensionsClient::GetWebstoreUpdateURL() const {
|
||||
return webstore_update_url_;
|
||||
}
|
||||
|
||||
bool AtomExtensionsClient::IsBlacklistUpdateURL(const GURL& url) const {
|
||||
// TODO(rockot): Maybe we want to do something else here. For now we accept
|
||||
// any URL as a blacklist URL because we don't really care.
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -0,0 +1,65 @@
|
|||
// 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_COMMON_EXTENSIONS_ATOM_EXTENSIONS_CLIENT_H_
|
||||
#define SHELL_COMMON_EXTENSIONS_ATOM_EXTENSIONS_CLIENT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "extensions/common/extensions_client.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace extensions {
|
||||
class APIPermissionSet;
|
||||
class Extension;
|
||||
class PermissionMessageProvider;
|
||||
class PermissionIDSet;
|
||||
class ScriptingWhitelist;
|
||||
class URLPatternSet;
|
||||
} // namespace extensions
|
||||
|
||||
namespace electron {
|
||||
|
||||
// The app_shell implementation of ExtensionsClient.
|
||||
class AtomExtensionsClient : public extensions::ExtensionsClient {
|
||||
public:
|
||||
typedef extensions::ExtensionsClient::ScriptingWhitelist ScriptingWhitelist;
|
||||
|
||||
AtomExtensionsClient();
|
||||
~AtomExtensionsClient() override;
|
||||
|
||||
// ExtensionsClient overrides:
|
||||
void Initialize() override;
|
||||
void InitializeWebStoreUrls(base::CommandLine* command_line) override;
|
||||
const extensions::PermissionMessageProvider& GetPermissionMessageProvider()
|
||||
const override;
|
||||
const std::string GetProductName() override;
|
||||
void FilterHostPermissions(
|
||||
const extensions::URLPatternSet& hosts,
|
||||
extensions::URLPatternSet* new_hosts,
|
||||
extensions::PermissionIDSet* permissions) const override;
|
||||
void SetScriptingWhitelist(const ScriptingWhitelist& whitelist) override;
|
||||
const ScriptingWhitelist& GetScriptingWhitelist() const override;
|
||||
extensions::URLPatternSet GetPermittedChromeSchemeHosts(
|
||||
const extensions::Extension* extension,
|
||||
const extensions::APIPermissionSet& api_permissions) const override;
|
||||
bool IsScriptableURL(const GURL& url, std::string* error) const override;
|
||||
const GURL& GetWebstoreBaseURL() const override;
|
||||
const GURL& GetWebstoreUpdateURL() const override;
|
||||
bool IsBlacklistUpdateURL(const GURL& url) const override;
|
||||
|
||||
private:
|
||||
ScriptingWhitelist scripting_whitelist_;
|
||||
|
||||
const GURL webstore_base_url_;
|
||||
const GURL webstore_update_url_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomExtensionsClient);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_COMMON_EXTENSIONS_ATOM_EXTENSIONS_CLIENT_H_
|
|
@ -50,6 +50,7 @@ void AtomRendererClient::RenderFrameCreated(
|
|||
|
||||
void AtomRendererClient::RunScriptsAtDocumentStart(
|
||||
content::RenderFrame* render_frame) {
|
||||
RendererClientBase::RunScriptsAtDocumentStart(render_frame);
|
||||
// Inform the document start pharse.
|
||||
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
|
||||
node::Environment* env = GetEnvironment(render_frame);
|
||||
|
@ -59,6 +60,7 @@ void AtomRendererClient::RunScriptsAtDocumentStart(
|
|||
|
||||
void AtomRendererClient::RunScriptsAtDocumentEnd(
|
||||
content::RenderFrame* render_frame) {
|
||||
RendererClientBase::RunScriptsAtDocumentEnd(render_frame);
|
||||
// Inform the document end pharse.
|
||||
v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
|
||||
node::Environment* env = GetEnvironment(render_frame);
|
||||
|
|
|
@ -165,6 +165,7 @@ void AtomSandboxedRendererClient::RenderViewCreated(
|
|||
|
||||
void AtomSandboxedRendererClient::RunScriptsAtDocumentStart(
|
||||
content::RenderFrame* render_frame) {
|
||||
RendererClientBase::RunScriptsAtDocumentStart(render_frame);
|
||||
if (injected_frames_.find(render_frame) == injected_frames_.end())
|
||||
return;
|
||||
|
||||
|
@ -180,6 +181,7 @@ void AtomSandboxedRendererClient::RunScriptsAtDocumentStart(
|
|||
|
||||
void AtomSandboxedRendererClient::RunScriptsAtDocumentEnd(
|
||||
content::RenderFrame* render_frame) {
|
||||
RendererClientBase::RunScriptsAtDocumentEnd(render_frame);
|
||||
if (injected_frames_.find(render_frame) == injected_frames_.end())
|
||||
return;
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
// 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.
|
||||
|
||||
#include "shell/renderer/extensions/atom_extensions_renderer_client.h"
|
||||
|
||||
#include "content/public/renderer/render_thread.h"
|
||||
#include "extensions/renderer/dispatcher.h"
|
||||
#include "extensions/renderer/dispatcher_delegate.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
AtomExtensionsRendererClient::AtomExtensionsRendererClient()
|
||||
: dispatcher_(std::make_unique<extensions::Dispatcher>(
|
||||
std::make_unique<extensions::DispatcherDelegate>())) {
|
||||
dispatcher_->OnRenderThreadStarted(content::RenderThread::Get());
|
||||
}
|
||||
|
||||
AtomExtensionsRendererClient::~AtomExtensionsRendererClient() {}
|
||||
|
||||
bool AtomExtensionsRendererClient::IsIncognitoProcess() const {
|
||||
// app_shell doesn't support off-the-record contexts.
|
||||
return false;
|
||||
}
|
||||
|
||||
int AtomExtensionsRendererClient::GetLowestIsolatedWorldId() const {
|
||||
// app_shell doesn't need to reserve world IDs for anything other than
|
||||
// extensions, so we always return 1. Note that 0 is reserved for the global
|
||||
// world.
|
||||
// TODO(samuelmaddock): skip electron worlds
|
||||
return 10;
|
||||
}
|
||||
|
||||
extensions::Dispatcher* AtomExtensionsRendererClient::GetDispatcher() {
|
||||
return dispatcher_.get();
|
||||
}
|
||||
|
||||
bool AtomExtensionsRendererClient::ExtensionAPIEnabledForServiceWorkerScript(
|
||||
const GURL& scope,
|
||||
const GURL& script_url) const {
|
||||
// TODO(nornagon): adapt logic from chrome's version
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtomExtensionsRendererClient::AllowPopup() {
|
||||
// TODO(samuelmaddock):
|
||||
return false;
|
||||
}
|
||||
|
||||
void AtomExtensionsRendererClient::RunScriptsAtDocumentStart(
|
||||
content::RenderFrame* render_frame) {
|
||||
dispatcher_->RunScriptsAtDocumentStart(render_frame);
|
||||
}
|
||||
|
||||
void AtomExtensionsRendererClient::RunScriptsAtDocumentEnd(
|
||||
content::RenderFrame* render_frame) {
|
||||
dispatcher_->RunScriptsAtDocumentEnd(render_frame);
|
||||
}
|
||||
|
||||
void AtomExtensionsRendererClient::RunScriptsAtDocumentIdle(
|
||||
content::RenderFrame* render_frame) {
|
||||
dispatcher_->RunScriptsAtDocumentIdle(render_frame);
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) 2017 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_RENDERER_EXTENSIONS_ATOM_EXTENSIONS_RENDERER_CLIENT_H_
|
||||
#define SHELL_RENDERER_EXTENSIONS_ATOM_EXTENSIONS_RENDERER_CLIENT_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "extensions/renderer/extensions_renderer_client.h"
|
||||
|
||||
namespace content {
|
||||
class RenderFrame;
|
||||
}
|
||||
|
||||
namespace extensions {
|
||||
class Dispatcher;
|
||||
}
|
||||
|
||||
namespace electron {
|
||||
|
||||
class AtomExtensionsRendererClient
|
||||
: public extensions::ExtensionsRendererClient {
|
||||
public:
|
||||
AtomExtensionsRendererClient();
|
||||
~AtomExtensionsRendererClient() override;
|
||||
|
||||
// ExtensionsRendererClient implementation.
|
||||
bool IsIncognitoProcess() const override;
|
||||
int GetLowestIsolatedWorldId() const override;
|
||||
extensions::Dispatcher* GetDispatcher() override;
|
||||
bool ExtensionAPIEnabledForServiceWorkerScript(
|
||||
const GURL& scope,
|
||||
const GURL& script_url) const override;
|
||||
|
||||
bool AllowPopup();
|
||||
|
||||
void RunScriptsAtDocumentStart(content::RenderFrame* render_frame);
|
||||
void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame);
|
||||
void RunScriptsAtDocumentIdle(content::RenderFrame* render_frame);
|
||||
|
||||
private:
|
||||
std::unique_ptr<extensions::Dispatcher> dispatcher_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomExtensionsRendererClient);
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // SHELL_RENDERER_EXTENSIONS_ATOM_EXTENSIONS_RENDERER_CLIENT_H_
|
|
@ -15,6 +15,7 @@
|
|||
#include "content/public/common/content_constants.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/renderer/render_frame.h"
|
||||
#include "content/public/renderer/render_thread.h"
|
||||
#include "content/public/renderer/render_view.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
@ -62,6 +63,17 @@
|
|||
#include "shell/renderer/printing/print_render_frame_helper_delegate.h"
|
||||
#endif // BUILDFLAG(ENABLE_PRINTING)
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
#include "extensions/common/extensions_client.h"
|
||||
#include "extensions/renderer/dispatcher.h"
|
||||
#include "extensions/renderer/extension_frame_helper.h"
|
||||
#include "extensions/renderer/guest_view/extensions_guest_view_container.h"
|
||||
#include "extensions/renderer/guest_view/extensions_guest_view_container_dispatcher.h"
|
||||
#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container.h"
|
||||
#include "shell/common/extensions/atom_extensions_client.h"
|
||||
#include "shell/renderer/extensions/atom_extensions_renderer_client.h"
|
||||
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
@ -128,6 +140,18 @@ void RendererClientBase::RenderThreadStarted() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto* thread = content::RenderThread::Get();
|
||||
|
||||
extensions_client_.reset(CreateExtensionsClient());
|
||||
extensions::ExtensionsClient::Set(extensions_client_.get());
|
||||
|
||||
extensions_renderer_client_.reset(new AtomExtensionsRendererClient);
|
||||
extensions::ExtensionsRendererClient::Set(extensions_renderer_client_.get());
|
||||
|
||||
thread->AddObserver(extensions_renderer_client_->GetDispatcher());
|
||||
#endif
|
||||
|
||||
blink::WebCustomElement::AddEmbedderCustomElementName("webview");
|
||||
blink::WebCustomElement::AddEmbedderCustomElementName("browserplugin");
|
||||
|
||||
|
@ -236,6 +260,14 @@ void RendererClientBase::RenderFrameCreated(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
auto* dispatcher = extensions_renderer_client_->GetDispatcher();
|
||||
// ExtensionFrameHelper destroys itself when the RenderFrame is destroyed.
|
||||
new extensions::ExtensionFrameHelper(render_frame, dispatcher);
|
||||
|
||||
dispatcher->OnRenderFrameCreated(render_frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RendererClientBase::DidClearWindowObject(
|
||||
|
@ -291,6 +323,27 @@ void RendererClientBase::DidSetUserAgent(const std::string& user_agent) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void RendererClientBase::RunScriptsAtDocumentStart(
|
||||
content::RenderFrame* render_frame) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
extensions_renderer_client_.get()->RunScriptsAtDocumentStart(render_frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RendererClientBase::RunScriptsAtDocumentIdle(
|
||||
content::RenderFrame* render_frame) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
extensions_renderer_client_.get()->RunScriptsAtDocumentIdle(render_frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RendererClientBase::RunScriptsAtDocumentEnd(
|
||||
content::RenderFrame* render_frame) {
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
extensions_renderer_client_.get()->RunScriptsAtDocumentEnd(render_frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> RendererClientBase::GetContext(
|
||||
blink::WebLocalFrame* frame,
|
||||
v8::Isolate* isolate) const {
|
||||
|
@ -310,6 +363,12 @@ v8::Local<v8::Value> RendererClientBase::RunScript(
|
|||
return script->Run(context).ToLocalChecked();
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
extensions::ExtensionsClient* RendererClientBase::CreateExtensionsClient() {
|
||||
return new AtomExtensionsClient;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool RendererClientBase::IsWebViewFrame(
|
||||
v8::Handle<v8::Context> context,
|
||||
content::RenderFrame* render_frame) const {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "content/public/renderer/content_renderer_client.h"
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "third_party/blink/public/web/web_local_frame.h"
|
||||
// In SHARED_INTERMEDIATE_DIR.
|
||||
#include "widevine_cdm_version.h" // NOLINT(build/include)
|
||||
|
@ -18,8 +19,18 @@
|
|||
#include "chrome/renderer/media/chrome_key_systems_provider.h" // nogncheck
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
namespace extensions {
|
||||
class ExtensionsClient;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
class AtomExtensionsRendererClient;
|
||||
#endif
|
||||
|
||||
class RendererClientBase : public content::ContentRendererClient {
|
||||
public:
|
||||
RendererClientBase();
|
||||
|
@ -67,7 +78,22 @@ class RendererClientBase : public content::ContentRendererClient {
|
|||
bool IsKeySystemsUpdateNeeded() override;
|
||||
void DidSetUserAgent(const std::string& user_agent) override;
|
||||
|
||||
void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override;
|
||||
void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override;
|
||||
void RunScriptsAtDocumentIdle(content::RenderFrame* render_frame) override;
|
||||
|
||||
protected:
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
// app_shell embedders may need custom extensions client interfaces.
|
||||
// This class takes ownership of the returned object.
|
||||
virtual extensions::ExtensionsClient* CreateExtensionsClient();
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
|
||||
std::unique_ptr<extensions::ExtensionsClient> extensions_client_;
|
||||
std::unique_ptr<AtomExtensionsRendererClient> extensions_renderer_client_;
|
||||
#endif
|
||||
#if defined(WIDEVINE_CDM_AVAILABLE)
|
||||
ChromeKeySystemsProvider key_systems_provider_;
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,7 @@ const dumpFileDynamic = path.join(os.tmpdir(), 'net_log_dynamic.json')
|
|||
const { expect } = chai
|
||||
chai.use(dirtyChai)
|
||||
const isCI = global.isCI
|
||||
const netLog = session.fromPartition('net-log').netLog
|
||||
const testNetLog = () => session.fromPartition('net-log').netLog
|
||||
|
||||
describe('netLog module', () => {
|
||||
let server
|
||||
|
@ -47,7 +47,7 @@ describe('netLog module', () => {
|
|||
})
|
||||
|
||||
beforeEach(() => {
|
||||
expect(netLog.currentlyLogging).to.be.false()
|
||||
expect(testNetLog().currentlyLogging).to.be.false()
|
||||
})
|
||||
afterEach(() => {
|
||||
try {
|
||||
|
@ -60,29 +60,29 @@ describe('netLog module', () => {
|
|||
} catch (e) {
|
||||
// Ignore error
|
||||
}
|
||||
expect(netLog.currentlyLogging).to.be.false()
|
||||
expect(testNetLog().currentlyLogging).to.be.false()
|
||||
})
|
||||
|
||||
it('should begin and end logging to file when .startLogging() and .stopLogging() is called', async () => {
|
||||
await netLog.startLogging(dumpFileDynamic)
|
||||
await testNetLog().startLogging(dumpFileDynamic)
|
||||
|
||||
expect(netLog.currentlyLogging).to.be.true()
|
||||
expect(testNetLog().currentlyLogging).to.be.true()
|
||||
|
||||
expect(netLog.currentlyLoggingPath).to.equal(dumpFileDynamic)
|
||||
expect(testNetLog().currentlyLoggingPath).to.equal(dumpFileDynamic)
|
||||
|
||||
await netLog.stopLogging()
|
||||
await testNetLog().stopLogging()
|
||||
|
||||
expect(fs.existsSync(dumpFileDynamic)).to.be.true()
|
||||
})
|
||||
|
||||
it('should throw an error when .stopLogging() is called without calling .startLogging()', async () => {
|
||||
await expect(netLog.stopLogging()).to.be.rejectedWith('No net log in progress')
|
||||
await expect(testNetLog().stopLogging()).to.be.rejectedWith('No net log in progress')
|
||||
})
|
||||
|
||||
it('should throw an error when .startLogging() is called with an invalid argument', () => {
|
||||
expect(() => netLog.startLogging('')).to.throw()
|
||||
expect(() => netLog.startLogging(null)).to.throw()
|
||||
expect(() => netLog.startLogging([])).to.throw()
|
||||
expect(() => testNetLog().startLogging('')).to.throw()
|
||||
expect(() => testNetLog().startLogging(null)).to.throw()
|
||||
expect(() => testNetLog().startLogging([])).to.throw()
|
||||
})
|
||||
|
||||
it('should begin and end logging automatically when --log-net-log is passed', done => {
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
import { expect } from 'chai'
|
||||
import { session, BrowserWindow, ipcMain } from 'electron'
|
||||
import { closeAllWindows } from './window-helpers'
|
||||
import * as http from 'http'
|
||||
import { AddressInfo } from 'net'
|
||||
import * as path from 'path'
|
||||
import { ifdescribe } from './spec-helpers'
|
||||
import { emittedOnce } from './events-helpers'
|
||||
|
||||
const fixtures = path.join(__dirname, 'fixtures')
|
||||
|
||||
ifdescribe(process.electronBinding('features').isExtensionsEnabled())('chrome extensions', () => {
|
||||
// NB. extensions are only allowed on http://, https:// and ftp:// (!) urls by default.
|
||||
let server: http.Server
|
||||
let url: string
|
||||
before(async () => {
|
||||
server = http.createServer((req, res) => res.end())
|
||||
await new Promise(resolve => server.listen(0, '127.0.0.1', () => {
|
||||
url = `http://127.0.0.1:${(server.address() as AddressInfo).port}`
|
||||
resolve()
|
||||
}))
|
||||
})
|
||||
after(() => {
|
||||
server.close()
|
||||
})
|
||||
|
||||
afterEach(closeAllWindows)
|
||||
it('loads an extension', async () => {
|
||||
// NB. we have to use a persist: session (i.e. non-OTR) because the
|
||||
// extension registry is redirected to the main session. so installing an
|
||||
// extension in an in-memory session results in it being installed in the
|
||||
// default session.
|
||||
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
|
||||
(customSession as any).loadChromeExtension(path.join(fixtures, 'extensions', 'red-bg'))
|
||||
const w = new BrowserWindow({show: false, webPreferences: {session: customSession}})
|
||||
await w.loadURL(url)
|
||||
const bg = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor')
|
||||
expect(bg).to.equal('red')
|
||||
})
|
||||
|
||||
it('confines an extension to the session it was loaded in', async () => {
|
||||
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
|
||||
(customSession as any).loadChromeExtension(path.join(fixtures, 'extensions', 'red-bg'))
|
||||
const w = new BrowserWindow({show: false}) // not in the session
|
||||
await w.loadURL(url)
|
||||
const bg = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor')
|
||||
expect(bg).to.equal('')
|
||||
})
|
||||
|
||||
describe('chrome.runtime', () => {
|
||||
let content: any
|
||||
before(async () => {
|
||||
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
|
||||
(customSession as any).loadChromeExtension(path.join(fixtures, 'extensions', 'chrome-runtime'))
|
||||
const w = new BrowserWindow({show: false, webPreferences: { session: customSession }})
|
||||
try {
|
||||
await w.loadURL(url)
|
||||
content = JSON.parse(await w.webContents.executeJavaScript('document.documentElement.textContent'))
|
||||
expect(content).to.be.an('object')
|
||||
} finally {
|
||||
w.destroy()
|
||||
}
|
||||
})
|
||||
it('getManifest()', () => {
|
||||
expect(content.manifest).to.be.an('object').with.property('name', 'chrome-runtime')
|
||||
})
|
||||
it('id', () => {
|
||||
expect(content.id).to.be.a('string').with.lengthOf(32)
|
||||
})
|
||||
it('getURL()', () => {
|
||||
expect(content.url).to.be.a('string').and.match(/^chrome-extension:\/\/.*main.js$/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('chrome.storage', () => {
|
||||
it('stores and retrieves a key', async () => {
|
||||
const customSession = session.fromPartition(`persist:${require('uuid').v4()}`);
|
||||
(customSession as any).loadChromeExtension(path.join(fixtures, 'extensions', 'chrome-storage'))
|
||||
const w = new BrowserWindow({show: false, webPreferences: { session: customSession, nodeIntegration: true }})
|
||||
try {
|
||||
const p = emittedOnce(ipcMain, 'storage-success')
|
||||
await w.loadURL(url)
|
||||
const [, v] = await p
|
||||
expect(v).to.equal('value')
|
||||
} finally {
|
||||
w.destroy()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,5 @@
|
|||
document.documentElement.textContent = JSON.stringify({
|
||||
manifest: chrome.runtime.getManifest(),
|
||||
id: chrome.runtime.id,
|
||||
url: chrome.runtime.getURL('main.js'),
|
||||
})
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "chrome-runtime",
|
||||
"version": "1.0",
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["main.js"],
|
||||
"run_at": "document_start"
|
||||
}
|
||||
],
|
||||
"manifest_version": 2
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
chrome.storage.local.set({key: 'value'}, () => {
|
||||
chrome.storage.local.get(['key'], ({key}) => {
|
||||
const script = document.createElement('script')
|
||||
script.textContent = `require('electron').ipcRenderer.send('storage-success', ${JSON.stringify(key)})`
|
||||
document.documentElement.appendChild(script)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "chrome-storage",
|
||||
"version": "1.0",
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["main.js"],
|
||||
"run_at": "document_start"
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
"storage"
|
||||
],
|
||||
"manifest_version": 2
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
document.documentElement.style.backgroundColor = 'red'
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "red-bg",
|
||||
"version": "1.0",
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["main.js"],
|
||||
"run_at": "document_start"
|
||||
}
|
||||
],
|
||||
"manifest_version": 2
|
||||
}
|
|
@ -10,6 +10,7 @@ declare namespace NodeJS {
|
|||
isViewApiEnabled(): boolean;
|
||||
isTtsEnabled(): boolean;
|
||||
isPrintingEnabled(): boolean;
|
||||
isExtensionsEnabled(): boolean;
|
||||
isComponentBuild(): boolean;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче