summaryrefslogtreecommitdiffstats
path: root/toolkit/components/normandy/lib/PrefUtils.jsm
blob: 6118bfc3660decae293433ca0faebbd689acd064 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* 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/. */
"use strict";

const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { XPCOMUtils } = ChromeUtils.import(
  "resource://gre/modules/XPCOMUtils.jsm"
);
ChromeUtils.defineModuleGetter(
  this,
  "LogManager",
  "resource://normandy/lib/LogManager.jsm"
);

var EXPORTED_SYMBOLS = ["PrefUtils"];

XPCOMUtils.defineLazyGetter(this, "log", () => {
  return LogManager.getLogger("preference-experiments");
});

const kPrefBranches = {
  user: Services.prefs,
  default: Services.prefs.getDefaultBranch(""),
};

var PrefUtils = {
  /**
   * Get a preference from the named branch
   * @param {string} branchName One of "default" or "user"
   * @param {string} pref
   * @param {string|boolean|integer|null} [default]
   *   The value to return if the preference does not exist. Defaults to null.
   */
  getPref(branchName, pref, defaultValue = null) {
    const branch = kPrefBranches[branchName];
    const type = branch.getPrefType(pref);

    try {
      switch (type) {
        case Services.prefs.PREF_BOOL: {
          return branch.getBoolPref(pref);
        }
        case Services.prefs.PREF_STRING: {
          return branch.getStringPref(pref);
        }
        case Services.prefs.PREF_INT: {
          return branch.getIntPref(pref);
        }
        case Services.prefs.PREF_INVALID: {
          return defaultValue;
        }
      }
    } catch (e) {
      if (branchName === "default" && e.result === Cr.NS_ERROR_UNEXPECTED) {
        // There is a value for the pref on the user branch but not on the default branch. This is ok.
        return defaultValue;
      }
      // Unexpected error, re-throw it
      throw e;
    }

    // If `type` isn't any of the above, throw an error. Don't do this in a
    // default branch of switch so that error handling is easier.
    throw new TypeError(`Unknown preference type (${type}) for ${pref}.`);
  },

  /**
   * Set a preference on the named branch
   * @param {string} branchName One of "default" or "user"
   * @param {string} pref
   * @param {string|boolean|integer|null} value
   *   The value to set. Must match the type named in `type`.
   */
  setPref(branchName, pref, value) {
    if (value === null) {
      this.clearPref(branchName, pref);
      return;
    }
    const branch = kPrefBranches[branchName];
    switch (typeof value) {
      case "boolean": {
        branch.setBoolPref(pref, value);
        break;
      }
      case "string": {
        branch.setStringPref(pref, value);
        break;
      }
      case "number": {
        branch.setIntPref(pref, value);
        break;
      }
      default: {
        throw new TypeError(
          `Unexpected value type (${typeof value}) for ${pref}.`
        );
      }
    }
  },

  /**
   * Remove a preference from a branch.
   * @param {string} branchName One of "default" or "user"
   * @param {string} pref
   */
  clearPref(branchName, pref) {
    if (branchName === "user") {
      kPrefBranches.user.clearUserPref(pref);
    } else if (branchName === "default") {
      log.warn(
        `Cannot not reset pref ${pref} on the default branch. Pref will be cleared at next restart.`
      );
    }
  },
};