gecko/dom/activities/ActivityProxy.js

143 lines
5.1 KiB
JavaScript

/* 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 Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsISyncMessageSender");
function debug(aMsg) {
//dump("-- ActivityProxy " + Date.now() + " : " + aMsg + "\n");
}
/**
* nsIActivityProxy implementation
* We keep a reference to the C++ Activity object, and
* communicate with the Message Manager to know when to
* fire events on it.
*/
function ActivityProxy() {
debug("ActivityProxy");
this.activity = null;
let inParent = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
debug("inParent: " + inParent);
Cu.import(inParent ? "resource://gre/modules/Webapps.jsm"
: "resource://gre/modules/AppsServiceChild.jsm");
}
ActivityProxy.prototype = {
startActivity: function actProxy_startActivity(aActivity, aOptions, aWindow,
aChildID) {
debug("startActivity");
this.window = aWindow;
this.activity = aActivity;
this.id = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator)
.generateUUID().toString();
// Retrieve the app's manifest url from the principal, so that we can
// later notify when the activity handler called postResult or postError
let principal = aWindow.document.nodePrincipal;
let appId = principal.appId;
let manifestURL = (appId != Ci.nsIScriptSecurityManager.NO_APP_ID &&
appId != Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID)
? DOMApplicationRegistry.getManifestURLByLocalId(appId)
: null;
// Only let certified apps enumerate providers for this filter.
if (aOptions.getFilterResults === true &&
principal.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
Services.DOMRequest.fireErrorAsync(this.activity, "SecurityError");
Services.obs.notifyObservers(null, "Activity:Error", null);
return;
}
// Only let certified app to initiate this activitiy.
if (aOptions.name === 'internal-system-engineering-mode' &&
principal.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
Services.DOMRequest.fireErrorAsync(this.activity, "SecurityError");
Services.obs.notifyObservers(null, "Activity:Error", null);
return;
}
// Check the activities that are restricted to be used in dev mode.
let devMode = false;
let isDevModeActivity = false;
try {
devMode = Services.prefs.getBoolPref("dom.apps.developer_mode");
isDevModeActivity =
Services.prefs.getCharPref("dom.activities.developer_mode_only")
.split(",").indexOf(aOptions.name) !== -1;
} catch(e) {}
if (isDevModeActivity && !devMode) {
Services.DOMRequest.fireErrorAsync(this.activity, "SecurityError");
Services.obs.notifyObservers(null, "Activity:Error", null);
return;
}
cpmm.addMessageListener("Activity:FireSuccess", this);
cpmm.addMessageListener("Activity:FireError", this);
cpmm.sendAsyncMessage("Activity:Start",
{
id: this.id,
options: {
name: aOptions.name,
data: aOptions.data
},
getFilterResults: aOptions.getFilterResults,
manifestURL: manifestURL,
pageURL: aWindow.document.location.href,
childID: aChildID });
},
receiveMessage: function actProxy_receiveMessage(aMessage) {
debug("Got message: " + aMessage.name);
let msg = aMessage.json;
if (msg.id != this.id)
return;
debug("msg=" + JSON.stringify(msg));
switch(aMessage.name) {
case "Activity:FireSuccess":
debug("FireSuccess");
Services.DOMRequest.fireSuccess(this.activity,
Cu.cloneInto(msg.result, this.window));
Services.obs.notifyObservers(null, "Activity:Success", null);
break;
case "Activity:FireError":
debug("FireError");
Services.DOMRequest.fireError(this.activity, msg.error);
Services.obs.notifyObservers(null, "Activity:Error", null);
break;
}
// We can only get one FireSuccess / FireError message, so cleanup as soon as possible.
this.cleanup();
},
cleanup: function actProxy_cleanup() {
debug("cleanup");
if (cpmm && !this.cleanedUp) {
cpmm.removeMessageListener("Activity:FireSuccess", this);
cpmm.removeMessageListener("Activity:FireError", this);
}
this.cleanedUp = true;
},
classID: Components.ID("{ba9bd5cb-76a0-4ecf-a7b3-d2f7c43c5949}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIActivityProxy])
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ActivityProxy]);