feat: [extensions] background pages (#21591)

This commit is contained in:
Jeremy Apthorp 2020-01-13 14:55:58 -08:00 committed by GitHub
parent cf497ea478
commit 8bc0c92137
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 477 additions and 11 deletions

View file

@ -28,6 +28,7 @@ scoped_refptr<const Extension> LoadUnpacked(
// 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.
// TODO(nornagon): these LOG()s should surface as JS exceptions
if (!base::DirectoryExists(extension_dir)) {
LOG(ERROR) << "Extension directory not found: "
<< extension_dir.AsUTF8Unsafe();

View file

@ -35,6 +35,8 @@
// #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"
#include "shell/browser/extensions/electron_extensions_api_client.h"
#include "shell/browser/extensions/electron_process_manager_delegate.h"
using content::BrowserContext;
using content::BrowserThread;
@ -42,10 +44,10 @@ using content::BrowserThread;
namespace electron {
AtomExtensionsBrowserClient::AtomExtensionsBrowserClient()
: api_client_(new extensions::ExtensionsAPIClient),
// : api_client_(new extensions::AtomExtensionsAPIClient),
: api_client_(new extensions::ElectronExtensionsAPIClient),
process_manager_delegate_(new extensions::ElectronProcessManagerDelegate),
extension_cache_(new extensions::NullExtensionCache()) {
// app_shell does not have a concept of channel yet, so leave UNKNOWN to
// Electron does not have a concept of channel, so leave UNKNOWN to
// enable all channel-dependent extension APIs.
extensions::SetCurrentChannel(version_info::Channel::UNKNOWN);
@ -168,7 +170,7 @@ void AtomExtensionsBrowserClient::GetEarlyExtensionPrefsObservers(
extensions::ProcessManagerDelegate*
AtomExtensionsBrowserClient::GetProcessManagerDelegate() const {
return NULL;
return process_manager_delegate_.get();
}
std::unique_ptr<extensions::ExtensionHostDelegate> AtomExtensionsBrowserClient::

View file

@ -21,6 +21,7 @@ namespace extensions {
class ExtensionsAPIClient;
class KioskDelegate;
class ProcessManagerDelegate;
class ElectronProcessManagerDelegate;
class ProcessMap;
} // namespace extensions
@ -134,6 +135,10 @@ class AtomExtensionsBrowserClient : public extensions::ExtensionsBrowserClient {
// Support for extension APIs.
std::unique_ptr<extensions::ExtensionsAPIClient> api_client_;
// Support for ProcessManager.
std::unique_ptr<extensions::ElectronProcessManagerDelegate>
process_manager_delegate_;
// The extension cache used for download and installation.
std::unique_ptr<extensions::ExtensionCache> extension_cache_;

View file

@ -0,0 +1,29 @@
// Copyright (c) 2019 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/extensions/electron_extensions_api_client.h"
#include <memory>
#include "shell/browser/extensions/atom_extension_web_contents_observer.h"
#include "shell/browser/extensions/electron_messaging_delegate.h"
namespace extensions {
ElectronExtensionsAPIClient::ElectronExtensionsAPIClient() = default;
ElectronExtensionsAPIClient::~ElectronExtensionsAPIClient() = default;
MessagingDelegate* ElectronExtensionsAPIClient::GetMessagingDelegate() {
if (!messaging_delegate_)
messaging_delegate_ = std::make_unique<ElectronMessagingDelegate>();
return messaging_delegate_.get();
}
void ElectronExtensionsAPIClient::AttachWebContentsHelpers(
content::WebContents* web_contents) const {
extensions::AtomExtensionWebContentsObserver::CreateForWebContents(
web_contents);
}
} // namespace extensions

View file

@ -0,0 +1,32 @@
// Copyright (c) 2019 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_EXTENSIONS_ELECTRON_EXTENSIONS_API_CLIENT_H_
#define SHELL_BROWSER_EXTENSIONS_ELECTRON_EXTENSIONS_API_CLIENT_H_
#include <memory>
#include "extensions/browser/api/extensions_api_client.h"
namespace extensions {
class ElectronMessagingDelegate;
class ElectronExtensionsAPIClient : public ExtensionsAPIClient {
public:
ElectronExtensionsAPIClient();
~ElectronExtensionsAPIClient() override;
// ExtensionsAPIClient
MessagingDelegate* GetMessagingDelegate() override;
void AttachWebContentsHelpers(
content::WebContents* web_contents) const override;
private:
std::unique_ptr<ElectronMessagingDelegate> messaging_delegate_;
};
} // namespace extensions
#endif // SHELL_BROWSER_EXTENSIONS_ELECTRON_EXTENSIONS_API_CLIENT_H_

View file

@ -0,0 +1,94 @@
// Copyright 2017 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/electron_messaging_delegate.h"
#include <memory>
#include "base/callback.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/api/messaging/extension_message_port.h"
#include "extensions/browser/api/messaging/native_message_host.h"
#include "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/browser/pref_names.h"
#include "extensions/common/api/messaging/port_id.h"
#include "extensions/common/extension.h"
#include "ui/gfx/native_widget_types.h"
#include "url/gurl.h"
namespace extensions {
ElectronMessagingDelegate::ElectronMessagingDelegate() = default;
ElectronMessagingDelegate::~ElectronMessagingDelegate() = default;
MessagingDelegate::PolicyPermission
ElectronMessagingDelegate::IsNativeMessagingHostAllowed(
content::BrowserContext* browser_context,
const std::string& native_host_name) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
return PolicyPermission::DISALLOW;
}
std::unique_ptr<base::DictionaryValue>
ElectronMessagingDelegate::MaybeGetTabInfo(content::WebContents* web_contents) {
return nullptr;
}
content::WebContents* ElectronMessagingDelegate::GetWebContentsByTabId(
content::BrowserContext* browser_context,
int tab_id) {
return nullptr;
}
std::unique_ptr<MessagePort> ElectronMessagingDelegate::CreateReceiverForTab(
base::WeakPtr<MessagePort::ChannelDelegate> channel_delegate,
const std::string& extension_id,
const PortId& receiver_port_id,
content::WebContents* receiver_contents,
int receiver_frame_id) {
// Frame ID -1 is every frame in the tab.
bool include_child_frames = receiver_frame_id == -1;
content::RenderFrameHost* receiver_rfh =
include_child_frames ? receiver_contents->GetMainFrame()
: ExtensionApiFrameIdMap::GetRenderFrameHostById(
receiver_contents, receiver_frame_id);
if (!receiver_rfh)
return nullptr;
return std::make_unique<ExtensionMessagePort>(
channel_delegate, receiver_port_id, extension_id, receiver_rfh,
include_child_frames);
}
std::unique_ptr<MessagePort>
ElectronMessagingDelegate::CreateReceiverForNativeApp(
content::BrowserContext* browser_context,
base::WeakPtr<MessagePort::ChannelDelegate> channel_delegate,
content::RenderFrameHost* source,
const std::string& extension_id,
const PortId& receiver_port_id,
const std::string& native_app_name,
bool allow_user_level,
std::string* error_out) {
return nullptr;
}
void ElectronMessagingDelegate::QueryIncognitoConnectability(
content::BrowserContext* context,
const Extension* target_extension,
content::WebContents* source_contents,
const GURL& source_url,
const base::Callback<void(bool)>& callback) {
DCHECK(context->IsOffTheRecord());
callback.Run(false);
}
} // namespace extensions

View file

@ -0,0 +1,58 @@
// Copyright (c) 2019 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef SHELL_BROWSER_EXTENSIONS_ELECTRON_MESSAGING_DELEGATE_H_
#define SHELL_BROWSER_EXTENSIONS_ELECTRON_MESSAGING_DELEGATE_H_
#include <memory>
#include <string>
#include "extensions/browser/api/messaging/messaging_delegate.h"
namespace extensions {
// Helper class for Chrome-specific features of the extension messaging API.
class ElectronMessagingDelegate : public MessagingDelegate {
public:
ElectronMessagingDelegate();
~ElectronMessagingDelegate() override;
// MessagingDelegate:
PolicyPermission IsNativeMessagingHostAllowed(
content::BrowserContext* browser_context,
const std::string& native_host_name) override;
std::unique_ptr<base::DictionaryValue> MaybeGetTabInfo(
content::WebContents* web_contents) override;
content::WebContents* GetWebContentsByTabId(
content::BrowserContext* browser_context,
int tab_id) override;
std::unique_ptr<MessagePort> CreateReceiverForTab(
base::WeakPtr<MessagePort::ChannelDelegate> channel_delegate,
const std::string& extension_id,
const PortId& receiver_port_id,
content::WebContents* receiver_contents,
int receiver_frame_id) override;
std::unique_ptr<MessagePort> CreateReceiverForNativeApp(
content::BrowserContext* browser_context,
base::WeakPtr<MessagePort::ChannelDelegate> channel_delegate,
content::RenderFrameHost* source,
const std::string& extension_id,
const PortId& receiver_port_id,
const std::string& native_app_name,
bool allow_user_level,
std::string* error_out) override;
void QueryIncognitoConnectability(
content::BrowserContext* context,
const Extension* extension,
content::WebContents* web_contents,
const GURL& url,
const base::Callback<void(bool)>& callback) override;
private:
DISALLOW_COPY_AND_ASSIGN(ElectronMessagingDelegate);
};
} // namespace extensions
#endif // SHELL_BROWSER_EXTENSIONS_ELECTRON_MESSAGING_DELEGATE_H_

View file

@ -0,0 +1,40 @@
// Copyright 2019 Slack Technologies, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/debug/stack_trace.h"
#include "shell/browser/extensions/electron_process_manager_delegate.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/one_shot_event.h"
#include "build/build_config.h"
#include "content/public/browser/notification_service.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/process_manager_factory.h"
#include "extensions/common/extension.h"
#include "extensions/common/permissions/permissions_data.h"
namespace extensions {
ElectronProcessManagerDelegate::ElectronProcessManagerDelegate() = default;
ElectronProcessManagerDelegate::~ElectronProcessManagerDelegate() = default;
bool ElectronProcessManagerDelegate::AreBackgroundPagesAllowedForContext(
content::BrowserContext* context) const {
return true;
}
bool ElectronProcessManagerDelegate::IsExtensionBackgroundPageAllowed(
content::BrowserContext* context,
const Extension& extension) const {
return true;
}
bool ElectronProcessManagerDelegate::DeferCreatingStartupBackgroundHosts(
content::BrowserContext* context) const {
return false;
}
} // namespace extensions

View file

@ -0,0 +1,41 @@
// Copyright 2019 Slack Technologies, Inc. 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_ELECTRON_PROCESS_MANAGER_DELEGATE_H_
#define SHELL_BROWSER_EXTENSIONS_ELECTRON_PROCESS_MANAGER_DELEGATE_H_
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "extensions/browser/process_manager_delegate.h"
class Browser;
class Profile;
namespace extensions {
// Support for ProcessManager. Controls cases where Electron wishes to disallow
// extension background pages or defer their creation.
class ElectronProcessManagerDelegate : public ProcessManagerDelegate {
public:
ElectronProcessManagerDelegate();
~ElectronProcessManagerDelegate() override;
// ProcessManagerDelegate implementation:
bool AreBackgroundPagesAllowedForContext(
content::BrowserContext* context) const override;
bool IsExtensionBackgroundPageAllowed(
content::BrowserContext* context,
const Extension& extension) const override;
bool DeferCreatingStartupBackgroundHosts(
content::BrowserContext* context) const override;
private:
DISALLOW_COPY_AND_ASSIGN(ElectronProcessManagerDelegate);
};
} // namespace extensions
#endif // SHELL_BROWSER_EXTENSIONS_ELECTRON_PROCESS_MANAGER_DELEGATE_H_