Created
July 26, 2016 17:24
-
-
Save rhelmer/8b52c3c2e078e5d3fe9521295877ef34 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/toolkit/components/extensions/ext-runtime.js b/toolkit/components/extensions/ext-runtime.js | |
| --- a/toolkit/components/extensions/ext-runtime.js | |
| +++ b/toolkit/components/extensions/ext-runtime.js | |
| @@ -1,15 +1,17 @@ | |
| "use strict"; | |
| var {classes: Cc, interfaces: Ci, utils: Cu} = Components; | |
| +Cu.import("resource://gre/modules/AddonManager.jsm"); | |
| Cu.import("resource://gre/modules/XPCOMUtils.jsm"); | |
| Cu.import("resource://gre/modules/ExtensionUtils.jsm"); | |
| + | |
| var { | |
| EventManager, | |
| ignoreEvent, | |
| } = ExtensionUtils; | |
| XPCOMUtils.defineLazyModuleGetter(this, "NativeApp", | |
| "resource://gre/modules/NativeMessaging.jsm"); | |
| @@ -24,16 +26,32 @@ extensions.registerSchemaAPI("runtime", | |
| }).api(), | |
| onInstalled: ignoreEvent(context, "runtime.onInstalled"), | |
| onMessage: context.messenger.onMessage("runtime.onMessage"), | |
| onConnect: context.messenger.onConnect("runtime.onConnect"), | |
| + onUpdateAvailable: function(aCallback) { | |
| + let instanceID = extension.addonData.instanceID; | |
| + AddonManager.addUpgradeListener(instanceID, upgrade => { | |
| + extension.upgradeCallback = upgrade; | |
| + }); | |
| + }, | |
| + | |
| + reload: () => { | |
| + if (extension.upgradeCallback) { | |
| + // there is a pending update, install it now. | |
| + extension.upgradeCallback.install(); | |
| + } else { | |
| + // TODO no pending upgrade, just reload. | |
| + } | |
| + }, | |
| + | |
| connect: function(extensionId, connectInfo) { | |
| let name = connectInfo !== null && connectInfo.name || ""; | |
| let recipient = extensionId !== null ? {extensionId} : {extensionId: extension.id}; | |
| return context.messenger.connect(Services.cpmm, name, recipient); | |
| }, | |
| sendMessage: function(...args) { | |
| diff --git a/toolkit/components/extensions/schemas/runtime.json b/toolkit/components/extensions/schemas/runtime.json | |
| --- a/toolkit/components/extensions/schemas/runtime.json | |
| +++ b/toolkit/components/extensions/schemas/runtime.json | |
| @@ -437,17 +437,16 @@ | |
| { | |
| "name": "onSuspendCanceled", | |
| "unsupported": true, | |
| "type": "function", | |
| "description": "Sent after onSuspend to indicate that the app won't be unloaded after all." | |
| }, | |
| { | |
| "name": "onUpdateAvailable", | |
| - "unsupported": true, | |
| "type": "function", | |
| "description": "Fired when an update is available, but isn't installed immediately because the app is currently running. If you do nothing, the update will be installed the next time the background page gets unloaded, if you want it to be installed sooner you can explicitly call $(ref:runtime.reload). If your extension is using a persistent background page, the background page of course never gets unloaded, so unless you call $(ref:runtime.reload) manually in response to this event the update will not get installed until the next time the browser itself restarts. If no handlers are listening for this event, and your extension has a persistent background page, it behaves as if $(ref:runtime.reload) is called in response to this event.", | |
| "parameters": [ | |
| { | |
| "type": "object", | |
| "name": "details", | |
| "properties": { | |
| "version": { | |
| diff --git a/toolkit/components/extensions/test/xpcshell/head.js b/toolkit/components/extensions/test/xpcshell/head.js | |
| --- a/toolkit/components/extensions/test/xpcshell/head.js | |
| +++ b/toolkit/components/extensions/test/xpcshell/head.js | |
| @@ -44,8 +44,28 @@ function* normalizeManifest(manifest, ba | |
| manifest = Object.assign({}, baseManifest, manifest); | |
| let normalized = Schemas.normalize(manifest, "manifest.WebExtensionManifest", context); | |
| normalized.errors = errors; | |
| return normalized; | |
| } | |
| + | |
| +function* generateAddon(data) { | |
| + const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator); | |
| + | |
| + let id = uuidGenerator.generateUUID().number; | |
| + | |
| + let xpi = Extension.generateXPI(id, data); | |
| + do_register_cleanup(() => { | |
| + Services.obs.notifyObservers(xpi, "flush-cache-entry", null); | |
| + xpi.remove(false); | |
| + }); | |
| + | |
| + let fileURI = Services.io.newFileURI(xpi); | |
| + let jarURI = NetUtil.newURI(`jar:${fileURI.spec}!/`); | |
| + | |
| + let extension = new ExtensionData(jarURI); | |
| + yield extension.readManifest(); | |
| + | |
| + return extension; | |
| +} | |
| diff --git a/toolkit/components/extensions/test/xpcshell/test_delay_update.js b/toolkit/components/extensions/test/xpcshell/test_delay_update.js | |
| new file mode 100644 | |
| --- /dev/null | |
| +++ b/toolkit/components/extensions/test/xpcshell/test_delay_update.js | |
| @@ -0,0 +1,15 @@ | |
| +"use strict"; | |
| + | |
| +add_task(function* test_background_delay_update() { | |
| + const ID = "background-delay-update@test.web.extension"; | |
| + | |
| + let xpi = Extension.generateXPI(ID, { | |
| + files: { | |
| + "manifest.json": String.raw`{ | |
| + "applications": {"gecko": {"id": "${ID}"}}, | |
| + "name": "Test that background.js can delay updates", | |
| + "version": "0.1" | |
| + }`, | |
| + }, | |
| + }); | |
| +}); | |
| diff --git a/toolkit/components/extensions/test/xpcshell/test_locale_data.js b/toolkit/components/extensions/test/xpcshell/test_locale_data.js | |
| --- a/toolkit/components/extensions/test/xpcshell/test_locale_data.js | |
| +++ b/toolkit/components/extensions/test/xpcshell/test_locale_data.js | |
| @@ -1,34 +1,14 @@ | |
| "use strict"; | |
| Cu.import("resource://gre/modules/Extension.jsm"); | |
| /* globals ExtensionData */ | |
| -const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator); | |
| - | |
| -function* generateAddon(data) { | |
| - let id = uuidGenerator.generateUUID().number; | |
| - | |
| - let xpi = Extension.generateXPI(id, data); | |
| - do_register_cleanup(() => { | |
| - Services.obs.notifyObservers(xpi, "flush-cache-entry", null); | |
| - xpi.remove(false); | |
| - }); | |
| - | |
| - let fileURI = Services.io.newFileURI(xpi); | |
| - let jarURI = NetUtil.newURI(`jar:${fileURI.spec}!/`); | |
| - | |
| - let extension = new ExtensionData(jarURI); | |
| - yield extension.readManifest(); | |
| - | |
| - return extension; | |
| -} | |
| - | |
| add_task(function* testMissingDefaultLocale() { | |
| let extension = yield generateAddon({ | |
| "files": { | |
| "_locales/en_US/messages.json": {}, | |
| }, | |
| }); | |
| equal(extension.errors.length, 0, "No errors reported"); | |
| diff --git a/toolkit/components/exthelper/extApplication.js b/toolkit/components/exthelper/extApplication.js | |
| --- a/toolkit/components/exthelper/extApplication.js | |
| +++ b/toolkit/components/exthelper/extApplication.js | |
| @@ -482,16 +482,17 @@ ExtensionObserver.prototype = { | |
| //================================================= | |
| // Extension constructor | |
| function Extension(aItem) { | |
| this._item = aItem; | |
| this._firstRun = false; | |
| this._prefs = new PreferenceBranch("extensions." + this.id + "."); | |
| this._storage = new SessionStorage(); | |
| + this._upgradeCallback = null; | |
| let id = this.id; | |
| this._events = { | |
| addListener: function ext_events_al(aEvent, aListener) { | |
| gExtensionObserver.addListener(id, aEvent, aListener); | |
| }, | |
| removeListener: function ext_events_rl(aEvent, aListener) { | |
| gExtensionObserver.addListener(id, aEvent, aListener); | |
| @@ -536,16 +537,24 @@ Extension.prototype = { | |
| get prefs() { | |
| return this._prefs; | |
| }, | |
| get events() { | |
| return this._events; | |
| }, | |
| + get upgradeCallback() { | |
| + return this._upgradeCallback; | |
| + }, | |
| + | |
| + set upgradeCallback(callback) { | |
| + this._upgradeCallback = callback; | |
| + } | |
| + | |
| QueryInterface: XPCOMUtils.generateQI([Ci.extIExtension]) | |
| }; | |
| //================================================= | |
| // Extensions constructor | |
| function Extensions(addons) { | |
| this._cache = {}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment