Commit b9da8b4e authored by Matt Howell's avatar Matt Howell
Browse files

Bug 1567247 Part 1 - Reflect a fixed list of prefs into the Windows registry...

Bug 1567247 Part 1 - Reflect a fixed list of prefs into the Windows registry so the installer can read them. r=agashlin

Differential Revision: https://phabricator.services.mozilla.com/D40326

--HG--
extra : moz-landing-system : lando
parent 4b595ec1
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* 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/. */
/**
* The installer prefs component provides a way to get a specific set of prefs
* from a profile into a place where the installer can read them. The primary
* reason for wanting to do this is so we can run things like Shield studies
* on installer features; normally those are enabled by setting a pref, but
* the installer runs outside of any profile and so has no access to prefs.
* So we need to do something else to allow it to read these prefs.
*
* The mechanism we use here is to reflect the values of a list of relevant
* prefs into registry values. One registry value is created for each pref
* that is set. Each installation of the product gets its own registry key
* (based on the path hash). This is obviously a somewhat wider scope than a
* single profile, but it should be close enough in enough cases to suit our
* purposes here.
*
* Currently this module only supports bool prefs. Other types could likely
* be added if needed, but it doesn't seem necessary for the primary use case.
*/
// All prefs processed through this component must be in this branch.
const INSTALLER_PREFS_BRANCH = "installer.";
// This is the list of prefs that will be reflected to the registry. It should
// be kept up to date so that it reflects the list of prefs that are in
// current use (e.g., currently active experiments).
// Only add prefs to this list which are in INSTALLER_PREFS_BRANCH;
// any others will be ignored.
const INSTALLER_PREFS_LIST = [];
const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
// This constructor can take a list of prefs to override the default one,
// but this is really only intended for tests to use. Normal usage should be
// to leave the parameter omitted/undefined.
function InstallerPrefs(prefsList) {
this.prefsList = prefsList || INSTALLER_PREFS_LIST;
// Each pref to be reflected will get a value created under this key, in HKCU.
// The path will look something like:
// "Software\Mozilla\Firefox\Installer\71AE18FE3142402B\".
XPCOMUtils.defineLazyGetter(this, "_registryKeyPath", function() {
const app = AppConstants.MOZ_APP_NAME;
const vendor = Services.appinfo.vendor || "Mozilla";
const xreDirProvider = Cc[
"@mozilla.org/xre/directory-provider;1"
].getService(Ci.nsIXREDirProvider);
const installHash = xreDirProvider.getInstallHash();
return `Software\\${vendor}\\${app}\\Installer\\${installHash}`;
});
}
InstallerPrefs.prototype = {
classID: Components.ID("{cd8a6995-1f19-4cdd-9ed1-d6263302f594}"),
contractID: "@mozilla.org/installerprefs;1",
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
observe(subject, topic, data) {
switch (topic) {
case "profile-after-change": {
if (
AppConstants.platform != "win" ||
!this.prefsList ||
!this.prefsList.length
) {
// This module has no work to do.
break;
}
const regKey = this._openRegKey();
this._reflectPrefsToRegistry(regKey);
this._registerPrefListeners();
regKey.close();
break;
}
case "nsPref:changed": {
const regKey = this._openRegKey();
if (this.prefsList.includes(data)) {
this._reflectOnePrefToRegistry(regKey, data);
}
regKey.close();
break;
}
}
},
_registerPrefListeners() {
Services.prefs.addObserver(INSTALLER_PREFS_BRANCH, this);
},
_cleanRegistryKey(regKey) {
for (let i = regKey.valueCount - 1; i >= 0; --i) {
regKey.removeValue(regKey.getValueName(i));
}
},
_reflectPrefsToRegistry(regKey) {
this._cleanRegistryKey(regKey);
this.prefsList.forEach(pref =>
this._reflectOnePrefToRegistry(regKey, pref)
);
},
_reflectOnePrefToRegistry(regKey, pref) {
if (!pref.startsWith(INSTALLER_PREFS_BRANCH)) {
return;
}
const value = Services.prefs.getBoolPref(pref, false);
if (value) {
regKey.writeIntValue(pref, 1);
} else {
try {
regKey.removeValue(pref);
} catch (ex) {
// This removeValue call is prone to failing because the value we
// tried to remove didn't exist. Obviously that isn't really an error
// that we need to handle.
}
}
},
_openRegKey() {
const key = Cc["@mozilla.org/windows-registry-key;1"].createInstance(
Ci.nsIWindowsRegKey
);
key.create(
key.ROOT_KEY_CURRENT_USER,
this._registryKeyPath,
key.ACCESS_READ | key.ACCESS_WRITE | key.WOW64_64
);
return key;
},
};
var EXPORTED_SYMBOLS = ["InstallerPrefs"];
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
Classes = [
{
'cid': '{cd8a6995-1f19-4cdd-9ed1-d6263302f594}',
'contract_ids': ['@mozilla.org/installerprefs;1'],
'jsm': 'resource:///modules/InstallerPrefs.jsm',
'constructor': 'InstallerPrefs',
'categories': {'profile-after-change': 'InstallerPrefs'},
'processes': ProcessSelector.MAIN_PROCESS_ONLY,
},
]
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Installer')
EXTRA_JS_MODULES += [
'InstallerPrefs.jsm',
]
XPCOM_MANIFESTS += [
'components.conf',
]
......@@ -66,6 +66,8 @@ if CONFIG['NIGHTLY_BUILD']:
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
DIRS += ['touchbar']
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
DIRS += ['installerprefs']
XPIDL_SOURCES += [
'nsIBrowserHandler.idl',
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment