Bug 1169290 - Reintroduce marionette.enabled pref. r?maja_zf draft
authorAndreas Tolfsen <ato@sny.no>
Sat, 27 Jan 2018 19:03:18 +0000
changeset 753895 e37d3479cd09c0f3128183fc1c0a71fb547caca3
parent 753894 b55b7c94dd2ff47819577da324beb4b03ebfc521
child 753896 6f37570a152e70287a00f07a1b216412ca7e1ff5
push id98715
push userbmo:ato@sny.no
push dateMon, 12 Feb 2018 16:37:16 +0000
reviewersmaja_zf
bugs1169290
milestone60.0a1
Bug 1169290 - Reintroduce marionette.enabled pref. r?maja_zf Some time ago it was decided to remove the marionette.enabled preference due to concerns that XPCOM addons would be able to flip arbitrary preferences, potentially causing the remote control protocol to be activiated unintentionally. Since then XPCOM based addons have been removed from Firefox in favour of WebExtensions which do not have the capability to modify preferences. There are no current plans to make WebExtensions able to change preferences: https://wiki.mozilla.org/WebExtensions/FAQ#Does_the_WebExtensions_API_provide_access_to_preferences.3F This patch reintroduces the marionette.enabled preference, which when flipped to true will enable Marionette and spin up the TCP listener. Conversely it will stop the TCP listener and disable the component when switched back to false. The primary motivation for reintroducing it is the forthcoming addition of a new navigator.webdriver WebIDL attribute. The WebIDL interfaces can be annotated with [Pref="<pref name>"] which will automatically generate C++ code for determining whether it should be present in the interface. This is the easiest and least obstrusive way for Marionette to cause the webdriver attribute to appear on the navigator global. MozReview-Commit-ID: 28wN8Z3Q2a6
testing/marionette/components/marionette.js
testing/marionette/prefs/marionette.js
--- a/testing/marionette/components/marionette.js
+++ b/testing/marionette/components/marionette.js
@@ -14,16 +14,17 @@ ChromeUtils.defineModuleGetter(this, "Lo
 ChromeUtils.defineModuleGetter(this, "Preferences",
     "resource://gre/modules/Preferences.jsm");
 XPCOMUtils.defineLazyGetter(this, "log", () => {
   let log = Log.repository.getLogger("Marionette");
   log.addAppender(new Log.DumpAppender());
   return log;
 });
 
+const PREF_ENABLED = "marionette.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 DEFAULT_LOG_LEVEL = "info";
 const NOTIFY_RUNNING = "remote-active";
 
@@ -146,26 +147,44 @@ class MarionetteComponent {
 
     // indicates that all pending window checks have been completed
     // and that we are ready to start the Marionette server
     this.finalUIStartup = false;
 
     log.level = prefs.logLevel;
 
     this.enabled = env.exists(ENV_ENABLED);
+
+    Services.prefs.addObserver(PREF_ENABLED, this);
   }
 
   get running() {
     return this.server && this.server.alive;
   }
 
+  set enabled(value) {
+    Services.prefs.setBoolPref(PREF_ENABLED, value);
+  }
+
+  get enabled() {
+    return Services.prefs.getBoolPref(PREF_ENABLED);
+  }
+
   observe(subject, topic) {
     log.debug(`Received observer notification ${topic}`);
 
     switch (topic) {
+      case "nsPref:changed":
+        if (Services.prefs.getBoolPref(PREF_ENABLED)) {
+          this.init();
+        } else {
+          this.uninit();
+        }
+        break;
+
       case "profile-after-change":
         Services.obs.addObserver(this, "command-line-startup");
         Services.obs.addObserver(this, "sessionstore-windows-restored");
 
         prefs.readFromEnvironment(ENV_PRESERVE_PREFS);
         break;
 
       // In safe mode the command line handlers are getting parsed after the
@@ -282,16 +301,17 @@ class MarionetteComponent {
       Services.obs.notifyObservers(this, NOTIFY_RUNNING);
     }
   }
 
   get QueryInterface() {
     return XPCOMUtils.generateQI([
       Ci.nsICommandLineHandler,
       Ci.nsIMarionette,
+      Ci.nsIObserver,
     ]);
   }
 }
 
 const MarionetteFactory = {
   createInstance(outer, iid) {
     if (outer) {
       throw Cr.NS_ERROR_NO_AGGREGATION;
--- a/testing/marionette/prefs/marionette.js
+++ b/testing/marionette/prefs/marionette.js
@@ -1,26 +1,25 @@
 /* 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/. */
 
 /* global pref */
 
 // Marionette is the remote protocol that lets OOP programs communicate
 // with, instrument, and control Gecko.
-//
-// It is included in Firefox, but not enabled by default unless the
-// -marionette flag is passed.
+
+// Controls whether the Marionette component is enabled.
+pref("marionette.enabled", false);
 
 // Delay server startup until a modal dialogue has been clicked to
 // allow time for user to set breakpoints in Browser Toolbox.
 pref("marionette.debugging.clicktostart", false);
 
 // Marionette logging verbosity.  Allowed values are "fatal", "error",
 // "warn", "info", "config", "debug", and "trace".
 pref("marionette.log.level", "info");
 
 // Port to start Marionette server on.
 pref("marionette.port", 2828);
 
-// Sets preferences recommended when using Firefox in automation with
-// Marionette.
+// Sets recommended automation preferences when Marionette is started.
 pref("marionette.prefs.recommended", true);