Bug 1344748 - Make Marionette respect marionette.enabled pref; r=whimboo
authorAndreas Tolfsen <ato@mozilla.com>
Thu, 09 Mar 2017 20:15:32 +0000
changeset 397853 728b96e6ccdd234919e50263521e8f080f505d5f
parent 397852 818abd440d52e010eb2ea2ec50f131da650551eb
child 397854 16ae5cf72cd684b87acaf61b183f05128a85fdab
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswhimboo
bugs1344748
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1344748 - Make Marionette respect marionette.enabled pref; r=whimboo This removes the internal enabledness state tracking in MarionetteComponent in favour of the marionette.enabled preference. When the marionette.enabled preference changes, Marionette is enabled or disabled. Depending on whether all the initialisation conditions have been met, Marionette is started. If it is running, it is stopped when toggling the preference back off. MozReview-Commit-ID: jQFYZhULqO
testing/marionette/components/marionette.js
--- 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]);