feat: preliminary support for //extensions (#17440)

This commit is contained in:
Samuel Maddock 2019-07-24 19:01:08 -04:00 коммит произвёл Jeremy Apthorp
Родитель bd526f97a5
Коммит 95977291f7
54 изменённых файлов: 2483 добавлений и 36 удалений

Просмотреть файл

@ -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
}

1
typings/internal-ambient.d.ts поставляемый
Просмотреть файл

@ -10,6 +10,7 @@ declare namespace NodeJS {
isViewApiEnabled(): boolean;
isTtsEnabled(): boolean;
isPrintingEnabled(): boolean;
isExtensionsEnabled(): boolean;
isComponentBuild(): boolean;
}