--- a/testing/marionette/components/marionette.js
+++ b/testing/marionette/components/marionette.js
@@ -9,16 +9,25 @@ const {Constructor: CC, interfaces: Ci,
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const MARIONETTE_CONTRACT_ID = "@mozilla.org/marionette;1";
const MARIONETTE_CID = Components.ID("{786a1369-dca5-4adc-8486-33d23c88010a}");
+const PREF_ENABLED = "marionette.enabled";
+const PREF_ENABLED_FALLBACK = "marionette.defaultPrefs.enabled";
+const PREF_PORT = "marionette.port";
+const PREF_PORT_FALLBACK = "marionette.defaultPrefs.port";
+const PREF_LOG_LEVEL = "marionette.log.level";
+const PREF_LOG_LEVEL_FALLBACK = "marionette.logging";
+const PREF_FORCE_LOCAL = "marionette.forcelocal";
+const PREF_FORCE_LOCAL_FALLBACK = "marionette.force-local";
+
const DEFAULT_PORT = 2828;
const DEFAULT_LOG_LEVEL = "info";
const LOG_LEVELS = new Map([
["fatal", Log.Level.Fatal],
["error", Log.Level.Error],
["warn", Log.Level.Warn],
["info", Log.Level.Info],
["config", Log.Level.Config],
@@ -45,30 +54,25 @@ const ServerSocket = CC("@mozilla.org/ne
"initSpecialConnection");
// Marionette preferences recently changed names. This is an abstraction
// that first looks for the new name, but falls back to using the old name
// if the new does not exist.
//
// This shim can be removed when Firefox 55 ships.
const prefs = {
- get enabled () {
- let fallback = Preferences.get("marionette.defaultPrefs.enabled", false);
- return Preferences.get("marionette.enabled", fallback);
- },
-
get port () {
- let fallback = Preferences.get("marionette.defaultPrefs.port", DEFAULT_PORT);
- return Preferences.get("marionette.port", fallback);
+ let fallback = Preferences.get(PREF_PORT_FALLBACK, DEFAULT_PORT);
+ return Preferences.get(PREF_PORT, fallback);
},
get logLevel () {
let level = DEFAULT_LOG_LEVEL;
- let fallback = Preferences.get("marionette.logging", level);
- let p = Preferences.get("marionette.log.level", fallback);
+ let fallback = Preferences.get(PREF_LOG_LEVEL_FALLBACK, level);
+ let p = Preferences.get(PREF_LOG_LEVEL, fallback);
switch (typeof p) {
// Gecko >= 46
case "string":
let s = p.toLowerCase();
if (LOG_LEVELS.has(s)) {
level = LOG_LEVELS.get(s);
}
@@ -81,18 +85,18 @@ const prefs = {
}
break;
}
return level;
},
get forceLocal () {
- let fallback = Preferences.get("marionette.force-local", true);
- return Preferences.get("marionette.forcelocal", fallback);
+ let fallback = Preferences.get(PREF_FORCE_LOCAL_FALLBACK, true);
+ return Preferences.get(PREF_FORCE_LOCAL, fallback);
},
readFromEnvironment (key) {
const env = Cc["@mozilla.org/process/environment;1"]
.getService(Ci.nsIEnvironment);
if (env.exists(key)) {
let prefs;
@@ -110,37 +114,39 @@ const prefs = {
Preferences.set("marionette." + prefName, prefs[prefName]);
}
}
}
},
};
function MarionetteComponent() {
- // keeps track of whether Marionette is available,
- // either as a result of the marionette.enabled pref
- // or by use of the --marionette flag
- this.enabled = prefs.enabled;
-
// guards against this component
// being initialised multiple times
this.running = false;
// holds a reference to server.TCPListener
this.server = null;
// holds reference to ChromeWindow
// used to run GFX sanity tests on Windows
this.gfxWindow = null;
// indicates that all pending window checks have been completed
// and that we are ready to start the Marionette server
this.finalUIStartup = false;
this.logger = this.setupLogger(prefs.logLevel);
+ Services.prefs.addObserver(PREF_ENABLED, this, false);
+
+ if (Preferences.isSet(PREF_ENABLED_FALLBACK)) {
+ this.logger.warn(`Deprecated preference ${PREF_ENABLED_FALLBACK} detected, ` +
+ `please use ${PREF_ENABLED}`);
+ Preferences.set(PREF_ENABLED, Preferences.get(PREF_ENABLED_FALLBACK));
+ }
}
MarionetteComponent.prototype = {
classDescription: "Marionette component",
classID: MARIONETTE_CID,
contractID: MARIONETTE_CONTRACT_ID,
QueryInterface: XPCOMUtils.generateQI(
[Ci.nsICommandLineHandler, Ci.nsIObserver]),
@@ -158,23 +164,39 @@ MarionetteComponent.prototype.onStopList
this.logger.info(`onStopListening for Marionette dummy socket, code ${status}`);
socket.close();
};
// Handle --marionette flag
MarionetteComponent.prototype.handle = function (cmdLine) {
if (cmdLine.handleFlag("marionette", false)) {
this.enabled = true;
- this.logger.debug("Marionette enabled via command-line flag");
- this.init();
}
};
+Object.defineProperty(MarionetteComponent.prototype, "enabled", {
+ set (value) {
+ Preferences.set(PREF_ENABLED, value);
+ },
+
+ get () {
+ return Preferences.get(PREF_ENABLED);
+ },
+});
+
MarionetteComponent.prototype.observe = function (subject, topic, data) {
switch (topic) {
+ case "nsPref:changed":
+ if (Preferences.get(PREF_ENABLED)) {
+ this.init();
+ } else {
+ this.uninit();
+ }
+ break;
+
case "profile-after-change":
// Using sessionstore-windows-restored as the xpcom category doesn't
// seem to work, so we wait for that by adding an observer here.
Services.obs.addObserver(this, "sessionstore-windows-restored", false);
prefs.readFromEnvironment(ENV_PREF_VAR);
if (this.enabled) {
@@ -251,18 +273,16 @@ MarionetteComponent.prototype.suppressSa
}, {once: true});
};
MarionetteComponent.prototype.init = function () {
if (this.running || !this.enabled || !this.finalUIStartup) {
return;
}
- this.running = true;
-
if (!prefs.forceLocal) {
// See bug 800138. Because the first socket that opens with
// force-local=false fails, we open a dummy socket that will fail.
// keepWhenOffline=true so that it still work when offline (local).
// This allows the following attempt by Marionette to open a socket
// to succeed.
let insaneSacrificialGoat =
new ServerSocket(666, Ci.nsIServerSocket.KeepWhenOffline, 4);
@@ -276,21 +296,23 @@ MarionetteComponent.prototype.init = fun
s.start();
this.logger.info(`Listening on port ${s.port}`);
} catch (e) {
this.logger.error(`Error on starting server: ${e}`);
dump(`${e.toString()}\n${e.stack}\n`);
} finally {
if (s) {
this.server = s;
+ this.running = true;
}
}
};
MarionetteComponent.prototype.uninit = function () {
if (!this.running) {
return;
}
this.server.stop();
+ this.logger.info("Ceased listening");
this.running = false;
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MarionetteComponent]);