|
1 From: various contributors |
|
2 Subject: replace gconf backend with more complete mapping for lockdown feature |
|
3 |
|
4 diff --git a/extensions/pref/Makefile.in b/extensions/pref/Makefile.in |
|
5 --- a/extensions/pref/Makefile.in |
|
6 +++ b/extensions/pref/Makefile.in |
|
7 @@ -40,13 +40,13 @@ DEPTH = ../.. |
|
8 topsrcdir = @top_srcdir@ |
|
9 srcdir = @srcdir@ |
|
10 VPATH = @srcdir@ |
|
11 |
|
12 include $(DEPTH)/config/autoconf.mk |
|
13 |
|
14 DIRS = autoconfig |
|
15 |
|
16 -ifdef MOZ_ENABLE_GTK2 |
|
17 +ifdef MOZ_ENABLE_GCONF |
|
18 DIRS += system-pref |
|
19 endif |
|
20 |
|
21 include $(topsrcdir)/config/rules.mk |
|
22 diff --git a/extensions/pref/system-pref/src/Makefile.in b/extensions/pref/system-pref/src/Makefile.in |
|
23 --- a/extensions/pref/system-pref/src/Makefile.in |
|
24 +++ b/extensions/pref/system-pref/src/Makefile.in |
|
25 @@ -38,47 +38,41 @@ |
|
26 DEPTH = ../../../.. |
|
27 topsrcdir = @top_srcdir@ |
|
28 srcdir = @srcdir@ |
|
29 VPATH = @srcdir@ |
|
30 |
|
31 include $(DEPTH)/config/autoconf.mk |
|
32 |
|
33 MODULE = system-pref |
|
34 -LIBRARY_NAME = system-pref_s |
|
35 +LIBRARY_NAME = system-pref |
|
36 ifneq ($(OS_ARCH),WINNT) |
|
37 SHORT_LIBNAME = syspref |
|
38 endif |
|
39 |
|
40 # We want to force the creation of a static lib. |
|
41 -FORCE_STATIC_LIB = 1 |
|
42 -LIBXUL_LIBRARY = 1 |
|
43 +#FORCE_STATIC_LIB = 1 |
|
44 +LIBXUL_LIBRARY = 1 |
|
45 +MODULE_NAME = nsSystemPrefModule |
|
46 +IS_COMPONENT = 1 |
|
47 +EXPORT_LIBRARY = 1 |
|
48 |
|
49 REQUIRES = xpcom \ |
|
50 string \ |
|
51 embedcomponents \ |
|
52 pref \ |
|
53 $(NULL) |
|
54 |
|
55 -ifdef MOZ_ENABLE_GTK2 |
|
56 -DIRS = gconf |
|
57 -endif |
|
58 +CPPSRCS = \ |
|
59 + nsSystemPref.cpp \ |
|
60 + nsSystemPrefFactory.cpp \ |
|
61 + $(NULL) |
|
62 |
|
63 EXTRA_DSO_LDOPTS = \ |
|
64 - -L$(DIST)/bin \ |
|
65 $(MOZ_COMPONENT_LIBS) \ |
|
66 $(NULL) |
|
67 |
|
68 -CPPSRCS = \ |
|
69 - nsSystemPref.cpp \ |
|
70 - $(NULL) |
|
71 - |
|
72 EXPORTS = \ |
|
73 - nsSystemPrefLog.h \ |
|
74 + nsISystemPrefService.h \ |
|
75 $(NULL) |
|
76 |
|
77 include $(topsrcdir)/config/rules.mk |
|
78 |
|
79 -ifdef MOZ_ENABLE_GTK2 |
|
80 -INCLUDES += \ |
|
81 - -I$(srcdir)/gconf \ |
|
82 - $(NULL) |
|
83 -endif |
|
84 diff --git a/extensions/pref/system-pref/src/gconf/Makefile.in b/extensions/pref/system-pref/src/gconf/Makefile.in |
|
85 --- a/extensions/pref/system-pref/src/gconf/Makefile.in |
|
86 +++ b/extensions/pref/system-pref/src/gconf/Makefile.in |
|
87 @@ -37,50 +37,37 @@ |
|
88 |
|
89 DEPTH = ../../../../.. |
|
90 topsrcdir = @top_srcdir@ |
|
91 srcdir = @srcdir@ |
|
92 VPATH = @srcdir@ |
|
93 |
|
94 include $(DEPTH)/config/autoconf.mk |
|
95 |
|
96 -MODULE = system-pref |
|
97 -LIBRARY_NAME = system-pref |
|
98 -LIBXUL_LIBRARY = 1 |
|
99 +MODULE = system-pref-gconf |
|
100 +LIBRARY_NAME = system-pref-gconf |
|
101 +IS_COMPONENT = 1 |
|
102 +MODULE_NAME = nsSystemPrefServiceModule |
|
103 +FORCE_SHARED_LIB = 1 |
|
104 |
|
105 REQUIRES = pref \ |
|
106 string \ |
|
107 xpcom \ |
|
108 - embedcomponents \ |
|
109 + necko \ |
|
110 $(NULL) |
|
111 |
|
112 CPPSRCS = \ |
|
113 nsSystemPrefService.cpp \ |
|
114 - nsSystemPrefFactory.cpp \ |
|
115 $(NULL) |
|
116 |
|
117 -SHARED_LIBRARY_LIBS = ../libsystem-pref_s.a |
|
118 +OS_INCLUDES += $(MOZ_GCONF_CFLAGS) |
|
119 + |
|
120 |
|
121 EXTRA_DSO_LDOPTS = \ |
|
122 - -L$(DIST)/bin \ |
|
123 - $(MOZ_COMPONENT_LIBS) \ |
|
124 - $(MOZ_GTK2_LIBS) \ |
|
125 + $(XPCOM_GLUE_LDOPTS) \ |
|
126 + $(MOZ_GCONF_LIBS) \ |
|
127 + $(NSPR_LIBS) \ |
|
128 $(NULL) |
|
129 |
|
130 -EXPORT_LIBRARY = 1 |
|
131 -IS_COMPONENT = 1 |
|
132 -MODULE_NAME = nsSystemPrefModule |
|
133 - |
|
134 -EXPORTS = \ |
|
135 - nsSystemPrefService.h \ |
|
136 - $(NULL) |
|
137 |
|
138 include $(topsrcdir)/config/rules.mk |
|
139 |
|
140 -CFLAGS += $(MOZ_GTK2_CFLAGS) |
|
141 -CXXFLAGS += $(MOZ_GTK2_CFLAGS) |
|
142 - |
|
143 -LOCAL_INCLUDES = -I$(srcdir)/.. |
|
144 - |
|
145 -export:: |
|
146 - $(INSTALL) $(srcdir)/../nsSystemPrefFactory.cpp . |
|
147 - |
|
148 GARBAGE += nsSystemPrefFactory.cpp |
|
149 diff --git a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp |
|
150 --- a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp |
|
151 +++ b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp |
|
152 @@ -18,17 +18,19 @@ |
|
153 * The Original Code is mozilla.org code. |
|
154 * |
|
155 * The Initial Developer of the Original Code is Sun Microsystems, Inc. |
|
156 * Portions created by Sun Microsystems are Copyright (C) 2003 Sun |
|
157 * Microsystems, Inc. All Rights Reserved. |
|
158 * |
|
159 * Original Author: Bolian Yin (bolian.yin@sun.com) |
|
160 * |
|
161 - * Contributor(s): |
|
162 + * Contributor(s): Robert O'Callahan/Novell (rocallahan@novell.com) |
|
163 + * Hubert Figuiere (hfiguiere@novell.com) |
|
164 + * Wolfgang Rosenauer (wr@rosenauer.org) |
|
165 * |
|
166 * Alternatively, the contents of this file may be used under the terms of |
|
167 * either the GNU General Public License Version 2 or later (the "GPL"), or |
|
168 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|
169 * in which case the provisions of the GPL or the LGPL are applicable instead |
|
170 * of those above. If you wish to allow use of your version of this file only |
|
171 * under the terms of either the GPL or the LGPL, and not to allow others to |
|
172 * use your version of this file under the terms of the NPL, indicate your |
|
173 @@ -36,299 +38,1300 @@ |
|
174 * and other provisions required by the GPL or the LGPL. If you do not delete |
|
175 * the provisions above, a recipient may use your version of this file under |
|
176 * the terms of any one of the NPL, the GPL or the LGPL. |
|
177 * |
|
178 * ***** END LICENSE BLOCK ***** */ |
|
179 |
|
180 #include <glib.h> |
|
181 #include <glib-object.h> |
|
182 +#include <gconf/gconf-client.h> |
|
183 |
|
184 #include "plstr.h" |
|
185 #include "nsCOMPtr.h" |
|
186 -#include "nsIPrefBranch.h" |
|
187 -#include "nsIPrefService.h" |
|
188 +#include "nsIPref.h" |
|
189 #include "nsIServiceManager.h" |
|
190 #include "nsIObserver.h" |
|
191 #include "nsWeakReference.h" |
|
192 +#include "nsIPrefBranch2.h" |
|
193 +#include "nsDataHashtable.h" |
|
194 +#include "nsHashKeys.h" |
|
195 +#include "nsICategoryManager.h" |
|
196 +#include "nsIGenericFactory.h" |
|
197 +#include "nsStringAPI.h" |
|
198 +#include "nsIPermissionManager.h" |
|
199 +#include "../nsSystemPref.h" |
|
200 |
|
201 -#include "nsString.h" |
|
202 -#include "nsSystemPrefLog.h" |
|
203 -#include "nsSystemPrefService.h" |
|
204 +#define NS_SYSTEMPREF_SERVICE_CID \ |
|
205 + { /* {3724e748-b088-4bf8-9298-aad426b66293} */ \ |
|
206 + 0x3724e748, \ |
|
207 + 0xb088, \ |
|
208 + 0x4bf8, \ |
|
209 + { 0x92, 0x98, 0xaa, 0xd4, 0x26, 0xb6, 0x62, 0x93 } \ |
|
210 + } |
|
211 |
|
212 -/************************************************************************* |
|
213 - * The strange thing here is that we load the gconf library manually and |
|
214 - * search the function pointers we need. If that process fails, no gconf |
|
215 - * support is available in mozilla. The aim is to make mozilla independent |
|
216 - * on gconf, in both compile time and run time. |
|
217 - ************************************************************************/ |
|
218 +#define NS_SYSTEMPREF_SERVICE_CLASSNAME "System Preferences Platform Service" |
|
219 |
|
220 -//gconf types |
|
221 -extern "C" { |
|
222 +NS_DEFINE_STATIC_IID_ACCESSOR(nsISystemPrefService, NS_ISYSTEMPREFSERVICE_IID) |
|
223 |
|
224 - typedef enum { |
|
225 - GCONF_VALUE_INVALID, |
|
226 - GCONF_VALUE_STRING, |
|
227 - GCONF_VALUE_INT, |
|
228 - GCONF_VALUE_FLOAT, |
|
229 - GCONF_VALUE_BOOL, |
|
230 - GCONF_VALUE_SCHEMA, |
|
231 +/** |
|
232 + * We can link directly to the gconf library. If it's not available, |
|
233 + * this component just won't load and no system prefs will be offered. |
|
234 + */ |
|
235 |
|
236 - GCONF_VALUE_LIST, |
|
237 - GCONF_VALUE_PAIR |
|
238 +#define NUM_ELEM(a) (sizeof(a)/sizeof(a[0])) |
|
239 |
|
240 - }GConfValueType; |
|
241 +class nsSystemPrefService; |
|
242 |
|
243 - typedef struct { |
|
244 - GConfValueType type; |
|
245 - }GConfValue; |
|
246 +/** |
|
247 + * List the preferences that have a simple mapping between Moz and gconf. |
|
248 + * These preferences have the same meaning and their values are |
|
249 + * automatically converted. |
|
250 + */ |
|
251 +struct SimplePrefMapping { |
|
252 + const char *mozPrefName; |
|
253 + const char *gconfPrefName; |
|
254 + /** |
|
255 + * If this is PR_FALSE, then we never allow Mozilla to change |
|
256 + * this setting. The Mozilla pref will always be locked. |
|
257 + * If this is PR_TRUE then Mozilla will be allowed to change |
|
258 + * the setting --- but only if it is writable in gconf. |
|
259 + */ |
|
260 + PRBool allowWritesFromMozilla; |
|
261 +}; |
|
262 +typedef nsresult (* ComplexGConfPrefChanged)(nsSystemPrefService* aPrefService, |
|
263 + GConfClient* aClient); |
|
264 +typedef nsresult (* ComplexMozPrefChanged)(nsSystemPrefService* aPrefService, |
|
265 + GConfClient* aClient); |
|
266 +struct ComplexGConfPrefMapping { |
|
267 + const char* gconfPrefName; |
|
268 + ComplexGConfPrefChanged callback; |
|
269 +}; |
|
270 |
|
271 - typedef void * (*GConfClientGetDefaultType) (void); |
|
272 - typedef PRBool (*GConfClientGetBoolType) (void *client, const gchar *key, |
|
273 - GError **err); |
|
274 - typedef gchar* (*GConfClientGetStringType) (void *client, const gchar *key, |
|
275 - GError **err); |
|
276 - typedef PRInt32 (*GConfClientGetIntType) (void *client, const gchar *key, |
|
277 - GError **err); |
|
278 - typedef GSList* (*GConfClientGetListType) (void *client, const gchar *key, |
|
279 - GConfValueType list_type, |
|
280 - GError **err); |
|
281 - typedef void (*GConfClientNotifyFuncType) (void* client, guint cnxn_id, |
|
282 - void *entry, |
|
283 - gpointer user_data); |
|
284 - typedef guint (*GConfClientNotifyAddType) (void* client, |
|
285 - const gchar* namespace_section, |
|
286 - GConfClientNotifyFuncType func, |
|
287 - gpointer user_data, |
|
288 - GFreeFunc destroy_notify, |
|
289 - GError** err); |
|
290 - typedef void (*GConfClientNotifyRemoveType) (void *client, |
|
291 - guint cnxn); |
|
292 - typedef void (*GConfClientAddDirType) (void *client, |
|
293 - const gchar *dir, |
|
294 - guint8 preload, |
|
295 - GError **err); |
|
296 - typedef void (*GConfClientRemoveDirType) (void *client, |
|
297 - const gchar *dir, |
|
298 - GError **err); |
|
299 +struct ComplexMozPrefMapping { |
|
300 + const char* mozPrefName; |
|
301 + ComplexMozPrefChanged callback; |
|
302 +}; |
|
303 |
|
304 - typedef const char* (*GConfEntryGetKeyType) (const void *entry); |
|
305 - typedef GConfValue* (*GConfEntryGetValueType) (const void *entry); |
|
306 +class nsSystemPrefService : public nsISystemPrefService, nsIPrefBranch |
|
307 + { |
|
308 + public: |
|
309 + NS_DECL_ISUPPORTS |
|
310 + NS_DECL_NSIPREFBRANCH |
|
311 |
|
312 - typedef const char* (*GConfValueGetStringType) (const GConfValue *value); |
|
313 - typedef PRInt32 (*GConfValueGetIntType) (const GConfValue *value); |
|
314 - typedef PRBool (*GConfValueGetBoolType) (const GConfValue *value); |
|
315 + nsresult Init(); |
|
316 |
|
317 - |
|
318 - static void gconf_key_listener (void* client, guint cnxn_id, |
|
319 - void *entry, gpointer user_data); |
|
320 -} |
|
321 + virtual nsresult LoadSystemPreferences(nsISystemPref* aPrefs); |
|
322 + virtual nsresult NotifyMozillaPrefChanged(const char* aPrefName); |
|
323 + virtual nsresult NotifyUnloadSystemPreferences(); |
|
324 |
|
325 -struct GConfCallbackData |
|
326 -{ |
|
327 - GConfProxy *proxy; |
|
328 - void * userData; |
|
329 - PRUint32 atom; |
|
330 - PRUint32 notifyId; |
|
331 -}; |
|
332 -////////////////////////////////////////////////////////////////////// |
|
333 -// GConPrxoy is a thin wrapper for easy use of gconf funcs. It loads the |
|
334 -// gconf library and initializes the func pointers for later use. |
|
335 -////////////////////////////////////////////////////////////////////// |
|
336 -class GConfProxy |
|
337 -{ |
|
338 -public: |
|
339 - GConfProxy(nsSystemPrefService* aSysPrefService); |
|
340 - ~GConfProxy(); |
|
341 - PRBool Init(); |
|
342 + nsSystemPrefService(); |
|
343 + virtual ~nsSystemPrefService(); |
|
344 |
|
345 - nsresult GetBoolPref(const char *aMozKey, PRBool *retval); |
|
346 - nsresult GetCharPref(const char *aMozKey, char **retval); |
|
347 - nsresult GetIntPref(const char *aMozKey, PRInt32 *retval); |
|
348 - |
|
349 - nsresult NotifyAdd (PRUint32 aAtom, void *aUserData); |
|
350 - nsresult NotifyRemove (PRUint32 aAtom, const void *aUserData); |
|
351 - |
|
352 - nsresult GetAtomForMozKey(const char *aMozKey, PRUint32 *aAtom) { |
|
353 - return GetAtom(aMozKey, 0, aAtom); |
|
354 + nsISystemPref* GetPrefs() { return mPref; } |
|
355 + SimplePrefMapping* GetSimpleCallbackData(PRUint32 aKey) { |
|
356 + SimplePrefMapping* result = nsnull; |
|
357 + mGConfSimpleCallbacks.Get(aKey, &result); |
|
358 + return result; |
|
359 } |
|
360 - const char *GetMozKey(PRUint32 aAtom) { |
|
361 - return GetKey(aAtom, 0); |
|
362 - } |
|
363 - |
|
364 - void OnNotify(void *aClient, void * aEntry, PRUint32 aNotifyId, |
|
365 - GConfCallbackData *aData); |
|
366 + ComplexGConfPrefMapping* GetComplexCallbackData(PRUint32 aKey) { |
|
367 + ComplexGConfPrefMapping* result = nsnull; |
|
368 + mGConfComplexCallbacks.Get(aKey, &result); |
|
369 + return result; |
|
370 + } |
|
371 |
|
372 private: |
|
373 - void *mGConfClient; |
|
374 - PRLibrary *mGConfLib; |
|
375 - PRBool mInitialized; |
|
376 - nsSystemPrefService *mSysPrefService; |
|
377 + nsISystemPref* mPref; |
|
378 + nsDataHashtable<nsUint32HashKey, SimplePrefMapping*> mGConfSimpleCallbacks; |
|
379 + nsDataHashtable<nsUint32HashKey, ComplexGConfPrefMapping*> mGConfComplexCallbacks; |
|
380 + // This is set to PR_FALSE temporarily to stop listening to gconf |
|
381 + // change notifications (while we change gconf values) |
|
382 + PRPackedBool mListenToGConf; |
|
383 |
|
384 - //listeners |
|
385 - nsAutoVoidArray *mObservers; |
|
386 - |
|
387 - void InitFuncPtrs(); |
|
388 - //gconf public func ptrs |
|
389 - |
|
390 - //gconf client funcs |
|
391 - GConfClientGetDefaultType GConfClientGetDefault; |
|
392 - GConfClientGetBoolType GConfClientGetBool; |
|
393 - GConfClientGetStringType GConfClientGetString; |
|
394 - GConfClientGetIntType GConfClientGetInt; |
|
395 - GConfClientGetListType GConfClientGetList; |
|
396 - GConfClientNotifyAddType GConfClientNotifyAdd; |
|
397 - GConfClientNotifyRemoveType GConfClientNotifyRemove; |
|
398 - GConfClientAddDirType GConfClientAddDir; |
|
399 - GConfClientRemoveDirType GConfClientRemoveDir; |
|
400 - |
|
401 - //gconf entry funcs |
|
402 - GConfEntryGetValueType GConfEntryGetValue; |
|
403 - GConfEntryGetKeyType GConfEntryGetKey; |
|
404 - |
|
405 - //gconf value funcs |
|
406 - GConfValueGetBoolType GConfValueGetBool; |
|
407 - GConfValueGetStringType GConfValueGetString; |
|
408 - GConfValueGetIntType GConfValueGetInt; |
|
409 - |
|
410 - //pref name translating stuff |
|
411 - nsresult GetAtom(const char *aKey, PRUint8 aNameType, PRUint32 *aAtom); |
|
412 - nsresult GetAtomForGConfKey(const char *aGConfKey, PRUint32 *aAtom) \ |
|
413 - {return GetAtom(aGConfKey, 1, aAtom);} |
|
414 - const char *GetKey(PRUint32 aAtom, PRUint8 aNameType); |
|
415 - const char *GetGConfKey(PRUint32 aAtom) \ |
|
416 - {return GetKey(aAtom, 1); } |
|
417 - inline const char *MozKey2GConfKey(const char *aMozKey); |
|
418 - |
|
419 - //const strings |
|
420 - static const char sPrefGConfKey[]; |
|
421 - static const char sDefaultLibName1[]; |
|
422 - static const char sDefaultLibName2[]; |
|
423 + GConfValue* GConfGet(const char *aPrefName); |
|
424 }; |
|
425 |
|
426 -struct SysPrefCallbackData { |
|
427 - nsISupports *observer; |
|
428 - PRBool bIsWeakRef; |
|
429 - PRUint32 prefAtom; |
|
430 -}; |
|
431 - |
|
432 -PRBool |
|
433 -sysPrefDeleteObserver(void *aElement, void *aData) { |
|
434 - SysPrefCallbackData *pElement = |
|
435 - static_cast<SysPrefCallbackData *>(aElement); |
|
436 - NS_RELEASE(pElement->observer); |
|
437 - nsMemory::Free(pElement); |
|
438 - return PR_TRUE; |
|
439 -} |
|
440 - |
|
441 -NS_IMPL_ISUPPORTS2(nsSystemPrefService, nsIPrefBranch, nsIPrefBranch2) |
|
442 - |
|
443 -/* public */ |
|
444 nsSystemPrefService::nsSystemPrefService() |
|
445 - :mInitialized(PR_FALSE), |
|
446 - mGConf(nsnull), |
|
447 - mObservers(nsnull) |
|
448 + : mPref(nsnull), mListenToGConf(PR_TRUE) |
|
449 { |
|
450 + mGConfSimpleCallbacks.Init(); |
|
451 + mGConfComplexCallbacks.Init(); |
|
452 } |
|
453 |
|
454 nsSystemPrefService::~nsSystemPrefService() |
|
455 { |
|
456 - mInitialized = PR_FALSE; |
|
457 - |
|
458 - if (mGConf) |
|
459 - delete mGConf; |
|
460 - if (mObservers) { |
|
461 - (void)mObservers->EnumerateForwards(sysPrefDeleteObserver, nsnull); |
|
462 - delete mObservers; |
|
463 - } |
|
464 + NotifyUnloadSystemPreferences(); |
|
465 } |
|
466 |
|
467 nsresult |
|
468 nsSystemPrefService::Init() |
|
469 { |
|
470 - if (!gSysPrefLog) { |
|
471 - gSysPrefLog = PR_NewLogModule("Syspref"); |
|
472 - if (!gSysPrefLog) return NS_ERROR_OUT_OF_MEMORY; |
|
473 + return NS_OK; |
|
474 +} |
|
475 + |
|
476 +NS_IMPL_ISUPPORTS2(nsSystemPrefService, |
|
477 + nsISystemPrefService, |
|
478 + nsIPrefBranch) |
|
479 + |
|
480 +static GConfClient* GetGConf() { |
|
481 + return gconf_client_get_default(); |
|
482 +} |
|
483 + |
|
484 +static PRBool VerifyMatchingTypes(nsISystemPref* aPrefs, |
|
485 + const char* aMozPref, GConfValue* aVal) |
|
486 +{ |
|
487 + nsCOMPtr<nsIPrefBranch2> prefBranch = aPrefs->GetPrefUserBranch(); |
|
488 + PRInt32 type; |
|
489 + nsresult rv = prefBranch->GetPrefType(aMozPref, &type); |
|
490 + if (NS_FAILED(rv)) { |
|
491 + // pref probably doesn't exist. Let gconf set it. |
|
492 + return PR_TRUE; |
|
493 } |
|
494 |
|
495 - SYSPREF_LOG(("Init SystemPref Service\n")); |
|
496 - if (mInitialized) |
|
497 + PRBool ok; |
|
498 + switch (aVal->type) { |
|
499 + case GCONF_VALUE_STRING: |
|
500 + ok = type == nsIPrefBranch2::PREF_STRING; |
|
501 + break; |
|
502 + case GCONF_VALUE_INT: |
|
503 + ok = type == nsIPrefBranch2::PREF_INT; |
|
504 + break; |
|
505 + case GCONF_VALUE_BOOL: |
|
506 + ok = type == nsIPrefBranch2::PREF_BOOL; |
|
507 + break; |
|
508 + default: |
|
509 + NS_ERROR("Unhandled gconf preference type"); |
|
510 + return PR_FALSE; |
|
511 + } |
|
512 + |
|
513 + NS_ASSERTION(ok, "Mismatched gconf/Mozilla pref types"); |
|
514 + return ok; |
|
515 +} |
|
516 + |
|
517 +/** |
|
518 + * Map a gconf pref value into the corresponding Mozilla pref. |
|
519 + */ |
|
520 +static nsresult ApplySimpleMapping(SimplePrefMapping* aMap, |
|
521 + nsISystemPref* aPrefs, |
|
522 + GConfClient* aClient) |
|
523 +{ |
|
524 + GConfValue* val = gconf_client_get(aClient, aMap->gconfPrefName, nsnull); |
|
525 + if (!val) { |
|
526 + // No gconf key, so there's really nothing to do |
|
527 + return NS_OK; |
|
528 + } |
|
529 + |
|
530 + VerifyMatchingTypes(aPrefs, aMap->mozPrefName, val); |
|
531 + |
|
532 + PRBool locked = !aMap->allowWritesFromMozilla || |
|
533 + !gconf_client_key_is_writable(aClient, aMap->gconfPrefName, nsnull); |
|
534 + nsresult rv; |
|
535 + switch (val->type) { |
|
536 + case GCONF_VALUE_STRING: { |
|
537 + const char* str = gconf_value_get_string(val); |
|
538 + rv = aPrefs->SetOverridingMozillaStringPref(aMap->mozPrefName, str, locked); |
|
539 + // XXX do we need to free 'str' here? |
|
540 + break; |
|
541 + } |
|
542 + case GCONF_VALUE_INT: |
|
543 + rv = aPrefs->SetOverridingMozillaIntPref(aMap->mozPrefName, |
|
544 + gconf_value_get_int(val), locked); |
|
545 + break; |
|
546 + case GCONF_VALUE_BOOL: |
|
547 + rv = aPrefs->SetOverridingMozillaBoolPref(aMap->mozPrefName, |
|
548 + gconf_value_get_bool(val), locked); |
|
549 + break; |
|
550 + default: |
|
551 + NS_ERROR("Unusable gconf value type"); |
|
552 + rv = NS_ERROR_FAILURE; |
|
553 + break; |
|
554 + } |
|
555 + |
|
556 + gconf_value_free(val); |
|
557 + return rv; |
|
558 +} |
|
559 + |
|
560 +/** |
|
561 + * Map a Mozilla pref into the corresponding gconf pref, if |
|
562 + * that's allowed. |
|
563 + */ |
|
564 +static nsresult ReverseApplySimpleMapping(SimplePrefMapping* aMap, |
|
565 + nsISystemPref* aPrefs, |
|
566 + GConfClient* aClient) |
|
567 +{ |
|
568 + // Verify that the gconf key has the right type, if it exists |
|
569 + GConfValue* val = gconf_client_get(aClient, aMap->gconfPrefName, nsnull); |
|
570 + if (val) { |
|
571 + VerifyMatchingTypes(aPrefs, aMap->mozPrefName, val); |
|
572 + gconf_value_free(val); |
|
573 + } |
|
574 + |
|
575 + PRBool writable = aMap->allowWritesFromMozilla && |
|
576 + gconf_client_key_is_writable(aClient, aMap->gconfPrefName, nsnull); |
|
577 + if (!writable) { |
|
578 + NS_ERROR("Gconf key is not writable"); |
|
579 return NS_ERROR_FAILURE; |
|
580 + } |
|
581 |
|
582 - if (!mGConf) { |
|
583 - mGConf = new GConfProxy(this); |
|
584 - if (!mGConf->Init()) { |
|
585 - delete mGConf; |
|
586 - mGConf = nsnull; |
|
587 + nsCOMPtr<nsIPrefBranch2> prefBranch = aPrefs->GetPrefUserBranch(); |
|
588 + PRInt32 type; |
|
589 + nsresult rv = prefBranch->GetPrefType(aMap->mozPrefName, &type); |
|
590 + if (NS_FAILED(rv)) { |
|
591 + NS_ERROR("Writing back a pref that doesn't exist?"); |
|
592 + return rv; |
|
593 + } |
|
594 + |
|
595 + switch (type) { |
|
596 + case nsIPrefBranch2::PREF_STRING: |
|
597 + { |
|
598 + char* result; |
|
599 + rv = prefBranch->GetCharPref(aMap->mozPrefName, &result); |
|
600 + if (NS_FAILED(rv)) |
|
601 + return rv; |
|
602 + |
|
603 + gconf_client_set_string(aClient, aMap->gconfPrefName, result, nsnull); |
|
604 + nsMemory::Free(result); |
|
605 + } |
|
606 + break; |
|
607 + case nsIPrefBranch2::PREF_INT: |
|
608 + { |
|
609 + PRInt32 result; |
|
610 + rv = prefBranch->GetIntPref(aMap->mozPrefName, &result); |
|
611 + if (NS_FAILED(rv)) |
|
612 + return rv; |
|
613 + |
|
614 + gconf_client_set_int(aClient, aMap->gconfPrefName, result, nsnull); |
|
615 + } |
|
616 + break; |
|
617 + case nsIPrefBranch2::PREF_BOOL: |
|
618 + { |
|
619 + PRBool result; |
|
620 + rv = prefBranch->GetBoolPref(aMap->mozPrefName, &result); |
|
621 + if (NS_FAILED(rv)) |
|
622 + return rv; |
|
623 + |
|
624 + gconf_client_set_bool(aClient, aMap->gconfPrefName, result, nsnull); |
|
625 + } |
|
626 + break; |
|
627 + default: |
|
628 + NS_ERROR("Unhandled gconf preference type"); |
|
629 + return NS_ERROR_FAILURE; |
|
630 + } |
|
631 + |
|
632 + return NS_OK; |
|
633 +} |
|
634 + |
|
635 +/* BEGIN preference mapping definition area |
|
636 + * |
|
637 + * There are a few rules that our preference maps have to obey: |
|
638 + * |
|
639 + * 1) Each mapping defines a relationship R between a set of GConf preferences and |
|
640 + * a set of Mozilla preferences that must *always* be true. Thus, when a Mozilla |
|
641 + * pref changes or a gconf pref changes, we may need to change something on the |
|
642 + * other side to preserve R. If a GConf preference is read-only, then we may |
|
643 + * need to lock one or more Mozilla preferences to avoid a situation where the |
|
644 + * Mozilla preference changes and we can't update the GConf preference to |
|
645 + * ensure R continues to hold. |
|
646 + * |
|
647 + * 2) If an unlocked Mozilla preference is changed, then we can only |
|
648 + * preserve R by changing GConf preferences; we are not allowed to |
|
649 + * change Mozilla preferences. |
|
650 + * |
|
651 + * 3) If a GConf preference is changed, then we can only preserve R by |
|
652 + * changing Moozilla preferences; we are nt allowed to change GConf |
|
653 + * preferences. |
|
654 + * |
|
655 + * For "simple" mappings, the relationship R is just of the form |
|
656 + * "GConf preference 'A' is equal to Mozilla preference 'B'". R is |
|
657 + * preserved by setting A to B when B changes, and by setting B to A |
|
658 + * when A changes. If A is read-only then we lock B (or we may just |
|
659 + * decide to lock B for other reasons). Thus rules 1-3 are satisfied. |
|
660 + * |
|
661 + * For "complex" mappings we have more complicated |
|
662 + * relationships. These are documented below. |
|
663 + */ |
|
664 + |
|
665 +static SimplePrefMapping sSimplePrefMappings[] = { |
|
666 + // GNOME accessibility setting; never allow this to be set by Firefox |
|
667 + {"config.use_system_prefs.accessibility", |
|
668 + "/desktop/gnome/interface/accessibility", PR_FALSE}, |
|
669 + |
|
670 + // GConf Firefox preferences; allow these to be set through the Firefox UI |
|
671 + {"security.enable_java", "/apps/firefox/web/java_enabled", PR_TRUE}, |
|
672 + {"javascript.enabled", "/apps/firefox/web/javascript_enabled", PR_TRUE}, |
|
673 + {"browser.startup.homepage", "/apps/firefox/general/homepage_url", PR_TRUE}, |
|
674 + {"browser.cache.disk.capacity", "/apps/firefox/web/cache_size", PR_TRUE}, |
|
675 + {"network.cookie.lifetimePolicy", "/apps/firefox/web/cookie_accept", PR_TRUE}, |
|
676 + |
|
677 + // UI lockdown settings; never allow these to be set by Firefox. There is no |
|
678 + // Firefox UI for these but they could otherwise be set via about:config. |
|
679 + {"config.lockdown.printing", "/desktop/gnome/lockdown/disable_printing", PR_FALSE}, |
|
680 + {"config.lockdown.printsetup", "/desktop/gnome/lockdown/disable_print_setup", PR_FALSE}, |
|
681 + {"config.lockdown.savepage", "/desktop/gnome/lockdown/disable_save_to_disk", PR_FALSE}, |
|
682 + {"config.lockdown.history", "/apps/firefox/lockdown/disable_history", PR_FALSE}, |
|
683 + {"config.lockdown.toolbarediting", "/apps/firefox/lockdown/disable_toolbar_editing", PR_FALSE}, |
|
684 + {"config.lockdown.urlbar", "/apps/firefox/lockdown/disable_url_bar", PR_FALSE}, |
|
685 + {"config.lockdown.bookmark", "/apps/firefox/lockdown/disable_bookmark_editing", PR_FALSE}, |
|
686 + {"config.lockdown.disable_themes", "/apps/firefox/lockdown/disable_themes", PR_FALSE}, |
|
687 + {"config.lockdown.disable_extensions", "/apps/firefox/lockdown/disable_extensions", PR_FALSE}, |
|
688 + {"config.lockdown.searchbar", "/apps/firefox/lockdown/disable_searchbar", PR_FALSE}, |
|
689 + {"config.lockdown.hidebookmark", "/apps/firefox/lockdown/hide_bookmark", PR_FALSE}, |
|
690 + {"config.lockdown.showsavedpasswords", "/apps/firefox/lockdown/disable_show_passwords", PR_FALSE}, |
|
691 +}; |
|
692 + |
|
693 +static nsresult ApplyListPref(nsSystemPrefService* aPrefService, |
|
694 + GConfClient* aClient, |
|
695 + const char* aGConfKey, const char* aMozKey, |
|
696 + char aSeparator) |
|
697 +{ |
|
698 + GSList* list = gconf_client_get_list(aClient, aGConfKey, |
|
699 + GCONF_VALUE_STRING, nsnull); |
|
700 + nsCAutoString str; |
|
701 + for (GSList* l = list; l; l = l->next) { |
|
702 + str.Append((const char*)l->data); |
|
703 + if (l->next) { |
|
704 + str.Append(aSeparator); |
|
705 + } |
|
706 + } |
|
707 + PRBool lock = !gconf_client_key_is_writable(aClient, aGConfKey, nsnull); |
|
708 + nsresult rv = aPrefService->GetPrefs()-> |
|
709 + SetOverridingMozillaStringPref(aMozKey, str.get(), lock); |
|
710 + // XXX does this free the strings? Should it? |
|
711 + g_slist_free(list); |
|
712 + return rv; |
|
713 +} |
|
714 +static nsresult ReverseApplyListPref(nsSystemPrefService* aPrefService, |
|
715 + GConfClient* aClient, |
|
716 + const char* aGConfKey, const char* aMozKey, |
|
717 + char aSeparator) |
|
718 +{ |
|
719 + char* data = nsnull; |
|
720 + nsCOMPtr<nsIPrefBranch2> prefs = |
|
721 + aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
722 + prefs->GetCharPref(aMozKey, &data); |
|
723 + if (!data) |
|
724 + return NS_ERROR_FAILURE; |
|
725 + nsresult rv = NS_OK; |
|
726 + GSList* list = nsnull; |
|
727 + PRInt32 i = 0; |
|
728 + while (data[i]) { |
|
729 + const char* nextComma = strchr(data+i, ','); |
|
730 + PRInt32 tokLen = nextComma ? nextComma - (data+i) : strlen(data+i); |
|
731 + char* tok = strndup(data+i, tokLen); |
|
732 + if (!tok) |
|
733 + break; |
|
734 + GSList* newList = g_slist_append(list, tok); |
|
735 + if (!newList) { |
|
736 + rv = NS_ERROR_OUT_OF_MEMORY; |
|
737 + break; |
|
738 + } |
|
739 + list = newList; |
|
740 + if (!nextComma) |
|
741 + break; |
|
742 + i = nextComma + 1 - data; |
|
743 + } |
|
744 + nsMemory::Free(data); |
|
745 + if (NS_SUCCEEDED(rv)) { |
|
746 + if (gconf_client_key_is_writable(aClient, aGConfKey, nsnull)) |
|
747 + gconf_client_set_list(aClient, aGConfKey, GCONF_VALUE_STRING, list, nsnull); |
|
748 + else |
|
749 + NS_ERROR("Gconf key is not writable"); |
|
750 + } |
|
751 + for (GSList* l = list; l; l = l->next) { |
|
752 + free(l->data); |
|
753 + } |
|
754 + g_slist_free(list); |
|
755 + return rv; |
|
756 +} |
|
757 + |
|
758 +/** |
|
759 + * The relationship R is |
|
760 + * "network.negotiate-auth.trusted-uris" is the comma-separated concatenation |
|
761 + * of the elements of the list "/apps/firefox/general/trusted_URIs" |
|
762 + */ |
|
763 +static const char GConfKey_TrustedURIs[] = "/apps/firefox/general/trusted_URIs"; |
|
764 +static const char MozKey_TrustedURIs[] = "network.negotiate-auth.trusted-uris"; |
|
765 +static nsresult ApplyTrustedURIs(nsSystemPrefService* aPrefService, |
|
766 + GConfClient* aClient) |
|
767 +{ |
|
768 + return ApplyListPref(aPrefService, aClient, |
|
769 + GConfKey_TrustedURIs, MozKey_TrustedURIs, ','); |
|
770 +} |
|
771 +static nsresult ReverseApplyTrustedURIs(nsSystemPrefService* aPrefService, |
|
772 + GConfClient* aClient) |
|
773 +{ |
|
774 + return ReverseApplyListPref(aPrefService, aClient, |
|
775 + GConfKey_TrustedURIs, MozKey_TrustedURIs, ','); |
|
776 +} |
|
777 + |
|
778 +/** |
|
779 + * The relationship R is |
|
780 + * "network.negotiate-auth.delegation-uris" is the comma-separated concatenation |
|
781 + * of the elements of the list "/apps/firefox/general/delegation_URIs" |
|
782 + */ |
|
783 +static const char GConfKey_DelegationURIs[] = "/apps/firefox/general/delegation_URIs"; |
|
784 +static const char MozKey_DelegationURIs[] = "network.negotiate-auth.delegation-uris"; |
|
785 +static nsresult ApplyDelegationURIs(nsSystemPrefService* aPrefService, |
|
786 + GConfClient* aClient) |
|
787 +{ |
|
788 + return ApplyListPref(aPrefService, aClient, |
|
789 + GConfKey_DelegationURIs, MozKey_DelegationURIs, ','); |
|
790 +} |
|
791 +static nsresult ReverseApplyDelegationURIs(nsSystemPrefService* aPrefService, |
|
792 + GConfClient* aClient) |
|
793 +{ |
|
794 + return ReverseApplyListPref(aPrefService, aClient, |
|
795 + GConfKey_DelegationURIs, MozKey_DelegationURIs, ','); |
|
796 +} |
|
797 + |
|
798 + |
|
799 +/** |
|
800 + * The relationship R is |
|
801 + * If "/apps/firefox/web/download_defaultfolder" is the empty string, then |
|
802 + * "browser.download.useDownloadDir" is false; |
|
803 + * otherwise "browser.download.useDownloadDir" is true and "browser.download.folderList" |
|
804 + * is (0 if "/apps/firefox/web/download_defaultfolder" is "Desktop"; |
|
805 + * 1 if "/apps/firefox/web/download_defaultfolder" is "My Downloads"; |
|
806 + * 3 if "/apps/firefox/web/download_defaultfolder" is "Home"; |
|
807 + * otherwise 2 and "browser.download.dir" = "/apps/firefox/web/download_defaultfolder") |
|
808 + */ |
|
809 +static const char GConfKey_DownloadFolder[] = "/apps/firefox/web/download_defaultfolder"; |
|
810 +static const char MozKey_UseDownloadDir[] = "browser.download.useDownloadDir"; |
|
811 +static const char MozKey_DownloadDirType[] = "browser.download.folderList"; |
|
812 +static const char MozKey_DownloadDirExplicit[] = "browser.download.dir"; |
|
813 +static nsresult ApplyDownloadFolder(nsSystemPrefService* aPrefService, |
|
814 + GConfClient* aClient) |
|
815 +{ |
|
816 + char* str = gconf_client_get_string(aClient, GConfKey_DownloadFolder, nsnull); |
|
817 + if (!str) |
|
818 + return NS_ERROR_FAILURE; |
|
819 + PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DownloadFolder, nsnull); |
|
820 + nsresult rv = aPrefService->GetPrefs()-> |
|
821 + SetOverridingMozillaBoolPref(MozKey_UseDownloadDir, *str != 0, lock); |
|
822 + if (NS_FAILED(rv)) { |
|
823 + g_free(str); |
|
824 + return rv; |
|
825 + } |
|
826 + PRInt32 dirType = 0; |
|
827 + if (!strcmp(str, "Desktop")) { |
|
828 + dirType = 0; |
|
829 + } else if (!strcmp(str, "My Downloads")) { |
|
830 + dirType = 1; |
|
831 + } else if (!strcmp(str, "Home")) { |
|
832 + dirType = 3; |
|
833 + } else { |
|
834 + dirType = 2; |
|
835 + } |
|
836 + // Always set all three Mozilla preferences. This is simpler and avoids |
|
837 + // problems; e.g., if the gconf value changes from "/home/rocallahan" to "Desktop" |
|
838 + // we might leave MozKey_DownloadDirType accidentally locked. |
|
839 + rv = aPrefService->GetPrefs()-> |
|
840 + SetOverridingMozillaIntPref(MozKey_DownloadDirType, dirType, lock); |
|
841 + if (NS_SUCCEEDED(rv)) { |
|
842 + rv = aPrefService->GetPrefs()-> |
|
843 + SetOverridingMozillaStringPref(MozKey_DownloadDirExplicit, str, lock); |
|
844 + } |
|
845 + g_free(str); |
|
846 + return rv; |
|
847 +} |
|
848 + |
|
849 +static nsresult ReverseApplyDownloadFolder(nsSystemPrefService* aPrefService, |
|
850 + GConfClient* aClient) |
|
851 +{ |
|
852 + PRBool useDownloadDir = PR_FALSE; |
|
853 + const char* result; |
|
854 + char* explicitStr = nsnull; |
|
855 + nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
856 + prefs->GetBoolPref(MozKey_UseDownloadDir, &useDownloadDir); |
|
857 + if (!useDownloadDir) { |
|
858 + result = ""; |
|
859 + } else { |
|
860 + PRInt32 type = -1; |
|
861 + prefs->GetIntPref(MozKey_DownloadDirType, &type); |
|
862 + if (type < 0) |
|
863 + return NS_ERROR_FAILURE; |
|
864 + switch (type) { |
|
865 + case 0: result = "Desktop"; break; |
|
866 + case 1: result = "Downloads"; break; |
|
867 + case 2: |
|
868 + prefs->GetCharPref(MozKey_DownloadDirExplicit, &explicitStr); |
|
869 + result = explicitStr; |
|
870 + break; |
|
871 + case 3: result = "Home"; break; |
|
872 + default: |
|
873 + NS_ERROR("Unknown download dir type"); |
|
874 return NS_ERROR_FAILURE; |
|
875 } |
|
876 } |
|
877 + if (!result) |
|
878 + return NS_ERROR_FAILURE; |
|
879 + if (gconf_client_key_is_writable(aClient, GConfKey_DownloadFolder, nsnull)) |
|
880 + gconf_client_set_string(aClient, GConfKey_DownloadFolder, |
|
881 + result, nsnull); |
|
882 + else |
|
883 + NS_ERROR("Gconf key is not writable"); |
|
884 + nsMemory::Free(explicitStr); |
|
885 + return NS_OK; |
|
886 +} |
|
887 |
|
888 - mInitialized = PR_TRUE; |
|
889 +/** |
|
890 + * The relationship R is |
|
891 + * "/apps/firefox/web/disable_cookies" is true if and only if |
|
892 + * "network.cookie.cookieBehavior" is 2 ('dontUse') |
|
893 + */ |
|
894 +static const char GConfKey_DisableCookies[] = "/apps/firefox/web/disable_cookies"; |
|
895 +static const char MozKey_CookieBehavior[] = "network.cookie.cookieBehavior"; |
|
896 +static const char MozKey_CookieExceptions[] = "network.cookie.honorExceptions"; |
|
897 +static const char MozKey_CookieViewExceptions[] = "pref.privacy.disable_button.cookie_exceptions"; |
|
898 +static nsresult ApplyDisableCookies(nsSystemPrefService* aPrefService, |
|
899 + GConfClient* aClient) |
|
900 +{ |
|
901 + gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableCookies, nsnull); |
|
902 + PRInt32 behavior = -1; |
|
903 + nsCOMPtr<nsIPrefBranch2> prefs = |
|
904 + aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
905 + prefs->GetIntPref(MozKey_CookieBehavior, &behavior); |
|
906 + if (behavior < 0) |
|
907 + return NS_ERROR_FAILURE; |
|
908 + if (disable) { |
|
909 + behavior = 2; |
|
910 + } else { |
|
911 + if (behavior == 2) { |
|
912 + behavior = 0; |
|
913 + } |
|
914 + } |
|
915 + PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableCookies, nsnull); |
|
916 + nsresult rv = aPrefService->GetPrefs()-> |
|
917 + SetOverridingMozillaBoolPref(MozKey_CookieExceptions, !lock, lock); |
|
918 + if (NS_FAILED(rv)) |
|
919 + return rv; |
|
920 + rv = aPrefService->GetPrefs()-> |
|
921 + SetOverridingMozillaBoolPref(MozKey_CookieViewExceptions, lock, lock); |
|
922 + if (NS_FAILED(rv)) |
|
923 + return rv; |
|
924 + return aPrefService->GetPrefs()-> |
|
925 + SetOverridingMozillaIntPref(MozKey_CookieBehavior, behavior, lock); |
|
926 +} |
|
927 +static nsresult ReverseApplyDisableCookies(nsSystemPrefService* aPrefService, |
|
928 + GConfClient* aClient) |
|
929 +{ |
|
930 + PRInt32 behavior = -1; |
|
931 + nsCOMPtr<nsIPrefBranch2> prefs = |
|
932 + aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
933 + prefs->GetIntPref(MozKey_CookieBehavior, &behavior); |
|
934 + if (behavior < 0) |
|
935 + return NS_ERROR_FAILURE; |
|
936 + if (gconf_client_key_is_writable(aClient, GConfKey_DisableCookies, nsnull)) |
|
937 + gconf_client_set_bool(aClient, GConfKey_DisableCookies, behavior == 2, nsnull); |
|
938 + else |
|
939 + NS_ERROR("Gconf key is not writable"); |
|
940 return NS_OK; |
|
941 } |
|
942 |
|
943 +static char const* windowOpenFeatures[] = { |
|
944 + "dom.disable_window_open_feature.close", |
|
945 + "dom.disable_window_open_feature.directories", |
|
946 + "dom.disable_window_open_feature.location", |
|
947 + "dom.disable_window_open_feature.menubar", |
|
948 + "dom.disable_window_open_feature.minimizable", |
|
949 + "dom.disable_window_open_feature.personalbar", |
|
950 + "dom.disable_window_open_feature.resizable", |
|
951 + "dom.disable_window_open_feature.scrollbars", |
|
952 + "dom.disable_window_open_feature.status", |
|
953 + "dom.disable_window_open_feature.titlebar", |
|
954 + "dom.disable_window_open_feature.toolbar" |
|
955 +}; |
|
956 +/** |
|
957 + * The relationship R is |
|
958 + * "/apps/firefox/lockdown/disable_javascript_chrome" is true if and only if |
|
959 + * all of windowOpenFeatures are true |
|
960 + */ |
|
961 +static const char GConfKey_DisableJSChrome[] = |
|
962 + "/apps/firefox/lockdown/disable_javascript_chrome"; |
|
963 +static nsresult ApplyWindowOpen(nsSystemPrefService* aPrefService, |
|
964 + GConfClient* aClient) |
|
965 +{ |
|
966 + gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableJSChrome, nsnull); |
|
967 + PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableJSChrome, nsnull); |
|
968 + PRBool curValues[NUM_ELEM(windowOpenFeatures)]; |
|
969 + PRUint32 i; |
|
970 + nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
971 + PRBool allDisabled = PR_TRUE; |
|
972 + for (i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) { |
|
973 + nsresult rv = prefs->GetBoolPref(windowOpenFeatures[i], &curValues[i]); |
|
974 + if (NS_FAILED(rv)) |
|
975 + return rv; |
|
976 + if (!curValues[i]) { |
|
977 + allDisabled = PR_FALSE; |
|
978 + } |
|
979 + } |
|
980 + for (i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) { |
|
981 + PRBool newVal = curValues[i]; |
|
982 + if (disable) { |
|
983 + newVal = PR_TRUE; |
|
984 + } else if (allDisabled) { |
|
985 + // If all disable-window-open-feature prefs are currently |
|
986 + // PR_TRUE, then we need to set at least one of them to |
|
987 + // PR_FALSE. Set all of them to PR_FALSE. |
|
988 + newVal = PR_FALSE; |
|
989 + } // If at least one disable-window-open-feature pref is |
|
990 + // currently PR_FALSE, then we don't need to change anything |
|
991 + // when the gconf pref says don't disable |
|
992 + nsresult rv = aPrefService->GetPrefs()-> |
|
993 + SetOverridingMozillaBoolPref(windowOpenFeatures[i], newVal, lock); |
|
994 + if (NS_FAILED(rv)) |
|
995 + return rv; |
|
996 + } |
|
997 + return NS_OK; |
|
998 +} |
|
999 + |
|
1000 +static nsresult ReverseApplyWindowOpen(nsSystemPrefService* aPrefService, |
|
1001 + GConfClient* aClient) |
|
1002 +{ |
|
1003 + nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
1004 + PRBool allDisabled = PR_TRUE; |
|
1005 + PRBool curValues[NUM_ELEM(windowOpenFeatures)]; |
|
1006 + for (PRUint32 i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) { |
|
1007 + nsresult rv = prefs->GetBoolPref(windowOpenFeatures[i], &curValues[i]); |
|
1008 + if (NS_FAILED(rv)) |
|
1009 + return rv; |
|
1010 + if (!curValues[i]) { |
|
1011 + allDisabled = PR_FALSE; |
|
1012 + } |
|
1013 + } |
|
1014 + if (gconf_client_key_is_writable(aClient, GConfKey_DisableJSChrome, nsnull)) |
|
1015 + gconf_client_set_bool(aClient, GConfKey_DisableJSChrome, allDisabled, nsnull); |
|
1016 + else |
|
1017 + NS_ERROR("Gconf key is not writable"); |
|
1018 + return NS_OK; |
|
1019 +} |
|
1020 + |
|
1021 +/** |
|
1022 + * The relationship R is |
|
1023 + * If "/apps/firefox/lockdown/disable_unsafe_protocol" is true then |
|
1024 + * -- "network.protocol-handler.blocked-default" is true |
|
1025 + * -- "network.protocol-handler.blocked.XYZ" is false if and only if |
|
1026 + * XYZ is a builtin non-disablable protocol or in |
|
1027 + * "/apps/firefox/lockdown/additional_safe_protocols" |
|
1028 + * AND if "/apps/firefox/lockdown/disable_unsafe_protocol" is false then |
|
1029 + * -- "network.protocol-handler.blocked-default" is false |
|
1030 + * -- if "network.protocol-handler.blocked.XYZ" exists then it is false |
|
1031 + */ |
|
1032 +static const char GConfKey_DisableUnsafeProtocols[] = |
|
1033 + "/apps/firefox/lockdown/disable_unsafe_protocol"; |
|
1034 +static const char GConfKey_AdditionalSafeProtocols[] = |
|
1035 + "/apps/firefox/lockdown/additional_safe_protocols"; |
|
1036 +static const char MozKey_BlockedDefault[] = |
|
1037 + "network.protocol-handler.blocked-default"; |
|
1038 +static const char MozKey_BlockedPrefix[] = |
|
1039 + "network.protocol-handler.blocked."; |
|
1040 +static const char* nonDisablableBuiltinProtocols[] = |
|
1041 + { "about", "data", "jar", "keyword", "resource", "viewsource", |
|
1042 + "chrome", "moz-icon", "javascript", "file" }; |
|
1043 +static PRBool FindString(const char** aList, PRInt32 aCount, |
|
1044 + const char* aStr) |
|
1045 +{ |
|
1046 + for (PRInt32 i = 0; i < aCount; ++i) { |
|
1047 + if (!strcmp(aStr, aList[i])) |
|
1048 + return PR_TRUE; |
|
1049 + } |
|
1050 + return PR_FALSE; |
|
1051 +} |
|
1052 +typedef nsDataHashtable<nsCStringHashKey,int> StringSet; |
|
1053 +/** Collect the set of protocol names that we want to set preferences for */ |
|
1054 +static nsresult AddAllProtocols(nsSystemPrefService* aPrefService, |
|
1055 + const char* aSafeProtocols, |
|
1056 + StringSet* aProtocolSet, |
|
1057 + StringSet* aSafeSet) |
|
1058 +{ |
|
1059 + nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
1060 + PRUint32 childCount; |
|
1061 + char **childArray = nsnull; |
|
1062 + nsresult rv = prefs->GetChildList(MozKey_BlockedPrefix, &childCount, &childArray); |
|
1063 + if (NS_FAILED(rv)) |
|
1064 + return rv; |
|
1065 + PRUint32 i; |
|
1066 + for (i = 0; i < childCount; ++i) { |
|
1067 + nsDependentCString tmp(childArray[i] + NUM_ELEM(MozKey_BlockedPrefix)-1); |
|
1068 + aProtocolSet->Put(tmp, 1); // copies |
|
1069 + } |
|
1070 + for (i = 0; i < NUM_ELEM(nonDisablableBuiltinProtocols); ++i) { |
|
1071 + nsDependentCString tmp(nonDisablableBuiltinProtocols[i]); |
|
1072 + aProtocolSet->Put(tmp, 1); |
|
1073 + } |
|
1074 + i = 0; |
|
1075 + while (aSafeProtocols[i]) { |
|
1076 + const char* nextComma = strchr(aSafeProtocols+i, ','); |
|
1077 + PRUint32 tokLen = nextComma ? nextComma - (aSafeProtocols+i) |
|
1078 + : strlen(aSafeProtocols+i); |
|
1079 + nsCAutoString tok(aSafeProtocols+i, tokLen); |
|
1080 + aProtocolSet->Put(tok, 1); |
|
1081 + aSafeSet->Put(tok, 1); |
|
1082 + if (nextComma) { |
|
1083 + i = nextComma - aSafeProtocols + 1; |
|
1084 + } else { |
|
1085 + break; |
|
1086 + } |
|
1087 + } |
|
1088 + NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray); |
|
1089 + return NS_OK; |
|
1090 +} |
|
1091 + |
|
1092 +struct ProtocolPrefClosure { |
|
1093 + StringSet safeProtocolSet; |
|
1094 + nsIPrefBranch2* prefs; |
|
1095 + nsISystemPref* prefSetter; |
|
1096 + PRPackedBool disableUnsafe; |
|
1097 + PRPackedBool lock; |
|
1098 +}; |
|
1099 + |
|
1100 +static PLDHashOperator PR_CALLBACK SetProtocolPref(const nsACString& aKey, |
|
1101 + int aItem, |
|
1102 + void* aClosure) |
|
1103 +{ |
|
1104 + ProtocolPrefClosure* closure = static_cast<ProtocolPrefClosure*>(aClosure); |
|
1105 + const nsCString& protocol = PromiseFlatCString(aKey); |
|
1106 + PRBool blockProtocol = PR_FALSE; |
|
1107 + if (closure->disableUnsafe && |
|
1108 + !FindString(nonDisablableBuiltinProtocols, |
|
1109 + NUM_ELEM(nonDisablableBuiltinProtocols), protocol.get()) && |
|
1110 + !closure->safeProtocolSet.Get(aKey, nsnull)) { |
|
1111 + blockProtocol = PR_TRUE; |
|
1112 + } |
|
1113 + |
|
1114 + nsCAutoString prefName; |
|
1115 + prefName.Append(MozKey_BlockedPrefix); |
|
1116 + prefName.Append(protocol); |
|
1117 + closure->prefSetter->SetOverridingMozillaBoolPref(prefName.get(), blockProtocol, |
|
1118 + closure->lock); |
|
1119 + return PL_DHASH_NEXT; |
|
1120 +} |
|
1121 +static nsresult ApplyUnsafeProtocols(nsSystemPrefService* aPrefService, |
|
1122 + GConfClient* aClient) |
|
1123 +{ |
|
1124 + PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableUnsafeProtocols, nsnull) |
|
1125 + || !gconf_client_key_is_writable(aClient, GConfKey_AdditionalSafeProtocols, nsnull); |
|
1126 + gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableUnsafeProtocols, nsnull); |
|
1127 + char* protocols = gconf_client_get_string(aClient, GConfKey_AdditionalSafeProtocols, nsnull); |
|
1128 + if (!protocols) |
|
1129 + return NS_ERROR_FAILURE; |
|
1130 + nsresult rv = aPrefService->GetPrefs()-> |
|
1131 + SetOverridingMozillaBoolPref(MozKey_BlockedDefault, disable, lock); |
|
1132 + StringSet protocolSet; |
|
1133 + ProtocolPrefClosure closure; |
|
1134 + protocolSet.Init(); |
|
1135 + closure.safeProtocolSet.Init(); |
|
1136 + if (NS_SUCCEEDED(rv)) { |
|
1137 + rv = AddAllProtocols(aPrefService, protocols, &protocolSet, |
|
1138 + &closure.safeProtocolSet); |
|
1139 + } |
|
1140 + if (NS_SUCCEEDED(rv)) { |
|
1141 + closure.disableUnsafe = disable; |
|
1142 + closure.lock = lock; |
|
1143 + closure.prefSetter = aPrefService->GetPrefs(); |
|
1144 + nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
1145 + closure.prefs = prefs; |
|
1146 + protocolSet.EnumerateRead(SetProtocolPref, &closure); |
|
1147 + } |
|
1148 + g_free(protocols); |
|
1149 + return rv; |
|
1150 +} |
|
1151 + |
|
1152 +static nsresult ReverseApplyUnsafeProtocols(nsSystemPrefService* aPrefService, |
|
1153 + GConfClient* aClient) |
|
1154 +{ |
|
1155 + nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
1156 + PRBool blockedDefault; |
|
1157 + nsresult rv = prefs->GetBoolPref(MozKey_BlockedDefault, &blockedDefault); |
|
1158 + if (NS_FAILED(rv)) |
|
1159 + return rv; |
|
1160 + nsCAutoString enabledProtocols; |
|
1161 + PRUint32 childCount; |
|
1162 + char **childArray = nsnull; |
|
1163 + rv = prefs->GetChildList(MozKey_BlockedPrefix, &childCount, &childArray); |
|
1164 + if (NS_FAILED(rv)) |
|
1165 + return rv; |
|
1166 + for (PRUint32 i = 0; i < childCount; ++i) { |
|
1167 + PRBool val = PR_FALSE; |
|
1168 + prefs->GetBoolPref(childArray[i], &val); |
|
1169 + if (val) { |
|
1170 + if (enabledProtocols.Length() > 0) { |
|
1171 + enabledProtocols.Append(','); |
|
1172 + } |
|
1173 + enabledProtocols.Append(childArray[i] + NUM_ELEM(MozKey_BlockedPrefix)-1); |
|
1174 + } |
|
1175 + } |
|
1176 + NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray); |
|
1177 + if (gconf_client_key_is_writable(aClient, GConfKey_DisableUnsafeProtocols, nsnull) && |
|
1178 + gconf_client_key_is_writable(aClient, GConfKey_AdditionalSafeProtocols, nsnull)) { |
|
1179 + gconf_client_set_bool(aClient, GConfKey_DisableUnsafeProtocols, blockedDefault, nsnull); |
|
1180 + gconf_client_set_string(aClient, GConfKey_AdditionalSafeProtocols, |
|
1181 + enabledProtocols.get(), nsnull); |
|
1182 + } else { |
|
1183 + NS_ERROR("Gconf key is not writable"); |
|
1184 + } |
|
1185 + return NS_OK; |
|
1186 +} |
|
1187 + |
|
1188 +/** |
|
1189 + * Set config.lockdown.setwallpaper if and only if |
|
1190 + * /desktop/gnome/background/picture_filename is write-only. Always |
|
1191 + * lock it. |
|
1192 + */ |
|
1193 +static const char MozKey_LockdownWallpaper[] = "config.lockdown.setwallpaper"; |
|
1194 +static const char GConfKey_WallpaperSetting[] = |
|
1195 + "/desktop/gnome/background/picture_filename"; |
|
1196 +static nsresult ApplyWallpaper(nsSystemPrefService* aPrefService, |
|
1197 + GConfClient* aClient) |
|
1198 +{ |
|
1199 + PRBool canSetWallpaper = |
|
1200 + gconf_client_key_is_writable(aClient, GConfKey_WallpaperSetting, nsnull); |
|
1201 + return aPrefService->GetPrefs()-> |
|
1202 + SetOverridingMozillaBoolPref(MozKey_LockdownWallpaper, |
|
1203 + !canSetWallpaper, PR_TRUE); |
|
1204 +} |
|
1205 +// No ReverseApplyWallpaper because this Mozilla pref can never be |
|
1206 +// modified |
|
1207 + |
|
1208 +/** |
|
1209 + * The relationship R is |
|
1210 + * "signon.rememberSignons" is true if and only if "/apps/firefox/web/disable_save_password" |
|
1211 + * is false. |
|
1212 + */ |
|
1213 +static const char MozKey_RememberSignons[] = "signon.rememberSignons"; |
|
1214 +static const char GConfKey_DisableSavePassword[] = "/apps/firefox/web/disable_save_password"; |
|
1215 +static nsresult ApplyDisableSavePassword(nsSystemPrefService* aPrefService, |
|
1216 + GConfClient* aClient) |
|
1217 +{ |
|
1218 + PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableSavePassword, nsnull); |
|
1219 + gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableSavePassword, nsnull); |
|
1220 + return aPrefService->GetPrefs()-> |
|
1221 + SetOverridingMozillaBoolPref(MozKey_RememberSignons, !disable, lock); |
|
1222 +} |
|
1223 + |
|
1224 +static nsresult ReverseApplyDisableSavePassword(nsSystemPrefService* aPrefService, |
|
1225 + GConfClient* aClient) |
|
1226 +{ |
|
1227 + nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
1228 + PRBool remember; |
|
1229 + nsresult rv = prefs->GetBoolPref(MozKey_RememberSignons, &remember); |
|
1230 + if (NS_FAILED(rv)) |
|
1231 + return rv; |
|
1232 + gconf_client_set_bool(aClient, GConfKey_DisableSavePassword, !remember, nsnull); |
|
1233 + return NS_OK; |
|
1234 +} |
|
1235 + |
|
1236 +/** |
|
1237 + * The relationship R is |
|
1238 + * "permissions.default.image" is 1 (nsIPermissionManager::ALLOW_ACTION) if and only if |
|
1239 + * "/apps/firefox/web/images_load" is 0, AND |
|
1240 + * "permissions.default.image" is 2 (nsIPermissionManager::DENY_ACTION) if and only if |
|
1241 + * "/apps/firefox/web/images_load" is 2, AND |
|
1242 + * "permissions.default.image" is 3 if and only if "/apps/firefox/web/images_load" is 1 |
|
1243 + * |
|
1244 + * Also, we set pref.advanced.images.disable_button.view_image iff |
|
1245 + * /apps/firefox/web/images_load is read-only |
|
1246 + * And we set permissions.default.honorExceptions iff |
|
1247 + * /apps/firefox/web/images_load is not read-only |
|
1248 + */ |
|
1249 +static const char MozKey_ImagePermissions[] = "permissions.default.image"; |
|
1250 +static const char MozKey_ImageExceptions[] = "permissions.honorExceptions.image"; |
|
1251 +static const char MozKey_ImageViewExceptions[] = "pref.advanced.images.disable_button.view_image"; |
|
1252 +static const char GConfKey_LoadImages[] = "/apps/firefox/web/images_load"; |
|
1253 +static nsresult ApplyLoadImages(nsSystemPrefService* aPrefService, |
|
1254 + GConfClient* aClient) |
|
1255 +{ |
|
1256 + PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_LoadImages, nsnull); |
|
1257 + // 0 == accept, 1 == no-foreign, 2 == reject |
|
1258 + gint setting = gconf_client_get_int(aClient, GConfKey_LoadImages, nsnull); |
|
1259 + PRInt32 pref; |
|
1260 + switch (setting) { |
|
1261 + case 0: pref = nsIPermissionManager::ALLOW_ACTION; break; |
|
1262 + case 2: pref = nsIPermissionManager::DENY_ACTION; break; |
|
1263 + case 1: pref = 3; break; |
|
1264 + default: return NS_ERROR_FAILURE; |
|
1265 + } |
|
1266 + nsresult rv = aPrefService->GetPrefs()-> |
|
1267 + SetOverridingMozillaBoolPref(MozKey_ImageExceptions, !lock, lock); |
|
1268 + if (NS_FAILED(rv)) |
|
1269 + return rv; |
|
1270 + rv = aPrefService->GetPrefs()-> |
|
1271 + SetOverridingMozillaBoolPref(MozKey_ImageViewExceptions, lock, lock); |
|
1272 + if (NS_FAILED(rv)) |
|
1273 + return rv; |
|
1274 + return aPrefService->GetPrefs()-> |
|
1275 + SetOverridingMozillaIntPref(MozKey_ImagePermissions, pref, lock); |
|
1276 +} |
|
1277 + |
|
1278 +static nsresult ReverseApplyLoadImages(nsSystemPrefService* aPrefService, |
|
1279 + GConfClient* aClient) |
|
1280 +{ |
|
1281 + nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
1282 + PRInt32 pref; |
|
1283 + nsresult rv = prefs->GetIntPref(MozKey_ImagePermissions, &pref); |
|
1284 + if (NS_FAILED(rv)) |
|
1285 + return rv; |
|
1286 + gint setting; |
|
1287 + switch (pref) { |
|
1288 + case nsIPermissionManager::ALLOW_ACTION: setting = 0; break; |
|
1289 + case nsIPermissionManager::DENY_ACTION: setting = 2; break; |
|
1290 + case 3: setting = 1; break; |
|
1291 + default: return NS_ERROR_FAILURE; |
|
1292 + } |
|
1293 + if (gconf_client_key_is_writable(aClient, GConfKey_LoadImages, nsnull)) |
|
1294 + gconf_client_set_int(aClient, GConfKey_LoadImages, setting, nsnull); |
|
1295 + else |
|
1296 + NS_ERROR("Gconf key is not writable"); |
|
1297 + return NS_OK; |
|
1298 +} |
|
1299 + |
|
1300 +/** |
|
1301 + * The relationship R is |
|
1302 + * "/apps/firefox/web/disable_popups" is true if and only if |
|
1303 + * "dom.disable_open_during_load" is true |
|
1304 + * AND if "/apps/firefox/web/disable_popups" is true then |
|
1305 + * "privacy.popups.showBrowserMessage" is false. |
|
1306 + */ |
|
1307 +static const char MozKey_DisablePopups[] = "dom.disable_open_during_load"; |
|
1308 +static const char MozKey_DisableBrowserPopupMessage[] = "privacy.popups.showBrowserMessage"; |
|
1309 +static const char GConfKey_DisablePopups[] = "/apps/firefox/web/disable_popups"; |
|
1310 +static nsresult ApplyDisablePopups(nsSystemPrefService* aPrefService, |
|
1311 + GConfClient* aClient) |
|
1312 +{ |
|
1313 + PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisablePopups, nsnull); |
|
1314 + gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisablePopups, nsnull); |
|
1315 + nsresult rv = aPrefService->GetPrefs()-> |
|
1316 + SetOverridingMozillaBoolPref(MozKey_DisablePopups, disable, lock); |
|
1317 + if (NS_SUCCEEDED(rv)) { |
|
1318 + if (disable) { |
|
1319 + rv = aPrefService->GetPrefs()-> |
|
1320 + SetOverridingMozillaBoolPref(MozKey_DisableBrowserPopupMessage, PR_TRUE, lock); |
|
1321 + } else { |
|
1322 + rv = aPrefService->GetPrefs()-> |
|
1323 + StopOverridingMozillaPref(MozKey_DisableBrowserPopupMessage); |
|
1324 + } |
|
1325 + } |
|
1326 + return rv; |
|
1327 +} |
|
1328 + |
|
1329 +static nsresult ReverseApplyDisablePopups(nsSystemPrefService* aPrefService, |
|
1330 + GConfClient* aClient) |
|
1331 +{ |
|
1332 + nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch(); |
|
1333 + PRBool disabled; |
|
1334 + nsresult rv = prefs->GetBoolPref(MozKey_DisablePopups, &disabled); |
|
1335 + if (NS_FAILED(rv)) |
|
1336 + return rv; |
|
1337 + if (gconf_client_key_is_writable(aClient, GConfKey_DisablePopups, nsnull)) |
|
1338 + gconf_client_set_bool(aClient, GConfKey_DisablePopups, disabled, nsnull); |
|
1339 + else |
|
1340 + NS_ERROR("Gconf key is not writable"); |
|
1341 + return NS_OK; |
|
1342 +} |
|
1343 + |
|
1344 +static ComplexGConfPrefMapping sComplexGConfPrefMappings[] = { |
|
1345 + {GConfKey_TrustedURIs, ApplyTrustedURIs}, |
|
1346 + {GConfKey_DelegationURIs, ApplyDelegationURIs}, |
|
1347 + {GConfKey_DownloadFolder, ApplyDownloadFolder}, |
|
1348 + {GConfKey_DisableCookies, ApplyDisableCookies}, |
|
1349 + {GConfKey_DisableJSChrome, ApplyWindowOpen}, |
|
1350 + {GConfKey_DisableUnsafeProtocols, ApplyUnsafeProtocols}, |
|
1351 + {GConfKey_AdditionalSafeProtocols, ApplyUnsafeProtocols}, |
|
1352 + {GConfKey_WallpaperSetting, ApplyWallpaper}, |
|
1353 + {GConfKey_DisableSavePassword, ApplyDisableSavePassword}, |
|
1354 + {GConfKey_LoadImages, ApplyLoadImages}, |
|
1355 + {GConfKey_DisablePopups, ApplyDisablePopups} |
|
1356 +}; |
|
1357 +static ComplexMozPrefMapping sComplexMozPrefMappings[] = { |
|
1358 + {MozKey_TrustedURIs, ReverseApplyTrustedURIs}, |
|
1359 + {MozKey_DelegationURIs, ReverseApplyDelegationURIs}, |
|
1360 + {MozKey_UseDownloadDir, ReverseApplyDownloadFolder}, |
|
1361 + {MozKey_DownloadDirType, ReverseApplyDownloadFolder}, |
|
1362 + {MozKey_DownloadDirExplicit, ReverseApplyDownloadFolder}, |
|
1363 + {MozKey_CookieBehavior, ReverseApplyDisableCookies}, |
|
1364 + {MozKey_RememberSignons, ReverseApplyDisableSavePassword}, |
|
1365 + {MozKey_ImagePermissions, ReverseApplyLoadImages}, |
|
1366 + {MozKey_DisablePopups, ReverseApplyDisablePopups} |
|
1367 +}; |
|
1368 +// The unsafe protocol preferences are handled specially because |
|
1369 +// they affect an unknown number of Mozilla preferences |
|
1370 +// Window opener permissions are also handled specially so we don't have to |
|
1371 +// repeat the windowOpenFeatures list. |
|
1372 + |
|
1373 +/* END preference mapping definition area */ |
|
1374 + |
|
1375 +static PR_CALLBACK void GConfSimpleNotification(GConfClient* client, |
|
1376 + guint cnxn_id, |
|
1377 + GConfEntry *entry, |
|
1378 + gpointer user_data) |
|
1379 +{ |
|
1380 + nsSystemPrefService* service = static_cast<nsSystemPrefService*>(user_data); |
|
1381 + SimplePrefMapping* map = static_cast<SimplePrefMapping*>( |
|
1382 + service->GetSimpleCallbackData(cnxn_id)); |
|
1383 + NS_ASSERTION(map, "Can't find mapping for callback"); |
|
1384 + if (!map) |
|
1385 + return; |
|
1386 + |
|
1387 + ApplySimpleMapping(map, service->GetPrefs(), client); |
|
1388 +} |
|
1389 + |
|
1390 +static PR_CALLBACK void GConfComplexNotification(GConfClient* client, |
|
1391 + guint cnxn_id, |
|
1392 + GConfEntry *entry, |
|
1393 + gpointer user_data) |
|
1394 +{ |
|
1395 + nsSystemPrefService* service = static_cast<nsSystemPrefService*>(user_data); |
|
1396 + ComplexGConfPrefMapping* map = static_cast<ComplexGConfPrefMapping*>( |
|
1397 + service->GetComplexCallbackData(cnxn_id)); |
|
1398 + NS_ASSERTION(map, "Can't find mapping for callback"); |
|
1399 + if (!map) |
|
1400 + return; |
|
1401 + |
|
1402 + map->callback(service, GetGConf()); |
|
1403 +} |
|
1404 + |
|
1405 +nsresult nsSystemPrefService::LoadSystemPreferences(nsISystemPref* aPrefs) |
|
1406 +{ |
|
1407 + mPref = aPrefs; |
|
1408 + |
|
1409 + GConfClient* client = GetGConf(); |
|
1410 + PRUint32 i; |
|
1411 + // Register simple mappings and callbacks |
|
1412 + for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) { |
|
1413 + guint cx = gconf_client_notify_add(client, |
|
1414 + sSimplePrefMappings[i].gconfPrefName, |
|
1415 + GConfSimpleNotification, this, |
|
1416 + nsnull, nsnull); |
|
1417 + mGConfSimpleCallbacks.Put(cx, &sSimplePrefMappings[i]); |
|
1418 + nsresult rv = ApplySimpleMapping(&sSimplePrefMappings[i], aPrefs, client); |
|
1419 + if (NS_FAILED(rv)) |
|
1420 + return rv; |
|
1421 + } |
|
1422 + |
|
1423 + // Update Mozilla settings with any gconf settings that have |
|
1424 + // changed from the default. Do it before we register our |
|
1425 + // Mozilla notifications. |
|
1426 + ComplexGConfPrefChanged lastCallback = nsnull; |
|
1427 + for (i = 0; i < NUM_ELEM(sComplexGConfPrefMappings); ++i) { |
|
1428 + guint cx = gconf_client_notify_add(client, |
|
1429 + sComplexGConfPrefMappings[i].gconfPrefName, |
|
1430 + GConfComplexNotification, this, |
|
1431 + nsnull, nsnull); |
|
1432 + mGConfComplexCallbacks.Put(cx, &sComplexGConfPrefMappings[i]); |
|
1433 + ComplexGConfPrefChanged cb = sComplexGConfPrefMappings[i].callback; |
|
1434 + if (cb != lastCallback) { |
|
1435 + cb(this, client); |
|
1436 + lastCallback = cb; |
|
1437 + } |
|
1438 + } |
|
1439 + |
|
1440 + nsCOMPtr<nsIPrefBranch2> userPrefs = aPrefs->GetPrefUserBranch(); |
|
1441 + |
|
1442 + // Update gconf settings with any Mozilla settings that have |
|
1443 + // changed from the default. |
|
1444 + for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) { |
|
1445 + gconf_client_add_dir(client, sSimplePrefMappings[i].gconfPrefName, |
|
1446 + GCONF_CLIENT_PRELOAD_NONE, nsnull); |
|
1447 + |
|
1448 + PRBool hasUserPref = PR_FALSE; |
|
1449 + nsresult rv = |
|
1450 + userPrefs->PrefHasUserValue(sSimplePrefMappings[i].mozPrefName, |
|
1451 + &hasUserPref); |
|
1452 + if (NS_FAILED(rv)) |
|
1453 + return rv; |
|
1454 + if (hasUserPref && sSimplePrefMappings[i].allowWritesFromMozilla) { |
|
1455 + rv = ReverseApplySimpleMapping(&sSimplePrefMappings[i], |
|
1456 + aPrefs, client); |
|
1457 + if (NS_FAILED(rv)) |
|
1458 + return rv; |
|
1459 + } |
|
1460 + } |
|
1461 + for (i = 0; i < NUM_ELEM(sComplexGConfPrefMappings); ++i) { |
|
1462 + gconf_client_add_dir(client, sComplexGConfPrefMappings[i].gconfPrefName, |
|
1463 + GCONF_CLIENT_PRELOAD_NONE, nsnull); |
|
1464 + } |
|
1465 + ComplexMozPrefChanged lastMozCallback = nsnull; |
|
1466 + for (i = 0; i < NUM_ELEM(sComplexMozPrefMappings); ++i) { |
|
1467 + PRBool hasUserPref = PR_FALSE; |
|
1468 + nsresult rv = |
|
1469 + userPrefs->PrefHasUserValue(sComplexMozPrefMappings[i].mozPrefName, |
|
1470 + &hasUserPref); |
|
1471 + if (NS_FAILED(rv)) |
|
1472 + return rv; |
|
1473 + if (hasUserPref) { |
|
1474 + ComplexMozPrefChanged cb = sComplexMozPrefMappings[i].callback; |
|
1475 + if (cb != lastMozCallback) { |
|
1476 + cb(this, client); |
|
1477 + lastMozCallback = cb; |
|
1478 + } |
|
1479 + } |
|
1480 + } |
|
1481 + |
|
1482 + ApplyUnsafeProtocols(this, client); |
|
1483 + |
|
1484 + return NS_OK; |
|
1485 +} |
|
1486 + |
|
1487 +nsresult nsSystemPrefService::NotifyMozillaPrefChanged(const char* aPrefName) |
|
1488 +{ |
|
1489 + PRUint32 i; |
|
1490 + GConfClient* client = GetGConf(); |
|
1491 + |
|
1492 + for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) { |
|
1493 + if (!strcmp(aPrefName, sSimplePrefMappings[i].mozPrefName)) { |
|
1494 + ReverseApplySimpleMapping(&sSimplePrefMappings[i], |
|
1495 + mPref, client); |
|
1496 + } |
|
1497 + } |
|
1498 + |
|
1499 + for (i = 0; i < NUM_ELEM(sComplexMozPrefMappings); ++i) { |
|
1500 + if (!strcmp(aPrefName, sComplexMozPrefMappings[i].mozPrefName)) { |
|
1501 + sComplexMozPrefMappings[i].callback(this, client); |
|
1502 + } |
|
1503 + } |
|
1504 + |
|
1505 + for (i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) { |
|
1506 + if (!strcmp(aPrefName, windowOpenFeatures[i])) { |
|
1507 + ReverseApplyWindowOpen(this, client); |
|
1508 + } |
|
1509 + } |
|
1510 + |
|
1511 + ReverseApplyUnsafeProtocols(this, client); |
|
1512 + |
|
1513 + return NS_OK; |
|
1514 +} |
|
1515 + |
|
1516 +static PLDHashOperator PR_CALLBACK UnregisterSimple(const PRUint32& aKey, |
|
1517 + SimplePrefMapping* aData, |
|
1518 + void* aClosure) |
|
1519 +{ |
|
1520 + GConfClient* client = GetGConf(); |
|
1521 + gconf_client_notify_remove(client, aKey); |
|
1522 + gconf_client_remove_dir(client, aData->gconfPrefName, nsnull); |
|
1523 + return PL_DHASH_NEXT; |
|
1524 +} |
|
1525 + |
|
1526 +static PLDHashOperator PR_CALLBACK UnregisterComplex(const PRUint32& aKey, |
|
1527 + ComplexGConfPrefMapping* aData, |
|
1528 + void* aClosure) |
|
1529 +{ |
|
1530 + GConfClient* client = GetGConf(); |
|
1531 + gconf_client_notify_remove(client, aKey); |
|
1532 + gconf_client_remove_dir(client, aData->gconfPrefName, nsnull); |
|
1533 + return PL_DHASH_NEXT; |
|
1534 +} |
|
1535 + |
|
1536 +nsresult nsSystemPrefService::NotifyUnloadSystemPreferences() |
|
1537 +{ |
|
1538 + // Unregister callbacks |
|
1539 + mGConfSimpleCallbacks.EnumerateRead(UnregisterSimple, this); |
|
1540 + mGConfSimpleCallbacks.Clear(); |
|
1541 + mGConfComplexCallbacks.EnumerateRead(UnregisterComplex, this); |
|
1542 + mGConfComplexCallbacks.Clear(); |
|
1543 + |
|
1544 + return NS_OK; |
|
1545 +} |
|
1546 + |
|
1547 +// PrefBranch interfaces |
|
1548 + |
|
1549 +GConfValue* nsSystemPrefService::GConfGet(const char *aPrefName) |
|
1550 +{ |
|
1551 + PRUint32 i; |
|
1552 + PRBool found = PR_FALSE; |
|
1553 + GConfValue *val = NULL; |
|
1554 + GConfClient* client = GetGConf(); |
|
1555 + NS_ASSERTION(client, "Could not get default GConf client"); |
|
1556 + if (!client) { |
|
1557 + return NULL; |
|
1558 + } |
|
1559 + for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) { |
|
1560 + if (!strcmp(aPrefName, sSimplePrefMappings[i].mozPrefName)) { |
|
1561 + found = PR_TRUE; |
|
1562 + break; |
|
1563 + } |
|
1564 + } |
|
1565 + if (found) { |
|
1566 + val = gconf_client_get(client, |
|
1567 + sSimplePrefMappings[i].gconfPrefName, |
|
1568 + NULL); |
|
1569 + } |
|
1570 + return val; |
|
1571 +} |
|
1572 + |
|
1573 /* readonly attribute string root; */ |
|
1574 NS_IMETHODIMP nsSystemPrefService::GetRoot(char * *aRoot) |
|
1575 { |
|
1576 return NS_ERROR_NOT_IMPLEMENTED; |
|
1577 } |
|
1578 |
|
1579 /* long getPrefType (in string aPrefName); */ |
|
1580 NS_IMETHODIMP nsSystemPrefService::GetPrefType(const char *aPrefName, PRInt32 *_retval) |
|
1581 { |
|
1582 return NS_ERROR_NOT_IMPLEMENTED; |
|
1583 } |
|
1584 |
|
1585 /* boolean getBoolPref (in string aPrefName); */ |
|
1586 NS_IMETHODIMP nsSystemPrefService::GetBoolPref(const char *aPrefName, PRBool *_retval) |
|
1587 { |
|
1588 - return mInitialized ? |
|
1589 - mGConf->GetBoolPref(aPrefName, _retval) : NS_ERROR_FAILURE; |
|
1590 + GConfValue *val = GConfGet(aPrefName); |
|
1591 + if (val) { |
|
1592 + *_retval = (PRBool)(gconf_value_get_bool(val)); |
|
1593 + return NS_OK; |
|
1594 + } |
|
1595 + return NS_ERROR_FAILURE; |
|
1596 } |
|
1597 |
|
1598 /* void setBoolPref (in string aPrefName, in long aValue); */ |
|
1599 NS_IMETHODIMP nsSystemPrefService::SetBoolPref(const char *aPrefName, PRInt32 aValue) |
|
1600 { |
|
1601 return NS_ERROR_NOT_IMPLEMENTED; |
|
1602 } |
|
1603 |
|
1604 /* string getCharPref (in string aPrefName); */ |
|
1605 NS_IMETHODIMP nsSystemPrefService::GetCharPref(const char *aPrefName, char **_retval) |
|
1606 { |
|
1607 - return mInitialized ? |
|
1608 - mGConf->GetCharPref(aPrefName, _retval) : NS_ERROR_FAILURE; |
|
1609 + GConfValue *val = GConfGet(aPrefName); |
|
1610 + if (val) { |
|
1611 + *_retval = (char*)(gconf_value_get_string(val)); |
|
1612 + return *_retval ? NS_OK : NS_ERROR_FAILURE; |
|
1613 + } |
|
1614 + return NS_ERROR_FAILURE; |
|
1615 } |
|
1616 |
|
1617 /* void setCharPref (in string aPrefName, in string aValue); */ |
|
1618 NS_IMETHODIMP nsSystemPrefService::SetCharPref(const char *aPrefName, const char *aValue) |
|
1619 { |
|
1620 return NS_ERROR_NOT_IMPLEMENTED; |
|
1621 } |
|
1622 |
|
1623 /* long getIntPref (in string aPrefName); */ |
|
1624 NS_IMETHODIMP nsSystemPrefService::GetIntPref(const char *aPrefName, PRInt32 *_retval) |
|
1625 { |
|
1626 - return mInitialized ? |
|
1627 - mGConf->GetIntPref(aPrefName, _retval) : NS_ERROR_FAILURE; |
|
1628 + GConfValue *val = GConfGet(aPrefName); |
|
1629 + if (val) { |
|
1630 + *_retval = (PRInt32)(gconf_value_get_int(val)); |
|
1631 + return NS_OK; |
|
1632 + } |
|
1633 + return NS_ERROR_FAILURE; |
|
1634 } |
|
1635 |
|
1636 /* void setIntPref (in string aPrefName, in long aValue); */ |
|
1637 NS_IMETHODIMP nsSystemPrefService::SetIntPref(const char *aPrefName, PRInt32 aValue) |
|
1638 { |
|
1639 return NS_ERROR_NOT_IMPLEMENTED; |
|
1640 } |
|
1641 |
|
1642 -/* void getComplexValue (in string aPrefName, in nsIIDRef aType, [iid_is (aType), retval] out nsQIResult aValue); */ |
|
1643 +/* void getComplexValue (in string aPrefName, in nsIIDRef aType, [iid_is |
|
1644 + * (aType), retval] out nsQIResult aValue); */ |
|
1645 NS_IMETHODIMP nsSystemPrefService::GetComplexValue(const char *aPrefName, const nsIID & aType, void * *aValue) |
|
1646 { |
|
1647 return NS_ERROR_NOT_IMPLEMENTED; |
|
1648 } |
|
1649 - |
|
1650 -/* void setComplexValue (in string aPrefName, in nsIIDRef aType, in nsISupports aValue); */ |
|
1651 +/* void setComplexValue (in string aPrefName, in nsIIDRef aType, in |
|
1652 + * nsISupports aValue); */ |
|
1653 NS_IMETHODIMP nsSystemPrefService::SetComplexValue(const char *aPrefName, const nsIID & aType, nsISupports *aValue) |
|
1654 { |
|
1655 return NS_ERROR_NOT_IMPLEMENTED; |
|
1656 } |
|
1657 |
|
1658 /* void clearUserPref (in string aPrefName); */ |
|
1659 NS_IMETHODIMP nsSystemPrefService::ClearUserPref(const char *aPrefName) |
|
1660 { |
|
1661 @@ -360,557 +1363,36 @@ NS_IMETHODIMP nsSystemPrefService::Unloc |
|
1662 } |
|
1663 |
|
1664 /* void deleteBranch (in string aStartingAt); */ |
|
1665 NS_IMETHODIMP nsSystemPrefService::DeleteBranch(const char *aStartingAt) |
|
1666 { |
|
1667 return NS_ERROR_NOT_IMPLEMENTED; |
|
1668 } |
|
1669 |
|
1670 -/* void getChildList (in string aStartingAt, out unsigned long aCount, [array, size_is (aCount), retval] out string aChildArray); */ |
|
1671 +/* void getChildList (in string aStartingAt, out unsigned long aCount, [array, |
|
1672 + * size_is (aCount), retval] out string aChildArray); */ |
|
1673 NS_IMETHODIMP nsSystemPrefService::GetChildList(const char *aStartingAt, PRUint32 *aCount, char ***aChildArray) |
|
1674 { |
|
1675 return NS_ERROR_NOT_IMPLEMENTED; |
|
1676 } |
|
1677 |
|
1678 /* void resetBranch (in string aStartingAt); */ |
|
1679 NS_IMETHODIMP nsSystemPrefService::ResetBranch(const char *aStartingAt) |
|
1680 { |
|
1681 return NS_ERROR_NOT_IMPLEMENTED; |
|
1682 } |
|
1683 |
|
1684 -/* void addObserver (in string aDomain, in nsIObserver aObserver, in boolean aHoldWeak); */ |
|
1685 -NS_IMETHODIMP nsSystemPrefService::AddObserver(const char *aDomain, nsIObserver *aObserver, PRBool aHoldWeak) |
|
1686 -{ |
|
1687 - nsresult rv; |
|
1688 |
|
1689 - NS_ENSURE_ARG_POINTER(aDomain); |
|
1690 - NS_ENSURE_ARG_POINTER(aObserver); |
|
1691 +// Factory stuff |
|
1692 |
|
1693 - NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); |
|
1694 +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPrefService, Init) |
|
1695 |
|
1696 - PRUint32 prefAtom; |
|
1697 - // make sure the pref name is supported |
|
1698 - rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom); |
|
1699 - NS_ENSURE_SUCCESS(rv, rv); |
|
1700 - |
|
1701 - if (!mObservers) { |
|
1702 - mObservers = new nsAutoVoidArray(); |
|
1703 - if (mObservers == nsnull) |
|
1704 - return NS_ERROR_OUT_OF_MEMORY; |
|
1705 - } |
|
1706 - |
|
1707 - SysPrefCallbackData *pCallbackData = (SysPrefCallbackData *) |
|
1708 - nsMemory::Alloc(sizeof(SysPrefCallbackData)); |
|
1709 - if (pCallbackData == nsnull) |
|
1710 - return NS_ERROR_OUT_OF_MEMORY; |
|
1711 - |
|
1712 - pCallbackData->bIsWeakRef = aHoldWeak; |
|
1713 - pCallbackData->prefAtom = prefAtom; |
|
1714 - // hold a weak reference to the observer if so requested |
|
1715 - nsCOMPtr<nsISupports> observerRef; |
|
1716 - if (aHoldWeak) { |
|
1717 - nsCOMPtr<nsISupportsWeakReference> weakRefFactory = |
|
1718 - do_QueryInterface(aObserver); |
|
1719 - if (!weakRefFactory) { |
|
1720 - // the caller didn't give us a object that supports weak reference. |
|
1721 - // ... tell them |
|
1722 - nsMemory::Free(pCallbackData); |
|
1723 - return NS_ERROR_INVALID_ARG; |
|
1724 - } |
|
1725 - nsCOMPtr<nsIWeakReference> tmp = do_GetWeakReference(weakRefFactory); |
|
1726 - observerRef = tmp; |
|
1727 - } else { |
|
1728 - observerRef = aObserver; |
|
1729 - } |
|
1730 - |
|
1731 - rv = mGConf->NotifyAdd(prefAtom, pCallbackData); |
|
1732 - if (NS_FAILED(rv)) { |
|
1733 - nsMemory::Free(pCallbackData); |
|
1734 - return rv; |
|
1735 - } |
|
1736 - |
|
1737 - pCallbackData->observer = observerRef; |
|
1738 - NS_ADDREF(pCallbackData->observer); |
|
1739 - |
|
1740 - mObservers->AppendElement(pCallbackData); |
|
1741 - return NS_OK; |
|
1742 -} |
|
1743 - |
|
1744 -/* void removeObserver (in string aDomain, in nsIObserver aObserver); */ |
|
1745 -NS_IMETHODIMP nsSystemPrefService::RemoveObserver(const char *aDomain, nsIObserver *aObserver) |
|
1746 -{ |
|
1747 - nsresult rv; |
|
1748 - |
|
1749 - NS_ENSURE_ARG_POINTER(aDomain); |
|
1750 - NS_ENSURE_ARG_POINTER(aObserver); |
|
1751 - NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); |
|
1752 - |
|
1753 - if (!mObservers) |
|
1754 - return NS_OK; |
|
1755 - |
|
1756 - PRUint32 prefAtom; |
|
1757 - // make sure the pref name is supported |
|
1758 - rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom); |
|
1759 - NS_ENSURE_SUCCESS(rv, rv); |
|
1760 - |
|
1761 - // need to find the index of observer, so we can remove it |
|
1762 - PRIntn count = mObservers->Count(); |
|
1763 - if (count <= 0) |
|
1764 - return NS_OK; |
|
1765 - |
|
1766 - PRIntn i; |
|
1767 - SysPrefCallbackData *pCallbackData; |
|
1768 - for (i = 0; i < count; ++i) { |
|
1769 - pCallbackData = (SysPrefCallbackData *)mObservers->ElementAt(i); |
|
1770 - if (pCallbackData) { |
|
1771 - nsCOMPtr<nsISupports> observerRef; |
|
1772 - if (pCallbackData->bIsWeakRef) { |
|
1773 - nsCOMPtr<nsISupportsWeakReference> weakRefFactory = |
|
1774 - do_QueryInterface(aObserver); |
|
1775 - if (weakRefFactory) { |
|
1776 - nsCOMPtr<nsIWeakReference> tmp = |
|
1777 - do_GetWeakReference(aObserver); |
|
1778 - observerRef = tmp; |
|
1779 - } |
|
1780 - } |
|
1781 - if (!observerRef) |
|
1782 - observerRef = aObserver; |
|
1783 - |
|
1784 - if (pCallbackData->observer == observerRef && |
|
1785 - pCallbackData->prefAtom == prefAtom) { |
|
1786 - rv = mGConf->NotifyRemove(prefAtom, pCallbackData); |
|
1787 - if (NS_SUCCEEDED(rv)) { |
|
1788 - mObservers->RemoveElementAt(i); |
|
1789 - NS_RELEASE(pCallbackData->observer); |
|
1790 - nsMemory::Free(pCallbackData); |
|
1791 - } |
|
1792 - return rv; |
|
1793 - } |
|
1794 - } |
|
1795 - } |
|
1796 - return NS_OK; |
|
1797 -} |
|
1798 - |
|
1799 -void |
|
1800 -nsSystemPrefService::OnPrefChange(PRUint32 aPrefAtom, void *aData) |
|
1801 -{ |
|
1802 - if (!mInitialized) |
|
1803 - return; |
|
1804 - |
|
1805 - SysPrefCallbackData *pData = (SysPrefCallbackData *)aData; |
|
1806 - if (pData->prefAtom != aPrefAtom) |
|
1807 - return; |
|
1808 - |
|
1809 - nsCOMPtr<nsIObserver> observer; |
|
1810 - if (pData->bIsWeakRef) { |
|
1811 - nsCOMPtr<nsIWeakReference> weakRef = |
|
1812 - do_QueryInterface(pData->observer); |
|
1813 - if(weakRef) |
|
1814 - observer = do_QueryReferent(weakRef); |
|
1815 - if (!observer) { |
|
1816 - // this weak referenced observer went away, remove it from the list |
|
1817 - nsresult rv = mGConf->NotifyRemove(aPrefAtom, pData); |
|
1818 - if (NS_SUCCEEDED(rv)) { |
|
1819 - mObservers->RemoveElement(pData); |
|
1820 - NS_RELEASE(pData->observer); |
|
1821 - nsMemory::Free(pData); |
|
1822 - } |
|
1823 - return; |
|
1824 - } |
|
1825 - } |
|
1826 - else |
|
1827 - observer = do_QueryInterface(pData->observer); |
|
1828 - |
|
1829 - if (observer) |
|
1830 - observer->Observe(static_cast<nsIPrefBranch *>(this), |
|
1831 - NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID, |
|
1832 - NS_ConvertUTF8toUTF16(mGConf->GetMozKey(aPrefAtom)). |
|
1833 - get()); |
|
1834 -} |
|
1835 - |
|
1836 -/************************************************************* |
|
1837 - * GConfProxy |
|
1838 - * |
|
1839 - ************************************************************/ |
|
1840 - |
|
1841 -struct GConfFuncListType { |
|
1842 - const char *FuncName; |
|
1843 - PRFuncPtr FuncPtr; |
|
1844 +static const nsModuleComponentInfo components[] = { |
|
1845 + { NS_SYSTEMPREF_SERVICE_CLASSNAME, |
|
1846 + NS_SYSTEMPREF_SERVICE_CID, |
|
1847 + NS_SYSTEMPREF_SERVICE_CONTRACTID, |
|
1848 + nsSystemPrefServiceConstructor, |
|
1849 + }, |
|
1850 }; |
|
1851 |
|
1852 -struct PrefNamePair { |
|
1853 - const char *mozPrefName; |
|
1854 - const char *gconfPrefName; |
|
1855 -}; |
|
1856 +NS_IMPL_NSGETMODULE(nsSystemPrefServiceModule, components) |
|
1857 |
|
1858 -const char |
|
1859 -GConfProxy::sPrefGConfKey[] = "accessibility.unix.gconf2.shared-library"; |
|
1860 -const char GConfProxy::sDefaultLibName1[] = "libgconf-2.so.4"; |
|
1861 -const char GConfProxy::sDefaultLibName2[] = "libgconf-2.so"; |
|
1862 - |
|
1863 -#define GCONF_FUNCS_POINTER_BEGIN \ |
|
1864 - static GConfFuncListType sGConfFuncList[] = { |
|
1865 -#define GCONF_FUNCS_POINTER_ADD(func_name) \ |
|
1866 - {func_name, nsnull}, |
|
1867 -#define GCONF_FUNCS_POINTER_END \ |
|
1868 - {nsnull, nsnull}, }; |
|
1869 - |
|
1870 -GCONF_FUNCS_POINTER_BEGIN |
|
1871 - GCONF_FUNCS_POINTER_ADD("gconf_client_get_default") // 0 |
|
1872 - GCONF_FUNCS_POINTER_ADD("gconf_client_get_bool") // 1 |
|
1873 - GCONF_FUNCS_POINTER_ADD("gconf_client_get_string") //2 |
|
1874 - GCONF_FUNCS_POINTER_ADD("gconf_client_get_int") //3 |
|
1875 - GCONF_FUNCS_POINTER_ADD("gconf_client_notify_add") //4 |
|
1876 - GCONF_FUNCS_POINTER_ADD("gconf_client_notify_remove") //5 |
|
1877 - GCONF_FUNCS_POINTER_ADD("gconf_client_add_dir") //6 |
|
1878 - GCONF_FUNCS_POINTER_ADD("gconf_client_remove_dir") //7 |
|
1879 - GCONF_FUNCS_POINTER_ADD("gconf_entry_get_value") //8 |
|
1880 - GCONF_FUNCS_POINTER_ADD("gconf_entry_get_key") //9 |
|
1881 - GCONF_FUNCS_POINTER_ADD("gconf_value_get_bool") //10 |
|
1882 - GCONF_FUNCS_POINTER_ADD("gconf_value_get_string") //11 |
|
1883 - GCONF_FUNCS_POINTER_ADD("gconf_value_get_int") //12 |
|
1884 - GCONF_FUNCS_POINTER_ADD("gconf_client_get_list") //13 |
|
1885 -GCONF_FUNCS_POINTER_END |
|
1886 - |
|
1887 -///////////////////////////////////////////////////////////////////////////// |
|
1888 -// the list is the mapping table, between mozilla prefs and gconf prefs |
|
1889 -// It is expected to include all the pref pairs that are related in mozilla |
|
1890 -// and gconf. |
|
1891 -// |
|
1892 -// Note: the prefs listed here are not neccessarily be read from gconf, they |
|
1893 -// are the prefs that could be read from gconf. Mozilla has another |
|
1894 -// list (see sSysPrefList in nsSystemPref.cpp) that decide which prefs |
|
1895 -// are really read. |
|
1896 -////////////////////////////////////////////////////////////////////////////// |
|
1897 - |
|
1898 -static const PrefNamePair sPrefNameMapping[] = { |
|
1899 -#include "gconf_pref_list.inc" |
|
1900 - {nsnull, nsnull}, |
|
1901 -}; |
|
1902 - |
|
1903 -PRBool |
|
1904 -gconfDeleteObserver(void *aElement, void *aData) { |
|
1905 - nsMemory::Free(aElement); |
|
1906 - return PR_TRUE; |
|
1907 -} |
|
1908 - |
|
1909 -GConfProxy::GConfProxy(nsSystemPrefService *aSysPrefService): |
|
1910 - mGConfClient(nsnull), |
|
1911 - mGConfLib(nsnull), |
|
1912 - mInitialized(PR_FALSE), |
|
1913 - mSysPrefService(aSysPrefService), |
|
1914 - mObservers(nsnull) |
|
1915 -{ |
|
1916 -} |
|
1917 - |
|
1918 -GConfProxy::~GConfProxy() |
|
1919 -{ |
|
1920 - if (mGConfClient) |
|
1921 - g_object_unref(G_OBJECT(mGConfClient)); |
|
1922 - |
|
1923 - if (mObservers) { |
|
1924 - (void)mObservers->EnumerateForwards(gconfDeleteObserver, nsnull); |
|
1925 - delete mObservers; |
|
1926 - } |
|
1927 - |
|
1928 - // bug 379666: can't unload GConf-2 since it registers atexit handlers |
|
1929 - //PR_UnloadLibrary(mGConfLib); |
|
1930 -} |
|
1931 - |
|
1932 -PRBool |
|
1933 -GConfProxy::Init() |
|
1934 -{ |
|
1935 - SYSPREF_LOG(("GConfProxy:: Init GConfProxy\n")); |
|
1936 - if (!mSysPrefService) |
|
1937 - return PR_FALSE; |
|
1938 - if (mInitialized) |
|
1939 - return PR_TRUE; |
|
1940 - |
|
1941 - nsCOMPtr<nsIPrefBranch> pref = do_GetService(NS_PREFSERVICE_CONTRACTID); |
|
1942 - |
|
1943 - if (!pref) |
|
1944 - return PR_FALSE; |
|
1945 - |
|
1946 - nsXPIDLCString gconfLibName; |
|
1947 - nsresult rv; |
|
1948 - |
|
1949 - //check if gconf-2 library is given in prefs |
|
1950 - rv = pref->GetCharPref(sPrefGConfKey, getter_Copies(gconfLibName)); |
|
1951 - if (NS_SUCCEEDED(rv)) { |
|
1952 - //use the library name in the preference |
|
1953 - SYSPREF_LOG(("GConf library in prefs is %s\n", gconfLibName.get())); |
|
1954 - mGConfLib = PR_LoadLibrary(gconfLibName.get()); |
|
1955 - } |
|
1956 - else { |
|
1957 - SYSPREF_LOG(("GConf library not specified in prefs, try the default: " |
|
1958 - "%s and %s\n", sDefaultLibName1, sDefaultLibName2)); |
|
1959 - mGConfLib = PR_LoadLibrary(sDefaultLibName1); |
|
1960 - if (!mGConfLib) |
|
1961 - mGConfLib = PR_LoadLibrary(sDefaultLibName2); |
|
1962 - } |
|
1963 - |
|
1964 - if (!mGConfLib) { |
|
1965 - SYSPREF_LOG(("Fail to load GConf library\n")); |
|
1966 - return PR_FALSE; |
|
1967 - } |
|
1968 - |
|
1969 - //check every func we need in the gconf library |
|
1970 - GConfFuncListType *funcList; |
|
1971 - PRFuncPtr func; |
|
1972 - for (funcList = sGConfFuncList; funcList->FuncName; ++funcList) { |
|
1973 - func = PR_FindFunctionSymbol(mGConfLib, funcList->FuncName); |
|
1974 - if (!func) { |
|
1975 - SYSPREF_LOG(("Check GConf Func Error: %s", funcList->FuncName)); |
|
1976 - goto init_failed_unload; |
|
1977 - } |
|
1978 - funcList->FuncPtr = func; |
|
1979 - } |
|
1980 - |
|
1981 - InitFuncPtrs(); |
|
1982 - |
|
1983 - mGConfClient = GConfClientGetDefault(); |
|
1984 - |
|
1985 - // Don't unload past this point, since GConf's initialization of ORBit |
|
1986 - // causes atexit handlers to be registered. |
|
1987 - |
|
1988 - if (!mGConfClient) { |
|
1989 - SYSPREF_LOG(("Fail to Get default gconf client\n")); |
|
1990 - goto init_failed; |
|
1991 - } |
|
1992 - mInitialized = PR_TRUE; |
|
1993 - return PR_TRUE; |
|
1994 - |
|
1995 - init_failed_unload: |
|
1996 - PR_UnloadLibrary(mGConfLib); |
|
1997 - init_failed: |
|
1998 - mGConfLib = nsnull; |
|
1999 - return PR_FALSE; |
|
2000 -} |
|
2001 - |
|
2002 -nsresult |
|
2003 -GConfProxy::GetBoolPref(const char *aMozKey, PRBool *retval) |
|
2004 -{ |
|
2005 - NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); |
|
2006 - *retval = GConfClientGetBool(mGConfClient, MozKey2GConfKey(aMozKey), NULL); |
|
2007 - return NS_OK; |
|
2008 -} |
|
2009 - |
|
2010 -nsresult |
|
2011 -GConfProxy::GetCharPref(const char *aMozKey, char **retval) |
|
2012 -{ |
|
2013 - NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); |
|
2014 - |
|
2015 - const gchar *gconfkey = MozKey2GConfKey(aMozKey); |
|
2016 - |
|
2017 - if (!strcmp (aMozKey, "network.proxy.no_proxies_on")) { |
|
2018 - GSList *s; |
|
2019 - nsCString noproxy; |
|
2020 - GSList *gslist = GConfClientGetList(mGConfClient, gconfkey, |
|
2021 - GCONF_VALUE_STRING, NULL); |
|
2022 - |
|
2023 - for (s = gslist; s; s = g_slist_next(s)) { |
|
2024 - noproxy += (char *)s->data; |
|
2025 - noproxy += ", "; |
|
2026 - g_free ((char *)s->data); |
|
2027 - } |
|
2028 - g_slist_free (gslist); |
|
2029 - |
|
2030 - *retval = PL_strdup(noproxy.get()); |
|
2031 - } else { |
|
2032 - gchar *str = GConfClientGetString(mGConfClient, gconfkey, NULL); |
|
2033 - if (str) { |
|
2034 - *retval = PL_strdup(str); |
|
2035 - g_free (str); |
|
2036 - } |
|
2037 - } |
|
2038 - |
|
2039 - return NS_OK; |
|
2040 -} |
|
2041 - |
|
2042 -nsresult |
|
2043 -GConfProxy::GetIntPref(const char *aMozKey, PRInt32 *retval) |
|
2044 -{ |
|
2045 - NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); |
|
2046 - if (strcmp (aMozKey, "network.proxy.type") == 0) { |
|
2047 - gchar *str; |
|
2048 - |
|
2049 - str = GConfClientGetString(mGConfClient, |
|
2050 - MozKey2GConfKey (aMozKey), NULL); |
|
2051 - |
|
2052 - if (str) { |
|
2053 - if (strcmp (str, "manual") == 0) |
|
2054 - *retval = 1; |
|
2055 - else if (strcmp (str, "auto") == 0) |
|
2056 - *retval = 2; |
|
2057 - else |
|
2058 - *retval = 0; |
|
2059 - |
|
2060 - g_free (str); |
|
2061 - } else |
|
2062 - *retval = 0; |
|
2063 - } else { |
|
2064 - *retval = GConfClientGetInt(mGConfClient, |
|
2065 - MozKey2GConfKey(aMozKey), NULL); |
|
2066 - } |
|
2067 - |
|
2068 - return NS_OK; |
|
2069 -} |
|
2070 - |
|
2071 -nsresult |
|
2072 -GConfProxy::NotifyAdd (PRUint32 aAtom, void *aUserData) |
|
2073 -{ |
|
2074 - NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); |
|
2075 - |
|
2076 - const char *gconfKey = GetGConfKey(aAtom); |
|
2077 - if (!gconfKey) |
|
2078 - return NS_ERROR_FAILURE; |
|
2079 - |
|
2080 - if (!mObservers) { |
|
2081 - mObservers = new nsAutoVoidArray(); |
|
2082 - if (mObservers == nsnull) |
|
2083 - return NS_ERROR_OUT_OF_MEMORY; |
|
2084 - } |
|
2085 - |
|
2086 - GConfCallbackData *pData = (GConfCallbackData *) |
|
2087 - nsMemory::Alloc(sizeof(GConfCallbackData)); |
|
2088 - NS_ENSURE_TRUE(pData, NS_ERROR_OUT_OF_MEMORY); |
|
2089 - |
|
2090 - pData->proxy = this; |
|
2091 - pData->userData = aUserData; |
|
2092 - pData->atom = aAtom; |
|
2093 - mObservers->AppendElement(pData); |
|
2094 - |
|
2095 - GConfClientAddDir(mGConfClient, gconfKey, |
|
2096 - 0, // GCONF_CLIENT_PRELOAD_NONE, don't preload anything |
|
2097 - NULL); |
|
2098 - |
|
2099 - pData->notifyId = GConfClientNotifyAdd(mGConfClient, gconfKey, |
|
2100 - gconf_key_listener, pData, |
|
2101 - NULL, NULL); |
|
2102 - return NS_OK; |
|
2103 -} |
|
2104 - |
|
2105 -nsresult |
|
2106 -GConfProxy::NotifyRemove (PRUint32 aAtom, const void *aUserData) |
|
2107 -{ |
|
2108 - NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); |
|
2109 - |
|
2110 - PRIntn count = mObservers->Count(); |
|
2111 - if (count <= 0) |
|
2112 - return NS_OK; |
|
2113 - |
|
2114 - PRIntn i; |
|
2115 - GConfCallbackData *pData; |
|
2116 - for (i = 0; i < count; ++i) { |
|
2117 - pData = (GConfCallbackData *)mObservers->ElementAt(i); |
|
2118 - if (pData && pData->atom == aAtom && pData->userData == aUserData) { |
|
2119 - GConfClientNotifyRemove(mGConfClient, pData->notifyId); |
|
2120 - GConfClientRemoveDir(mGConfClient, |
|
2121 - GetGConfKey(pData->atom), NULL); |
|
2122 - mObservers->RemoveElementAt(i); |
|
2123 - nsMemory::Free(pData); |
|
2124 - break; |
|
2125 - } |
|
2126 - } |
|
2127 - return NS_OK; |
|
2128 -} |
|
2129 - |
|
2130 -void |
|
2131 -GConfProxy::InitFuncPtrs() |
|
2132 -{ |
|
2133 - //gconf client funcs |
|
2134 - GConfClientGetDefault = |
|
2135 - (GConfClientGetDefaultType) sGConfFuncList[0].FuncPtr; |
|
2136 - GConfClientGetBool = |
|
2137 - (GConfClientGetBoolType) sGConfFuncList[1].FuncPtr; |
|
2138 - GConfClientGetString = |
|
2139 - (GConfClientGetStringType) sGConfFuncList[2].FuncPtr; |
|
2140 - GConfClientGetInt = |
|
2141 - (GConfClientGetIntType) sGConfFuncList[3].FuncPtr; |
|
2142 - GConfClientNotifyAdd = |
|
2143 - (GConfClientNotifyAddType) sGConfFuncList[4].FuncPtr; |
|
2144 - GConfClientNotifyRemove = |
|
2145 - (GConfClientNotifyRemoveType) sGConfFuncList[5].FuncPtr; |
|
2146 - GConfClientAddDir = |
|
2147 - (GConfClientAddDirType) sGConfFuncList[6].FuncPtr; |
|
2148 - GConfClientRemoveDir = |
|
2149 - (GConfClientRemoveDirType) sGConfFuncList[7].FuncPtr; |
|
2150 - |
|
2151 - //gconf entry funcs |
|
2152 - GConfEntryGetValue = (GConfEntryGetValueType) sGConfFuncList[8].FuncPtr; |
|
2153 - GConfEntryGetKey = (GConfEntryGetKeyType) sGConfFuncList[9].FuncPtr; |
|
2154 - |
|
2155 - //gconf value funcs |
|
2156 - GConfValueGetBool = (GConfValueGetBoolType) sGConfFuncList[10].FuncPtr; |
|
2157 - GConfValueGetString = (GConfValueGetStringType) sGConfFuncList[11].FuncPtr; |
|
2158 - GConfValueGetInt = (GConfValueGetIntType) sGConfFuncList[12].FuncPtr; |
|
2159 - |
|
2160 - //gconf client list func |
|
2161 - GConfClientGetList = |
|
2162 - (GConfClientGetListType) sGConfFuncList[13].FuncPtr; |
|
2163 -} |
|
2164 - |
|
2165 -void |
|
2166 -GConfProxy::OnNotify(void *aClient, void * aEntry, PRUint32 aNotifyId, |
|
2167 - GConfCallbackData *aData) |
|
2168 -{ |
|
2169 - if (!mInitialized || !aEntry || (mGConfClient != aClient) || !aData) |
|
2170 - return; |
|
2171 - |
|
2172 - if (GConfEntryGetValue(aEntry) == NULL) |
|
2173 - return; |
|
2174 - |
|
2175 - PRUint32 prefAtom; |
|
2176 - nsresult rv = GetAtomForGConfKey(GConfEntryGetKey(aEntry), &prefAtom); |
|
2177 - if (NS_FAILED(rv)) |
|
2178 - return; |
|
2179 - |
|
2180 - mSysPrefService->OnPrefChange(prefAtom, aData->userData); |
|
2181 -} |
|
2182 - |
|
2183 -nsresult |
|
2184 -GConfProxy::GetAtom(const char *aKey, PRUint8 aNameType, PRUint32 *aAtom) |
|
2185 -{ |
|
2186 - if (!aKey) |
|
2187 - return NS_ERROR_FAILURE; |
|
2188 - PRUint32 prefSize = sizeof(sPrefNameMapping) / sizeof(sPrefNameMapping[0]); |
|
2189 - for (PRUint32 index = 0; index < prefSize; ++index) { |
|
2190 - if (!strcmp((aNameType == 0) ? sPrefNameMapping[index].mozPrefName : |
|
2191 - sPrefNameMapping[index].gconfPrefName, aKey)) { |
|
2192 - *aAtom = index; |
|
2193 - return NS_OK; |
|
2194 - } |
|
2195 - } |
|
2196 - return NS_ERROR_FAILURE; |
|
2197 -} |
|
2198 - |
|
2199 -const char * |
|
2200 -GConfProxy::GetKey(PRUint32 aAtom, PRUint8 aNameType) |
|
2201 -{ |
|
2202 - PRUint32 mapSize = sizeof(sPrefNameMapping) / sizeof(sPrefNameMapping[0]); |
|
2203 - if (aAtom >= 0 && aAtom < mapSize) |
|
2204 - return (aNameType == 0) ? sPrefNameMapping[aAtom].mozPrefName : |
|
2205 - sPrefNameMapping[aAtom].gconfPrefName; |
|
2206 - return NULL; |
|
2207 -} |
|
2208 - |
|
2209 -inline const char * |
|
2210 -GConfProxy::MozKey2GConfKey(const char *aMozKey) |
|
2211 -{ |
|
2212 - PRUint32 atom; |
|
2213 - nsresult rv = GetAtomForMozKey(aMozKey, &atom); |
|
2214 - if (NS_SUCCEEDED(rv)) |
|
2215 - return GetGConfKey(atom); |
|
2216 - return NULL; |
|
2217 -} |
|
2218 - |
|
2219 -/* static */ |
|
2220 -void gconf_key_listener (void* client, guint cnxn_id, |
|
2221 - void *entry, gpointer user_data) |
|
2222 -{ |
|
2223 - SYSPREF_LOG(("...SYSPREF_LOG...key listener get called \n")); |
|
2224 - if (!user_data) |
|
2225 - return; |
|
2226 - GConfCallbackData *pData = reinterpret_cast<GConfCallbackData *> |
|
2227 - (user_data); |
|
2228 - pData->proxy->OnNotify(client, entry, cnxn_id, pData); |
|
2229 -} |
|
2230 diff --git a/extensions/pref/system-pref/src/nsISystemPrefService.h b/extensions/pref/system-pref/src/nsISystemPrefService.h |
|
2231 new file mode 100644 |
|
2232 --- /dev/null |
|
2233 +++ b/extensions/pref/system-pref/src/nsISystemPrefService.h |
|
2234 @@ -0,0 +1,107 @@ |
|
2235 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2236 +/* vim:expandtab:shiftwidth=4:tabstop=4: |
|
2237 + */ |
|
2238 +/* ***** BEGIN LICENSE BLOCK ***** |
|
2239 + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
|
2240 + * |
|
2241 + * |
|
2242 + * The contents of this file are subject to the Mozilla Public |
|
2243 + * License Version 1.1 (the "License"); you may not use this file |
|
2244 + * except in compliance with the License. You may obtain a copy of |
|
2245 + * the License at http://www.mozilla.org/MPL/ |
|
2246 + * |
|
2247 + * Software distributed under the License is distributed on an "AS |
|
2248 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
|
2249 + * implied. See the License for the specific language governing |
|
2250 + * rights and limitations under the License. |
|
2251 + * |
|
2252 + * The Original Code is mozilla.org code. |
|
2253 + * |
|
2254 + * The Initial Developer of the Original Code is Novell |
|
2255 + * Portions created by Novell are Copyright (C) 2005 Novell, |
|
2256 + * All Rights Reserved. |
|
2257 + * |
|
2258 + * Original Author: Robert O'Callahan (rocallahan@novell.com) |
|
2259 + * |
|
2260 + * Contributor(s): |
|
2261 + * |
|
2262 + * Alternatively, the contents of this file may be used under the terms of |
|
2263 + * either the GNU General Public License Version 2 or later (the "GPL"), or |
|
2264 + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|
2265 + * in which case the provisions of the GPL or the LGPL are applicable instead |
|
2266 + * of those above. If you wish to allow use of your version of this file only |
|
2267 + * under the terms of either the GPL or the LGPL, and not to allow others to |
|
2268 + * use your version of this file under the terms of the NPL, indicate your |
|
2269 + * decision by deleting the provisions above and replace them with the notice |
|
2270 + * and other provisions required by the GPL or the LGPL. If you do not delete |
|
2271 + * the provisions above, a recipient may use your version of this file under |
|
2272 + * the terms of any one of the NPL, the GPL or the LGPL. |
|
2273 + * |
|
2274 + * ***** END LICENSE BLOCK ***** */ |
|
2275 + |
|
2276 +#ifndef nsISystemPrefService_h__ |
|
2277 +#define nsISystemPrefService_h__ |
|
2278 + |
|
2279 +#include "nsCOMPtr.h" |
|
2280 +#include "nsIPrefBranchInternal.h" |
|
2281 + |
|
2282 +#define NS_SYSTEMPREF_SERVICE_CONTRACTID "@mozilla.org/system-preference-service;1" |
|
2283 + |
|
2284 +#define NS_ISYSTEMPREFSERVICE_IID \ |
|
2285 +{ 0x006e1cfd, 0xd66a, 0x40b9, \ |
|
2286 + { 0x84, 0xa1, 0x84, 0xf3, 0xe6, 0xa2, 0xca, 0xbc } } |
|
2287 + |
|
2288 +class nsISystemPref { |
|
2289 +public: |
|
2290 + /** |
|
2291 + * Call one of these three methods to override a Mozilla |
|
2292 + * preference with a system value. You can call it multiple |
|
2293 + * times to change the value of a given preference to track |
|
2294 + * the underlying system value. |
|
2295 + * |
|
2296 + * If aLocked is true then we set the default preference and |
|
2297 + * lock it so the user value is ignored. If aLocked is false |
|
2298 + * then we unlock the Mozilla preference and set the Mozilla |
|
2299 + * user value. |
|
2300 + */ |
|
2301 + virtual nsresult SetOverridingMozillaBoolPref(const char* aPrefName, |
|
2302 + PRBool aValue, PRBool aLocked, |
|
2303 + PRBool aPresent = PR_TRUE) = 0; |
|
2304 + virtual nsresult SetOverridingMozillaIntPref(const char* aPrefName, |
|
2305 + PRInt32 aValue, PRBool aLocked, |
|
2306 + PRBool aPresent = PR_TRUE) = 0; |
|
2307 + virtual nsresult SetOverridingMozillaStringPref(const char* aPrefName, |
|
2308 + const char* aValue, PRBool aLocked, |
|
2309 + PRBool aPresent = PR_TRUE) = 0; |
|
2310 + virtual nsresult StopOverridingMozillaPref(const char* aPrefName) = 0; |
|
2311 + virtual already_AddRefed<nsIPrefBranch2> GetPrefUserBranch() = 0; |
|
2312 + virtual already_AddRefed<nsIPrefBranch> GetPrefDefaultBranch() = 0; |
|
2313 +}; |
|
2314 + |
|
2315 +class nsISystemPrefService : public nsISupports { |
|
2316 +public: |
|
2317 + NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISYSTEMPREFSERVICE_IID) |
|
2318 + |
|
2319 + /** |
|
2320 + * Load the system prefs from the store into their corresponding |
|
2321 + * Mozilla prefs, calling SetOverridingMozillaPref on each |
|
2322 + * such pref. |
|
2323 + */ |
|
2324 + virtual nsresult LoadSystemPreferences(nsISystemPref* aPrefs) = 0; |
|
2325 + |
|
2326 + /** |
|
2327 + * Notify that a Mozilla user pref that is being overridden by the |
|
2328 + * store has changed. The new value of the Mozilla pref should be |
|
2329 + * written back to the store. |
|
2330 + */ |
|
2331 + virtual nsresult NotifyMozillaPrefChanged(const char* aPrefName) = 0; |
|
2332 + |
|
2333 + /** |
|
2334 + * Notify that we're about to stop using the system prefs. After |
|
2335 + * this, nsSystemPref will automatically stop overriding all |
|
2336 + * Mozilla prefs that are being overridden. |
|
2337 + */ |
|
2338 + virtual nsresult NotifyUnloadSystemPreferences() = 0; |
|
2339 +}; |
|
2340 + |
|
2341 +#endif |
|
2342 diff --git a/extensions/pref/system-pref/src/nsSystemPref.cpp b/extensions/pref/system-pref/src/nsSystemPref.cpp |
|
2343 --- a/extensions/pref/system-pref/src/nsSystemPref.cpp |
|
2344 +++ b/extensions/pref/system-pref/src/nsSystemPref.cpp |
|
2345 @@ -19,16 +19,17 @@ |
|
2346 * |
|
2347 * The Initial Developer of the Original Code is Sun Microsystems, Inc. |
|
2348 * Portions created by Sun Microsystems are Copyright (C) 2003 Sun |
|
2349 * Microsystems, Inc. All Rights Reserved. |
|
2350 * |
|
2351 * Original Author: Bolian Yin (bolian.yin@sun.com) |
|
2352 * |
|
2353 * Contributor(s): |
|
2354 + * Robert O'Callahan (rocallahan@novell.com) |
|
2355 * |
|
2356 * Alternatively, the contents of this file may be used under the terms of |
|
2357 * either the GNU General Public License Version 2 or later (the "GPL"), or |
|
2358 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|
2359 * in which case the provisions of the GPL or the LGPL are applicable instead |
|
2360 * of those above. If you wish to allow use of your version of this file only |
|
2361 * under the terms of either the GPL or the LGPL, and not to allow others to |
|
2362 * use your version of this file under the terms of the NPL, indicate your |
|
2363 @@ -36,76 +37,72 @@ |
|
2364 * and other provisions required by the GPL or the LGPL. If you do not delete |
|
2365 * the provisions above, a recipient may use your version of this file under |
|
2366 * the terms of any one of the NPL, the GPL or the LGPL. |
|
2367 * |
|
2368 * ***** END LICENSE BLOCK ***** */ |
|
2369 |
|
2370 #include "nsSystemPref.h" |
|
2371 #include "nsIObserverService.h" |
|
2372 +#include "nsIAppStartupNotifier.h" |
|
2373 +#include "nsIPrefService.h" |
|
2374 +#include "nsIPrefBranch.h" |
|
2375 +#include "nsICategoryManager.h" |
|
2376 +#include "nsIServiceManager.h" |
|
2377 |
|
2378 #include "nsSystemPrefLog.h" |
|
2379 -#include "nsSystemPrefService.h" |
|
2380 #include "nsString.h" |
|
2381 |
|
2382 -const char sSysPrefString[] = "config.use_system_prefs"; |
|
2383 -union MozPrefValue { |
|
2384 - char * stringVal; |
|
2385 - PRInt32 intVal; |
|
2386 - PRBool boolVal; |
|
2387 -}; |
|
2388 +#include <stdlib.h> |
|
2389 |
|
2390 struct SysPrefItem { |
|
2391 - const char *prefName; // mozilla pref string name |
|
2392 - MozPrefValue defaultValue; // store the mozilla default value |
|
2393 - PRBool isLocked; // store the mozilla lock status |
|
2394 + // Saved values on both branches |
|
2395 + PRInt32 savedUserValueScalar; |
|
2396 + char* savedUserValueString; |
|
2397 + PRInt32 savedDefaultValueScalar; |
|
2398 + char* savedDefaultValueString; |
|
2399 + // When this is true, then the value was locked originally |
|
2400 + PRPackedBool savedLocked; |
|
2401 + // When this is true, then there was a user value |
|
2402 + PRPackedBool savedUserPresent; |
|
2403 + PRPackedBool ignore; |
|
2404 + |
|
2405 SysPrefItem() { |
|
2406 - prefName = nsnull; |
|
2407 - defaultValue.intVal = 0; |
|
2408 - defaultValue.stringVal = nsnull; |
|
2409 - defaultValue.boolVal = PR_FALSE; |
|
2410 - isLocked = PR_FALSE; |
|
2411 + savedUserValueScalar = 0; |
|
2412 + savedUserValueString = nsnull; |
|
2413 + savedDefaultValueScalar = 0; |
|
2414 + savedDefaultValueString = nsnull; |
|
2415 + savedUserPresent = PR_FALSE; |
|
2416 + savedLocked = PR_FALSE; |
|
2417 + ignore = PR_FALSE; |
|
2418 } |
|
2419 - void SetPrefName(const char *aPrefName) { |
|
2420 - prefName = aPrefName; |
|
2421 + |
|
2422 + virtual ~SysPrefItem() { |
|
2423 + nsMemory::Free(savedUserValueString); |
|
2424 + nsMemory::Free(savedDefaultValueString); |
|
2425 } |
|
2426 }; |
|
2427 |
|
2428 -// all prefs that mozilla need to read from host system if they are available |
|
2429 -static const char *sSysPrefList[] = { |
|
2430 - "network.proxy.http", |
|
2431 - "network.proxy.http_port", |
|
2432 - "network.proxy.ftp", |
|
2433 - "network.proxy.ftp_port", |
|
2434 - "network.proxy.ssl", |
|
2435 - "network.proxy.ssl_port", |
|
2436 - "network.proxy.socks", |
|
2437 - "network.proxy.socks_port", |
|
2438 - "network.proxy.no_proxies_on", |
|
2439 - "network.proxy.autoconfig_url", |
|
2440 - "network.proxy.type", |
|
2441 - "config.use_system_prefs.accessibility", |
|
2442 -}; |
|
2443 +NS_DEFINE_STATIC_IID_ACCESSOR(nsISystemPrefService, NS_ISYSTEMPREFSERVICE_IID) |
|
2444 + |
|
2445 +static const char sSysPrefString[] = "config.use_system_prefs"; |
|
2446 |
|
2447 PRLogModuleInfo *gSysPrefLog = NULL; |
|
2448 |
|
2449 NS_IMPL_ISUPPORTS2(nsSystemPref, nsIObserver, nsISupportsWeakReference) |
|
2450 |
|
2451 -nsSystemPref::nsSystemPref(): |
|
2452 - mSysPrefService(nsnull), |
|
2453 - mEnabled(PR_FALSE), |
|
2454 - mSysPrefs(nsnull) |
|
2455 +nsSystemPref::nsSystemPref() : mIgnorePrefSetting(PR_FALSE) |
|
2456 { |
|
2457 + mSavedPrefs.Init(); |
|
2458 + mCachedUserPrefBranch = nsnull; |
|
2459 + mCachedDefaultPrefBranch = nsnull; |
|
2460 } |
|
2461 |
|
2462 nsSystemPref::~nsSystemPref() |
|
2463 { |
|
2464 - mSysPrefService = nsnull; |
|
2465 - mEnabled = PR_FALSE; |
|
2466 - delete [] mSysPrefs; |
|
2467 } |
|
2468 |
|
2469 /////////////////////////////////////////////////////////////////////////////// |
|
2470 // nsSystemPref::Init |
|
2471 // Setup log and listen on NS_PREFSERVICE_READ_TOPIC_ID from pref service |
|
2472 /////////////////////////////////////////////////////////////////////////////// |
|
2473 nsresult |
|
2474 nsSystemPref::Init(void) |
|
2475 @@ -126,349 +123,519 @@ nsSystemPref::Init(void) |
|
2476 PR_FALSE); |
|
2477 rv = observerService->AddObserver(this, "profile-before-change", |
|
2478 PR_FALSE); |
|
2479 SYSPREF_LOG(("Add Observer for %s\n", NS_PREFSERVICE_READ_TOPIC_ID)); |
|
2480 } |
|
2481 return(rv); |
|
2482 } |
|
2483 |
|
2484 +already_AddRefed<nsIPrefBranch2> |
|
2485 +nsSystemPref::GetPrefUserBranch() |
|
2486 +{ |
|
2487 + if (mCachedUserPrefBranch) { |
|
2488 + NS_ADDREF(mCachedUserPrefBranch); |
|
2489 + return mCachedUserPrefBranch; |
|
2490 + } |
|
2491 + |
|
2492 + nsresult rv; |
|
2493 + nsCOMPtr<nsIPrefService> prefService = |
|
2494 + do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); |
|
2495 + if (NS_FAILED(rv)) |
|
2496 + return nsnull; |
|
2497 + nsCOMPtr<nsIPrefBranch> prefBranch; |
|
2498 + rv = prefService->GetBranch(nsnull, getter_AddRefs(prefBranch)); |
|
2499 + if (NS_FAILED(rv)) |
|
2500 + return nsnull; |
|
2501 + nsCOMPtr<nsIPrefBranch2> pb2(do_QueryInterface(prefBranch)); |
|
2502 + if (!pb2) |
|
2503 + return nsnull; |
|
2504 + |
|
2505 + nsIPrefBranch2* result = nsnull; |
|
2506 + pb2.swap(result); |
|
2507 + return result; |
|
2508 +} |
|
2509 + |
|
2510 +already_AddRefed<nsIPrefBranch> |
|
2511 +nsSystemPref::GetPrefDefaultBranch() |
|
2512 +{ |
|
2513 + if (mCachedDefaultPrefBranch) { |
|
2514 + NS_ADDREF(mCachedDefaultPrefBranch); |
|
2515 + return mCachedDefaultPrefBranch; |
|
2516 + } |
|
2517 + |
|
2518 + nsresult rv; |
|
2519 + nsCOMPtr<nsIPrefService> prefService = |
|
2520 + do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); |
|
2521 + if (NS_FAILED(rv)) |
|
2522 + return nsnull; |
|
2523 + nsCOMPtr<nsIPrefBranch> prefBranch; |
|
2524 + rv = prefService->GetDefaultBranch(nsnull, getter_AddRefs(prefBranch)); |
|
2525 + if (NS_FAILED(rv)) |
|
2526 + return nsnull; |
|
2527 + nsIPrefBranch* pb = nsnull; |
|
2528 + prefBranch.swap(pb); |
|
2529 + return pb; |
|
2530 +} |
|
2531 + |
|
2532 /////////////////////////////////////////////////////////////////////////////// |
|
2533 // nsSystemPref::Observe |
|
2534 // Observe notifications from mozilla pref system and system prefs (if enabled) |
|
2535 /////////////////////////////////////////////////////////////////////////////// |
|
2536 NS_IMETHODIMP |
|
2537 nsSystemPref::Observe(nsISupports *aSubject, |
|
2538 const char *aTopic, |
|
2539 const PRUnichar *aData) |
|
2540 { |
|
2541 nsresult rv = NS_OK; |
|
2542 |
|
2543 if (!aTopic) |
|
2544 return NS_OK; |
|
2545 |
|
2546 - // if we are notified by pref service |
|
2547 - // check the system pref settings |
|
2548 + nsCOMPtr<nsIPrefBranch2> userBranch = GetPrefUserBranch(); |
|
2549 + nsCOMPtr<nsIPrefBranch> defaultBranch = GetPrefDefaultBranch(); |
|
2550 + |
|
2551 + // Check the default branch first. If system prefs are enabled |
|
2552 + // by default, then don't check the user prefs; we don't want |
|
2553 + // to allow users to change the default. |
|
2554 + PRBool defaultEnabled; |
|
2555 + rv = defaultBranch->GetBoolPref(sSysPrefString, &defaultEnabled); |
|
2556 + if (NS_FAILED(rv)) { |
|
2557 + SYSPREF_LOG(("...Failed to Get %s\n", sSysPrefString)); |
|
2558 + return rv; |
|
2559 + } |
|
2560 + PRBool enabled = defaultEnabled; |
|
2561 + if (!enabled) { |
|
2562 + rv = userBranch->GetBoolPref(sSysPrefString, &enabled); |
|
2563 + |
|
2564 + if (NS_FAILED(rv)) { |
|
2565 + SYSPREF_LOG(("...Failed to Get %s\n", sSysPrefString)); |
|
2566 + return rv; |
|
2567 + } |
|
2568 + } |
|
2569 if (!nsCRT::strcmp(aTopic, NS_PREFSERVICE_READ_TOPIC_ID)) { |
|
2570 + // The prefs have just loaded. This is the first thing that |
|
2571 + // happens to us. |
|
2572 SYSPREF_LOG(("Observed: %s\n", aTopic)); |
|
2573 + |
|
2574 |
|
2575 - nsCOMPtr<nsIPrefBranch2> prefBranch = |
|
2576 - do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); |
|
2577 + // listen on changes to use_system_pref. It's OK to |
|
2578 + // hold a strong reference because we don't keep a reference |
|
2579 + // to the pref branch. |
|
2580 + rv = userBranch->AddObserver(sSysPrefString, this, PR_TRUE); |
|
2581 + |
|
2582 + if (NS_FAILED(rv)) { |
|
2583 + SYSPREF_LOG(("...Failed to add observer for %s\n", sSysPrefString)); |
|
2584 + return rv; |
|
2585 + } |
|
2586 + NS_ASSERTION(!mSysPrefService, "Should not be already enabled"); |
|
2587 + if (!enabled) { |
|
2588 + // Don't load the system pref service if the preference is |
|
2589 + // not set. |
|
2590 + return NS_OK; |
|
2591 + } |
|
2592 + |
|
2593 + SYSPREF_LOG(("%s is enabled\n", sSysPrefString)); |
|
2594 + |
|
2595 + rv = LoadSystemPrefs(); |
|
2596 if (NS_FAILED(rv)) |
|
2597 return rv; |
|
2598 |
|
2599 - rv = prefBranch->GetBoolPref(sSysPrefString, &mEnabled); |
|
2600 - if (NS_FAILED(rv)) { |
|
2601 - SYSPREF_LOG(("...FAil to Get %s\n", sSysPrefString)); |
|
2602 - return rv; |
|
2603 - } |
|
2604 - |
|
2605 - // if there is no system pref service, assume nothing happen to us |
|
2606 - mSysPrefService = do_GetService(NS_SYSTEMPREF_SERVICE_CONTRACTID, &rv); |
|
2607 - if (NS_FAILED(rv) || !mSysPrefService) { |
|
2608 - SYSPREF_LOG(("...No System Pref Service\n")); |
|
2609 - return NS_OK; |
|
2610 - } |
|
2611 - |
|
2612 - // listen on its changes |
|
2613 - rv = prefBranch->AddObserver(sSysPrefString, this, PR_TRUE); |
|
2614 - if (NS_FAILED(rv)) { |
|
2615 - SYSPREF_LOG(("...FAil to add observer for %s\n", sSysPrefString)); |
|
2616 - return rv; |
|
2617 - } |
|
2618 - |
|
2619 - if (!mEnabled) { |
|
2620 - SYSPREF_LOG(("%s is disabled\n", sSysPrefString)); |
|
2621 - return NS_OK; |
|
2622 - } |
|
2623 - SYSPREF_LOG(("%s is enabled\n", sSysPrefString)); |
|
2624 - rv = UseSystemPrefs(); |
|
2625 - |
|
2626 - } |
|
2627 - // sSysPrefString value was changed, update ... |
|
2628 - else if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) && |
|
2629 - NS_ConvertUTF8toUTF16(sSysPrefString).Equals(aData)) { |
|
2630 - SYSPREF_LOG(("++++++ Notify: topic=%s data=%s\n", |
|
2631 - aTopic, NS_ConvertUTF16toUTF8(aData).get())); |
|
2632 - |
|
2633 - nsCOMPtr<nsIPrefBranch> prefBranch = |
|
2634 - do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); |
|
2635 - if (NS_FAILED(rv)) |
|
2636 - return rv; |
|
2637 - |
|
2638 - PRBool enabled = mEnabled; |
|
2639 - rv = prefBranch->GetBoolPref(sSysPrefString, &mEnabled); |
|
2640 - if (enabled != mEnabled) { |
|
2641 - if (mEnabled) |
|
2642 - //read prefs from system |
|
2643 - rv = UseSystemPrefs(); |
|
2644 - else |
|
2645 - //roll back to mozilla prefs |
|
2646 - rv = UseMozillaPrefs(); |
|
2647 + // Lock config.use_system_prefs so the user can't undo |
|
2648 + // it. But only do this if it was set by in the default prefs; |
|
2649 + // if it was not set by default, then locking it would actually |
|
2650 + // unset the value! And the user should be allowed to turn off |
|
2651 + // something they set themselves. |
|
2652 + if (NS_SUCCEEDED(rv) && defaultEnabled) { |
|
2653 + userBranch->LockPref(sSysPrefString); |
|
2654 } |
|
2655 } |
|
2656 |
|
2657 - // if the system pref notify us that some pref has been changed by user |
|
2658 - // outside mozilla. We need to read it again. |
|
2659 - else if (!nsCRT::strcmp(aTopic, NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID) && |
|
2660 - aData) { |
|
2661 - NS_ASSERTION(mEnabled == PR_TRUE, "Should not listen when disabled"); |
|
2662 - SYSPREF_LOG(("====== System Pref Notify topic=%s data=%s\n", |
|
2663 - aTopic, (char*)aData)); |
|
2664 - rv = ReadSystemPref(NS_LossyConvertUTF16toASCII(aData).get()); |
|
2665 + if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) && |
|
2666 + nsDependentString(aData).EqualsASCII(sSysPrefString)) { |
|
2667 + // sSysPrefString value was changed, update... |
|
2668 + SYSPREF_LOG(("++++++ Notify: topic=%s data=%s\n", |
|
2669 + aTopic, NS_ConvertUTF16toUTF8(aData).get())); |
|
2670 + if (mSysPrefService && !enabled) |
|
2671 + return RestoreMozillaPrefs(); |
|
2672 + if (!mSysPrefService && enabled) { |
|
2673 + // Don't lock it. If the user enabled use_system_prefs, |
|
2674 + // they should be allowed to unlock it. |
|
2675 + return LoadSystemPrefs(); |
|
2676 + } |
|
2677 + |
|
2678 + // didn't change? |
|
2679 return NS_OK; |
|
2680 - } else if (!nsCRT::strcmp(aTopic,"profile-before-change")) { |
|
2681 - //roll back to mozilla prefs |
|
2682 - if (mEnabled) |
|
2683 - UseMozillaPrefs(); |
|
2684 - mEnabled = PR_FALSE; |
|
2685 - mSysPrefService = nsnull; |
|
2686 - delete [] mSysPrefs; |
|
2687 - mSysPrefs = nsnull; |
|
2688 - } else |
|
2689 - SYSPREF_LOG(("Not needed topic Received %s\n", aTopic)); |
|
2690 + } |
|
2691 + |
|
2692 + if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) { |
|
2693 + // some other pref changed, tell the backend if there is one |
|
2694 + if (mSysPrefService && !mIgnorePrefSetting) { |
|
2695 + NS_LossyConvertUTF16toASCII tmp(aData); |
|
2696 +#ifdef DEBUG |
|
2697 + PRBool isLocked; |
|
2698 + userBranch->PrefIsLocked(tmp.get(), &isLocked); |
|
2699 + NS_ASSERTION(!isLocked, "Locked pref is changing?"); |
|
2700 +#endif |
|
2701 + SysPrefItem* item; |
|
2702 + if (!mSavedPrefs.Get(tmp, &item)) { |
|
2703 + NS_ERROR("Notified about pref change that we didn't ask about?"); |
|
2704 + } else { |
|
2705 + if (!item->ignore) { |
|
2706 + mSysPrefService->NotifyMozillaPrefChanged(tmp.get()); |
|
2707 + } |
|
2708 + } |
|
2709 + } |
|
2710 + return NS_OK; |
|
2711 + } |
|
2712 + |
|
2713 + if (!nsCRT::strcmp(aTopic,"profile-before-change")) |
|
2714 + return RestoreMozillaPrefs(); |
|
2715 + |
|
2716 + SYSPREF_LOG(("Not needed topic Received %s\n", aTopic)); |
|
2717 + |
|
2718 return rv; |
|
2719 } |
|
2720 |
|
2721 -/* private */ |
|
2722 +nsresult |
|
2723 +nsSystemPref::SetOverridingMozillaBoolPref(const char* aPrefName, |
|
2724 + PRBool aValue, PRBool aLock, PRBool aPresent) |
|
2725 +{ |
|
2726 + return OverridePref(aPrefName, nsIPrefBranch::PREF_BOOL, |
|
2727 + (void*)aValue, aLock, aPresent); |
|
2728 +} |
|
2729 |
|
2730 -//////////////////////////////////////////////////////////////// |
|
2731 -// nsSystemPref::UseSystemPrefs |
|
2732 -// Read all the prefs in the table from system, listen for their |
|
2733 -// changes in system pref service. |
|
2734 -//////////////////////////////////////////////////////////////// |
|
2735 nsresult |
|
2736 -nsSystemPref::UseSystemPrefs() |
|
2737 +nsSystemPref::SetOverridingMozillaIntPref(const char* aPrefName, |
|
2738 + PRInt32 aValue, PRBool aLock, PRBool aPresent) |
|
2739 { |
|
2740 - SYSPREF_LOG(("\n====Now Use system prefs==\n")); |
|
2741 - nsresult rv = NS_OK; |
|
2742 - if (!mSysPrefService) { |
|
2743 + return OverridePref(aPrefName, nsIPrefBranch::PREF_INT, |
|
2744 + (void*)aValue, aLock, aPresent); |
|
2745 +} |
|
2746 + |
|
2747 + |
|
2748 +nsresult |
|
2749 +nsSystemPref::SetOverridingMozillaStringPref(const char* aPrefName, |
|
2750 + const char* aValue, PRBool aLock, PRBool aPresent) |
|
2751 +{ |
|
2752 + return OverridePref(aPrefName, nsIPrefBranch::PREF_STRING, |
|
2753 + (void*)aValue, aLock, aPresent); |
|
2754 +} |
|
2755 + |
|
2756 +static nsresult RestorePrefValue(PRInt32 aPrefType, |
|
2757 + const char* aPrefName, |
|
2758 + SysPrefItem* aItem, |
|
2759 + nsIPrefBranch* aUser, |
|
2760 + nsIPrefBranch* aDefault) |
|
2761 +{ |
|
2762 + switch (aPrefType) { |
|
2763 + |
|
2764 + case nsIPrefBranch::PREF_STRING: |
|
2765 + aDefault->SetCharPref(aPrefName, |
|
2766 + aItem->savedDefaultValueString); |
|
2767 + if (aItem->savedUserPresent) { |
|
2768 + aUser->SetCharPref(aPrefName, aItem->savedUserValueString); |
|
2769 + } |
|
2770 + break; |
|
2771 + case nsIPrefBranch::PREF_INT: |
|
2772 + aDefault->SetBoolPref(aPrefName, aItem->savedDefaultValueScalar); |
|
2773 + if (aItem->savedUserPresent) { |
|
2774 + aUser->SetBoolPref(aPrefName, aItem->savedUserValueScalar); |
|
2775 + } |
|
2776 + break; |
|
2777 + case nsIPrefBranch::PREF_BOOL: |
|
2778 + aDefault->SetBoolPref(aPrefName, aItem->savedDefaultValueScalar); |
|
2779 + if (aItem->savedUserPresent) { |
|
2780 + aUser->SetBoolPref(aPrefName, aItem->savedUserValueScalar); |
|
2781 + } |
|
2782 + break; |
|
2783 + default: |
|
2784 + NS_ERROR("Unknown preference type"); |
|
2785 return NS_ERROR_FAILURE; |
|
2786 } |
|
2787 |
|
2788 - PRIntn sysPrefCount= sizeof(sSysPrefList) / sizeof(sSysPrefList[0]); |
|
2789 - |
|
2790 - if (!mSysPrefs) { |
|
2791 - mSysPrefs = new SysPrefItem[sysPrefCount]; |
|
2792 - if (!mSysPrefs) |
|
2793 - return NS_ERROR_OUT_OF_MEMORY; |
|
2794 - for (PRIntn index = 0; index < sysPrefCount; ++index) |
|
2795 - mSysPrefs[index].SetPrefName(sSysPrefList[index]); |
|
2796 + if (!aItem->savedUserPresent) { |
|
2797 + aUser->DeleteBranch(aPrefName); |
|
2798 } |
|
2799 |
|
2800 - for (PRIntn index = 0; index < sysPrefCount; ++index) { |
|
2801 - // save mozilla prefs |
|
2802 - SaveMozDefaultPref(mSysPrefs[index].prefName, |
|
2803 - &mSysPrefs[index].defaultValue, |
|
2804 - &mSysPrefs[index].isLocked); |
|
2805 + return NS_OK; |
|
2806 +} |
|
2807 |
|
2808 - // get the system prefs |
|
2809 - ReadSystemPref(mSysPrefs[index].prefName); |
|
2810 - SYSPREF_LOG(("Add Listener on %s\n", mSysPrefs[index].prefName)); |
|
2811 - mSysPrefService->AddObserver(mSysPrefs[index].prefName, |
|
2812 - this, PR_TRUE); |
|
2813 +static PLDHashOperator PR_CALLBACK RestorePref(const nsACString& aKey, |
|
2814 + SysPrefItem* aItem, |
|
2815 + void* aClosure) |
|
2816 +{ |
|
2817 + nsSystemPref* prefs = static_cast<nsSystemPref*>(aClosure); |
|
2818 + nsCOMPtr<nsIPrefBranch2> userBranch = prefs->GetPrefUserBranch(); |
|
2819 + const nsCString& prefName = PromiseFlatCString(aKey); |
|
2820 + |
|
2821 + PRInt32 prefType = nsIPrefBranch::PREF_INVALID; |
|
2822 + nsresult rv = userBranch->GetPrefType(prefName.get(), &prefType); |
|
2823 + if (NS_FAILED(rv)) |
|
2824 + return PL_DHASH_NEXT; |
|
2825 + PRBool isLocked; |
|
2826 + userBranch->PrefIsLocked(prefName.get(), &isLocked); |
|
2827 + if (NS_FAILED(rv)) |
|
2828 + return PL_DHASH_NEXT; |
|
2829 + |
|
2830 + |
|
2831 + // Remove our observer before we change the value |
|
2832 + userBranch->RemoveObserver(prefName.get(), prefs); |
|
2833 + // Remember to ignore this item. Because some prefs start with "config.use_system_prefs", |
|
2834 + // which we always observe, even after we remove the observer, changes to the pref will |
|
2835 + // still be observed by us. We must ignore them. |
|
2836 + aItem->ignore = PR_TRUE; |
|
2837 + |
|
2838 + |
|
2839 + // Unlock the pref so we can set it |
|
2840 + if (isLocked) { |
|
2841 + userBranch->UnlockPref(prefName.get()); |
|
2842 } |
|
2843 + |
|
2844 + nsCOMPtr<nsIPrefBranch> defaultBranch = prefs->GetPrefDefaultBranch(); |
|
2845 + |
|
2846 + RestorePrefValue(prefType, prefName.get(), aItem, |
|
2847 + userBranch, defaultBranch); |
|
2848 + |
|
2849 + if (aItem->savedLocked) { |
|
2850 + userBranch->LockPref(prefName.get()); |
|
2851 + } |
|
2852 + |
|
2853 + return PL_DHASH_NEXT; |
|
2854 +} |
|
2855 + |
|
2856 +nsresult |
|
2857 +nsSystemPref::StopOverridingMozillaPref(const char* aPrefName) |
|
2858 +{ |
|
2859 + SysPrefItem* item; |
|
2860 + nsDependentCString prefNameStr(aPrefName); |
|
2861 + if (!mSavedPrefs.Get(prefNameStr, &item)) |
|
2862 + return NS_OK; |
|
2863 + |
|
2864 + RestorePref(prefNameStr, item, this); |
|
2865 + mSavedPrefs.Remove(prefNameStr); |
|
2866 + delete item; |
|
2867 + return NS_OK; |
|
2868 +} |
|
2869 + |
|
2870 +/* private */ |
|
2871 + |
|
2872 +nsresult |
|
2873 +nsSystemPref::OverridePref(const char* aPrefName, PRInt32 aType, |
|
2874 + void* aValue, PRBool aLock, PRBool aPresent) |
|
2875 +{ |
|
2876 + nsCOMPtr<nsIPrefBranch2> userBranch = GetPrefUserBranch(); |
|
2877 + nsCOMPtr<nsIPrefBranch> defaultBranch = GetPrefDefaultBranch(); |
|
2878 + |
|
2879 + PRInt32 prefType = nsIPrefBranch::PREF_INVALID; |
|
2880 + nsresult rv = userBranch->GetPrefType(aPrefName, &prefType); |
|
2881 + PRBool isLocked; |
|
2882 + rv = userBranch->PrefIsLocked(aPrefName, &isLocked); |
|
2883 + if (NS_FAILED(rv)) |
|
2884 + return rv; |
|
2885 + PRBool hasUserValue; |
|
2886 + rv = userBranch->PrefHasUserValue(aPrefName, &hasUserValue); |
|
2887 + if (NS_FAILED(rv)) |
|
2888 + return rv; |
|
2889 + if (prefType == 0) { |
|
2890 + // Preference does not exist. Allow the system prefs to |
|
2891 + // set it. |
|
2892 + } else { |
|
2893 + NS_ASSERTION(aType == prefType, |
|
2894 + "System pref engine passed incorrect type for Mozilla pref"); |
|
2895 + if (aType != prefType) |
|
2896 + return NS_ERROR_FAILURE; |
|
2897 + } |
|
2898 + |
|
2899 + if (prefType != 0) { |
|
2900 + nsDependentCString prefNameStr(aPrefName); |
|
2901 + SysPrefItem* item = nsnull; |
|
2902 + if (!mSavedPrefs.Get(prefNameStr, &item)) { |
|
2903 + // Need to save the existing value away |
|
2904 + item = new SysPrefItem(); |
|
2905 + if (!item) |
|
2906 + return NS_ERROR_OUT_OF_MEMORY; |
|
2907 + |
|
2908 + item->savedLocked = isLocked; |
|
2909 + item->savedUserPresent = hasUserValue; |
|
2910 + |
|
2911 + switch (prefType) { |
|
2912 + case nsIPrefBranch::PREF_STRING: |
|
2913 + if (hasUserValue) { |
|
2914 + userBranch->GetCharPref(aPrefName, &item->savedUserValueString); |
|
2915 + } |
|
2916 + defaultBranch->GetCharPref(aPrefName, &item->savedDefaultValueString); |
|
2917 + break; |
|
2918 + case nsIPrefBranch::PREF_INT: |
|
2919 + if (hasUserValue) { |
|
2920 + userBranch->GetIntPref(aPrefName, &item->savedUserValueScalar); |
|
2921 + } |
|
2922 + defaultBranch->GetIntPref(aPrefName, &item->savedDefaultValueScalar); |
|
2923 + break; |
|
2924 + case nsIPrefBranch::PREF_BOOL: |
|
2925 + if (hasUserValue) { |
|
2926 + userBranch->GetBoolPref(aPrefName, &item->savedUserValueScalar); |
|
2927 + } |
|
2928 + defaultBranch->GetBoolPref(aPrefName, &item->savedDefaultValueScalar); |
|
2929 + break; |
|
2930 + default: |
|
2931 + NS_ERROR("Unknown preference type"); |
|
2932 + delete item; |
|
2933 + return NS_ERROR_FAILURE; |
|
2934 + } |
|
2935 + |
|
2936 + mSavedPrefs.Put(prefNameStr, item); |
|
2937 + |
|
2938 + // Watch the user value in case it changes on the Mozilla side |
|
2939 + // If 'aLock' is true then it shouldn't change and we don't |
|
2940 + // need the observer, but don't bother optimizing for that. |
|
2941 + userBranch->AddObserver(aPrefName, this, PR_TRUE); |
|
2942 + } else { |
|
2943 + if (isLocked != aLock) { |
|
2944 + // restore pref value on user and default branches |
|
2945 + RestorePrefValue(prefType, aPrefName, item, |
|
2946 + userBranch, defaultBranch); |
|
2947 + } |
|
2948 + } |
|
2949 + } |
|
2950 + |
|
2951 + // We need to ignore pref changes due to our own calls here |
|
2952 + mIgnorePrefSetting = PR_TRUE; |
|
2953 + |
|
2954 + // Unlock it if it's locked, so we can set it |
|
2955 + if (isLocked) { |
|
2956 + rv = userBranch->UnlockPref(aPrefName); |
|
2957 + if (NS_FAILED(rv)) |
|
2958 + return rv; |
|
2959 + } |
|
2960 + |
|
2961 + // Set the pref on the default branch if we're locking it, because |
|
2962 + // only the default branch gets used when the pref is locked. |
|
2963 + // Set the pref on the user branch if we're not locking it, because |
|
2964 + // that's where the user change will go. |
|
2965 + nsIPrefBranch* settingBranch = |
|
2966 + aLock ? defaultBranch.get() : static_cast<nsIPrefBranch*>(userBranch.get()); |
|
2967 + |
|
2968 + if (!aPresent) { |
|
2969 + rv = settingBranch->DeleteBranch(aPrefName); |
|
2970 + } else { |
|
2971 + switch (aType) { |
|
2972 + case nsIPrefBranch::PREF_STRING: |
|
2973 + rv = settingBranch->SetCharPref(aPrefName, (const char*)aValue); |
|
2974 + break; |
|
2975 + case nsIPrefBranch::PREF_INT: |
|
2976 + rv = settingBranch->SetIntPref(aPrefName, (PRInt32)(NS_PTR_TO_INT32(aValue))); |
|
2977 + break; |
|
2978 + case nsIPrefBranch::PREF_BOOL: |
|
2979 + rv = settingBranch->SetBoolPref(aPrefName, (PRBool)(NS_PTR_TO_INT32(aValue))); |
|
2980 + break; |
|
2981 + default: |
|
2982 + NS_ERROR("Unknown preference type"); |
|
2983 + mIgnorePrefSetting = PR_FALSE; |
|
2984 + return NS_ERROR_FAILURE; |
|
2985 + } |
|
2986 + } |
|
2987 + |
|
2988 + if (NS_FAILED(rv)) |
|
2989 + return rv; |
|
2990 + if (aLock) { |
|
2991 + rv = userBranch->LockPref(aPrefName); |
|
2992 + } |
|
2993 + |
|
2994 + mIgnorePrefSetting = PR_FALSE; |
|
2995 return rv; |
|
2996 } |
|
2997 |
|
2998 -////////////////////////////////////////////////////////////////////// |
|
2999 -// nsSystemPref::ReadSystemPref |
|
3000 -// Read a pref value from system pref service, and lock it in mozilla. |
|
3001 -////////////////////////////////////////////////////////////////////// |
|
3002 + |
|
3003 nsresult |
|
3004 -nsSystemPref::ReadSystemPref(const char *aPrefName) |
|
3005 +nsSystemPref::FixupLockdownPrefs() |
|
3006 { |
|
3007 - if (!mSysPrefService) |
|
3008 - return NS_ERROR_FAILURE; |
|
3009 - nsresult rv; |
|
3010 - |
|
3011 - nsCOMPtr<nsIPrefBranch> prefBranch |
|
3012 - (do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); |
|
3013 + nsCOMPtr<nsIPrefBranch2> userPrefs = GetPrefUserBranch(); |
|
3014 + nsCOMPtr<nsIPrefBranch2> defaultPrefs = GetPrefUserBranch(); |
|
3015 + PRUint32 childCount; |
|
3016 + char **childArray = nsnull; |
|
3017 + nsresult rv = userPrefs->GetChildList("config.lockdown.", |
|
3018 + &childCount, &childArray); |
|
3019 if (NS_FAILED(rv)) |
|
3020 return rv; |
|
3021 - |
|
3022 - SYSPREF_LOG(("about to read aPrefName %s\n", aPrefName)); |
|
3023 - |
|
3024 - prefBranch->UnlockPref(aPrefName); |
|
3025 - |
|
3026 - PRInt32 prefType = nsIPrefBranch::PREF_INVALID; |
|
3027 - nsXPIDLCString strValue; |
|
3028 - PRInt32 intValue = 0; |
|
3029 - PRBool boolValue = PR_FALSE; |
|
3030 - |
|
3031 - rv = prefBranch->GetPrefType(aPrefName, &prefType); |
|
3032 - if (NS_FAILED(rv)) |
|
3033 - return rv; |
|
3034 - switch (prefType) { |
|
3035 - case nsIPrefBranch::PREF_STRING: |
|
3036 - mSysPrefService->GetCharPref(aPrefName, getter_Copies(strValue)); |
|
3037 - SYSPREF_LOG(("system value is %s\n", strValue.get())); |
|
3038 - |
|
3039 - prefBranch->SetCharPref(aPrefName, strValue.get()); |
|
3040 - break; |
|
3041 - case nsIPrefBranch::PREF_INT: |
|
3042 - mSysPrefService->GetIntPref(aPrefName, &intValue); |
|
3043 - SYSPREF_LOG(("system value is %d\n", intValue)); |
|
3044 - |
|
3045 - prefBranch->SetIntPref(aPrefName, intValue); |
|
3046 - break; |
|
3047 - case nsIPrefBranch::PREF_BOOL: |
|
3048 - mSysPrefService->GetBoolPref(aPrefName, &boolValue); |
|
3049 - SYSPREF_LOG(("system value is %s\n", boolValue ? "TRUE" : "FALSE")); |
|
3050 - |
|
3051 - prefBranch->SetBoolPref(aPrefName, boolValue); |
|
3052 - break; |
|
3053 - default: |
|
3054 - SYSPREF_LOG(("Fail to system value for it\n")); |
|
3055 - return NS_ERROR_FAILURE; |
|
3056 + for (PRUint32 i = 0; i < childCount; ++i) { |
|
3057 + PRInt32 type; |
|
3058 + rv = defaultPrefs->GetPrefType(childArray[i], &type); |
|
3059 + if (NS_FAILED(rv)) |
|
3060 + return rv; |
|
3061 + NS_ASSERTION(type == nsIPrefBranch2::PREF_BOOL, |
|
3062 + "All config.lockdown.* prefs should be boolean"); |
|
3063 + if (type == nsIPrefBranch2::PREF_BOOL) { |
|
3064 + rv = defaultPrefs->SetBoolPref(childArray[i], PR_FALSE); |
|
3065 + if (NS_FAILED(rv)) |
|
3066 + return rv; |
|
3067 + } |
|
3068 } |
|
3069 - prefBranch->LockPref(aPrefName); |
|
3070 + NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray); |
|
3071 return NS_OK; |
|
3072 } |
|
3073 |
|
3074 -////////////////////////////////////////////////////////////////////// |
|
3075 -// nsSystemPref::UseMozillaPrefs |
|
3076 -// Restore mozilla default prefs, remove system pref listeners |
|
3077 -///////////////////////////////////////////////////////////////////// |
|
3078 + |
|
3079 nsresult |
|
3080 -nsSystemPref::UseMozillaPrefs() |
|
3081 +nsSystemPref::LoadSystemPrefs() |
|
3082 { |
|
3083 - nsresult rv = NS_OK; |
|
3084 - SYSPREF_LOG(("\n====Now rollback to Mozilla prefs==\n")); |
|
3085 + SYSPREF_LOG(("\n====Now Use system prefs==\n")); |
|
3086 + NS_ASSERTION(!mSysPrefService, |
|
3087 + "Shouldn't have the pref service here"); |
|
3088 + nsresult rv; |
|
3089 + mSysPrefService = do_GetService(NS_SYSTEMPREF_SERVICE_CONTRACTID, &rv); |
|
3090 + if (NS_FAILED(rv) || !mSysPrefService) { |
|
3091 + FixupLockdownPrefs(); |
|
3092 + SYSPREF_LOG(("...No System Pref Service\n")); |
|
3093 + return NS_OK; |
|
3094 + } |
|
3095 |
|
3096 - // if we did not use system prefs, do nothing |
|
3097 - if (!mSysPrefService) |
|
3098 - return NS_OK; |
|
3099 + // Cache the pref-branch while we load up the system prefs. |
|
3100 + NS_ASSERTION(!mCachedUserPrefBranch, |
|
3101 + "Shouldn't have a cache here"); |
|
3102 + nsCOMPtr<nsIPrefBranch2> userBranch = GetPrefUserBranch(); |
|
3103 + nsCOMPtr<nsIPrefBranch> defaultBranch = GetPrefDefaultBranch(); |
|
3104 + mCachedDefaultPrefBranch = defaultBranch; |
|
3105 + mCachedUserPrefBranch = userBranch; |
|
3106 + rv = mSysPrefService->LoadSystemPreferences(this); |
|
3107 + mCachedDefaultPrefBranch = nsnull; |
|
3108 + mCachedUserPrefBranch = nsnull; |
|
3109 |
|
3110 - PRIntn sysPrefCount= sizeof(sSysPrefList) / sizeof(sSysPrefList[0]); |
|
3111 - for (PRIntn index = 0; index < sysPrefCount; ++index) { |
|
3112 - // restore mozilla default value and free string memory if needed |
|
3113 - RestoreMozDefaultPref(mSysPrefs[index].prefName, |
|
3114 - &mSysPrefs[index].defaultValue, |
|
3115 - mSysPrefs[index].isLocked); |
|
3116 - SYSPREF_LOG(("stop listening on %s\n", mSysPrefs[index].prefName)); |
|
3117 - mSysPrefService->RemoveObserver(mSysPrefs[index].prefName, |
|
3118 - this); |
|
3119 + if (NS_FAILED(rv)) { |
|
3120 + // Restore all modified preferences to their original values |
|
3121 + mSavedPrefs.EnumerateRead(RestorePref, this); |
|
3122 + mSavedPrefs.Clear(); |
|
3123 + mSysPrefService = nsnull; |
|
3124 } |
|
3125 + |
|
3126 return rv; |
|
3127 } |
|
3128 |
|
3129 -//////////////////////////////////////////////////////////////////////////// |
|
3130 -// nsSystemPref::RestoreMozDefaultPref |
|
3131 -// Save the saved mozilla default value. |
|
3132 -// It is also responsible for allocate the string memory when needed, because |
|
3133 -// this method know what type of value is stored. |
|
3134 -///////////////////////////////////////////////////////////////////////////// |
|
3135 + |
|
3136 nsresult |
|
3137 -nsSystemPref::SaveMozDefaultPref(const char *aPrefName, |
|
3138 - MozPrefValue *aPrefValue, |
|
3139 - PRBool *aLocked) |
|
3140 +nsSystemPref::RestoreMozillaPrefs() |
|
3141 { |
|
3142 - NS_ENSURE_ARG_POINTER(aPrefName); |
|
3143 - NS_ENSURE_ARG_POINTER(aPrefValue); |
|
3144 - NS_ENSURE_ARG_POINTER(aLocked); |
|
3145 + SYSPREF_LOG(("\n====Now rollback to Mozilla prefs==\n")); |
|
3146 |
|
3147 - nsresult rv; |
|
3148 + NS_ASSERTION(mSysPrefService, |
|
3149 + "Should have the pref service here"); |
|
3150 + if (!mSysPrefService) |
|
3151 + return NS_ERROR_FAILURE; |
|
3152 |
|
3153 - nsCOMPtr<nsIPrefBranch> prefBranch = |
|
3154 - do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); |
|
3155 - if (NS_FAILED(rv)) |
|
3156 - return rv; |
|
3157 + nsCOMPtr<nsIPrefBranch2> userBranch = GetPrefUserBranch(); |
|
3158 + nsCOMPtr<nsIPrefBranch> defaultBranch = GetPrefDefaultBranch(); |
|
3159 + mCachedDefaultPrefBranch = defaultBranch; |
|
3160 + mCachedUserPrefBranch = userBranch; |
|
3161 |
|
3162 - SYSPREF_LOG(("Save Mozilla value for %s\n", aPrefName)); |
|
3163 + mSysPrefService->NotifyUnloadSystemPreferences(); |
|
3164 + // Restore all modified preferences to their original values |
|
3165 + mSavedPrefs.EnumerateRead(RestorePref, this); |
|
3166 + mSavedPrefs.Clear(); |
|
3167 |
|
3168 - PRInt32 prefType = nsIPrefBranch::PREF_INVALID; |
|
3169 - nsXPIDLCString strValue; |
|
3170 + mCachedDefaultPrefBranch = nsnull; |
|
3171 + mCachedUserPrefBranch = nsnull; |
|
3172 + |
|
3173 + mSysPrefService = nsnull; |
|
3174 |
|
3175 - rv = prefBranch->GetPrefType(aPrefName, &prefType); |
|
3176 - if (NS_FAILED(rv)) |
|
3177 - return rv; |
|
3178 - switch (prefType) { |
|
3179 - case nsIPrefBranch::PREF_STRING: |
|
3180 - prefBranch->GetCharPref(aPrefName, |
|
3181 - getter_Copies(strValue)); |
|
3182 - SYSPREF_LOG(("Mozilla value is %s", strValue.get())); |
|
3183 + FixupLockdownPrefs(); |
|
3184 |
|
3185 - if (aPrefValue->stringVal) |
|
3186 - PL_strfree(aPrefValue->stringVal); |
|
3187 - aPrefValue->stringVal = PL_strdup(strValue.get()); |
|
3188 - break; |
|
3189 - case nsIPrefBranch::PREF_INT: |
|
3190 - prefBranch->GetIntPref(aPrefName, &aPrefValue->intVal); |
|
3191 - SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue->intVal)); |
|
3192 - |
|
3193 - break; |
|
3194 - case nsIPrefBranch::PREF_BOOL: |
|
3195 - prefBranch->GetBoolPref(aPrefName, &aPrefValue->boolVal); |
|
3196 - SYSPREF_LOG(("Mozilla value is %s\n", |
|
3197 - aPrefValue->boolVal ? "TRUE" : "FALSE")); |
|
3198 - |
|
3199 - break; |
|
3200 - default: |
|
3201 - SYSPREF_LOG(("Fail to Read Mozilla value for it\n")); |
|
3202 - return NS_ERROR_FAILURE; |
|
3203 - } |
|
3204 - rv = prefBranch->PrefIsLocked(aPrefName, aLocked); |
|
3205 - SYSPREF_LOG((" (%s).\n", aLocked ? "Locked" : "NOT Locked")); |
|
3206 - return rv; |
|
3207 -} |
|
3208 - |
|
3209 -//////////////////////////////////////////////////////////////////////////// |
|
3210 -// nsSystemPref::RestoreMozDefaultPref |
|
3211 -// Restore the saved mozilla default value to pref service. |
|
3212 -// It is also responsible for free the string memory when needed, because |
|
3213 -// this method know what type of value is stored. |
|
3214 -///////////////////////////////////////////////////////////////////////////// |
|
3215 -nsresult |
|
3216 -nsSystemPref::RestoreMozDefaultPref(const char *aPrefName, |
|
3217 - MozPrefValue *aPrefValue, |
|
3218 - PRBool aLocked) |
|
3219 -{ |
|
3220 - NS_ENSURE_ARG_POINTER(aPrefName); |
|
3221 - |
|
3222 - nsresult rv; |
|
3223 - |
|
3224 - nsCOMPtr<nsIPrefBranch> prefBranch = |
|
3225 - do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); |
|
3226 - if (NS_FAILED(rv)) |
|
3227 - return rv; |
|
3228 - |
|
3229 - SYSPREF_LOG(("Restore Mozilla value for %s\n", aPrefName)); |
|
3230 - |
|
3231 - PRInt32 prefType = nsIPrefBranch::PREF_INVALID; |
|
3232 - rv = prefBranch->GetPrefType(aPrefName, &prefType); |
|
3233 - if (NS_FAILED(rv)) |
|
3234 - return rv; |
|
3235 - |
|
3236 - // unlock, if it is locked |
|
3237 - prefBranch->UnlockPref(aPrefName); |
|
3238 - |
|
3239 - switch (prefType) { |
|
3240 - case nsIPrefBranch::PREF_STRING: |
|
3241 - prefBranch->SetCharPref(aPrefName, |
|
3242 - aPrefValue->stringVal); |
|
3243 - SYSPREF_LOG(("Mozilla value is %s\n", aPrefValue->stringVal)); |
|
3244 - |
|
3245 - PL_strfree(aPrefValue->stringVal); |
|
3246 - aPrefValue->stringVal = nsnull; |
|
3247 - |
|
3248 - break; |
|
3249 - case nsIPrefBranch::PREF_INT: |
|
3250 - prefBranch->SetIntPref(aPrefName, aPrefValue->intVal); |
|
3251 - SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue->intVal)); |
|
3252 - |
|
3253 - break; |
|
3254 - case nsIPrefBranch::PREF_BOOL: |
|
3255 - prefBranch->SetBoolPref(aPrefName, aPrefValue->boolVal); |
|
3256 - SYSPREF_LOG(("Mozilla value is %s\n", |
|
3257 - aPrefValue->boolVal ? "TRUE" : "FALSE")); |
|
3258 - |
|
3259 - break; |
|
3260 - default: |
|
3261 - SYSPREF_LOG(("Fail to Restore Mozilla value for it\n")); |
|
3262 - return NS_ERROR_FAILURE; |
|
3263 - } |
|
3264 - |
|
3265 - // restore its old lock status |
|
3266 - if (aLocked) |
|
3267 - prefBranch->LockPref(aPrefName); |
|
3268 return NS_OK; |
|
3269 } |
|
3270 diff --git a/extensions/pref/system-pref/src/nsSystemPref.h b/extensions/pref/system-pref/src/nsSystemPref.h |
|
3271 --- a/extensions/pref/system-pref/src/nsSystemPref.h |
|
3272 +++ b/extensions/pref/system-pref/src/nsSystemPref.h |
|
3273 @@ -18,17 +18,17 @@ |
|
3274 * The Original Code is mozilla.org code. |
|
3275 * |
|
3276 * The Initial Developer of the Original Code is Sun Microsystems, Inc. |
|
3277 * Portions created by Sun Microsystems are Copyright (C) 2003 Sun |
|
3278 * Microsystems, Inc. All Rights Reserved. |
|
3279 * |
|
3280 * Original Author: Bolian Yin (bolian.yin@sun.com) |
|
3281 * |
|
3282 - * Contributor(s): |
|
3283 + * Contributor(s): Robert O'Callahan/Novell (rocallahan@novell.com) |
|
3284 * |
|
3285 * Alternatively, the contents of this file may be used under the terms of |
|
3286 * either the GNU General Public License Version 2 or later (the "GPL"), or |
|
3287 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|
3288 * in which case the provisions of the GPL or the LGPL are applicable instead |
|
3289 * of those above. If you wish to allow use of your version of this file only |
|
3290 * under the terms of either the GPL or the LGPL, and not to allow others to |
|
3291 * use your version of this file under the terms of the NPL, indicate your |
|
3292 @@ -40,71 +40,101 @@ |
|
3293 * ***** END LICENSE BLOCK ***** */ |
|
3294 |
|
3295 #ifndef __SYSTEM_PREF_H__ |
|
3296 #define __SYSTEM_PREF_H__ |
|
3297 |
|
3298 #include "nsCOMPtr.h" |
|
3299 #include "nsXPCOM.h" |
|
3300 #include "nsCRT.h" |
|
3301 -#include "nsIAppStartupNotifier.h" |
|
3302 -#include "nsICategoryManager.h" |
|
3303 -#include "nsIServiceManager.h" |
|
3304 #include "nsWeakReference.h" |
|
3305 -#include "nsIPrefService.h" |
|
3306 -#include "nsIPrefBranch2.h" |
|
3307 +#include "nsClassHashtable.h" |
|
3308 +#include "nsHashKeys.h" |
|
3309 +#include "nsMemory.h" |
|
3310 |
|
3311 -#include <nsIObserver.h> |
|
3312 +#include "nsISystemPrefService.h" |
|
3313 +#include "nsIObserver.h" |
|
3314 |
|
3315 -union MozPrefValue; |
|
3316 struct SysPrefItem; |
|
3317 |
|
3318 ////////////////////////////////////////////////////////////////////////// |
|
3319 // |
|
3320 // nsSystemPref, as an extension of mozilla pref service, reads some mozilla |
|
3321 // prefs from host system when the feature is enabled ("config.system-pref"). |
|
3322 // |
|
3323 -// nsSystemPref listens on NS_PREFSERVICE_READ_TOPIC_ID. When notified, |
|
3324 -// nsSystemPref will start the nsSystemPrefService (platform specific) to |
|
3325 -// read all the interested prefs (listed in sSysPrefList table) from system |
|
3326 -// and lock these prefs from user's modification. |
|
3327 +// nsSystemPref listens on NS_PREFSERVICE_READ_TOPIC_ID. When |
|
3328 +// notified, nsSystemPref will start the nsSystemPrefService (platform |
|
3329 +// specific) and tell it to override Mozilla prefs with its own |
|
3330 +// settings. |
|
3331 // |
|
3332 -// This feature will make mozilla integrated better into host platforms. If |
|
3333 -// users want to change the prefs read from system, the system provided pref |
|
3334 -// editor (i.e. gconf-editor in gnome) should be used. |
|
3335 +// When overriding a Mozilla preference the prefservice can request the |
|
3336 +// pref be locked or unlocked. If the pref is locked then we set the default |
|
3337 +// value and lock it in Mozilla so the user value is ignored and the user cannot |
|
3338 +// change the value. If the pref is unlocked then we set the user value |
|
3339 +// and unlock it in Mozilla so the user can change it. If the user changes it, |
|
3340 +// then the prefservice is notified so it can copy the value back to its |
|
3341 +// underlying store. |
|
3342 +// |
|
3343 +// We detect changes to Mozilla prefs by observing pref changes in the |
|
3344 +// user branch. |
|
3345 +// |
|
3346 +// For testing purposes, if the user toggles on |
|
3347 +// config.use_system_prefs then we save the current preferences before |
|
3348 +// overriding them from gconf, and if the user toggles off |
|
3349 +// config.use_system_prefs *in the same session* then we restore the |
|
3350 +// preferences. If the user exits without turning off use_system_prefs |
|
3351 +// then the saved values are lost and the new values are permanent. |
|
3352 +// |
|
3353 ////////////////////////////////////////////////////////////////////////// |
|
3354 |
|
3355 class nsSystemPref : public nsIObserver, |
|
3356 - public nsSupportsWeakReference |
|
3357 + public nsSupportsWeakReference, |
|
3358 + public nsISystemPref |
|
3359 { |
|
3360 public: |
|
3361 NS_DECL_ISUPPORTS |
|
3362 NS_DECL_NSIOBSERVER |
|
3363 |
|
3364 nsSystemPref(); |
|
3365 virtual ~nsSystemPref(); |
|
3366 nsresult Init(void); |
|
3367 |
|
3368 + // nsISystemPref |
|
3369 + virtual nsresult SetOverridingMozillaBoolPref(const char* aPrefName, |
|
3370 + PRBool aValue, PRBool aLocked, |
|
3371 + PRBool aPresent = PR_TRUE); |
|
3372 + virtual nsresult SetOverridingMozillaIntPref(const char* aPrefName, |
|
3373 + PRInt32 aValue, PRBool aLocked, |
|
3374 + PRBool aPresent = PR_TRUE); |
|
3375 + virtual nsresult SetOverridingMozillaStringPref(const char* aPrefName, |
|
3376 + const char* aValue, PRBool aLocked, |
|
3377 + PRBool aPresent = PR_TRUE); |
|
3378 + virtual nsresult StopOverridingMozillaPref(const char* aPrefName); |
|
3379 + virtual already_AddRefed<nsIPrefBranch2> GetPrefUserBranch(); |
|
3380 + virtual already_AddRefed<nsIPrefBranch> GetPrefDefaultBranch(); |
|
3381 + |
|
3382 private: |
|
3383 - // funcs used to load system prefs and save mozilla default prefs |
|
3384 - nsresult UseSystemPrefs(); |
|
3385 - nsresult ReadSystemPref(const char *aPrefName); |
|
3386 - nsresult SaveMozDefaultPref(const char *aPrefName, |
|
3387 - MozPrefValue *aPrefVal, |
|
3388 - PRBool *aLocked); |
|
3389 + // If we don't load the system prefs for any reason, then |
|
3390 + // set all config.lockdown.* preferences to PR_FALSE so that |
|
3391 + // residual lockdown settings are removed. |
|
3392 + nsresult FixupLockdownPrefs(); |
|
3393 |
|
3394 - // funcs used to load mozilla default prefs |
|
3395 - nsresult UseMozillaPrefs(); |
|
3396 - nsresult RestoreMozDefaultPref(const char *aPrefName, |
|
3397 - MozPrefValue *aPrefVal, |
|
3398 - PRBool aLocked); |
|
3399 + nsresult LoadSystemPrefs(); |
|
3400 |
|
3401 - nsCOMPtr<nsIPrefBranch2> mSysPrefService; |
|
3402 - PRBool mEnabled; // system pref is enabled or not |
|
3403 - SysPrefItem *mSysPrefs; |
|
3404 + nsresult RestoreMozillaPrefs(); |
|
3405 + |
|
3406 + nsresult OverridePref(const char* aPrefName, PRInt32 aType, |
|
3407 + void* aValue, PRBool aLock, PRBool aPresent); |
|
3408 + |
|
3409 + nsCOMPtr<nsISystemPrefService> mSysPrefService; |
|
3410 + nsClassHashtable<nsCStringHashKey,SysPrefItem> mSavedPrefs; |
|
3411 + // weak pointers to cached prefbranches |
|
3412 + nsIPrefBranch2* mCachedUserPrefBranch; |
|
3413 + nsIPrefBranch* mCachedDefaultPrefBranch; |
|
3414 + PRPackedBool mIgnorePrefSetting; |
|
3415 }; |
|
3416 |
|
3417 #define NS_SYSTEMPREF_CID \ |
|
3418 { /* {549abb24-7c9d-4aba-915e-7ce0b716b32f} */ \ |
|
3419 0x549abb24, \ |
|
3420 0x7c9d, \ |
|
3421 0x4aba, \ |
|
3422 { 0x91, 0x5e, 0x7c, 0xe0, 0xb7, 0x16, 0xb3, 0x2f } \ |
|
3423 diff --git a/extensions/pref/system-pref/src/nsSystemPrefFactory.cpp b/extensions/pref/system-pref/src/nsSystemPrefFactory.cpp |
|
3424 --- a/extensions/pref/system-pref/src/nsSystemPrefFactory.cpp |
|
3425 +++ b/extensions/pref/system-pref/src/nsSystemPrefFactory.cpp |
|
3426 @@ -37,20 +37,20 @@ |
|
3427 * the provisions above, a recipient may use your version of this file under |
|
3428 * the terms of any one of the NPL, the GPL or the LGPL. |
|
3429 * |
|
3430 * ***** END LICENSE BLOCK ***** */ |
|
3431 |
|
3432 #include "nsICategoryManager.h" |
|
3433 #include "nsIGenericFactory.h" |
|
3434 #include "nsSystemPref.h" |
|
3435 -#include "nsSystemPrefService.h" |
|
3436 +#include "nsIServiceManager.h" |
|
3437 +#include "nsIAppStartupNotifier.h" |
|
3438 |
|
3439 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPref, Init) |
|
3440 -NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPrefService, Init) |
|
3441 |
|
3442 // Registering nsSystemPref module as part of the app-startup category to get |
|
3443 // it instantiated. |
|
3444 |
|
3445 static NS_METHOD |
|
3446 RegisterSystemPref(nsIComponentManager *aCompMgr, |
|
3447 nsIFile *aPath, |
|
3448 const char *registryLocation, |
|
3449 @@ -91,16 +91,11 @@ UnRegisterSystemPref(nsIComponentManager |
|
3450 static const nsModuleComponentInfo components[] = { |
|
3451 { NS_SYSTEMPREF_CLASSNAME, |
|
3452 NS_SYSTEMPREF_CID, |
|
3453 NS_SYSTEMPREF_CONTRACTID, |
|
3454 nsSystemPrefConstructor, |
|
3455 RegisterSystemPref, |
|
3456 UnRegisterSystemPref, |
|
3457 }, |
|
3458 - { NS_SYSTEMPREF_SERVICE_CLASSNAME, |
|
3459 - NS_SYSTEMPREF_SERVICE_CID, |
|
3460 - NS_SYSTEMPREF_SERVICE_CONTRACTID, |
|
3461 - nsSystemPrefServiceConstructor, |
|
3462 - }, |
|
3463 }; |
|
3464 |
|
3465 NS_IMPL_NSGETMODULE(nsSystemPrefModule, components) |
|
3466 diff --git a/toolkit/library/Makefile.in b/toolkit/library/Makefile.in |
|
3467 --- a/toolkit/library/Makefile.in |
|
3468 +++ b/toolkit/library/Makefile.in |
|
3469 @@ -229,16 +229,20 @@ endif |
|
3470 ifdef NS_OSSO |
|
3471 EXTRA_DSO_LDOPTS += $(LIBOSSO_LIBS) |
|
3472 endif |
|
3473 |
|
3474 ifdef MOZ_ENABLE_DBUS |
|
3475 EXTRA_DSO_LDOPTS += $(MOZ_DBUS_GLIB_LIBS) |
|
3476 endif |
|
3477 |
|
3478 +ifdef MOZ_ENABLE_GCONF |
|
3479 +EXTRA_DSO_LDOPTS += $(MOZ_GCONF_LIBS) |
|
3480 +endif |
|
3481 + |
|
3482 ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT)) |
|
3483 EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) $(XEXT_LIBS) $(XCOMPOSITE_LIBS) $(MOZ_PANGO_LIBS) $(MOZ_GTK2_LIBS) $(XT_LIBS) -lgthread-2.0 |
|
3484 EXTRA_DSO_LDOPTS += $(FT2_LIBS) |
|
3485 endif |
|
3486 |
|
3487 ifeq (qt,$(MOZ_WIDGET_TOOLKIT)) |
|
3488 EXTRA_DSO_LDOPTS += $(XLDFLAGS) $(XLIBS) $(XT_LIBS) $(MOZ_QT_LIBS) -lgthread-2.0 |
|
3489 EXTRA_DSO_LDOPTS += $(FT2_LIBS) |
|
3490 diff --git a/toolkit/toolkit-tiers.mk b/toolkit/toolkit-tiers.mk |
|
3491 --- a/toolkit/toolkit-tiers.mk |
|
3492 +++ b/toolkit/toolkit-tiers.mk |
|
3493 @@ -253,16 +253,23 @@ endif |
|
3494 ifdef MOZ_ENABLE_LIBXUL |
|
3495 tier_toolkit_dirs += xpcom/stub |
|
3496 endif |
|
3497 |
|
3498 ifdef NS_TRACE_MALLOC |
|
3499 tier_toolkit_dirs += tools/trace-malloc |
|
3500 endif |
|
3501 |
|
3502 +# gconf module is external |
|
3503 +ifdef MOZ_PREF_EXTENSIONS |
|
3504 +ifdef MOZ_ENABLE_GCONF |
|
3505 +tier_toolkit_dirs += extensions/pref/system-pref/src/gconf |
|
3506 +endif |
|
3507 +endif |
|
3508 + |
|
3509 ifdef MOZ_ENABLE_GNOME_COMPONENT |
|
3510 tier_toolkit_dirs += toolkit/system/gnome |
|
3511 endif |
|
3512 |
|
3513 ifndef MOZ_ENABLE_LIBCONIC |
|
3514 # if libconic is present, it will do its own network monitoring |
|
3515 ifdef MOZ_ENABLE_DBUS |
|
3516 tier_toolkit_dirs += toolkit/system/dbus |