Bug 1118138 - Add support to bootstrap b2g from a manifest url r=vingtetun

This commit is contained in:
Fabrice Desré 2015-01-23 10:23:45 -08:00
Родитель 9d6b2993ee
Коммит 3b77722c8f
7 изменённых файлов: 222 добавлений и 1 удалений

Просмотреть файл

@ -108,7 +108,7 @@ SettingsListener.observe('language.current', 'en-US', function(value) {
Services.prefs.setCharPref(prefName, value);
if (shell.hasStarted() == false) {
shell.start();
shell.bootstrap();
}
});

Просмотреть файл

@ -222,6 +222,20 @@ var shell = {
return this._started;
},
bootstrap: function() {
let startManifestURL =
Cc['@mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap']
.getService(Ci.nsISupports).wrappedJSObject.startManifestURL;
if (startManifestURL) {
Cu.import('resource://gre/modules/Bootstraper.jsm');
Bootstraper.ensureSystemAppInstall(startManifestURL)
.then(this.start.bind(this))
.catch(Bootstraper.bailout);
} else {
this.start();
}
},
start: function shell_start() {
this._started = true;

Просмотреть файл

@ -100,6 +100,11 @@ contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds {385993f
category command-line-handler m-b2gcmds @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds
#endif
# BootstrapCommandLine.js
component {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44} BootstrapCommandLine.js
contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44}
category command-line-handler m-b2gbootstrap @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap
# MobileIdentityUIGlue.js
component {83dbe26a-81f3-4a75-9541-3d0b7ca496b5} MobileIdentityUIGlue.js
contract @mozilla.org/services/mobileid-ui-glue;1 {83dbe26a-81f3-4a75-9541-3d0b7ca496b5}

Просмотреть файл

@ -0,0 +1,52 @@
/* 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/. */
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
function BootstrapCommandlineHandler() {
this.wrappedJSObject = this;
this.startManifestURL = null;
}
BootstrapCommandlineHandler.prototype = {
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);
},
handle: function(aCmdLine) {
this.startManifestURL = null;
try {
// Returns null if the argument was not specified. Throws
// NS_ERROR_INVALID_ARG if there is no parameter specified (because
// it was the last argument or the next argument starts with '-').
// However, someone could still explicitly pass an empty argument!
this.startManifestURL = aCmdLine.handleFlagWithParam("start-manifest", false);
} catch(e) {
return;
}
if (!this.startManifestURL) {
return;
}
if (!isAbsoluteURI(this.startManifestURL)) {
this.bailout("The start manifest url must be absolute.");
return;
}
},
helpInfo: "--start-manifest=manifest_url",
classID: Components.ID("{fd663ec8-cf3f-4c2b-aacb-17a6915ccb44}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler])
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BootstrapCommandlineHandler]);

Просмотреть файл

@ -0,0 +1,147 @@
/* 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);
});
}
};

Просмотреть файл

@ -12,6 +12,7 @@ EXTRA_COMPONENTS += [
'B2GAboutRedirector.js',
'B2GAppMigrator.js',
'B2GPresentationDevicePrompt.js',
'BootstrapCommandLine.js',
'ContentPermissionPrompt.js',
'FilePicker.js',
'FxAccountsUIGlue.js',
@ -49,6 +50,7 @@ if CONFIG['MOZ_UPDATER']:
EXTRA_JS_MODULES += [
'AlertsHelper.jsm',
'Bootstraper.jsm',
'ContentRequestHelper.jsm',
'DebuggerActors.js',
'ErrorPage.jsm',

Просмотреть файл

@ -477,6 +477,7 @@
@BINPATH@/components/OopCommandLine.js
@BINPATH@/components/CommandLine.js
#endif
@BINPATH@/components/BootstrapCommandLine.js
#ifdef MOZ_UPDATER
@BINPATH@/components/nsUpdateService.manifest