michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: const Cu = Components.utils; michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: XPCOMUtils.defineLazyServiceGetter(this, "cpmm", michael@0: "@mozilla.org/childprocessmessagemanager;1", michael@0: "nsISyncMessageSender"); michael@0: michael@0: function debug(aMsg) { michael@0: //dump("-- ActivityProxy " + Date.now() + " : " + aMsg + "\n"); michael@0: } michael@0: michael@0: /** michael@0: * nsIActivityProxy implementation michael@0: * We keep a reference to the C++ Activity object, and michael@0: * communicate with the Message Manager to know when to michael@0: * fire events on it. michael@0: */ michael@0: function ActivityProxy() { michael@0: debug("ActivityProxy"); michael@0: this.activity = null; michael@0: let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) michael@0: .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; michael@0: debug("inParent: " + inParent); michael@0: Cu.import(inParent ? "resource://gre/modules/Webapps.jsm" michael@0: : "resource://gre/modules/AppsServiceChild.jsm"); michael@0: } michael@0: michael@0: ActivityProxy.prototype = { michael@0: startActivity: function actProxy_startActivity(aActivity, aOptions, aWindow) { michael@0: debug("startActivity"); michael@0: michael@0: this.window = aWindow; michael@0: this.activity = aActivity; michael@0: this.id = Cc["@mozilla.org/uuid-generator;1"] michael@0: .getService(Ci.nsIUUIDGenerator) michael@0: .generateUUID().toString(); michael@0: // Retrieve the app's manifest url from the principal, so that we can michael@0: // later notify when the activity handler called postResult or postError michael@0: let principal = aWindow.document.nodePrincipal; michael@0: let appId = principal.appId; michael@0: let manifestURL = (appId != Ci.nsIScriptSecurityManager.NO_APP_ID && michael@0: appId != Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) michael@0: ? DOMApplicationRegistry.getManifestURLByLocalId(appId) michael@0: : null; michael@0: cpmm.sendAsyncMessage("Activity:Start", { id: this.id, michael@0: options: { michael@0: name: aOptions.name, michael@0: data: aOptions.data michael@0: }, michael@0: manifestURL: manifestURL, michael@0: pageURL: aWindow.document.location.href }); michael@0: michael@0: cpmm.addMessageListener("Activity:FireSuccess", this); michael@0: cpmm.addMessageListener("Activity:FireError", this); michael@0: }, michael@0: michael@0: receiveMessage: function actProxy_receiveMessage(aMessage) { michael@0: debug("Got message: " + aMessage.name); michael@0: let msg = aMessage.json; michael@0: if (msg.id != this.id) michael@0: return; michael@0: debug("msg=" + JSON.stringify(msg)); michael@0: michael@0: switch(aMessage.name) { michael@0: case "Activity:FireSuccess": michael@0: debug("FireSuccess"); michael@0: Services.DOMRequest.fireSuccess(this.activity, michael@0: Cu.cloneInto(msg.result, this.window)); michael@0: Services.obs.notifyObservers(null, "Activity:Success", null); michael@0: break; michael@0: case "Activity:FireError": michael@0: debug("FireError"); michael@0: Services.DOMRequest.fireError(this.activity, msg.error); michael@0: Services.obs.notifyObservers(null, "Activity:Error", null); michael@0: break; michael@0: } michael@0: // We can only get one FireSuccess / FireError message, so cleanup as soon as possible. michael@0: this.cleanup(); michael@0: }, michael@0: michael@0: cleanup: function actProxy_cleanup() { michael@0: debug("cleanup"); michael@0: if (cpmm && !this.cleanedUp) { michael@0: cpmm.removeMessageListener("Activity:FireSuccess", this); michael@0: cpmm.removeMessageListener("Activity:FireError", this); michael@0: } michael@0: this.cleanedUp = true; michael@0: }, michael@0: michael@0: classID: Components.ID("{ba9bd5cb-76a0-4ecf-a7b3-d2f7c43c5949}"), michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIActivityProxy]) michael@0: } michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ActivityProxy]);