зеркало из https://github.com/mozilla/gecko-dev.git
141 строка
5.1 KiB
JavaScript
141 строка
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) {
|
|
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 });
|
|
},
|
|
|
|
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]);
|