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