2015-01-23 21:23:45 +03:00
|
|
|
/* 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);
|
|
|
|
},
|
|
|
|
|
2015-10-01 00:49:00 +03:00
|
|
|
/**
|
|
|
|
* Check if we are already configured to run from this manifest url.
|
|
|
|
*/
|
|
|
|
isInstallRequired: function(aManifestURL) {
|
|
|
|
try {
|
|
|
|
if (Services.prefs.getCharPref("b2g.system_manifest_url") == aManifestURL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} catch(e) { }
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
2015-01-23 21:23:45 +03:00
|
|
|
/**
|
|
|
|
* Resolves once we have installed the app.
|
|
|
|
*/
|
|
|
|
ensureSystemAppInstall: function(aManifestURL) {
|
|
|
|
this._manifestURL = aManifestURL;
|
|
|
|
debug("Installing app from " + this._manifestURL);
|
|
|
|
|
2015-10-01 00:49:00 +03:00
|
|
|
if (!this.isInstallRequired(this._manifestURL)) {
|
|
|
|
debug("Already configured for " + this._manifestURL);
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
2015-01-23 21:23:45 +03:00
|
|
|
|
|
|
|
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);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|