gecko-dev/b2g/components/Bootstraper.jsm

148 lines
4.7 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";
this.EXPORTED_SYMBOLS = ["Bootstraper"];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const CC = Components.Constructor;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Webapps.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
function debug(aMsg) {
//dump("-*- Bootstraper: " + aMsg + "\n");
}
/**
* This module loads the manifest for app from the --start-url enpoint and
* ensures that it's installed as the system app.
*/
this.Bootstraper = {
_manifestURL: null,
_startupURL: null,
bailout: function(aMsg) {
dump("************************************************************\n");
dump("* /!\\ " + aMsg + "\n");
dump("************************************************************\n");
let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
.getService(Ci.nsIAppStartup);
appStartup.quit(appStartup.eForceQuit);
},
installSystemApp: function(aManifest) {
// Get the appropriate startup url from the manifest launch_path.
let base = Services.io.newURI(this._manifestURL, null, null);
let origin = base.prePath;
let helper = new ManifestHelper(aManifest, origin, this._manifestURL);
this._startupURL = helper.fullLaunchPath();
return new Promise((aResolve, aReject) => {
debug("Origin is " + origin);
let appData = {
app: {
installOrigin: origin,
origin: origin,
manifest: aManifest,
manifestURL: this._manifestURL,
manifestHash: AppsUtils.computeHash(JSON.stringify(aManifest)),
appStatus: Ci.nsIPrincipal.APP_STATUS_CERTIFIED
},
appId: 1,
isBrowser: false,
isPackage: false
};
DOMApplicationRegistry.confirmInstall(appData, null, aResolve);
});
},
/**
* Resolves to a json manifest.
*/
loadManifest: function() {
return new Promise((aResolve, aReject) => {
debug("Loading manifest " + this._manifestURL);
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
xhr.mozBackgroundRequest = true;
xhr.open("GET", this._manifestURL);
xhr.responseType = "json";
xhr.addEventListener("load", () => {
if (xhr.status >= 200 && xhr.status < 400) {
debug("Success loading " + this._manifestURL);
aResolve(xhr.response);
} else {
aReject("Error loading " + this._manifestURL);
}
});
xhr.addEventListener("error", () => {
aReject("Error loading " + this._manifestURL);
});
xhr.send(null);
});
},
configure: function() {
debug("Setting startup prefs... " + this._startupURL);
Services.prefs.setCharPref("b2g.system_manifest_url", this._manifestURL);
Services.prefs.setCharPref("b2g.system_startup_url", this._startupURL);
return Promise.resolve();
},
/**
* If a system app is already installed, uninstall it so that we can
* cleanly replace it by the current one.
*/
uninstallPreviousSystemApp: function() {
let oldManifestURL;
try{
oldManifestURL = Services.prefs.getCharPref("b2g.system_manifest_url");
} catch(e) {
// No preference set, so nothing to uninstall.
return Promise.resolve();
}
let id = DOMApplicationRegistry.getAppLocalIdByManifestURL(oldManifestURL);
if (id == Ci.nsIScriptSecurityManager.NO_APP_ID) {
return Promise.resolve();
}
debug("Uninstalling " + oldManifestURL);
return DOMApplicationRegistry.uninstall(oldManifestURL);
},
/**
* Resolves once we have installed the app.
*/
ensureSystemAppInstall: function(aManifestURL) {
this._manifestURL = aManifestURL;
debug("Installing app from " + this._manifestURL);
// Check if we are already configured to run from this manifest url, and
// skip reinstall if that's the case.
try {
if (Services.prefs.getCharPref("b2g.system_manifest_url") == this._manifestURL) {
debug("Already configured for " + this._manifestURL);
return Promise.resolve();
}
} catch(e) { }
return new Promise((aResolve, aReject) => {
DOMApplicationRegistry.registryReady
.then(this.uninstallPreviousSystemApp.bind(this))
.then(this.loadManifest.bind(this))
.then(this.installSystemApp.bind(this))
.then(this.configure.bind(this))
.then(aResolve)
.catch(aReject);
});
}
};