From d41a5e64ac8e67656df2b4e4d9b68424a9470ed4 Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Mon, 23 Mar 2015 08:40:08 -0500 Subject: [PATCH] Bug 1129040 - Add a blocklist shim in the content process and forward requests to the parent process. r=Mossop --- .../mozapps/extensions/extensions.manifest | 9 ++- toolkit/mozapps/extensions/moz.build | 1 + .../mozapps/extensions/nsBlocklistService.js | 25 +++++- .../extensions/nsBlocklistServiceContent.js | 80 +++++++++++++++++++ 4 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 toolkit/mozapps/extensions/nsBlocklistServiceContent.js diff --git a/toolkit/mozapps/extensions/extensions.manifest b/toolkit/mozapps/extensions/extensions.manifest index f0f00545f68..edf05f20ee9 100644 --- a/toolkit/mozapps/extensions/extensions.manifest +++ b/toolkit/mozapps/extensions/extensions.manifest @@ -1,6 +1,9 @@ -component {66354bc9-7ed1-4692-ae1d-8da97d6b205e} nsBlocklistService.js -contract @mozilla.org/extensions/blocklist;1 {66354bc9-7ed1-4692-ae1d-8da97d6b205e} -category profile-after-change nsBlocklistService @mozilla.org/extensions/blocklist;1 +component {66354bc9-7ed1-4692-ae1d-8da97d6b205e} nsBlocklistService.js process=main +contract @mozilla.org/extensions/blocklist;1 {66354bc9-7ed1-4692-ae1d-8da97d6b205e} process=main +category profile-after-change nsBlocklistService @mozilla.org/extensions/blocklist;1 process=main +component {e0a106ed-6ad4-47a4-b6af-2f1c8aa4712d} nsBlocklistServiceContent.js process=content +contract @mozilla.org/extensions/blocklist;1 {e0a106ed-6ad4-47a4-b6af-2f1c8aa4712d} process=content + #ifndef MOZ_WIDGET_GONK category update-timer nsBlocklistService @mozilla.org/extensions/blocklist;1,getService,blocklist-background-update-timer,extensions.blocklist.interval,86400 component {4399533d-08d1-458c-a87a-235f74451cfa} addonManager.js diff --git a/toolkit/mozapps/extensions/moz.build b/toolkit/mozapps/extensions/moz.build index 234fda4ec7b..702063c3534 100644 --- a/toolkit/mozapps/extensions/moz.build +++ b/toolkit/mozapps/extensions/moz.build @@ -26,6 +26,7 @@ EXTRA_COMPONENTS += [ EXTRA_PP_COMPONENTS += [ 'extensions.manifest', 'nsBlocklistService.js', + 'nsBlocklistServiceContent.js', ] EXTRA_JS_MODULES += [ diff --git a/toolkit/mozapps/extensions/nsBlocklistService.js b/toolkit/mozapps/extensions/nsBlocklistService.js index e3210a4e547..68f228d3563 100644 --- a/toolkit/mozapps/extensions/nsBlocklistService.js +++ b/toolkit/mozapps/extensions/nsBlocklistService.js @@ -297,6 +297,8 @@ function Blocklist() { gPref.addObserver("extensions.blocklist.", this, false); gPref.addObserver(PREF_EM_LOGGING_ENABLED, this, false); this.wrappedJSObject = this; + // requests from child processes come in here, see receiveMessage. + Services.ppmm.addMessageListener("Blocklist::getPluginBlocklistState", this); } Blocklist.prototype = { @@ -318,12 +320,17 @@ Blocklist.prototype = { _addonEntries: null, _pluginEntries: null, + shutdown: function () { + Services.obs.removeObserver(this, "xpcom-shutdown"); + Services.ppmm.removeMessageListener("Blocklist::getPluginBlocklistState", this); + gPref.removeObserver("extensions.blocklist.", this); + gPref.removeObserver(PREF_EM_LOGGING_ENABLED, this); + }, + observe: function Blocklist_observe(aSubject, aTopic, aData) { switch (aTopic) { case "xpcom-shutdown": - Services.obs.removeObserver(this, "xpcom-shutdown"); - gPref.removeObserver("extensions.blocklist.", this); - gPref.removeObserver(PREF_EM_LOGGING_ENABLED, this); + this.shutdown(); break; case "nsPref:changed": switch (aData) { @@ -349,6 +356,18 @@ Blocklist.prototype = { } }, + // Message manager message handlers + receiveMessage: function (aMsg) { + switch (aMsg.name) { + case "Blocklist::getPluginBlocklistState": + return this.getPluginBlocklistState(aMsg.data.addonData, + aMsg.data.appVersion, + aMsg.data.toolkitVersion); + default: + throw new Error("Unknown blocklist message received from content: " + aMsg.name); + } + }, + /* See nsIBlocklistService */ isAddonBlocklisted: function Blocklist_isAddonBlocklisted(addon, appVersion, toolkitVersion) { return this.getAddonBlocklistState(addon, appVersion, toolkitVersion) == diff --git a/toolkit/mozapps/extensions/nsBlocklistServiceContent.js b/toolkit/mozapps/extensions/nsBlocklistServiceContent.js new file mode 100644 index 00000000000..972daa1a480 --- /dev/null +++ b/toolkit/mozapps/extensions/nsBlocklistServiceContent.js @@ -0,0 +1,80 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +Components.utils.import("resource://gre/modules/Services.jsm"); + +const kMissingAPIMessage = "Unsupported blocklist call in the child process." + +/* + * A lightweight blocklist proxy for the content process that traps plugin + * related blocklist checks and forwards them to the parent. This interface is + * primarily designed to insure overlays work.. it does not control plugin + * or addon loading. + */ + +function Blocklist() { +} + +Blocklist.prototype = { + classID: Components.ID("{e0a106ed-6ad4-47a4-b6af-2f1c8aa4712d}"), + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIBlocklistService]), + + /* + * A helper that queries key data from a plugin or addon object + * and generates a simple data wrapper suitable for ipc. We hand + * these directly to the nsBlockListService in the parent which + * doesn't query for much.. allowing us to get away with this. + */ + flattenObject: function (aTag) { + // Based on debugging the nsBlocklistService, these are the props the + // parent side will check on our objects. + let props = ["name", "description", "filename", "version"]; + let dataWrapper = {}; + for (let prop of props) { + dataWrapper[prop] = aTag[prop]; + } + return dataWrapper; + }, + + // We support the addon methods here for completeness, but content currently + // only calls getPluginBlocklistState. + + isAddonBlocklisted: function (aAddon, aAppVersion, aToolkitVersion) { + throw new Error(kMissingAPIMessage); + }, + + getAddonBlocklistState: function (aAddon, aAppVersion, aToolkitVersion) { + throw new Error(kMissingAPIMessage); + }, + + getPluginBlocklistState: function (aPluginTag, aAppVersion, aToolkitVersion) { + return Services.cpmm.sendSyncMessage("Blocklist::getPluginBlocklistState", { + addonData: this.flattenObject(aPluginTag), + appVersion: aAppVersion, + toolkitVersion: aToolkitVersion + })[0]; + }, + + getAddonBlocklistURL: function (aAddon, aAppVersion, aToolkitVersion) { + throw new Error(kMissingAPIMessage); + }, + + getPluginBlocklistURL: function (aPluginTag) { + throw new Error(kMissingAPIMessage); + }, + + getPluginInfoURL: function (aPluginTag) { + throw new Error(kMissingAPIMessage); + } +}; + +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Blocklist]);