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:
Kris Maglione 2017-05-26 12:07:06 -07:00
Родитель 2f16ad43cb
Коммит 1bc28104c6
10 изменённых файлов: 66 добавлений и 74 удалений

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

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