mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
Bug 828863 - Add a remote debugger actor to install apps r=past
This commit is contained in:
parent
2c0c73b5c0
commit
6882d62977
260
b2g/chrome/content/dbg-webapps-actors.js
Normal file
260
b2g/chrome/content/dbg-webapps-actors.js
Normal file
@ -0,0 +1,260 @@
|
||||
/* 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 Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
function debug(aMsg) {
|
||||
/*
|
||||
Cc["@mozilla.org/consoleservice;1"]
|
||||
.getService(Ci.nsIConsoleService)
|
||||
.logStringMessage("--*-- WebappsActor : " + aMsg);
|
||||
*/
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
const DIRECTORY_NAME = "webappsDir";
|
||||
#else
|
||||
const DIRECTORY_NAME = "ProfD";
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Creates a WebappsActor. WebappsActor provides remote access to
|
||||
* install apps.
|
||||
*/
|
||||
function WebappsActor(aConnection) { debug("init"); }
|
||||
|
||||
WebappsActor.prototype = {
|
||||
actorPrefix: "webapps",
|
||||
|
||||
_registerApp: function wa_actorRegisterApp(aApp, aId, aDir) {
|
||||
let reg = DOMApplicationRegistry;
|
||||
let self = this;
|
||||
|
||||
aApp.installTime = Date.now();
|
||||
aApp.installState = "installed";
|
||||
aApp.removable = true;
|
||||
aApp.id = aId;
|
||||
aApp.basePath = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], true).path;
|
||||
aApp.localId = (aId in reg.webapps) ? reg.webapps[aId].localId
|
||||
: reg._nextLocalId();
|
||||
|
||||
reg.webapps[aId] = aApp;
|
||||
reg.updatePermissionsForApp(aId);
|
||||
|
||||
reg._readManifests([{ id: aId }], function(aResult) {
|
||||
let manifest = aResult[0].manifest;
|
||||
aApp.name = manifest.name;
|
||||
reg._registerSystemMessages(manifest, aApp);
|
||||
reg._registerActivities(manifest, aApp, true);
|
||||
reg._saveApps(function() {
|
||||
aApp.manifest = manifest;
|
||||
reg.broadcastMessage("Webapps:Install:Return:OK",
|
||||
{ app: aApp,
|
||||
oid: "foo",
|
||||
requestID: "bar"
|
||||
});
|
||||
delete aApp.manifest;
|
||||
reg.broadcastMessage("Webapps:AddApp", { id: aId, app: aApp });
|
||||
self.conn.send({ from: self.actorID,
|
||||
type: "webappsEvent",
|
||||
appId: aId
|
||||
});
|
||||
|
||||
// We can't have appcache for packaged apps.
|
||||
if (!aApp.origin.startsWith("app://")) {
|
||||
reg.startOfflineCacheDownload(new ManifestHelper(manifest, aApp.origin));
|
||||
}
|
||||
});
|
||||
// Cleanup by removing the temporary directory.
|
||||
aDir.remove(true);
|
||||
});
|
||||
},
|
||||
|
||||
_sendError: function wa_actorSendError(aMsg, aId) {
|
||||
debug("Sending error: " + aMsg);
|
||||
this.conn.send(
|
||||
{ from: this.actorID,
|
||||
type: "webappsEvent",
|
||||
appId: aId,
|
||||
error: "installationFailed",
|
||||
message: aMsg
|
||||
});
|
||||
},
|
||||
|
||||
installHostedApp: function wa_actorInstallHosted(aDir, aId, aType) {
|
||||
debug("installHostedApp");
|
||||
let self = this;
|
||||
|
||||
let runnable = {
|
||||
run: function run() {
|
||||
try {
|
||||
// The destination directory for this app.
|
||||
let installDir = FileUtils.getDir(DIRECTORY_NAME,
|
||||
["webapps", aId], true);
|
||||
|
||||
// Move manifest.webapp to the destination directory.
|
||||
let manFile = aDir.clone();
|
||||
manFile.append("manifest.webapp");
|
||||
manFile.moveTo(installDir, "manifest.webapp");
|
||||
|
||||
// Read the origin and manifest url from metadata.json
|
||||
let metaFile = aDir.clone();
|
||||
metaFile.append("metadata.json");
|
||||
DOMApplicationRegistry._loadJSONAsync(metaFile, function(aMetadata) {
|
||||
if (!aMetadata) {
|
||||
self._sendError("Error Parsing metadata.json", aId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aMetadata.origin) {
|
||||
self._sendError("Missing 'origin' propery in metadata.json", aId);
|
||||
return;
|
||||
}
|
||||
|
||||
let origin = aMetadata.origin;
|
||||
let manifestURL = aMetadata.manifestURL ||
|
||||
origin + "/manifest.webapp";
|
||||
// Create a fake app object with the minimum set of properties we need.
|
||||
let app = {
|
||||
origin: origin,
|
||||
installOrigin: aMetadata.installOrigin || origin,
|
||||
manifestURL: manifestURL,
|
||||
appStatus: aType
|
||||
}
|
||||
|
||||
self._registerApp(app, aId, aDir);
|
||||
});
|
||||
} catch(e) {
|
||||
// If anything goes wrong, just send it back.
|
||||
self.sendError(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Services.tm.currentThread.dispatch(runnable,
|
||||
Ci.nsIThread.DISPATCH_NORMAL);
|
||||
},
|
||||
|
||||
installPackagedApp: function wa_actorInstallPackaged(aDir, aId, aType) {
|
||||
debug("installPackagedApp");
|
||||
let self = this;
|
||||
|
||||
let runnable = {
|
||||
run: function run() {
|
||||
try {
|
||||
// The destination directory for this app.
|
||||
let installDir = FileUtils.getDir(DIRECTORY_NAME,
|
||||
["webapps", aId], true);
|
||||
|
||||
// Move application.zip to the destination directory.
|
||||
let zipFile = aDir.clone();
|
||||
zipFile.append("application.zip");
|
||||
zipFile.moveTo(installDir, "application.zip");
|
||||
|
||||
// Extract the manifest.webapp file from the zip.
|
||||
zipFile = installDir.clone();
|
||||
zipFile.append("application.zip");
|
||||
let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"]
|
||||
.createInstance(Ci.nsIZipReader);
|
||||
zipReader.open(zipFile);
|
||||
|
||||
let manFile = installDir.clone();
|
||||
manFile.append("manifest.webapp");
|
||||
zipReader.extract("manifest.webapp", manFile);
|
||||
zipReader.close();
|
||||
|
||||
let origin = "app://" + aId;
|
||||
|
||||
// Create a fake app object with the minimum set of properties we need.
|
||||
let app = {
|
||||
origin: origin,
|
||||
installOrigin: origin,
|
||||
manifestURL: origin + "/manifest.webapp",
|
||||
appStatus: aType
|
||||
}
|
||||
|
||||
self._registerApp(app, aId, aDir);
|
||||
} catch(e) {
|
||||
// If anything goes wrong, just send it back.
|
||||
self._sendError(e.toString(), aId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Services.tm.currentThread.dispatch(runnable,
|
||||
Ci.nsIThread.DISPATCH_NORMAL);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param appId : The id of the app we want to install. We will look for
|
||||
* the files for the app in $TMP/b2g/$appId :
|
||||
* For packaged apps: application.zip
|
||||
* For hosted apps: metadata.json and manifest.webapp
|
||||
* @param appType : The privilege status of the app, as defined in
|
||||
* nsIPrincipal. It's optional and default to
|
||||
* APP_STATUS_INSTALLED
|
||||
*/
|
||||
install: function wa_actorInstall(aRequest) {
|
||||
debug("install");
|
||||
|
||||
Cu.import("resource://gre/modules/Webapps.jsm");
|
||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
let appId = aRequest.appId;
|
||||
if (!appId) {
|
||||
return { error: "missingParameter",
|
||||
message: "missing parameter appId" }
|
||||
}
|
||||
|
||||
let appType = aRequest.appType || Ci.nsIPrincipal.APP_STATUS_INSTALLED;
|
||||
let appDir = FileUtils.getDir("TmpD", ["b2g", appId], false, false);
|
||||
|
||||
if (!appDir || !appDir.exists()) {
|
||||
return { error: "badParameterType",
|
||||
message: "missing directory " + appDir.path
|
||||
}
|
||||
}
|
||||
|
||||
let testFile = appDir.clone();
|
||||
testFile.append("application.zip");
|
||||
|
||||
if (testFile.exists()) {
|
||||
this.installPackagedApp(appDir, appId, appType);
|
||||
} else {
|
||||
let missing =
|
||||
["manifest.webapp", "metadata.json"]
|
||||
.some(function(aName) {
|
||||
testFile = appDir.clone();
|
||||
testFile.append(aName);
|
||||
return !testFile.exists();
|
||||
});
|
||||
|
||||
if (missing) {
|
||||
try {
|
||||
aDir.remove(true);
|
||||
} catch(e) {}
|
||||
return { error: "badParameterType",
|
||||
message: "hosted app file is missing" }
|
||||
}
|
||||
|
||||
this.installHostedApp(appDir, appId, appType);
|
||||
}
|
||||
|
||||
return { appId: appId, path: appDir.path }
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The request types this actor can handle.
|
||||
*/
|
||||
WebappsActor.prototype.requestTypes = {
|
||||
"install": WebappsActor.prototype.install
|
||||
};
|
||||
|
||||
DebuggerServer.addGlobalActor(WebappsActor, "webappsActor");
|
@ -899,6 +899,7 @@ let RemoteDebugger = {
|
||||
DebuggerServer.init(this.prompt.bind(this));
|
||||
DebuggerServer.addBrowserActors();
|
||||
DebuggerServer.addActors('chrome://browser/content/dbg-browser-actors.js');
|
||||
DebuggerServer.addActors('chrome://browser/content/dbg-webapps-actors.js');
|
||||
}
|
||||
|
||||
let port = Services.prefs.getIntPref('devtools.debugger.remote-port') || 6000;
|
||||
|
@ -10,6 +10,7 @@ chrome.jar:
|
||||
|
||||
content/arrow.svg (content/arrow.svg)
|
||||
content/dbg-browser-actors.js (content/dbg-browser-actors.js)
|
||||
* content/dbg-webapps-actors.js (content/dbg-webapps-actors.js)
|
||||
content/forms.js (content/forms.js)
|
||||
* content/settings.js (content/settings.js)
|
||||
* content/shell.xul (content/shell.xul)
|
||||
|
@ -178,7 +178,8 @@ const UnsolicitedNotifications = {
|
||||
"newScript": "newScript",
|
||||
"tabDetached": "tabDetached",
|
||||
"tabNavigated": "tabNavigated",
|
||||
"pageError": "pageError"
|
||||
"pageError": "pageError",
|
||||
"webappsEvent": "webappsEvent"
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user