michael@0: /** michael@0: * Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ michael@0: */ michael@0: michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: michael@0: function testForExpectedSymbols(stage, data) { michael@0: const expectedSymbols = [ "Worker", "ChromeWorker" ]; michael@0: for each (var symbol in expectedSymbols) { michael@0: Services.prefs.setBoolPref("workertest.bootstrap." + stage + "." + symbol, michael@0: symbol in this); michael@0: } michael@0: } michael@0: michael@0: var gWorkerAndCallback = { michael@0: _ensureStarted: function() { michael@0: if (!this._worker) { michael@0: throw new Error("Not yet started!"); michael@0: } michael@0: }, michael@0: michael@0: start: function(data) { michael@0: if (!this._worker) { michael@0: var file = data.installPath; michael@0: var fileuri = file.isDirectory() ? michael@0: Services.io.newFileURI(file) : michael@0: Services.io.newURI('jar:' + file.path + '!/', null, null); michael@0: var resourceName = encodeURIComponent(data.id); michael@0: michael@0: Services.io.getProtocolHandler("resource"). michael@0: QueryInterface(Ci.nsIResProtocolHandler). michael@0: setSubstitution(resourceName, fileuri); michael@0: michael@0: this._worker = new Worker("resource://" + resourceName + "/worker.js"); michael@0: this._worker.onerror = function(event) { michael@0: Cu.reportError(event.message); michael@0: event.preventDefault(); michael@0: }; michael@0: } michael@0: }, michael@0: michael@0: stop: function() { michael@0: if (this._worker) { michael@0: this._worker.terminate(); michael@0: delete this._worker; michael@0: } michael@0: }, michael@0: michael@0: set callback(val) { michael@0: this._ensureStarted(); michael@0: var callback = val.QueryInterface(Ci.nsIObserver); michael@0: if (this._callback != callback) { michael@0: if (callback) { michael@0: this._worker.onmessage = function(event) { michael@0: callback.observe(this, event.type, event.data); michael@0: }; michael@0: this._worker.onerror = function(event) { michael@0: callback.observe(this, event.type, event.message); michael@0: event.preventDefault(); michael@0: }; michael@0: } michael@0: else { michael@0: this._worker.onmessage = null; michael@0: this._worker.onerror = null; michael@0: } michael@0: this._callback = callback; michael@0: } michael@0: }, michael@0: michael@0: get callback() { michael@0: return this._callback; michael@0: }, michael@0: michael@0: postMessage: function(data) { michael@0: this._ensureStarted(); michael@0: this._worker.postMessage(data); michael@0: }, michael@0: michael@0: terminate: function() { michael@0: this._ensureStarted(); michael@0: this._worker.terminate(); michael@0: delete this._callback; michael@0: } michael@0: }; michael@0: michael@0: function WorkerTestBootstrap() { michael@0: } michael@0: WorkerTestBootstrap.prototype = { michael@0: observe: function(subject, topic, data) { michael@0: michael@0: gWorkerAndCallback.callback = subject; michael@0: michael@0: switch (topic) { michael@0: case "postMessage": michael@0: gWorkerAndCallback.postMessage(data); michael@0: break; michael@0: michael@0: case "terminate": michael@0: gWorkerAndCallback.terminate(); michael@0: break; michael@0: michael@0: default: michael@0: throw new Error("Unknown worker command"); michael@0: } michael@0: }, michael@0: michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]) michael@0: }; michael@0: michael@0: var gFactory = { michael@0: register: function() { michael@0: var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); michael@0: michael@0: var classID = Components.ID("{36b5df0b-8dcf-4aa2-9c45-c51d871295f9}"); michael@0: var description = "WorkerTestBootstrap"; michael@0: var contractID = "@mozilla.org/test/workertestbootstrap;1"; michael@0: var factory = XPCOMUtils._getFactory(WorkerTestBootstrap); michael@0: michael@0: registrar.registerFactory(classID, description, contractID, factory); michael@0: michael@0: this.unregister = function() { michael@0: registrar.unregisterFactory(classID, factory); michael@0: delete this.unregister; michael@0: }; michael@0: } michael@0: }; michael@0: michael@0: function install(data, reason) { michael@0: testForExpectedSymbols("install"); michael@0: } michael@0: michael@0: function startup(data, reason) { michael@0: testForExpectedSymbols("startup"); michael@0: gFactory.register(); michael@0: gWorkerAndCallback.start(data); michael@0: } michael@0: michael@0: function shutdown(data, reason) { michael@0: testForExpectedSymbols("shutdown"); michael@0: gWorkerAndCallback.stop(); michael@0: gFactory.unregister(); michael@0: } michael@0: michael@0: function uninstall(data, reason) { michael@0: testForExpectedSymbols("uninstall"); michael@0: }