Bug 1067380 - Refactor webide to use app actor front. r=jryans

This commit is contained in:
Alexandre Poirot 2014-09-24 08:21:00 -04:00
parent b431b29868
commit 9fb4871b0d
6 changed files with 337 additions and 191 deletions

View File

@ -954,9 +954,12 @@ let Cmds = {
let runtimeappsHeaderNode = document.querySelector("#panel-header-runtimeapps");
let sortedApps = AppManager.webAppsStore.object.all;
let sortedApps = [];
for (let [manifestURL, app] of AppManager.apps) {
sortedApps.push(app);
}
sortedApps = sortedApps.sort((a, b) => {
return a.name > b.name;
return a.manifest.name > b.manifest.name;
});
let mainProcess = AppManager.isMainProcessDebuggable();
if (AppManager.connection.status == Connection.Status.CONNECTED &&
@ -991,16 +994,16 @@ let Cmds = {
let app = sortedApps[i];
let panelItemNode = document.createElement("toolbarbutton");
panelItemNode.className = "panel-item";
panelItemNode.setAttribute("label", app.name);
panelItemNode.setAttribute("label", app.manifest.name);
panelItemNode.setAttribute("image", app.iconURL);
runtimeAppsNode.appendChild(panelItemNode);
panelItemNode.addEventListener("click", () => {
UI.hidePanels();
AppManager.selectedProject = {
type: "runtimeApp",
app: app,
app: app.manifest,
icon: app.iconURL,
name: app.name
name: app.manifest.name
};
}, true);
}

View File

@ -14,11 +14,10 @@ const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm");
const {EventEmitter} = Cu.import("resource://gre/modules/devtools/event-emitter.js");
const {TextEncoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
const {AppProjects} = require("devtools/app-manager/app-projects");
const WebappsStore = require("devtools/app-manager/webapps-store");
const TabStore = require("devtools/webide/tab-store");
const {AppValidator} = require("devtools/app-manager/app-validator");
const {ConnectionManager, Connection} = require("devtools/client/connection-manager");
const AppActorFront = require("devtools/app-actor-front");
const {AppActorFront} = require("devtools/app-actor-front");
const {getDeviceFront} = require("devtools/server/actors/device");
const {getPreferenceFront} = require("devtools/server/actors/preference");
const {setTimeout} = require("sdk/timers");
@ -46,9 +45,6 @@ exports.AppManager = AppManager = {
this.onConnectionChanged = this.onConnectionChanged.bind(this);
this.connection.on(Connection.Events.STATUS_CHANGED, this.onConnectionChanged);
this.onWebAppsStoreready = this.onWebAppsStoreready.bind(this);
this.webAppsStore = new WebappsStore(this.connection);
this.webAppsStore.on("store-ready", this.onWebAppsStoreready);
this.tabStore = new TabStore(this.connection);
this.onTabNavigate = this.onTabNavigate.bind(this);
this.onTabClosed = this.onTabClosed.bind(this);
@ -69,25 +65,18 @@ exports.AppManager = AppManager = {
this.trackSimulatorRuntimes();
this.onInstallProgress = this.onInstallProgress.bind(this);
AppActorFront.on("install-progress", this.onInstallProgress);
this.observe = this.observe.bind(this);
Services.prefs.addObserver(WIFI_SCANNING_PREF, this, false);
},
uninit: function() {
AppActorFront.off("install-progress", this.onInstallProgress);
this._unlistenToApps();
this.selectedProject = null;
this.selectedRuntime = null;
this.untrackUSBRuntimes();
this.untrackWiFiRuntimes();
this.untrackSimulatorRuntimes();
this._runningApps.clear();
this.runtimeList = null;
this.webAppsStore.off("store-ready", this.onWebAppsStoreready);
this.webAppsStore.destroy();
this.webAppsStore = null;
this.tabStore.off("navigate", this.onTabNavigate);
this.tabStore.off("closed", this.onTabClosed);
this.tabStore.destroy();
@ -136,14 +125,25 @@ exports.AppManager = AppManager = {
if (this.connection.status != Connection.Status.CONNECTED) {
console.log("Connection status changed: " + this.connection.status);
this._runningApps.clear();
this._unlistenToApps();
if (this._appsFront) {
this._appsFront.off("install-progress", this.onInstallProgress);
this._appsFront.unwatchApps();
this._appsFront = null;
}
this._listTabsResponse = null;
} else {
this.connection.client.listTabs((response) => {
this._listenToApps();
let front = new AppActorFront(this.connection.client,
response);
front.on("install-progress", this.onInstallProgress);
front.watchApps(() => this.checkIfProjectIsRunning())
.then(() => front.fetchIcons())
.then(() => {
this._appsFront = front;
this.checkIfProjectIsRunning();
this.update("runtime-apps-found");
});
this._listTabsResponse = response;
this._getRunningApps();
this.update("list-tabs-response");
});
}
@ -151,64 +151,26 @@ exports.AppManager = AppManager = {
this.update("connection");
},
get apps() {
if (this._appsFront) {
return this._appsFront.apps;
} else {
return new Map();
}
},
onInstallProgress: function(event, details) {
this.update("install-progress", details);
},
onWebAppsStoreready: function() {
this.update("runtime-apps-found");
},
_runningApps: new Set(),
_getRunningApps: function() {
let client = this.connection.client;
if (!this._listTabsResponse.webappsActor) {
return;
}
let request = {
to: this._listTabsResponse.webappsActor,
type: "listRunningApps"
};
client.request(request, (res) => {
if (res.error) {
this.reportError("error_listRunningApps");
console.error("listRunningApps error: " + res.error);
}
for (let m of res.apps) {
this._runningApps.add(m);
}
});
this.checkIfProjectIsRunning();
},
_listenToApps: function() {
let client = this.connection.client;
client.addListener("appOpen", (type, { manifestURL }) => {
this._runningApps.add(manifestURL);
this.checkIfProjectIsRunning();
});
client.addListener("appClose", (type, { manifestURL }) => {
this._runningApps.delete(manifestURL);
this.checkIfProjectIsRunning();
});
client.addListener("appUninstall", (type, { manifestURL }) => {
this._runningApps.delete(manifestURL);
this.checkIfProjectIsRunning();
});
},
_unlistenToApps: function() {
// Is that even possible?
// connection.client is null now.
},
isProjectRunning: function() {
if (this.selectedProject.type == "mainProcess" ||
this.selectedProject.type == "tab") {
return true;
}
let manifest = this.getProjectManifestURL(this.selectedProject);
return manifest && this._runningApps.has(manifest);
let app = this._getProjectFront(this.selectedProject);
return app && app.running;
},
checkIfProjectIsRunning: function() {
@ -260,12 +222,10 @@ exports.AppManager = AppManager = {
}
return this.getTarget().then(target => {
target.activeTab.reload();
});
}, console.error.bind(console));
},
getTarget: function() {
let client = this.connection.client;
if (this.selectedProject.type == "mainProcess") {
return devtools.TargetFactory.forRemoteTab({
form: this._listTabsResponse,
@ -278,13 +238,11 @@ exports.AppManager = AppManager = {
return this.tabStore.getTargetForTab();
}
let manifest = this.getProjectManifestURL(this.selectedProject);
if (!manifest) {
console.error("Can't find manifestURL for selected project");
return promise.reject();
let app = this._getProjectFront(this.selectedProject);
if (!app) {
return promise.reject("Can't find app front for selected project");
}
let actor = this._listTabsResponse.webappsActor;
return Task.spawn(function* () {
// Once we asked the app to launch, the app isn't necessary completely loaded.
// launch request only ask the app to launch and immediatly returns.
@ -292,21 +250,18 @@ exports.AppManager = AppManager = {
for (let i = 0; i < 10; i++) {
try {
let target = yield AppActorFront.getTargetForApp(client, actor, manifest);
// Success
return target;
return yield app.getTarget();
} catch(e) {}
let deferred = promise.defer();
setTimeout(deferred.resolve, 500);
yield deferred.promise;
}
AppManager.reportError("error_cantConnectToApp", manifest);
AppManager.reportError("error_cantConnectToApp", app.manifest.manifestURL);
throw new Error("can't connect to app");
});
},
getProjectManifestURL: function(project) {
let manifest = null;
if (project.type == "runtimeApp") {
@ -324,6 +279,14 @@ exports.AppManager = AppManager = {
return manifest;
},
_getProjectFront: function(project) {
let manifest = this.getProjectManifestURL(project);
if (manifest && this._appsFront) {
return this._appsFront.apps.get(manifest);
}
return null;
},
_selectedProject: null,
set selectedProject(value) {
// A regular comparison still sees a difference when equal in some cases
@ -445,23 +408,19 @@ exports.AppManager = AppManager = {
if (this.selectedProject && this.selectedProject.type != "runtimeApp") {
return promise.reject("attempting to launch a non-runtime app");
}
let client = this.connection.client;
let actor = this._listTabsResponse.webappsActor;
let manifest = this.getProjectManifestURL(this.selectedProject);
return AppActorFront.launchApp(client, actor, manifest);
let app = this._getProjectFront(this.selectedProject);
return app.launch();
},
launchOrReloadRuntimeApp: function() {
if (this.selectedProject && this.selectedProject.type != "runtimeApp") {
return promise.reject("attempting to launch / reload a non-runtime app");
}
let client = this.connection.client;
let actor = this._listTabsResponse.webappsActor;
let manifest = this.getProjectManifestURL(this.selectedProject);
if (!this.isProjectRunning()) {
return AppActorFront.launchApp(client, actor, manifest);
let app = this._getProjectFront(this.selectedProject);
if (!app.running) {
return app.launch();
} else {
return AppActorFront.reloadApp(client, actor, manifest);
return app.reload();
}
},
@ -488,22 +447,20 @@ exports.AppManager = AppManager = {
return;
}
let client = self.connection.client;
let actor = self._listTabsResponse.webappsActor;
let installPromise;
if (project.type != "packaged" && project.type != "hosted") {
return promise.reject("Don't know how to install project");
}
let response;
if (project.type == "packaged") {
let {appId} = yield AppActorFront.installPackaged(client,
actor,
project.location,
project.packagedAppOrigin);
response = yield self._appsFront.installPackaged(project.location,
project.packagedAppOrigin);
// If the packaged app specified a custom origin override,
// we need to update the local project origin
project.packagedAppOrigin = appId;
project.packagedAppOrigin = response.appId;
// And ensure the indexed db on disk is also updated
AppProjects.update(project);
}
@ -516,15 +473,13 @@ exports.AppManager = AppManager = {
origin: origin.spec,
manifestURL: project.location
};
yield AppActorFront.installHosted(client,
actor,
appId,
metadata,
project.manifest);
response = yield self._appsFront.installHosted(appId,
metadata,
project.manifest);
}
let manifest = self.getProjectManifestURL(project);
if (!self._runningApps.has(manifest)) {
let {app} = response;
if (!app.running) {
let deferred = promise.defer();
self.on("app-manager-update", function onUpdate(event, what) {
if (what == "project-is-running") {
@ -532,20 +487,17 @@ exports.AppManager = AppManager = {
deferred.resolve();
}
});
yield AppActorFront.launchApp(client, actor, manifest);
yield app.launch();
yield deferred.promise;
} else {
yield AppActorFront.reloadApp(client, actor, manifest);
yield app.reload();
}
});
},
stopRunningApp: function() {
let client = this.connection.client;
let actor = this._listTabsResponse.webappsActor;
let manifest = this.getProjectManifestURL(this.selectedProject);
return AppActorFront.closeApp(client, actor, manifest);
let app = this._getProjectFront(this.selectedProject);
return app.close();
},
/* PROJECT VALIDATION */

View File

@ -26,7 +26,6 @@
let appmgr = win.AppManager;
ok(appmgr.connection, "App Manager connection ready");
ok(appmgr.runtimeList, "Runtime list ready");
ok(appmgr.webAppsStore, "WebApps store ready");
// test error reporting
let nbox = win.document.querySelector("#notificationbox");

View File

@ -84,15 +84,15 @@ function zipDirectory(zipFile, dirToArchive) {
return deferred.promise;
}
function uploadPackage(client, webappsActor, packageFile) {
function uploadPackage(client, webappsActor, packageFile, progressCallback) {
if (client.traits.bulk) {
return uploadPackageBulk(client, webappsActor, packageFile);
return uploadPackageBulk(client, webappsActor, packageFile, progressCallback);
} else {
return uploadPackageJSON(client, webappsActor, packageFile);
return uploadPackageJSON(client, webappsActor, packageFile, progressCallback);
}
}
function uploadPackageJSON(client, webappsActor, packageFile) {
function uploadPackageJSON(client, webappsActor, packageFile, progressCallback) {
let deferred = promise.defer();
let request = {
@ -107,7 +107,7 @@ function uploadPackageJSON(client, webappsActor, packageFile) {
let bytesRead = 0;
function emitProgress() {
emitInstallProgress({
progressCallback({
bytesSent: bytesRead,
totalBytes: fileSize
});
@ -163,7 +163,7 @@ function uploadPackageJSON(client, webappsActor, packageFile) {
return deferred.promise;
}
function uploadPackageBulk(client, webappsActor, packageFile) {
function uploadPackageBulk(client, webappsActor, packageFile, progressCallback) {
let deferred = promise.defer();
let request = {
@ -190,7 +190,7 @@ function uploadPackageBulk(client, webappsActor, packageFile) {
NetUtil.asyncFetch(packageFile, function(inputStream) {
let copying = copyFrom(inputStream);
copying.on("progress", (e, progress) => {
emitInstallProgress(progress);
progressCallback(progress);
});
copying.then(() => {
console.log("Bulk upload done");
@ -212,7 +212,14 @@ function removeServerTemporaryFile(client, fileActor) {
client.request(request);
}
function installPackaged(client, webappsActor, packagePath, appId) {
/**
* progressCallback argument:
* Function called as packaged app installation proceeds.
* The progress object passed to this function contains:
* * bytesSent: The number of bytes sent so far
* * totalBytes: The total number of bytes to send
*/
function installPackaged(client, webappsActor, packagePath, appId, progressCallback) {
let deferred = promise.defer();
let file = FileUtils.File(packagePath);
let packagePromise;
@ -225,7 +232,7 @@ function installPackaged(client, webappsActor, packagePath, appId) {
packagePromise = promise.resolve(file);
}
packagePromise.then((zipFile) => {
uploadPackage(client, webappsActor, zipFile)
uploadPackage(client, webappsActor, zipFile, progressCallback)
.then((fileActor) => {
let request = {
to: webappsActor,
@ -260,16 +267,6 @@ function installPackaged(client, webappsActor, packagePath, appId) {
}
exports.installPackaged = installPackaged;
/**
* Emits numerous events as packaged app installation proceeds.
* The progress object contains:
* * bytesSent: The number of bytes sent so far
* * totalBytes: The total number of bytes to send
*/
function emitInstallProgress(progress) {
exports.emit("install-progress", progress);
}
function installHosted(client, webappsActor, appId, metadata, manifest) {
let deferred = promise.defer();
let request = {
@ -396,6 +393,8 @@ function App(client, webappsActor, manifest) {
// This attribute is managed by the AppActorFront
this.running = false;
this.iconURL = null;
}
App.prototype = {
@ -427,6 +426,48 @@ App.prototype = {
});
return this._target = target;
});
},
launch: function () {
return launchApp(this.client, this.webappsActor,
this.manifest.manifestURL);
},
reload: function () {
return reloadApp(this.client, this.webappsActor,
this.manifest.manifestURL);
},
close: function () {
return closeApp(this.client, this.webappsActor,
this.manifest.manifestURL)
},
getIcon: function () {
if (this.iconURL) {
return promise.resolve(this.iconURL);
}
let deferred = promise.defer();
let request = {
to: this.webappsActor,
type: "getIconAsDataURL",
manifestURL: this.manifest.manifestURL
};
this.client.request(request, res => {
if (res.error) {
deferred.reject(res.message || res.error);
} else if (res.url) {
this.iconURL = res.url;
deferred.resolve(res.url);
} else {
deferred.reject("Unable to fetch app icon");
}
});
return deferred.promise;
}
};
@ -439,8 +480,10 @@ function AppActorFront(client, form) {
this.actor = form.webappsActor;
this._clientListener = this._clientListener.bind(this);
this._onInstallProgress = this._onInstallProgress.bind(this);
this._listeners = [];
EventEmitter.decorate(this);
}
AppActorFront.prototype = {
@ -475,7 +518,7 @@ AppActorFront.prototype = {
* (and cache it per AppActorFront object)
*/
_getApp: function (manifestURL) {
let app = this._apps.get(manifestURL);
let app = this._apps ? this._apps.get(manifestURL) : null;
if (app) {
return promise.resolve(app);
} else {
@ -487,7 +530,9 @@ AppActorFront.prototype = {
return this.client.request(request)
.then(res => {
let app = new App(this.client, this.actor, res.app);
this._apps.set(manifestURL, app);
if (this._apps) {
this._apps.set(manifestURL, app);
}
return app;
}, e => {
console.error("Unable to retrieve app", manifestURL, e);
@ -500,33 +545,31 @@ AppActorFront.prototype = {
* Needs to be called before using `apps` or `runningApps` attributes.
*/
watchApps: function (listener) {
this._listeners.push(listener);
// Fixes race between two references to the same front
// calling watchApps at the same time
if (this._loadingPromise) {
return this._loadingPromise;
}
// Only call watchApps for the first listener being register,
// for all next ones, just send fake appOpen events for already
// opened apps
if (this._listeners.length > 1) {
if (this._apps) {
this.runningApps.forEach((app, manifestURL) => {
listener("appOpen", app);
});
return promise.resolve();
}
let client = this.client;
let f = this._clientListener;
client.addListener("appOpen", f);
client.addListener("appClose", f);
client.addListener("appInstall", f);
client.addListener("appUninstall", f);
// First retrieve all installed apps and create
// related `App` object for each
let request = {
to: this.actor,
type: "getAll"
};
return this.client.request(request)
return this._loadingPromise = this.client.request(request)
.then(res => {
delete this._loadingPromise;
this._apps = new Map();
for (let a of res.apps) {
let app = new App(this.client, this.actor, a);
@ -556,16 +599,80 @@ AppActorFront.prototype = {
})
.then(() => {
// Finally ask to receive all app events
let request = {
to: this.actor,
type: "watchApps"
};
return this.client.request(request);
return this._listenAppEvents(listener);
});
},
fetchIcons: function () {
// On demand, retrieve apps icons in order to be able
// to synchronously retrieve it on `App` objects
let promises = [];
for (let [manifestURL, app] of this._apps) {
promises.push(app.getIcon());
}
return promise.all(promises)
.then(null, () => {}); // Ignore any failure
},
_listenAppEvents: function (listener) {
this._listeners.push(listener);
if (this._listeners.length > 1) {
return promise.resolve();
}
let client = this.client;
let f = this._clientListener;
client.addListener("appOpen", f);
client.addListener("appClose", f);
client.addListener("appInstall", f);
client.addListener("appUninstall", f);
let request = {
to: this.actor,
type: "watchApps"
};
return this.client.request(request);
},
_unlistenAppEvents: function (listener) {
let idx = this._listeners.indexOf(listener);
if (idx != -1) {
this._listeners.splice(idx, 1);
}
// Until we released all listener, we don't ask to stop sending events
if (this._listeners.length != 0) {
return promise.resolve();
}
let client = this.client;
let f = this._clientListener;
client.removeListener("appOpen", f);
client.removeListener("appClose", f);
client.removeListener("appInstall", f);
client.removeListener("appUninstall", f);
// Remove `_apps` in order to allow calling watchApps again
// and repopulate the apps Map.
delete this._apps;
let request = {
to: this.actor,
type: "unwatchApps"
};
return this.client.request(request);
},
_clientListener: function (type, message) {
let { manifestURL } = message;
// Reset the app object to get a fresh copy when we (re)install the app.
if (type == "appInstall" && this._apps && this._apps.has(manifestURL)) {
this._apps.delete(manifestURL);
}
this._getApp(manifestURL).then((app) => {
switch(type) {
case "appOpen":
@ -573,8 +680,23 @@ AppActorFront.prototype = {
break;
case "appClose":
app.running = false;
break;
case "appInstall":
// The call to _getApp is going to create App object
// This app may have been running while being installed, so check the list
// of running apps again to get the right answer.
let request = {
to: this.actor,
type: "listRunningApps"
};
this.client.request(request)
.then(res => {
if (res.apps.indexOf(manifestURL) !== -1) {
app.running = true;
this._notifyListeners("appOpen", app);
}
});
break;
case "appUninstall":
// Fake a appClose event if we didn't got one before uninstall
@ -588,6 +710,7 @@ AppActorFront.prototype = {
return;
}
this._notifyListeners(type, app);
});
},
@ -598,31 +721,101 @@ AppActorFront.prototype = {
},
unwatchApps: function (listener) {
let idx = this._listeners.indexOf(listener);
if (idx != -1) {
this._listeners.splice(idx, 1);
}
return this._unlistenAppEvents(listener);
},
// Until we released all listener, we don't ask to stop sending events
if (this._listeners.length != 0) {
return;
}
let request = {
to: this.actor,
type: "unwatchApps"
/*
* Install a packaged app.
*
* Events are going to be emitted on the front
* as install progresses. Events will have the following fields:
* * bytesSent: The number of bytes sent so far
* * totalBytes: The total number of bytes to send
*/
installPackaged: function (packagePath, appId) {
let request = () => {
return installPackaged(this.client, this.actor, packagePath, appId,
this._onInstallProgress)
.then(response => ({
appId: response.appId,
manifestURL: "app://" + response.appId + "/manifest.webapp"
}));
};
this.client.request(request);
return this._install(request);
},
let client = this.client;
let f = this._clientListener;
client.removeListener("appOpen", f);
client.removeListener("appClose", f);
client.removeListener("appInstall", f);
client.removeListener("appUninstall", f);
_onInstallProgress: function (progress) {
this.emit("install-progress", progress);
},
_install: function (request) {
let deferred = promise.defer();
let finalAppId = null, manifestURL = null;
let installs = {};
// We need to resolve only once the request is done *AND*
// once we receive the related appInstall message for
// the same manifestURL
let resolve = app => {
this._unlistenAppEvents(listener);
installs = null;
deferred.resolve({ app: app, appId: finalAppId });
};
// Listen for appInstall event, in order to resolve with
// the matching app object.
let listener = (type, app) => {
if (type == "appInstall") {
// Resolves immediately if the request has already resolved
// or just flag the installed app to eventually resolve
// when the request gets its response.
if (app.manifest.manifestURL === manifestURL) {
resolve(app);
} else {
installs[app.manifest.manifestURL] = app;
}
}
};
this._listenAppEvents(listener)
// Execute the request
.then(request)
.then(response => {
finalAppId = response.appId;
manifestURL = response.manifestURL;
// Resolves immediately if the appInstall event
// was dispatched during the request.
if (manifestURL in installs) {
resolve(installs[manifestURL]);
}
}, deferred.reject);
return deferred.promise;
},
/*
* Install a hosted app.
*
* Events are going to be emitted on the front
* as install progresses. Events will have the following fields:
* * bytesSent: The number of bytes sent so far
* * totalBytes: The total number of bytes to send
*/
installHosted: function (appId, metadata, manifest) {
let manifestURL = metadata.manifestURL ||
metadata.origin + "/manifest.webapp";
let request = () => {
return installHosted(this.client, this.actor, appId, metadata,
manifest)
.then(response => ({
appId: response.appId,
manifestURL: manifestURL
}));
};
return this._install(request);
}
}
exports.AppActorFront = AppActorFront;
EventEmitter.decorate(exports);

View File

@ -13,8 +13,11 @@ Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const {require} = devtools;
const {AppActorFront} = require("devtools/app-actor-front");
let gClient, gActor;
let gClient, gActor, gActorFront;
function connect(onDone) {
// Initialize a loopback remote protocol connection
@ -28,6 +31,7 @@ function connect(onDone) {
gClient.connect(function onConnect() {
gClient.listTabs(function onListTabs(aResponse) {
gActor = aResponse.webappsActor;
gActorFront = new AppActorFront(gClient, aResponse);
onDone();
});
});

View File

@ -1,10 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const {require} = devtools;
const AppActorFront = require("devtools/app-actor-front");
const {installHosted, installPackaged} = AppActorFront;
const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
let gAppId = "actor-test";
@ -183,15 +179,15 @@ add_test(function testFileUploadInstall() {
let progressDeferred = promise.defer();
// Ensure we get at least one progress event at the end
AppActorFront.on("install-progress", function onProgress(e, progress) {
gActorFront.on("install-progress", function onProgress(e, progress) {
if (progress.bytesSent == progress.totalBytes) {
AppActorFront.off("install-progress", onProgress);
gActorFront.off("install-progress", onProgress);
progressDeferred.resolve();
}
});
let installed =
installPackaged(gClient, gActor, packageFile.path, gAppId)
gActorFront.installPackaged(packageFile.path, gAppId)
.then(function ({ appId }) {
do_check_eq(appId, gAppId);
}, function (e) {
@ -212,15 +208,15 @@ add_test(function testBulkUploadInstall() {
let progressDeferred = promise.defer();
// Ensure we get at least one progress event at the end
AppActorFront.on("install-progress", function onProgress(e, progress) {
gActorFront.on("install-progress", function onProgress(e, progress) {
if (progress.bytesSent == progress.totalBytes) {
AppActorFront.off("install-progress", onProgress);
gActorFront.off("install-progress", onProgress);
progressDeferred.resolve();
}
});
let installed =
installPackaged(gClient, gActor, packageFile.path, gAppId)
gActorFront.installPackaged(packageFile.path, gAppId)
.then(function ({ appId }) {
do_check_eq(appId, gAppId);
}, function (e) {
@ -242,15 +238,14 @@ add_test(function testInstallHosted() {
name: "My hosted app",
csp: "script-src: http://foo.com"
};
installHosted(gClient, gActor, gAppId, metadata, manifest).then(
function ({ appId }) {
do_check_eq(appId, gAppId);
run_next_test();
},
function (e) {
do_throw("Failed installing hosted app: " + e.error + ": " + e.message);
}
);
gActorFront.installHosted(gAppId, metadata, manifest)
.then(function ({ appId }) {
do_check_eq(appId, gAppId);
run_next_test();
},
function (e) {
do_throw("Failed installing hosted app: " + e.error + ": " + e.message);
});
});
add_test(function testCheckHostedApp() {