Bug 1090949 - Make Firefox OS Simulator accept launch options. r=ochameau
authorJan Keromnes <janx@linux.com>
Thu, 11 Dec 2014 09:18:00 +0100
changeset 219488 8132d858fefec2c174859d6e348226f416232d53
parent 219487 63527327468c592cd84145090add07db16258535
child 219489 80f3ab1c6cf230969248a57b0435b8d8c37dac72
push idunknown
push userunknown
push dateunknown
reviewersochameau
bugs1090949
milestone37.0a1
Bug 1090949 - Make Firefox OS Simulator accept launch options. r=ochameau
b2g/simulator/lib/main.js
b2g/simulator/lib/simulator-process.js
--- 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;