/* 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'; this.EXPORTED_SYMBOLS = []; #ifdef XP_WIN #ifdef MOZ_METRO const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu, manager: Cm} = Components; const PREF_BASE_KEY = "Software\\Mozilla\\Firefox\\Metro\\Prefs\\"; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); this.EXPORTED_SYMBOLS = [ "WindowsPrefSync" ]; /** * Manages preferences that need to be pulled and pushed between Metro * and desktop. */ this.WindowsPrefSync = { init: function() { this.pullSharedPrefs(); this.prefListToPush.forEach(function(prefName) { this.pushSharedPref(prefName); Services.prefs.addObserver(prefName, this, false); }, this); }, uninit: function() { this.prefListToPush.forEach(function(prefName) { Services.prefs.removeObserver(prefName, this); }, this); }, /** * Returns the list of prefs that should be pushed for the current * environment. */ get prefListToPush() { return !Services.metro.immersive ? this.desktopControlledPrefs : this.metroControlledPrefs; }, /** * Returns the list of prefs that should be pulled for the current * environment. */ get prefListToPull() { return Services.metro.immersive ? this.desktopControlledPrefs : this.metroControlledPrefs; }, /** * The following preferences will be pushed to registry from Desktop * Firefox and pulled in from Metro Firefox. * * app.update.* prefs are because Metro shares an installation directory with * Firefox, and the options for these are only present in the Desktop options. * * browser.sessionstore.resume_session_once is mainly for the switch to Metro * and switch to Desktop feature. * * browser.startup.page - if a desktop Firefox user wants her/his sessions * to always restore, we need to honor that in metro Firefox as well. */ desktopControlledPrefs: ["app.update.auto", "app.update.enabled", "app.update.service.enabled", "app.update.metro.enabled", "browser.sessionstore.resume_session_once", "browser.startup.page"], /** * Returns the base path where registry sync prefs are stored. */ get prefRegistryPath() { let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]. createInstance(Ci.nsIToolkitProfileService); return PREF_BASE_KEY + profileService.selectedProfile.name + "\\"; }, /** * The following preferences will be pushed to registry from Metro * Firefox and pulled in from Desktop Firefox. * * browser.sessionstore.resume_session_once is mainly for the switch to Metro * and switch to Desktop feature. */ metroControlledPrefs: ["browser.sessionstore.resume_session_once"], /** * Observes preference changes and writes them to the registry, only * the list of preferences initialized will be observed */ observe: function (aSubject, aTopic, aPrefName) { if (aTopic != "nsPref:changed") return; this.pushSharedPref(aPrefName); }, /** * Writes the pref to HKCU in the registry and adds a pref-observer to keep * the registry in sync with changes to the value. */ pushSharedPref : function(aPrefName) { let registry = Cc["@mozilla.org/windows-registry-key;1"]. createInstance(Ci.nsIWindowsRegKey); try { var prefType = Services.prefs.getPrefType(aPrefName); let prefFunc; if (prefType == Ci.nsIPrefBranch.PREF_INT) prefFunc = "getIntPref"; else if (prefType == Ci.nsIPrefBranch.PREF_BOOL) prefFunc = "getBoolPref"; else if (prefType == Ci.nsIPrefBranch.PREF_STRING) prefFunc = "getCharPref"; else throw "Unsupported pref type"; let prefValue = Services.prefs[prefFunc](aPrefName); registry.create(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, this.prefRegistryPath + prefType, Ci.nsIWindowsRegKey.ACCESS_WRITE); // Always write as string, but the registry subfolder will determine // how Metro interprets that string value. registry.writeStringValue(aPrefName, prefValue); } catch (ex) { Cu.reportError("Couldn't push pref " + aPrefName + ": " + ex); } finally { registry.close(); } }, /** * Pulls in all shared prefs from the registry */ pullSharedPrefs: function() { function pullSharedPrefType(prefType, prefFunc) { try { registry.create(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, self.prefRegistryPath + prefType, Ci.nsIWindowsRegKey.ACCESS_ALL); for (let i = 0; i < registry.valueCount; i++) { let prefName = registry.getValueName(i); let prefValue = registry.readStringValue(prefName); if (prefType == Ci.nsIPrefBranch.PREF_BOOL) { prefValue = prefValue == "true"; } if (self.prefListToPull.indexOf(prefName) != -1) { Services.prefs[prefFunc](prefName, prefValue); } } } catch (ex) { dump("Could not pull for prefType " + prefType + ": " + ex + "\n"); } finally { registry.close(); } } let self = this; let registry = Cc["@mozilla.org/windows-registry-key;1"]. createInstance(Ci.nsIWindowsRegKey); pullSharedPrefType(Ci.nsIPrefBranch.PREF_INT, "setIntPref"); pullSharedPrefType(Ci.nsIPrefBranch.PREF_BOOL, "setBoolPref"); pullSharedPrefType(Ci.nsIPrefBranch.PREF_STRING, "setCharPref"); } }; #endif #endif