Backed out 2 changesets (bug 1855992) for causing talos failures @ mozilla::net:...
[gecko.git] / remote / marionette / prefs.sys.mjs
blob17df13d0fdfc4a454cd651910b8bbfa2ae990790
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 const { PREF_BOOL, PREF_INT, PREF_INVALID, PREF_STRING } = Ci.nsIPrefBranch;
7 export class Branch {
8   /**
9    * @param {string=} branch
10    *     Preference subtree.  Uses root tree given `null`.
11    */
12   constructor(branch) {
13     this._branch = Services.prefs.getBranch(branch);
14   }
16   /**
17    * Gets value of `pref` in its known type.
18    *
19    * @param {string} pref
20    *     Preference name.
21    * @param {*=} fallback
22    *     Fallback value to return if `pref` does not exist.
23    *
24    * @returns {(string|boolean|number)}
25    *     Value of `pref`, or the `fallback` value if `pref` does
26    *     not exist.
27    *
28    * @throws {TypeError}
29    *     If `pref` is not a recognised preference and no `fallback`
30    *     value has been provided.
31    */
32   get(pref, fallback = null) {
33     switch (this._branch.getPrefType(pref)) {
34       case PREF_STRING:
35         return this._branch.getStringPref(pref);
37       case PREF_BOOL:
38         return this._branch.getBoolPref(pref);
40       case PREF_INT:
41         return this._branch.getIntPref(pref);
43       case PREF_INVALID:
44       default:
45         if (fallback != null) {
46           return fallback;
47         }
48         throw new TypeError(`Unrecognised preference: ${pref}`);
49     }
50   }
52   /**
53    * Sets the value of `pref`.
54    *
55    * @param {string} pref
56    *     Preference name.
57    * @param {(string|boolean|number)} value
58    *     `pref`'s new value.
59    *
60    * @throws {TypeError}
61    *     If `value` is not the correct type for `pref`.
62    */
63   set(pref, value) {
64     let typ;
65     if (typeof value != "undefined" && value != null) {
66       typ = value.constructor.name;
67     }
69     switch (typ) {
70       case "String":
71         // Unicode compliant
72         return this._branch.setStringPref(pref, value);
74       case "Boolean":
75         return this._branch.setBoolPref(pref, value);
77       case "Number":
78         return this._branch.setIntPref(pref, value);
80       default:
81         throw new TypeError(`Illegal preference type value: ${typ}`);
82     }
83   }
86 /**
87  * Provides shortcuts for lazily getting and setting typed Marionette
88  * preferences.
89  *
90  * Some of Marionette's preferences are stored using primitive values
91  * that internally are represented by complex types.
92  *
93  * Because we cannot trust the input of many of these preferences,
94  * this class provides abstraction that lets us safely deal with
95  * potentially malformed input.
96  *
97  * A further complication is that we cannot rely on `Preferences.sys.mjs`
98  * in Marionette.  See https://bugzilla.mozilla.org/show_bug.cgi?id=1357517
99  * for further details.
100  */
101 class MarionetteBranch extends Branch {
102   constructor(branch = "marionette.") {
103     super(branch);
104   }
106   /**
107    * The `marionette.debugging.clicktostart` preference delays
108    * server startup until a modal dialogue has been clicked to allow
109    * time for user to set breakpoints in the Browser Toolbox.
110    *
111    * @returns {boolean}
112    */
113   get clickToStart() {
114     return this.get("debugging.clicktostart", false);
115   }
117   /**
118    * The `marionette.port` preference, detailing which port
119    * the TCP server should listen on.
120    *
121    * @returns {number}
122    */
123   get port() {
124     return this.get("port", 2828);
125   }
127   set port(newPort) {
128     this.set("port", newPort);
129   }
131   /**
132    * Gets the `marionette.setpermission.enabled` preference, should
133    * only be used for testdriver's set_permission API.
134    *
135    * @returns {boolean}
136    */
137   get setPermissionEnabled() {
138     return this.get("setpermission.enabled", false);
139   }
142 /** Reads a JSON serialised blob stored in the environment. */
143 export class EnvironmentPrefs {
144   /**
145    * Reads the environment variable `key` and tries to parse it as
146    * JSON Object, then provides an iterator over its keys and values.
147    *
148    * If the environment variable is not set, this function returns empty.
149    *
150    * @param {string} key
151    *     Environment variable.
152    *
153    * @returns {Iterable.<string, (string|boolean|number)>}
154    */
155   static *from(key) {
156     if (!Services.env.exists(key)) {
157       return;
158     }
160     let prefs;
161     try {
162       prefs = JSON.parse(Services.env.get(key));
163     } catch (e) {
164       throw new TypeError(`Unable to parse prefs from ${key}`, e);
165     }
167     for (let prefName of Object.keys(prefs)) {
168       yield [prefName, prefs[prefName]];
169     }
170   }
173 // There is a future potential of exposing this as Marionette.prefs.port
174 // if we introduce a Marionette.jsm module.
175 export const MarionettePrefs = new MarionetteBranch();