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("-- ActivityWrapper.js " + Date.now() + " : " + aMsg + "\n"); michael@0: } michael@0: michael@0: /** michael@0: * nsISystemMessagesWrapper implementation. Will return a michael@0: * nsIDOMMozActivityRequestHandler michael@0: */ michael@0: function ActivityWrapper() { michael@0: debug("ActivityWrapper"); michael@0: } michael@0: michael@0: ActivityWrapper.prototype = { michael@0: wrapMessage: function wrapMessage(aMessage, aWindow) { michael@0: debug("Wrapping " + JSON.stringify(aMessage)); michael@0: michael@0: // This message is useful to communicate that the activity message has been michael@0: // properly received by the app. If the app will be killed, the michael@0: // ActivitiesService will be able to fire an error and complete the michael@0: // Activity workflow. michael@0: cpmm.sendAsyncMessage("Activity:Ready", { id: aMessage.id }); michael@0: michael@0: let handler = new aWindow.ActivityRequestHandler(aMessage.id, aMessage.payload); michael@0: michael@0: // When the activity window is closed, fire an error to notify the activity michael@0: // caller of the situation. michael@0: // We don't need to check whether the activity itself already sent michael@0: // back something since ActivitiesService.jsm takes care of that. michael@0: let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) michael@0: .getInterface(Ci.nsIDOMWindowUtils); michael@0: let innerWindowID = util.currentInnerWindowID; michael@0: michael@0: let observer = { michael@0: observe: function(aSubject, aTopic, aData) { michael@0: michael@0: switch (aTopic) { michael@0: case 'inner-window-destroyed': michael@0: let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data; michael@0: if (wId == innerWindowID) { michael@0: debug("Closing activity window " + innerWindowID); michael@0: Services.obs.removeObserver(observer, "inner-window-destroyed"); michael@0: cpmm.sendAsyncMessage("Activity:PostError", michael@0: { id: aMessage.id, michael@0: error: "ActivityCanceled" michael@0: }); michael@0: } michael@0: break; michael@0: case 'activity-error': michael@0: case 'activity-success': michael@0: if (aData !== aMessage.id) { michael@0: return; michael@0: } michael@0: Services.obs.removeObserver(observer, "activity-error"); michael@0: Services.obs.removeObserver(observer, "activity-success"); michael@0: let docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) michael@0: .getInterface(Ci.nsIWebNavigation); michael@0: Services.obs.notifyObservers(docshell, "activity-done", aTopic); michael@0: break; michael@0: } michael@0: } michael@0: } michael@0: michael@0: Services.obs.addObserver(observer, "activity-error", false); michael@0: Services.obs.addObserver(observer, "activity-success", false); michael@0: Services.obs.addObserver(observer, "inner-window-destroyed", false); michael@0: return handler; michael@0: }, michael@0: michael@0: classID: Components.ID("{5430d6f9-32d6-4924-ba39-6b6d1b093cd6}"), michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesWrapper]) michael@0: } michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ActivityWrapper]); michael@0: