Bug 1090949 - Make Firefox OS Simulator accept launch options. r=ochameau
--- a/b2g/simulator/lib/main.js
+++ b/b2g/simulator/lib/main.js
@@ -1,30 +1,67 @@
/* 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 { Cc, Ci, Cu } = require("chrome");
-const { SimulatorProcess } = require("./simulator-process");
+const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
+const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const { Simulator } = Cu.import("resource://gre/modules/devtools/Simulator.jsm");
-const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
+const { SimulatorProcess } = require("./simulator-process");
+const Runtime = require("sdk/system/runtime");
+const URL = require("sdk/url");
+
+const ROOT_URI = require("addon").uri;
+const PROFILE_URL = ROOT_URI + "profile/";
+const BIN_URL = ROOT_URI + "b2g/";
let process;
-function launch({ port }) {
- // Close already opened simulation
+function launch(options) {
+ // Close already opened simulation.
if (process) {
- return close().then(launch.bind(null, { port: port }));
+ return close().then(launch.bind(null, options));
}
- process = SimulatorProcess();
- process.remoteDebuggerPort = port;
+ // Compute B2G runtime path.
+ let path;
+ try {
+ let pref = "extensions." + require("addon").id + ".customRuntime";
+ path = Services.prefs.getComplexValue(pref, Ci.nsIFile);
+ } catch(e) {}
+
+ if (!path) {
+ let executables = {
+ WINNT: "b2g-bin.exe",
+ Darwin: "B2G.app/Contents/MacOS/b2g-bin",
+ Linux: "b2g-bin",
+ };
+ path = URL.toFilename(BIN_URL);
+ path += Runtime.OS == "WINNT" ? "\\" : "/";
+ path += executables[Runtime.OS];
+ }
+ options.runtimePath = path;
+ console.log("simulator path:", options.runtimePath);
+
+ // Compute Gaia profile path.
+ if (!options.profilePath) {
+ let gaiaProfile;
+ try {
+ let pref = "extensions." + require("addon").id + ".gaiaProfile";
+ gaiaProfile = Services.prefs.getComplexValue(pref, Ci.nsIFile).path;
+ } catch(e) {}
+
+ options.profilePath = gaiaProfile || URL.toFilename(PROFILE_URL);
+ }
+
+ process = new SimulatorProcess(options);
process.run();
return promise.resolve();
}
function close() {
if (!process) {
return promise.resolve();
--- a/b2g/simulator/lib/simulator-process.js
+++ b/b2g/simulator/lib/simulator-process.js
@@ -4,48 +4,43 @@
*/
'use strict';
const { Cc, Ci, Cu, ChromeWorker } = require("chrome");
Cu.import("resource://gre/modules/Services.jsm");
-const { EventTarget } = require("sdk/event/target");
-const { emit, off } = require("sdk/event/core");
-const { Class } = require("sdk/core/heritage");
const Environment = require("sdk/system/environment").env;
const Runtime = require("sdk/system/runtime");
-const URL = require("sdk/url");
const Subprocess = require("sdk/system/child_process/subprocess");
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
+const { EventEmitter } = Cu.import("resource://gre/modules/devtools/event-emitter.js", {});
-const ROOT_URI = require("addon").uri;
-const PROFILE_URL = ROOT_URI + "profile/";
-const BIN_URL = ROOT_URI + "b2g/";
// Log subprocess error and debug messages to the console. This logs messages
// for all consumers of the API. We trim the messages because they sometimes
// have trailing newlines. And note that registerLogHandler actually registers
// an error handler, despite its name.
Subprocess.registerLogHandler(
function(s) console.error("subprocess: " + s.trim())
);
Subprocess.registerDebugHandler(
function(s) console.debug("subprocess: " + s.trim())
);
-exports.SimulatorProcess = Class({
- extends: EventTarget,
- initialize: function initialize(options) {
- EventTarget.prototype.initialize.call(this, options);
+function SimulatorProcess(options) {
+ this.options = options;
- this.on("stdout", function onStdout(data) console.log(data.trim()));
- this.on("stderr", function onStderr(data) console.error(data.trim()));
- },
+ EventEmitter.decorate(this);
+ this.on("stdout", data => { console.log(data.trim()) });
+ this.on("stderr", data => { console.error(data.trim()) });
+}
+
+SimulatorProcess.prototype = {
// check if b2g is running
get isRunning() !!this.process,
/**
* Start the process and connect the debugger client.
*/
run: function() {
@@ -72,131 +67,97 @@ exports.SimulatorProcess = Class({
command: "/usr/bin/osascript",
arguments: ["-e", 'tell application "' + path + '" to activate'],
});
}
});
let environment;
if (Runtime.OS == "Linux") {
- environment = ["TMPDIR=" + Services.dirsvc.get("TmpD",Ci.nsIFile).path];
+ environment = ["TMPDIR=" + Services.dirsvc.get("TmpD", Ci.nsIFile).path];
if ("DISPLAY" in Environment) {
environment.push("DISPLAY=" + Environment.DISPLAY);
}
}
// spawn a b2g instance
this.process = Subprocess.call({
command: b2gExecutable,
arguments: this.b2gArguments,
environment: environment,
// emit stdout event
- stdout: (function(data) {
- emit(this, "stdout", data);
- }).bind(this),
+ stdout: data => {
+ this.emit("stdout", data);
+ },
// emit stderr event
- stderr: (function(data) {
- emit(this, "stderr", data);
- }).bind(this),
+ stderr: data => {
+ this.emit("stderr", data);
+ },
- // on b2g instance exit, reset tracked process, remoteDebuggerPort and
+ // on b2g instance exit, reset tracked process, remote debugger port and
// shuttingDown flag, then finally emit an exit event
done: (function(result) {
- console.log(this.b2gFilename + " terminated with " + result.exitCode);
+ console.log("B2G terminated with " + result.exitCode);
this.process = null;
- emit(this, "exit", result.exitCode);
+ this.emit("exit", result.exitCode);
}).bind(this)
});
},
// request a b2g instance kill
kill: function() {
let deferred = promise.defer();
if (this.process) {
this.once("exit", (exitCode) => {
this.shuttingDown = false;
deferred.resolve(exitCode);
});
if (!this.shuttingDown) {
this.shuttingDown = true;
- emit(this, "kill", null);
+ this.emit("kill", null);
this.process.kill();
}
return deferred.promise;
} else {
return promise.resolve(undefined);
}
},
- // compute current b2g filename
- get b2gFilename() {
- return this._executable ? this._executableFilename : "B2G";
- },
-
// compute current b2g file handle
get b2gExecutable() {
if (this._executable) {
return this._executable;
}
- let customRuntime;
- try {
- let pref = "extensions." + require("addon").id + ".customRuntime";
- customRuntime = Services.prefs.getComplexValue(pref, Ci.nsIFile);
- } catch(e) {}
-
- if (customRuntime) {
- this._executable = customRuntime;
- this._executableFilename = "Custom runtime";
- return this._executable;
- }
-
- let bin = URL.toFilename(BIN_URL);
- let executables = {
- WINNT: "b2g-bin.exe",
- Darwin: "B2G.app/Contents/MacOS/b2g-bin",
- Linux: "b2g-bin",
- };
-
- let path = bin;
- path += Runtime.OS == "WINNT" ? "\\" : "/";
- path += executables[Runtime.OS];
- console.log("simulator path: " + path);
let executable = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
- executable.initWithPath(path);
+ executable.initWithPath(this.options.runtimePath);
if (!executable.exists()) {
// B2G binaries not found
throw Error("b2g-desktop Executable not found.");
}
this._executable = executable;
- this._executableFilename = "b2g-bin";
return executable;
},
// compute b2g CLI arguments
get b2gArguments() {
let args = [];
- let gaiaProfile;
- try {
- let pref = "extensions." + require("addon").id + ".gaiaProfile";
- gaiaProfile = Services.prefs.getComplexValue(pref, Ci.nsIFile).path;
- } catch(e) {}
-
- let profile = gaiaProfile || URL.toFilename(PROFILE_URL);
+ let profile = this.options.profilePath;
args.push("-profile", profile);
console.log("profile", profile);
// NOTE: push dbgport option on the b2g-desktop commandline
- args.push("-start-debugger-server", "" + this.remoteDebuggerPort);
+ args.push("-start-debugger-server", "" + this.options.port);
// Ignore eventual zombie instances of b2g that are left over
args.push("-no-remote");
return args;
},
-});
+};
+exports.SimulatorProcess = SimulatorProcess;