|
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 |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 'use strict'; |
|
6 |
|
7 this.EXPORTED_SYMBOLS = []; |
|
8 |
|
9 #ifdef XP_WIN |
|
10 #ifdef MOZ_METRO |
|
11 |
|
12 const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu, manager: Cm} = |
|
13 Components; |
|
14 const PREF_BASE_KEY = "Software\\Mozilla\\Firefox\\Metro\\Prefs\\"; |
|
15 |
|
16 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
17 Cu.import("resource://gre/modules/Services.jsm"); |
|
18 |
|
19 this.EXPORTED_SYMBOLS = [ "WindowsPrefSync" ]; |
|
20 |
|
21 /** |
|
22 * Manages preferences that need to be pulled and pushed between Metro |
|
23 * and desktop. |
|
24 */ |
|
25 this.WindowsPrefSync = { |
|
26 init: function() { |
|
27 this.pullSharedPrefs(); |
|
28 this.prefListToPush.forEach(function(prefName) { |
|
29 this.pushSharedPref(prefName); |
|
30 Services.prefs.addObserver(prefName, this, false); |
|
31 }, this); |
|
32 }, |
|
33 |
|
34 uninit: function() { |
|
35 this.prefListToPush.forEach(function(prefName) { |
|
36 Services.prefs.removeObserver(prefName, this); |
|
37 }, this); |
|
38 }, |
|
39 |
|
40 /** |
|
41 * Returns the list of prefs that should be pushed for the current |
|
42 * environment. |
|
43 */ |
|
44 get prefListToPush() { |
|
45 return !Services.metro.immersive ? this.desktopControlledPrefs : |
|
46 this.metroControlledPrefs; |
|
47 }, |
|
48 |
|
49 /** |
|
50 * Returns the list of prefs that should be pulled for the current |
|
51 * environment. |
|
52 */ |
|
53 get prefListToPull() { |
|
54 return Services.metro.immersive ? this.desktopControlledPrefs : |
|
55 this.metroControlledPrefs; |
|
56 }, |
|
57 |
|
58 /** |
|
59 * The following preferences will be pushed to registry from Desktop |
|
60 * Firefox and pulled in from Metro Firefox. |
|
61 * |
|
62 * app.update.* prefs are because Metro shares an installation directory with |
|
63 * Firefox, and the options for these are only present in the Desktop options. |
|
64 * |
|
65 * browser.sessionstore.resume_session_once is mainly for the switch to Metro |
|
66 * and switch to Desktop feature. |
|
67 * |
|
68 * browser.startup.page - if a desktop Firefox user wants her/his sessions |
|
69 * to always restore, we need to honor that in metro Firefox as well. |
|
70 */ |
|
71 desktopControlledPrefs: ["app.update.auto", |
|
72 "app.update.enabled", |
|
73 "app.update.service.enabled", |
|
74 "app.update.metro.enabled", |
|
75 "browser.sessionstore.resume_session_once", |
|
76 "browser.startup.page"], |
|
77 |
|
78 /** |
|
79 * Returns the base path where registry sync prefs are stored. |
|
80 */ |
|
81 get prefRegistryPath() { |
|
82 let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]. |
|
83 createInstance(Ci.nsIToolkitProfileService); |
|
84 return PREF_BASE_KEY + profileService.selectedProfile.name + "\\"; |
|
85 }, |
|
86 |
|
87 /** |
|
88 * The following preferences will be pushed to registry from Metro |
|
89 * Firefox and pulled in from Desktop Firefox. |
|
90 * |
|
91 * browser.sessionstore.resume_session_once is mainly for the switch to Metro |
|
92 * and switch to Desktop feature. |
|
93 */ |
|
94 metroControlledPrefs: ["browser.sessionstore.resume_session_once"], |
|
95 |
|
96 /** |
|
97 * Observes preference changes and writes them to the registry, only |
|
98 * the list of preferences initialized will be observed |
|
99 */ |
|
100 observe: function (aSubject, aTopic, aPrefName) { |
|
101 if (aTopic != "nsPref:changed") |
|
102 return; |
|
103 |
|
104 this.pushSharedPref(aPrefName); |
|
105 }, |
|
106 |
|
107 /** |
|
108 * Writes the pref to HKCU in the registry and adds a pref-observer to keep |
|
109 * the registry in sync with changes to the value. |
|
110 */ |
|
111 pushSharedPref : function(aPrefName) { |
|
112 let registry = Cc["@mozilla.org/windows-registry-key;1"]. |
|
113 createInstance(Ci.nsIWindowsRegKey); |
|
114 try { |
|
115 var prefType = Services.prefs.getPrefType(aPrefName); |
|
116 let prefFunc; |
|
117 if (prefType == Ci.nsIPrefBranch.PREF_INT) |
|
118 prefFunc = "getIntPref"; |
|
119 else if (prefType == Ci.nsIPrefBranch.PREF_BOOL) |
|
120 prefFunc = "getBoolPref"; |
|
121 else if (prefType == Ci.nsIPrefBranch.PREF_STRING) |
|
122 prefFunc = "getCharPref"; |
|
123 else |
|
124 throw "Unsupported pref type"; |
|
125 |
|
126 let prefValue = Services.prefs[prefFunc](aPrefName); |
|
127 registry.create(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, |
|
128 this.prefRegistryPath + prefType, Ci.nsIWindowsRegKey.ACCESS_WRITE); |
|
129 // Always write as string, but the registry subfolder will determine |
|
130 // how Metro interprets that string value. |
|
131 registry.writeStringValue(aPrefName, prefValue); |
|
132 } catch (ex) { |
|
133 Cu.reportError("Couldn't push pref " + aPrefName + ": " + ex); |
|
134 } finally { |
|
135 registry.close(); |
|
136 } |
|
137 }, |
|
138 |
|
139 /** |
|
140 * Pulls in all shared prefs from the registry |
|
141 */ |
|
142 pullSharedPrefs: function() { |
|
143 function pullSharedPrefType(prefType, prefFunc) { |
|
144 try { |
|
145 registry.create(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, |
|
146 self.prefRegistryPath + prefType, |
|
147 Ci.nsIWindowsRegKey.ACCESS_ALL); |
|
148 for (let i = 0; i < registry.valueCount; i++) { |
|
149 let prefName = registry.getValueName(i); |
|
150 let prefValue = registry.readStringValue(prefName); |
|
151 if (prefType == Ci.nsIPrefBranch.PREF_BOOL) { |
|
152 prefValue = prefValue == "true"; |
|
153 } |
|
154 if (self.prefListToPull.indexOf(prefName) != -1) { |
|
155 Services.prefs[prefFunc](prefName, prefValue); |
|
156 } |
|
157 } |
|
158 } catch (ex) { |
|
159 dump("Could not pull for prefType " + prefType + ": " + ex + "\n"); |
|
160 } finally { |
|
161 registry.close(); |
|
162 } |
|
163 } |
|
164 let self = this; |
|
165 let registry = Cc["@mozilla.org/windows-registry-key;1"]. |
|
166 createInstance(Ci.nsIWindowsRegKey); |
|
167 pullSharedPrefType(Ci.nsIPrefBranch.PREF_INT, "setIntPref"); |
|
168 pullSharedPrefType(Ci.nsIPrefBranch.PREF_BOOL, "setBoolPref"); |
|
169 pullSharedPrefType(Ci.nsIPrefBranch.PREF_STRING, "setCharPref"); |
|
170 } |
|
171 }; |
|
172 #endif |
|
173 #endif |