зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1118138 - Add support to bootstrap b2g from a manifest url r=vingtetun
This commit is contained in:
Родитель
9d6b2993ee
Коммит
3b77722c8f
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче