зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1368102: Part 8 - Move extension page matching into C++. r=billm,mixedpuppy
Bill, can you please review the WebIDL change, and Shane the rest? MozReview-Commit-ID: 6N3sGrAsHzs --HG-- extra : rebase_source : adb925ec3dc2a350fc6f9d6cde7a3607f6877384
This commit is contained in:
Родитель
2f16ad43cb
Коммит
1bc28104c6
|
@ -77,6 +77,9 @@ interface WebExtensionPolicy {
|
|||
attribute boolean active;
|
||||
|
||||
|
||||
static readonly attribute boolean isExtensionProcess;
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the extension has cross-origin access to the given URI.
|
||||
*/
|
||||
|
|
|
@ -22,9 +22,6 @@ XPCOMUtils.defineLazyGetter(this, "UUIDMap", () => {
|
|||
return UUIDMap;
|
||||
});
|
||||
|
||||
const {appinfo} = Services;
|
||||
const isParentProcess = appinfo.processType === appinfo.PROCESS_TYPE_DEFAULT;
|
||||
|
||||
/*
|
||||
* This file should be kept short and simple since it's loaded even
|
||||
* when no extensions are running.
|
||||
|
@ -88,10 +85,7 @@ var ExtensionManagement = {
|
|||
},
|
||||
|
||||
get isExtensionProcess() {
|
||||
if (this.useRemoteWebExtensions) {
|
||||
return appinfo.remoteType === E10SUtils.EXTENSION_REMOTE_TYPE;
|
||||
}
|
||||
return isParentProcess;
|
||||
return WebExtensionPolicy.isExtensionProcess;
|
||||
},
|
||||
|
||||
// Called when a new extension is loaded.
|
||||
|
|
|
@ -23,8 +23,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionChildDevToolsUtils",
|
||||
"resource://gre/modules/ExtensionChildDevToolsUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionManagement",
|
||||
"resource://gre/modules/ExtensionManagement.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Schemas",
|
||||
"resource://gre/modules/Schemas.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "WebNavigationFrames",
|
||||
|
@ -406,7 +404,7 @@ ExtensionPageChild = {
|
|||
},
|
||||
|
||||
init(global) {
|
||||
if (!ExtensionManagement.isExtensionProcess) {
|
||||
if (!WebExtensionPolicy.isExtensionProcess) {
|
||||
throw new Error("Cannot init extension page global in current process");
|
||||
}
|
||||
|
||||
|
@ -440,7 +438,7 @@ ExtensionPageChild = {
|
|||
initExtensionContext(extension, contentWindow) {
|
||||
this._init();
|
||||
|
||||
if (!ExtensionManagement.isExtensionProcess) {
|
||||
if (!WebExtensionPolicy.isExtensionProcess) {
|
||||
throw new Error("Cannot create an extension page context in current process");
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,14 @@
|
|||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozIExtensionProcessScript.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -54,6 +57,8 @@ ProcessScript()
|
|||
* ExtensionPolicyService
|
||||
*****************************************************************************/
|
||||
|
||||
/* static */ bool ExtensionPolicyService::sRemoteExtensions;
|
||||
|
||||
/* static */ ExtensionPolicyService&
|
||||
ExtensionPolicyService::GetSingleton()
|
||||
{
|
||||
|
@ -71,10 +76,23 @@ ExtensionPolicyService::ExtensionPolicyService()
|
|||
mObs = services::GetObserverService();
|
||||
MOZ_RELEASE_ASSERT(mObs);
|
||||
|
||||
Preferences::AddBoolVarCache(&sRemoteExtensions, "extensions.webextensions.remote", false);
|
||||
|
||||
RegisterObservers();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ExtensionPolicyService::IsExtensionProcess() const
|
||||
{
|
||||
if (sRemoteExtensions && XRE_IsContentProcess()) {
|
||||
auto& remoteType = dom::ContentChild::GetSingleton()->GetRemoteType();
|
||||
return remoteType.EqualsLiteral(EXTENSION_REMOTE_TYPE);
|
||||
}
|
||||
return XRE_IsParentProcess();
|
||||
}
|
||||
|
||||
|
||||
WebExtensionPolicy*
|
||||
ExtensionPolicyService::GetByURL(const URLInfo& aURL)
|
||||
{
|
||||
|
@ -227,6 +245,17 @@ ExtensionPolicyService::CheckDocument(nsIDocument* aDocument)
|
|||
nsCOMPtr<nsPIDOMWindowOuter> win = aDocument->GetWindow();
|
||||
if (win) {
|
||||
CheckContentScripts(win.get(), false);
|
||||
|
||||
nsIPrincipal* principal = aDocument->NodePrincipal();
|
||||
|
||||
nsAutoString addonId;
|
||||
Unused << principal->GetAddonId(addonId);
|
||||
|
||||
RefPtr<WebExtensionPolicy> policy = GetByID(addonId);
|
||||
if (policy) {
|
||||
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDocument);
|
||||
ProcessScript().InitExtensionDocument(policy, doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,8 @@ public:
|
|||
void BaseCSP(nsAString& aDefaultCSP) const;
|
||||
void DefaultCSP(nsAString& aDefaultCSP) const;
|
||||
|
||||
bool IsExtensionProcess() const;
|
||||
|
||||
protected:
|
||||
virtual ~ExtensionPolicyService() = default;
|
||||
|
||||
|
@ -94,6 +96,8 @@ private:
|
|||
nsRefPtrHashtable<nsCStringHashKey, WebExtensionPolicy> mExtensionHosts;
|
||||
|
||||
nsCOMPtr<nsIObserverService> mObs;
|
||||
|
||||
static bool sRemoteExtensions;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -239,6 +239,12 @@ WebExtensionPolicy::GetURL(const nsAString& aPath) const
|
|||
return NS_ConvertUTF8toUTF16(spec);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
WebExtensionPolicy::IsExtensionProcess(GlobalObject& aGlobal)
|
||||
{
|
||||
return EPS().IsExtensionProcess();
|
||||
}
|
||||
|
||||
nsCString
|
||||
WebExtensionPolicy::BackgroundPageHTML() const
|
||||
{
|
||||
|
|
|
@ -131,6 +131,9 @@ public:
|
|||
GetByURI(dom::GlobalObject& aGlobal, nsIURI* aURI);
|
||||
|
||||
|
||||
static bool IsExtensionProcess(dom::GlobalObject& aGlobal);
|
||||
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::HandleObject aGivenProto) override;
|
||||
|
|
|
@ -15,8 +15,6 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionManagement",
|
||||
"resource://gre/modules/ExtensionManagement.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "MessageChannel",
|
||||
"resource://gre/modules/MessageChannel.jsm");
|
||||
|
||||
|
@ -93,9 +91,6 @@ class ExtensionGlobal {
|
|||
MessageChannel.addListener(global, "WebNavigation:GetAllFrames", this);
|
||||
}
|
||||
|
||||
uninit() {
|
||||
}
|
||||
|
||||
get messageFilterStrict() {
|
||||
return {
|
||||
innerWindowID: getInnerWindowID(this.global.content),
|
||||
|
@ -143,17 +138,9 @@ DocumentManager = {
|
|||
Services.obs.addObserver(this, "tab-content-frameloader-created"); // eslint-disable-line mozilla/balanced-listeners
|
||||
},
|
||||
|
||||
// Initialize listeners that we need when any extension is enabled.
|
||||
init() {
|
||||
Services.obs.addObserver(this, "document-element-inserted");
|
||||
},
|
||||
uninit() {
|
||||
Services.obs.removeObserver(this, "document-element-inserted");
|
||||
},
|
||||
|
||||
extensionProcessInitialized: false,
|
||||
initExtensionProcess() {
|
||||
if (this.extensionProcessInitialized || !ExtensionManagement.isExtensionProcess) {
|
||||
if (this.extensionProcessInitialized || !WebExtensionPolicy.isExtensionProcess) {
|
||||
return;
|
||||
}
|
||||
this.extensionProcessInitialized = true;
|
||||
|
@ -172,8 +159,7 @@ DocumentManager = {
|
|||
});
|
||||
|
||||
this.globals.set(global, new ExtensionGlobal(global));
|
||||
this.initExtensionProcess();
|
||||
if (this.extensionProcessInitialized && ExtensionManagement.isExtensionProcess) {
|
||||
if (this.extensionProcessInitialized && WebExtensionPolicy.isExtensionProcess) {
|
||||
ExtensionPageChild.init(global);
|
||||
}
|
||||
},
|
||||
|
@ -181,50 +167,21 @@ DocumentManager = {
|
|||
if (this.extensionProcessInitialized) {
|
||||
ExtensionPageChild.uninit(global);
|
||||
}
|
||||
this.globals.get(global).uninit();
|
||||
this.globals.delete(global);
|
||||
},
|
||||
|
||||
initExtension(extension) {
|
||||
if (this.extensionCount === 0) {
|
||||
this.init();
|
||||
this.initExtensionProcess();
|
||||
}
|
||||
this.extensionCount++;
|
||||
this.initExtensionProcess();
|
||||
|
||||
this.injectExtensionScripts(extension);
|
||||
},
|
||||
uninitExtension(extension) {
|
||||
this.extensionCount--;
|
||||
if (this.extensionCount === 0) {
|
||||
this.uninit();
|
||||
}
|
||||
},
|
||||
|
||||
extensionCount: 0,
|
||||
|
||||
// Listeners
|
||||
|
||||
observers: {
|
||||
"document-element-inserted"(document) {
|
||||
let window = document.defaultView;
|
||||
if (!document.location || !window ||
|
||||
// Make sure we only load into frames that belong to tabs, or other
|
||||
// special areas that we want to load content scripts into.
|
||||
!this.globals.has(getMessageManager(window))) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadInto(window);
|
||||
},
|
||||
|
||||
"tab-content-frameloader-created"(global) {
|
||||
this.initGlobal(global);
|
||||
},
|
||||
},
|
||||
|
||||
observe(subject, topic, data) {
|
||||
this.observers[topic].call(this, subject, topic, data);
|
||||
if (topic == "tab-content-frameloader-created") {
|
||||
this.initGlobal(subject);
|
||||
}
|
||||
},
|
||||
|
||||
// Script loading
|
||||
|
@ -281,19 +238,9 @@ DocumentManager = {
|
|||
return true;
|
||||
},
|
||||
|
||||
loadInto(window) {
|
||||
let {addonId} = Cu.getObjectPrincipal(window);
|
||||
if (!addonId) {
|
||||
return;
|
||||
}
|
||||
|
||||
let policy = WebExtensionPolicy.getByID(addonId);
|
||||
if (!policy) {
|
||||
throw new Error(`No registered extension for ID ${addonId}`);
|
||||
}
|
||||
|
||||
loadInto(policy, window) {
|
||||
let extension = extensions.get(policy);
|
||||
if (this.checkParentFrames(window, addonId) && ExtensionManagement.isExtensionProcess) {
|
||||
if (WebExtensionPolicy.isExtensionProcess && this.checkParentFrames(window, policy.id)) {
|
||||
// We're in a top-level extension frame, or a sub-frame thereof,
|
||||
// in the extension process. Inject the full extension page API.
|
||||
ExtensionPageChild.initExtensionContext(extension, window);
|
||||
|
@ -395,8 +342,6 @@ ExtensionManager = {
|
|||
extensions.get(policy).shutdown();
|
||||
}
|
||||
|
||||
DocumentManager.uninitExtension(policy);
|
||||
|
||||
if (isContentProcess) {
|
||||
policy.active = false;
|
||||
}
|
||||
|
@ -431,6 +376,12 @@ ExtensionProcessScript.prototype = {
|
|||
classID: Components.ID("{21f9819e-4cdf-49f9-85a0-850af91a5058}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.mozIExtensionProcessScript]),
|
||||
|
||||
initExtensionDocument(policy, doc) {
|
||||
if (DocumentManager.globals.has(getMessageManager(doc.defaultView))) {
|
||||
DocumentManager.loadInto(policy, doc.defaultView);
|
||||
}
|
||||
},
|
||||
|
||||
preloadContentScript(contentScript) {
|
||||
contentScripts.get(contentScript).preload();
|
||||
},
|
||||
|
|
|
@ -88,3 +88,5 @@ XPCSHELL_TESTS_MANIFESTS += [
|
|||
'test/xpcshell/xpcshell-remote.ini',
|
||||
'test/xpcshell/xpcshell.ini',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
interface mozIDOMWindowProxy;
|
||||
interface nsIDOMDocument;
|
||||
|
||||
[scriptable,uuid(6b09dc51-6caa-4ca7-9d6d-30c87258a630)]
|
||||
interface mozIExtensionProcessScript : nsISupports
|
||||
|
@ -13,4 +14,5 @@ interface mozIExtensionProcessScript : nsISupports
|
|||
|
||||
void loadContentScript(in nsISupports contentScript, in mozIDOMWindowProxy window);
|
||||
|
||||
void initExtensionDocument(in nsISupports extension, in nsIDOMDocument doc);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче