forked from pool/MozillaFirefox
3268 lines
121 KiB
Diff
3268 lines
121 KiB
Diff
|
Index: extensions/pref/system-pref/src/nsSystemPref.h
|
||
|
================================================================================
|
||
|
--- browser/installer/unix/packages-static
|
||
|
+++ browser/installer/unix/packages-static
|
||
|
@@ -210,6 +210,7 @@
|
||
|
bin/components/nsUpdateService.js
|
||
|
bin/components/extensions.xpt
|
||
|
bin/components/update.xpt
|
||
|
+bin/components/libsystem-pref-gconf.so
|
||
|
bin/components/nsBookmarkTransactionManager.js
|
||
|
bin/components/nsSessionStartup.js
|
||
|
bin/components/nsSessionStore.js
|
||
|
--- config/autoconf.mk.in
|
||
|
+++ config/autoconf.mk.in
|
||
|
@@ -226,6 +226,7 @@
|
||
|
MOZ_GNOMEVFS_CFLAGS = @MOZ_GNOMEVFS_CFLAGS@
|
||
|
MOZ_GNOMEVFS_LIBS = @MOZ_GNOMEVFS_LIBS@
|
||
|
|
||
|
+MOZ_ENABLE_GCONF = @MOZ_ENABLE_GCONF@
|
||
|
MOZ_GCONF_CFLAGS = @MOZ_GCONF_CFLAGS@
|
||
|
MOZ_GCONF_LIBS = @MOZ_GCONF_LIBS@
|
||
|
|
||
|
--- configure.in
|
||
|
+++ configure.in
|
||
|
@@ -4709,6 +4709,7 @@
|
||
|
])
|
||
|
fi
|
||
|
|
||
|
+ AC_SUBST(MOZ_ENABLE_GCONF)
|
||
|
AC_SUBST(MOZ_GCONF_CFLAGS)
|
||
|
AC_SUBST(MOZ_GCONF_LIBS)
|
||
|
|
||
|
--- extensions/pref/system-pref/src/Makefile.in
|
||
|
+++ extensions/pref/system-pref/src/Makefile.in
|
||
|
@@ -47,14 +47,13 @@
|
||
|
include $(DEPTH)/config/autoconf.mk
|
||
|
|
||
|
MODULE = system-pref
|
||
|
-LIBRARY_NAME = system-pref_s
|
||
|
+LIBRARY_NAME = system-pref
|
||
|
ifneq ($(OS_ARCH),WINNT)
|
||
|
SHORT_LIBNAME = syspref
|
||
|
endif
|
||
|
|
||
|
-# We want to force the creation of a static lib.
|
||
|
-FORCE_STATIC_LIB = 1
|
||
|
MOZILLA_INTERNAL_API = 1
|
||
|
+GRE_MODULE = 1
|
||
|
|
||
|
REQUIRES = xpcom \
|
||
|
string \
|
||
|
@@ -62,27 +61,25 @@
|
||
|
pref \
|
||
|
$(NULL)
|
||
|
|
||
|
-ifdef MOZ_ENABLE_GTK2
|
||
|
+ifdef MOZ_ENABLE_GCONF
|
||
|
DIRS = gconf
|
||
|
endif
|
||
|
|
||
|
-EXTRA_DSO_LDOPTS = \
|
||
|
- -L$(DIST)/bin \
|
||
|
- $(MOZ_COMPONENT_LIBS) \
|
||
|
- $(NULL)
|
||
|
-
|
||
|
CPPSRCS = \
|
||
|
nsSystemPref.cpp \
|
||
|
+ nsSystemPrefFactory.cpp \
|
||
|
$(NULL)
|
||
|
|
||
|
+EXTRA_DSO_LDOPTS = \
|
||
|
+ $(MOZ_COMPONENT_LIBS) \
|
||
|
+ $(NULL)
|
||
|
+
|
||
|
EXPORTS = \
|
||
|
- nsSystemPrefLog.h \
|
||
|
+ nsISystemPrefService.h \
|
||
|
$(NULL)
|
||
|
|
||
|
-include $(topsrcdir)/config/rules.mk
|
||
|
+EXPORT_LIBRARY = 1
|
||
|
+IS_COMPONENT = 1
|
||
|
+MODULE_NAME = nsSystemPrefModule
|
||
|
|
||
|
-ifdef MOZ_ENABLE_GTK2
|
||
|
-INCLUDES += \
|
||
|
- -I$(srcdir)/gconf \
|
||
|
- $(NULL)
|
||
|
-endif
|
||
|
+include $(topsrcdir)/config/rules.mk
|
||
|
--- extensions/pref/system-pref/src/gconf/Makefile.in
|
||
|
+++ extensions/pref/system-pref/src/gconf/Makefile.in
|
||
|
@@ -46,44 +46,36 @@
|
||
|
|
||
|
include $(DEPTH)/config/autoconf.mk
|
||
|
|
||
|
-MODULE = system-pref
|
||
|
-LIBRARY_NAME = system-pref
|
||
|
+MODULE = system-pref-gconf
|
||
|
+LIBRARY_NAME = system-pref-gconf
|
||
|
GRE_MODULE = 1
|
||
|
MOZILLA_INTERNAL_API = 1
|
||
|
|
||
|
+PACKAGE_FILE = gconf.pkg
|
||
|
+
|
||
|
REQUIRES = pref \
|
||
|
+ system-pref \
|
||
|
string \
|
||
|
xpcom \
|
||
|
embedcomponents \
|
||
|
+ necko \
|
||
|
$(NULL)
|
||
|
|
||
|
CPPSRCS = \
|
||
|
nsSystemPrefService.cpp \
|
||
|
- nsSystemPrefFactory.cpp \
|
||
|
$(NULL)
|
||
|
|
||
|
-SHARED_LIBRARY_LIBS = $(DIST)/lib/libsystem-pref_s.a
|
||
|
-
|
||
|
EXTRA_DSO_LDOPTS = \
|
||
|
- -L$(DIST)/bin \
|
||
|
$(MOZ_COMPONENT_LIBS) \
|
||
|
- $(MOZ_GTK2_LIBS) \
|
||
|
+ $(MOZ_GTK2_LIBS) \
|
||
|
+ $(MOZ_GCONF_LIBS) \
|
||
|
$(NULL)
|
||
|
|
||
|
-EXPORT_LIBRARY = 1
|
||
|
+#EXPORT_LIBRARY = 1
|
||
|
IS_COMPONENT = 1
|
||
|
-MODULE_NAME = nsSystemPrefModule
|
||
|
-
|
||
|
-EXPORTS = \
|
||
|
- nsSystemPrefService.h \
|
||
|
- $(NULL)
|
||
|
+FORCE_SHARED_LIB = 1
|
||
|
|
||
|
include $(topsrcdir)/config/rules.mk
|
||
|
|
||
|
-CFLAGS += $(MOZ_GTK2_CFLAGS)
|
||
|
-CXXFLAGS += $(MOZ_GTK2_CFLAGS)
|
||
|
-
|
||
|
-LOCAL_INCLUDES = -I$(srcdir)/..
|
||
|
-
|
||
|
-export::
|
||
|
- $(INSTALL) $(srcdir)/../nsSystemPrefFactory.cpp .
|
||
|
+CFLAGS += $(MOZ_GTK2_CFLAGS) $(MOZ_GCONF_CFLAGS)
|
||
|
+CXXFLAGS += $(MOZ_GTK2_CFLAGS) $(MOZ_GCONF_CFLAGS)
|
||
|
--- extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
|
||
|
+++ extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp
|
||
|
@@ -23,7 +23,7 @@
|
||
|
*
|
||
|
* Original Author: Bolian Yin (bolian.yin@sun.com)
|
||
|
*
|
||
|
- * Contributor(s):
|
||
|
+ * Contributor(s): Robert O'Callahan/Novell (rocallahan@novell.com)
|
||
|
*
|
||
|
* Alternatively, the contents of this file may be used under the terms of
|
||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||
|
@@ -41,6 +41,7 @@
|
||
|
|
||
|
#include <glib.h>
|
||
|
#include <glib-object.h>
|
||
|
+#include <gconf/gconf-client.h>
|
||
|
|
||
|
#include "plstr.h"
|
||
|
#include "nsCOMPtr.h"
|
||
|
@@ -48,837 +49,1259 @@
|
||
|
#include "nsIServiceManager.h"
|
||
|
#include "nsIObserver.h"
|
||
|
#include "nsWeakReference.h"
|
||
|
-
|
||
|
+#include "nsIPrefBranch2.h"
|
||
|
+#include "nsISystemPrefService.h"
|
||
|
+#include "nsDataHashtable.h"
|
||
|
+#include "nsHashKeys.h"
|
||
|
+#include "nsICategoryManager.h"
|
||
|
+#include "nsIGenericFactory.h"
|
||
|
#include "nsString.h"
|
||
|
-#include "nsSystemPrefLog.h"
|
||
|
-#include "nsSystemPrefService.h"
|
||
|
-
|
||
|
-/*************************************************************************
|
||
|
- * The strange thing here is that we load the gconf library manually and
|
||
|
- * search the function pointers we need. If that process fails, no gconf
|
||
|
- * support is available in mozilla. The aim is to make mozilla independent
|
||
|
- * on gconf, in both compile time and run time.
|
||
|
- ************************************************************************/
|
||
|
-
|
||
|
-//gconf types
|
||
|
-extern "C" {
|
||
|
-
|
||
|
- typedef enum {
|
||
|
- GCONF_VALUE_INVALID,
|
||
|
- GCONF_VALUE_STRING,
|
||
|
- GCONF_VALUE_INT,
|
||
|
- GCONF_VALUE_FLOAT,
|
||
|
- GCONF_VALUE_BOOL,
|
||
|
- GCONF_VALUE_SCHEMA,
|
||
|
-
|
||
|
- GCONF_VALUE_LIST,
|
||
|
- GCONF_VALUE_PAIR
|
||
|
-
|
||
|
- }GConfValueType;
|
||
|
-
|
||
|
- typedef struct {
|
||
|
- GConfValueType type;
|
||
|
- }GConfValue;
|
||
|
-
|
||
|
- typedef void * (*GConfClientGetDefaultType) (void);
|
||
|
- typedef PRBool (*GConfClientGetBoolType) (void *client, const gchar *key,
|
||
|
- GError **err);
|
||
|
- typedef gchar* (*GConfClientGetStringType) (void *client, const gchar *key,
|
||
|
- GError **err);
|
||
|
- typedef PRInt32 (*GConfClientGetIntType) (void *client, const gchar *key,
|
||
|
- GError **err);
|
||
|
- typedef void (*GConfClientNotifyFuncType) (void* client, guint cnxn_id,
|
||
|
- void *entry,
|
||
|
- gpointer user_data);
|
||
|
- typedef guint (*GConfClientNotifyAddType) (void* client,
|
||
|
- const gchar* namespace_section,
|
||
|
- GConfClientNotifyFuncType func,
|
||
|
- gpointer user_data,
|
||
|
- GFreeFunc destroy_notify,
|
||
|
- GError** err);
|
||
|
- typedef void (*GConfClientNotifyRemoveType) (void *client,
|
||
|
- guint cnxn);
|
||
|
- typedef void (*GConfClientAddDirType) (void *client,
|
||
|
- const gchar *dir,
|
||
|
- guint8 preload,
|
||
|
- GError **err);
|
||
|
- typedef void (*GConfClientRemoveDirType) (void *client,
|
||
|
- const gchar *dir,
|
||
|
- GError **err);
|
||
|
-
|
||
|
- typedef const char* (*GConfEntryGetKeyType) (const void *entry);
|
||
|
- typedef GConfValue* (*GConfEntryGetValueType) (const void *entry);
|
||
|
-
|
||
|
- typedef const char* (*GConfValueGetStringType) (const GConfValue *value);
|
||
|
- typedef PRInt32 (*GConfValueGetIntType) (const GConfValue *value);
|
||
|
- typedef PRBool (*GConfValueGetBoolType) (const GConfValue *value);
|
||
|
+#include "nsIPermissionManager.h"
|
||
|
|
||
|
-
|
||
|
- static void gconf_key_listener (void* client, guint cnxn_id,
|
||
|
- void *entry, gpointer user_data);
|
||
|
-}
|
||
|
+#define NS_SYSTEMPREF_SERVICE_CID \
|
||
|
+ { /* {3724e748-b088-4bf8-9298-aad426b66293} */ \
|
||
|
+ 0x3724e748, \
|
||
|
+ 0xb088, \
|
||
|
+ 0x4bf8, \
|
||
|
+ { 0x92, 0x98, 0xaa, 0xd4, 0x26, 0xb6, 0x62, 0x93 } \
|
||
|
+ }
|
||
|
+
|
||
|
+#define NS_SYSTEMPREF_SERVICE_CLASSNAME "System Preferences Platform Service"
|
||
|
+
|
||
|
+/**
|
||
|
+ * We can link directly to the gconf library. If it's not available,
|
||
|
+ * this component just won't load and no system prefs will be offered.
|
||
|
+ */
|
||
|
+
|
||
|
+#define NUM_ELEM(a) (sizeof(a)/sizeof(a[0]))
|
||
|
+
|
||
|
+class nsSystemPrefService;
|
||
|
+
|
||
|
+/**
|
||
|
+ * List the preferences that have a simple mapping between Moz and gconf.
|
||
|
+ * These preferences have the same meaning and their values are
|
||
|
+ * automatically converted.
|
||
|
+ */
|
||
|
+struct SimplePrefMapping {
|
||
|
+ const char *mozPrefName;
|
||
|
+ const char *gconfPrefName;
|
||
|
+ /**
|
||
|
+ * If this is PR_FALSE, then we never allow Mozilla to change
|
||
|
+ * this setting. The Mozilla pref will always be locked.
|
||
|
+ * If this is PR_TRUE then Mozilla will be allowed to change
|
||
|
+ * the setting --- but only if it is writable in gconf.
|
||
|
+ */
|
||
|
+ PRBool allowWritesFromMozilla;
|
||
|
+};
|
||
|
+typedef nsresult (* ComplexGConfPrefChanged)(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient);
|
||
|
+typedef nsresult (* ComplexMozPrefChanged)(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient);
|
||
|
+struct ComplexGConfPrefMapping {
|
||
|
+ const char* gconfPrefName;
|
||
|
+ ComplexGConfPrefChanged callback;
|
||
|
+};
|
||
|
|
||
|
-struct GConfCallbackData
|
||
|
-{
|
||
|
- GConfProxy *proxy;
|
||
|
- void * userData;
|
||
|
- PRUint32 atom;
|
||
|
- PRUint32 notifyId;
|
||
|
+struct ComplexMozPrefMapping {
|
||
|
+ const char* mozPrefName;
|
||
|
+ ComplexMozPrefChanged callback;
|
||
|
};
|
||
|
-//////////////////////////////////////////////////////////////////////
|
||
|
-// GConPrxoy is a thin wrapper for easy use of gconf funcs. It loads the
|
||
|
-// gconf library and initializes the func pointers for later use.
|
||
|
-//////////////////////////////////////////////////////////////////////
|
||
|
-class GConfProxy
|
||
|
+
|
||
|
+class nsSystemPrefService : public nsISystemPrefService
|
||
|
{
|
||
|
public:
|
||
|
- GConfProxy(nsSystemPrefService* aSysPrefService);
|
||
|
- ~GConfProxy();
|
||
|
- PRBool Init();
|
||
|
-
|
||
|
- nsresult GetBoolPref(const char *aMozKey, PRBool *retval);
|
||
|
- nsresult GetCharPref(const char *aMozKey, char **retval);
|
||
|
- nsresult GetIntPref(const char *aMozKey, PRInt32 *retval);
|
||
|
+ NS_DECL_ISUPPORTS
|
||
|
|
||
|
- nsresult NotifyAdd (PRUint32 aAtom, void *aUserData);
|
||
|
- nsresult NotifyRemove (PRUint32 aAtom, const void *aUserData);
|
||
|
+ nsresult Init();
|
||
|
|
||
|
- nsresult GetAtomForMozKey(const char *aMozKey, PRUint32 *aAtom) {
|
||
|
- return GetAtom(aMozKey, 0, aAtom);
|
||
|
- }
|
||
|
- const char *GetMozKey(PRUint32 aAtom) {
|
||
|
- return GetKey(aAtom, 0);
|
||
|
+ virtual nsresult LoadSystemPreferences(nsISystemPref* aPrefs);
|
||
|
+ virtual nsresult NotifyMozillaPrefChanged(const char* aPrefName);
|
||
|
+ virtual nsresult NotifyUnloadSystemPreferences();
|
||
|
+
|
||
|
+ nsSystemPrefService();
|
||
|
+ virtual ~nsSystemPrefService();
|
||
|
+
|
||
|
+ nsISystemPref* GetPrefs() { return mPref; }
|
||
|
+ SimplePrefMapping* GetSimpleCallbackData(PRUint32 aKey) {
|
||
|
+ SimplePrefMapping* result = nsnull;
|
||
|
+ mGConfSimpleCallbacks.Get(aKey, &result);
|
||
|
+ return result;
|
||
|
+ }
|
||
|
+ ComplexGConfPrefMapping* GetComplexCallbackData(PRUint32 aKey) {
|
||
|
+ ComplexGConfPrefMapping* result = nsnull;
|
||
|
+ mGConfComplexCallbacks.Get(aKey, &result);
|
||
|
+ return result;
|
||
|
}
|
||
|
|
||
|
- void OnNotify(void *aClient, void * aEntry, PRUint32 aNotifyId,
|
||
|
- GConfCallbackData *aData);
|
||
|
-
|
||
|
private:
|
||
|
- void *mGConfClient;
|
||
|
- PRLibrary *mGConfLib;
|
||
|
- PRBool mInitialized;
|
||
|
- nsSystemPrefService *mSysPrefService;
|
||
|
-
|
||
|
- //listeners
|
||
|
- nsAutoVoidArray *mObservers;
|
||
|
-
|
||
|
- void InitFuncPtrs();
|
||
|
- //gconf public func ptrs
|
||
|
-
|
||
|
- //gconf client funcs
|
||
|
- GConfClientGetDefaultType GConfClientGetDefault;
|
||
|
- GConfClientGetBoolType GConfClientGetBool;
|
||
|
- GConfClientGetStringType GConfClientGetString;
|
||
|
- GConfClientGetIntType GConfClientGetInt;
|
||
|
- GConfClientNotifyAddType GConfClientNotifyAdd;
|
||
|
- GConfClientNotifyRemoveType GConfClientNotifyRemove;
|
||
|
- GConfClientAddDirType GConfClientAddDir;
|
||
|
- GConfClientRemoveDirType GConfClientRemoveDir;
|
||
|
-
|
||
|
- //gconf entry funcs
|
||
|
- GConfEntryGetValueType GConfEntryGetValue;
|
||
|
- GConfEntryGetKeyType GConfEntryGetKey;
|
||
|
-
|
||
|
- //gconf value funcs
|
||
|
- GConfValueGetBoolType GConfValueGetBool;
|
||
|
- GConfValueGetStringType GConfValueGetString;
|
||
|
- GConfValueGetIntType GConfValueGetInt;
|
||
|
-
|
||
|
- //pref name translating stuff
|
||
|
- nsresult GetAtom(const char *aKey, PRUint8 aNameType, PRUint32 *aAtom);
|
||
|
- nsresult GetAtomForGConfKey(const char *aGConfKey, PRUint32 *aAtom) \
|
||
|
- {return GetAtom(aGConfKey, 1, aAtom);}
|
||
|
- const char *GetKey(PRUint32 aAtom, PRUint8 aNameType);
|
||
|
- const char *GetGConfKey(PRUint32 aAtom) \
|
||
|
- {return GetKey(aAtom, 1); }
|
||
|
- inline const char *MozKey2GConfKey(const char *aMozKey);
|
||
|
-
|
||
|
- //const strings
|
||
|
- static const char sPrefGConfKey[];
|
||
|
- static const char sDefaultLibName1[];
|
||
|
- static const char sDefaultLibName2[];
|
||
|
+ nsISystemPref* mPref;
|
||
|
+ nsDataHashtable<nsUint32HashKey, SimplePrefMapping*> mGConfSimpleCallbacks;
|
||
|
+ nsDataHashtable<nsUint32HashKey, ComplexGConfPrefMapping*> mGConfComplexCallbacks;
|
||
|
+ // This is set to PR_FALSE temporarily to stop listening to gconf
|
||
|
+ // change notifications (while we change gconf values)
|
||
|
+ PRPackedBool mListenToGConf;
|
||
|
};
|
||
|
|
||
|
-struct SysPrefCallbackData {
|
||
|
- nsISupports *observer;
|
||
|
- PRBool bIsWeakRef;
|
||
|
- PRUint32 prefAtom;
|
||
|
-};
|
||
|
-
|
||
|
-PRBool PR_CALLBACK
|
||
|
-sysPrefDeleteObserver(void *aElement, void *aData) {
|
||
|
- SysPrefCallbackData *pElement =
|
||
|
- NS_STATIC_CAST(SysPrefCallbackData *, aElement);
|
||
|
- NS_RELEASE(pElement->observer);
|
||
|
- nsMemory::Free(pElement);
|
||
|
- return PR_TRUE;
|
||
|
-}
|
||
|
-
|
||
|
-NS_IMPL_ISUPPORTS2(nsSystemPrefService, nsIPrefBranch, nsIPrefBranch2)
|
||
|
-
|
||
|
-/* public */
|
||
|
nsSystemPrefService::nsSystemPrefService()
|
||
|
- :mInitialized(PR_FALSE),
|
||
|
- mGConf(nsnull),
|
||
|
- mObservers(nsnull)
|
||
|
+ : mPref(nsnull), mListenToGConf(PR_TRUE)
|
||
|
{
|
||
|
+ mGConfSimpleCallbacks.Init();
|
||
|
+ mGConfComplexCallbacks.Init();
|
||
|
}
|
||
|
|
||
|
nsSystemPrefService::~nsSystemPrefService()
|
||
|
{
|
||
|
- mInitialized = PR_FALSE;
|
||
|
-
|
||
|
- if (mGConf)
|
||
|
- delete mGConf;
|
||
|
- if (mObservers) {
|
||
|
- (void)mObservers->EnumerateForwards(sysPrefDeleteObserver, nsnull);
|
||
|
- delete mObservers;
|
||
|
- }
|
||
|
+ NotifyUnloadSystemPreferences();
|
||
|
}
|
||
|
|
||
|
nsresult
|
||
|
nsSystemPrefService::Init()
|
||
|
{
|
||
|
- if (!gSysPrefLog) {
|
||
|
- gSysPrefLog = PR_NewLogModule("Syspref");
|
||
|
- if (!gSysPrefLog) return NS_ERROR_OUT_OF_MEMORY;
|
||
|
- }
|
||
|
-
|
||
|
- SYSPREF_LOG(("Init SystemPref Service\n"));
|
||
|
- if (mInitialized)
|
||
|
- return NS_ERROR_FAILURE;
|
||
|
-
|
||
|
- if (!mGConf) {
|
||
|
- mGConf = new GConfProxy(this);
|
||
|
- if (!mGConf->Init()) {
|
||
|
- delete mGConf;
|
||
|
- mGConf = nsnull;
|
||
|
- return NS_ERROR_FAILURE;
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
- mInitialized = PR_TRUE;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
-/* readonly attribute string root; */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::GetRoot(char * *aRoot)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
-}
|
||
|
+NS_IMPL_ISUPPORTS1(nsSystemPrefService, nsISystemPrefService)
|
||
|
|
||
|
-/* long getPrefType (in string aPrefName); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::GetPrefType(const char *aPrefName, PRInt32 *_retval)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
+static GConfClient* GetGConf() {
|
||
|
+ return gconf_client_get_default();
|
||
|
}
|
||
|
|
||
|
-/* boolean getBoolPref (in string aPrefName); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::GetBoolPref(const char *aPrefName, PRBool *_retval)
|
||
|
+static PRBool VerifyMatchingTypes(nsISystemPref* aPrefs,
|
||
|
+ const char* aMozPref, GConfValue* aVal)
|
||
|
{
|
||
|
- return mInitialized ?
|
||
|
- mGConf->GetBoolPref(aPrefName, _retval) : NS_ERROR_FAILURE;
|
||
|
-}
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefBranch = aPrefs->GetPrefUserBranch();
|
||
|
+ PRInt32 type;
|
||
|
+ nsresult rv = prefBranch->GetPrefType(aMozPref, &type);
|
||
|
+ if (NS_FAILED(rv)) {
|
||
|
+ // pref probably doesn't exist. Let gconf set it.
|
||
|
+ return PR_TRUE;
|
||
|
+ }
|
||
|
|
||
|
-/* void setBoolPref (in string aPrefName, in long aValue); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::SetBoolPref(const char *aPrefName, PRInt32 aValue)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
+ PRBool ok;
|
||
|
+ switch (aVal->type) {
|
||
|
+ case GCONF_VALUE_STRING:
|
||
|
+ ok = type == nsIPrefBranch2::PREF_STRING;
|
||
|
+ break;
|
||
|
+ case GCONF_VALUE_INT:
|
||
|
+ ok = type == nsIPrefBranch2::PREF_INT;
|
||
|
+ break;
|
||
|
+ case GCONF_VALUE_BOOL:
|
||
|
+ ok = type == nsIPrefBranch2::PREF_BOOL;
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ NS_ERROR("Unhandled gconf preference type");
|
||
|
+ return PR_FALSE;
|
||
|
+ }
|
||
|
+
|
||
|
+ NS_ASSERTION(ok, "Mismatched gconf/Mozilla pref types");
|
||
|
+ return ok;
|
||
|
}
|
||
|
|
||
|
-/* string getCharPref (in string aPrefName); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::GetCharPref(const char *aPrefName, char **_retval)
|
||
|
-{
|
||
|
- return mInitialized ?
|
||
|
- mGConf->GetCharPref(aPrefName, _retval) : NS_ERROR_FAILURE;
|
||
|
-}
|
||
|
+/**
|
||
|
+ * Map a gconf pref value into the corresponding Mozilla pref.
|
||
|
+ */
|
||
|
+static nsresult ApplySimpleMapping(SimplePrefMapping* aMap,
|
||
|
+ nsISystemPref* aPrefs,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ GConfValue* val = gconf_client_get(aClient, aMap->gconfPrefName, nsnull);
|
||
|
+ if (!val) {
|
||
|
+ // No gconf key, so there's really nothing to do
|
||
|
+ return NS_OK;
|
||
|
+ }
|
||
|
|
||
|
-/* void setCharPref (in string aPrefName, in string aValue); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::SetCharPref(const char *aPrefName, const char *aValue)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
-}
|
||
|
+ VerifyMatchingTypes(aPrefs, aMap->mozPrefName, val);
|
||
|
|
||
|
-/* long getIntPref (in string aPrefName); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::GetIntPref(const char *aPrefName, PRInt32 *_retval)
|
||
|
-{
|
||
|
- return mInitialized ?
|
||
|
- mGConf->GetIntPref(aPrefName, _retval) : NS_ERROR_FAILURE;
|
||
|
-}
|
||
|
+ PRBool locked = !aMap->allowWritesFromMozilla ||
|
||
|
+ !gconf_client_key_is_writable(aClient, aMap->gconfPrefName, nsnull);
|
||
|
+ nsresult rv;
|
||
|
+ switch (val->type) {
|
||
|
+ case GCONF_VALUE_STRING: {
|
||
|
+ const char* str = gconf_value_get_string(val);
|
||
|
+ rv = aPrefs->SetOverridingMozillaStringPref(aMap->mozPrefName, str, locked);
|
||
|
+ // XXX do we need to free 'str' here?
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ case GCONF_VALUE_INT:
|
||
|
+ rv = aPrefs->SetOverridingMozillaIntPref(aMap->mozPrefName,
|
||
|
+ gconf_value_get_int(val), locked);
|
||
|
+ break;
|
||
|
+ case GCONF_VALUE_BOOL:
|
||
|
+ rv = aPrefs->SetOverridingMozillaBoolPref(aMap->mozPrefName,
|
||
|
+ gconf_value_get_bool(val), locked);
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ NS_ERROR("Unusable gconf value type");
|
||
|
+ rv = NS_ERROR_FAILURE;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
+ gconf_value_free(val);
|
||
|
+ return rv;
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * Map a Mozilla pref into the corresponding gconf pref, if
|
||
|
+ * that's allowed.
|
||
|
+ */
|
||
|
+static nsresult ReverseApplySimpleMapping(SimplePrefMapping* aMap,
|
||
|
+ nsISystemPref* aPrefs,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ // Verify that the gconf key has the right type, if it exists
|
||
|
+ GConfValue* val = gconf_client_get(aClient, aMap->gconfPrefName, nsnull);
|
||
|
+ if (val) {
|
||
|
+ VerifyMatchingTypes(aPrefs, aMap->mozPrefName, val);
|
||
|
+ gconf_value_free(val);
|
||
|
+ }
|
||
|
+
|
||
|
+ PRBool writable = aMap->allowWritesFromMozilla &&
|
||
|
+ gconf_client_key_is_writable(aClient, aMap->gconfPrefName, nsnull);
|
||
|
+ if (!writable) {
|
||
|
+ NS_ERROR("Gconf key is not writable");
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ }
|
||
|
|
||
|
-/* void setIntPref (in string aPrefName, in long aValue); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::SetIntPref(const char *aPrefName, PRInt32 aValue)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
-}
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefBranch = aPrefs->GetPrefUserBranch();
|
||
|
+ PRInt32 type;
|
||
|
+ nsresult rv = prefBranch->GetPrefType(aMap->mozPrefName, &type);
|
||
|
+ if (NS_FAILED(rv)) {
|
||
|
+ NS_ERROR("Writing back a pref that doesn't exist?");
|
||
|
+ return rv;
|
||
|
+ }
|
||
|
|
||
|
-/* void getComplexValue (in string aPrefName, in nsIIDRef aType, [iid_is (aType), retval] out nsQIResult aValue); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::GetComplexValue(const char *aPrefName, const nsIID & aType, void * *aValue)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
-}
|
||
|
+ switch (type) {
|
||
|
+ case nsIPrefBranch2::PREF_STRING:
|
||
|
+ {
|
||
|
+ char* result;
|
||
|
+ rv = prefBranch->GetCharPref(aMap->mozPrefName, &result);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
|
||
|
-/* void setComplexValue (in string aPrefName, in nsIIDRef aType, in nsISupports aValue); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::SetComplexValue(const char *aPrefName, const nsIID & aType, nsISupports *aValue)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
-}
|
||
|
+ gconf_client_set_string(aClient, aMap->gconfPrefName, result, nsnull);
|
||
|
+ nsMemory::Free(result);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case nsIPrefBranch2::PREF_INT:
|
||
|
+ {
|
||
|
+ PRInt32 result;
|
||
|
+ rv = prefBranch->GetIntPref(aMap->mozPrefName, &result);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
|
||
|
-/* void clearUserPref (in string aPrefName); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::ClearUserPref(const char *aPrefName)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
-}
|
||
|
+ gconf_client_set_int(aClient, aMap->gconfPrefName, result, nsnull);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case nsIPrefBranch2::PREF_BOOL:
|
||
|
+ {
|
||
|
+ PRBool result;
|
||
|
+ rv = prefBranch->GetBoolPref(aMap->mozPrefName, &result);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
|
||
|
-/* void lockPref (in string aPrefName); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::LockPref(const char *aPrefName)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
-}
|
||
|
+ gconf_client_set_bool(aClient, aMap->gconfPrefName, result, nsnull);
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ NS_ERROR("Unhandled gconf preference type");
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ }
|
||
|
|
||
|
-/* boolean prefHasUserValue (in string aPrefName); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::PrefHasUserValue(const char *aPrefName, PRBool *_retval)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
+ return NS_OK;
|
||
|
}
|
||
|
|
||
|
-/* boolean prefIsLocked (in string aPrefName); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::PrefIsLocked(const char *aPrefName, PRBool *_retval)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
-}
|
||
|
+/* BEGIN preference mapping definition area
|
||
|
+ *
|
||
|
+ * There are a few rules that our preference maps have to obey:
|
||
|
+ *
|
||
|
+ * 1) Each mapping defines a relationship R between a set of GConf preferences and
|
||
|
+ * a set of Mozilla preferences that must *always* be true. Thus, when a Mozilla
|
||
|
+ * pref changes or a gconf pref changes, we may need to change something on the
|
||
|
+ * other side to preserve R. If a GConf preference is read-only, then we may
|
||
|
+ * need to lock one or more Mozilla preferences to avoid a situation where the
|
||
|
+ * Mozilla preference changes and we can't update the GConf preference to
|
||
|
+ * ensure R continues to hold.
|
||
|
+ *
|
||
|
+ * 2) If an unlocked Mozilla preference is changed, then we can only
|
||
|
+ * preserve R by changing GConf preferences; we are not allowed to
|
||
|
+ * change Mozilla preferences.
|
||
|
+ *
|
||
|
+ * 3) If a GConf preference is changed, then we can only preserve R by
|
||
|
+ * changing Moozilla preferences; we are nt allowed to change GConf
|
||
|
+ * preferences.
|
||
|
+ *
|
||
|
+ * For "simple" mappings, the relationship R is just of the form
|
||
|
+ * "GConf preference 'A' is equal to Mozilla preference 'B'". R is
|
||
|
+ * preserved by setting A to B when B changes, and by setting B to A
|
||
|
+ * when A changes. If A is read-only then we lock B (or we may just
|
||
|
+ * decide to lock B for other reasons). Thus rules 1-3 are satisfied.
|
||
|
+ *
|
||
|
+ * For "complex" mappings we have more complicated
|
||
|
+ * relationships. These are documented below.
|
||
|
+ */
|
||
|
+
|
||
|
+static SimplePrefMapping sSimplePrefMappings[] = {
|
||
|
+ // GNOME proxy settings; allow these to be set through the Firefox UI
|
||
|
+ {"network.proxy.http", "/system/http_proxy/host", PR_TRUE},
|
||
|
+ {"network.proxy.http_port", "/system/http_proxy/port", PR_TRUE},
|
||
|
+ {"network.proxy.ftp", "/system/proxy/ftp_host", PR_TRUE},
|
||
|
+ {"network.proxy.ftp_port", "/system/proxy/ftp_port", PR_TRUE},
|
||
|
+ {"network.proxy.ssl", "/system/proxy/secure_host", PR_TRUE},
|
||
|
+ {"network.proxy.ssl_port", "/system/proxy/secure_port", PR_TRUE},
|
||
|
+ {"network.proxy.socks", "/system/proxy/socks_host", PR_TRUE},
|
||
|
+ {"network.proxy.socks_port", "/system/proxy/socks_port", PR_TRUE},
|
||
|
+ {"network.proxy.autoconfig_url", "/system/proxy/autoconfig_url", PR_TRUE},
|
||
|
+
|
||
|
+ // GNOME accessibility setting; never allow this to be set by Firefox
|
||
|
+ {"config.use_system_prefs.accessibility",
|
||
|
+ "/desktop/gnome/interface/accessibility", PR_FALSE},
|
||
|
+
|
||
|
+ // GConf Firefox preferences; allow these to be set through the Firefox UI
|
||
|
+ {"security.enable_java", "/apps/firefox/web/java_enabled", PR_TRUE},
|
||
|
+ {"javascript.enabled", "/apps/firefox/web/javascript_enabled", PR_TRUE},
|
||
|
+ {"browser.startup.homepage", "/apps/firefox/general/homepage_url", PR_TRUE},
|
||
|
+ {"browser.cache.disk.capacity", "/apps/firefox/web/cache_size", PR_TRUE},
|
||
|
+ {"network.cookie.lifetimePolicy", "/apps/firefox/web/cookie_accept", PR_TRUE},
|
||
|
+
|
||
|
+ // UI lockdown settings; never allow these to be set by Firefox. There is no
|
||
|
+ // Firefox UI for these but they could otherwise be set via about:config.
|
||
|
+ {"config.lockdown.printing", "/desktop/gnome/lockdown/disable_printing", PR_FALSE},
|
||
|
+ {"config.lockdown.printsetup", "/desktop/gnome/lockdown/disable_print_setup", PR_FALSE},
|
||
|
+ {"config.lockdown.savepage", "/desktop/gnome/lockdown/disable_save_to_disk", PR_FALSE},
|
||
|
+ {"config.lockdown.history", "/apps/firefox/lockdown/disable_history", PR_FALSE},
|
||
|
+ {"config.lockdown.toolbarediting", "/apps/firefox/lockdown/disable_toolbar_editing", PR_FALSE},
|
||
|
+ {"config.lockdown.urlbar", "/apps/firefox/lockdown/disable_url_bar", PR_FALSE},
|
||
|
+ {"config.lockdown.bookmark", "/apps/firefox/lockdown/disable_bookmark_editing", PR_FALSE},
|
||
|
+ {"config.lockdown.disable_themes", "/apps/firefox/lockdown/disable_themes", PR_FALSE},
|
||
|
+ {"config.lockdown.disable_extensions", "/apps/firefox/lockdown/disable_extensions", PR_FALSE},
|
||
|
+ {"config.lockdown.searchbar", "/apps/firefox/lockdown/disable_searchbar", PR_FALSE},
|
||
|
+ {"config.lockdown.hidebookmark", "/apps/firefox/lockdown/hide_bookmark", PR_FALSE},
|
||
|
+};
|
||
|
|
||
|
-/* void unlockPref (in string aPrefName); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::UnlockPref(const char *aPrefName)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
+static nsresult ApplyListPref(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient,
|
||
|
+ const char* aGConfKey, const char* aMozKey,
|
||
|
+ char aSeparator)
|
||
|
+{
|
||
|
+ GSList* list = gconf_client_get_list(aClient, aGConfKey,
|
||
|
+ GCONF_VALUE_STRING, nsnull);
|
||
|
+ nsCAutoString str;
|
||
|
+ for (GSList* l = list; l; l = l->next) {
|
||
|
+ str.Append((const char*)l->data);
|
||
|
+ if (l->next) {
|
||
|
+ str.Append(aSeparator);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ PRBool lock = !gconf_client_key_is_writable(aClient, aGConfKey, nsnull);
|
||
|
+ nsresult rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaStringPref(aMozKey, str.get(), lock);
|
||
|
+ // XXX does this free the strings? Should it?
|
||
|
+ g_slist_free(list);
|
||
|
+ return rv;
|
||
|
+}
|
||
|
+static nsresult ReverseApplyListPref(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient,
|
||
|
+ const char* aGConfKey, const char* aMozKey,
|
||
|
+ char aSeparator)
|
||
|
+{
|
||
|
+ char* data = nsnull;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs =
|
||
|
+ aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ prefs->GetCharPref(aMozKey, &data);
|
||
|
+ if (!data)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ nsresult rv = NS_OK;
|
||
|
+ GSList* list = nsnull;
|
||
|
+ PRInt32 i = 0;
|
||
|
+ while (data[i]) {
|
||
|
+ const char* nextComma = strchr(data+i, ',');
|
||
|
+ PRInt32 tokLen = nextComma ? nextComma - (data+i) : strlen(data+i);
|
||
|
+ char* tok = strndup(data+i, tokLen);
|
||
|
+ if (!tok)
|
||
|
+ break;
|
||
|
+ GSList* newList = g_slist_append(list, tok);
|
||
|
+ if (!newList) {
|
||
|
+ rv = NS_ERROR_OUT_OF_MEMORY;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ list = newList;
|
||
|
+ if (!nextComma)
|
||
|
+ break;
|
||
|
+ i = nextComma + 1 - data;
|
||
|
+ }
|
||
|
+ nsMemory::Free(data);
|
||
|
+ if (NS_SUCCEEDED(rv)) {
|
||
|
+ gconf_client_set_list(aClient, aGConfKey, GCONF_VALUE_STRING, list, nsnull);
|
||
|
+ }
|
||
|
+ for (GSList* l = list; l; l = l->next) {
|
||
|
+ free(l->data);
|
||
|
+ }
|
||
|
+ g_slist_free(list);
|
||
|
+ return rv;
|
||
|
}
|
||
|
|
||
|
-/* void deleteBranch (in string aStartingAt); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::DeleteBranch(const char *aStartingAt)
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * "network.negotiate-auth.trusted-uris" is the comma-separated concatenation
|
||
|
+ * of the elements of the list "/apps/firefox/general/trusted_URIs"
|
||
|
+ */
|
||
|
+static const char GConfKey_TrustedURIs[] = "/apps/firefox/general/trusted_URIs";
|
||
|
+static const char MozKey_TrustedURIs[] = "network.negotiate-auth.trusted-uris";
|
||
|
+static nsresult ApplyTrustedURIs(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ return ApplyListPref(aPrefService, aClient,
|
||
|
+ GConfKey_TrustedURIs, MozKey_TrustedURIs, ',');
|
||
|
+}
|
||
|
+static nsresult ReverseApplyTrustedURIs(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ return ReverseApplyListPref(aPrefService, aClient,
|
||
|
+ GConfKey_TrustedURIs, MozKey_TrustedURIs, ',');
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * "network.negotiate-auth.delegation-uris" is the comma-separated concatenation
|
||
|
+ * of the elements of the list "/apps/firefox/general/delegation_URIs"
|
||
|
+ */
|
||
|
+static const char GConfKey_DelegationURIs[] = "/apps/firefox/general/delegation_URIs";
|
||
|
+static const char MozKey_DelegationURIs[] = "network.negotiate-auth.delegation-uris";
|
||
|
+static nsresult ApplyDelegationURIs(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ return ApplyListPref(aPrefService, aClient,
|
||
|
+ GConfKey_DelegationURIs, MozKey_DelegationURIs, ',');
|
||
|
+}
|
||
|
+static nsresult ReverseApplyDelegationURIs(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ return ReverseApplyListPref(aPrefService, aClient,
|
||
|
+ GConfKey_DelegationURIs, MozKey_DelegationURIs, ',');
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * "network.proxy.no_proxies_on" is the comma-separated concatenation
|
||
|
+ * of the elements of the list "/system/http_proxy/ignore_hosts"
|
||
|
+ */
|
||
|
+static const char GConfKey_IgnoreHosts[] = "/system/http_proxy/ignore_hosts";
|
||
|
+static const char MozKey_IgnoreHosts[] = "network.proxy.no_proxies_on";
|
||
|
+static nsresult ApplyIgnoreHosts(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ return ApplyListPref(aPrefService, aClient,
|
||
|
+ GConfKey_IgnoreHosts, MozKey_IgnoreHosts, ',');
|
||
|
+}
|
||
|
+static nsresult ReverseApplyIgnoreHosts(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ return ReverseApplyListPref(aPrefService, aClient,
|
||
|
+ GConfKey_IgnoreHosts, MozKey_IgnoreHosts, ',');
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * ("/system/proxy/mode" is 'manual' if and only if "network.proxy.type" is eProxyConfig_Manual (1))
|
||
|
+ * AND ("/system/proxy/mode" is 'auto' if and only if "network.proxy.type" is eProxyConfig_PAC (2))
|
||
|
+ *
|
||
|
+ * [This means 'none' matches any value of "network.proxy.type" other than 1 or 2.]
|
||
|
+ */
|
||
|
+static const char GConfKey_ProxyMode[] = "/system/proxy/mode";
|
||
|
+static const char MozKey_ProxyMode[] = "network.proxy.type";
|
||
|
+static nsresult ApplyProxyMode(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
+ char* str = gconf_client_get_string(aClient, GConfKey_ProxyMode, nsnull);
|
||
|
+ if (!str)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ PRInt32 val = -1;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs =
|
||
|
+ aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ prefs->GetIntPref(MozKey_ProxyMode, &val);
|
||
|
+ if (val < 0)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ if (!strcmp(str, "manual")) {
|
||
|
+ val = 1;
|
||
|
+ } else if (!strcmp(str, "auto")) {
|
||
|
+ val = 2;
|
||
|
+ } else if (strcmp(str, "none")) {
|
||
|
+ // invalid value for this gconf pref; do nothing
|
||
|
+ g_free(str);
|
||
|
+ return NS_OK;
|
||
|
+ } else {
|
||
|
+ if (val == 1 || val == 2) {
|
||
|
+ // We need to make it something that 'none' maps to
|
||
|
+ val = 0;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ g_free(str);
|
||
|
+ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_ProxyMode, nsnull);
|
||
|
+ nsresult rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaIntPref(MozKey_ProxyMode, val, lock);
|
||
|
+ return rv;
|
||
|
+}
|
||
|
+static nsresult ReverseApplyProxyMode(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ PRInt32 val = -1;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs =
|
||
|
+ aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ prefs->GetIntPref(MozKey_ProxyMode, &val);
|
||
|
+ if (val < 0)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ const char* str;
|
||
|
+ switch (val) {
|
||
|
+ case 1: str = "manual"; break;
|
||
|
+ case 2: str = "auto"; break;
|
||
|
+ default: str = "none"; break;
|
||
|
+ }
|
||
|
+ gconf_client_set_string(aClient, GConfKey_ProxyMode, str, nsnull);
|
||
|
+ return NS_OK;
|
||
|
}
|
||
|
|
||
|
-/* void getChildList (in string aStartingAt, out unsigned long aCount, [array, size_is (aCount), retval] out string aChildArray); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::GetChildList(const char *aStartingAt, PRUint32 *aCount, char ***aChildArray)
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * If "/apps/firefox/web/download_defaultfolder" is the empty string, then
|
||
|
+ * "browser.download.useDownloadDir" is false;
|
||
|
+ * otherwise "browser.download.useDownloadDir" is true and "browser.download.folderList"
|
||
|
+ * is (0 if "/apps/firefox/web/download_defaultfolder" is "Desktop";
|
||
|
+ * 1 if "/apps/firefox/web/download_defaultfolder" is "My Downloads";
|
||
|
+ * 3 if "/apps/firefox/web/download_defaultfolder" is "Home";
|
||
|
+ * otherwise 2 and "browser.download.dir" = "/apps/firefox/web/download_defaultfolder")
|
||
|
+ */
|
||
|
+static const char GConfKey_DownloadFolder[] = "/apps/firefox/web/download_defaultfolder";
|
||
|
+static const char MozKey_UseDownloadDir[] = "browser.download.useDownloadDir";
|
||
|
+static const char MozKey_DownloadDirType[] = "browser.download.folderList";
|
||
|
+static const char MozKey_DownloadDirExplicit[] = "browser.download.dir";
|
||
|
+static nsresult ApplyDownloadFolder(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
+ char* str = gconf_client_get_string(aClient, GConfKey_DownloadFolder, nsnull);
|
||
|
+ if (!str)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DownloadFolder, nsnull);
|
||
|
+ nsresult rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_UseDownloadDir, *str != 0, lock);
|
||
|
+ if (NS_FAILED(rv)) {
|
||
|
+ g_free(str);
|
||
|
+ return rv;
|
||
|
+ }
|
||
|
+ PRInt32 dirType = 0;
|
||
|
+ if (!strcmp(str, "Desktop")) {
|
||
|
+ dirType = 0;
|
||
|
+ } else if (!strcmp(str, "My Downloads")) {
|
||
|
+ dirType = 1;
|
||
|
+ } else if (!strcmp(str, "Home")) {
|
||
|
+ dirType = 3;
|
||
|
+ } else {
|
||
|
+ dirType = 2;
|
||
|
+ }
|
||
|
+ // Always set all three Mozilla preferences. This is simpler and avoids
|
||
|
+ // problems; e.g., if the gconf value changes from "/home/rocallahan" to "Desktop"
|
||
|
+ // we might leave MozKey_DownloadDirType accidentally locked.
|
||
|
+ rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaIntPref(MozKey_DownloadDirType, dirType, lock);
|
||
|
+ if (NS_SUCCEEDED(rv)) {
|
||
|
+ rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaStringPref(MozKey_DownloadDirExplicit, str, lock);
|
||
|
+ }
|
||
|
+ g_free(str);
|
||
|
+ return rv;
|
||
|
}
|
||
|
|
||
|
-/* void resetBranch (in string aStartingAt); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::ResetBranch(const char *aStartingAt)
|
||
|
-{
|
||
|
- return NS_ERROR_NOT_IMPLEMENTED;
|
||
|
+static nsresult ReverseApplyDownloadFolder(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ PRBool useDownloadDir = PR_FALSE;
|
||
|
+ const char* result;
|
||
|
+ char* explicitStr = nsnull;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ prefs->GetBoolPref(MozKey_UseDownloadDir, &useDownloadDir);
|
||
|
+ if (!useDownloadDir) {
|
||
|
+ result = "";
|
||
|
+ } else {
|
||
|
+ PRInt32 type = -1;
|
||
|
+ prefs->GetIntPref(MozKey_DownloadDirType, &type);
|
||
|
+ if (type < 0)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ switch (type) {
|
||
|
+ case 0: result = "Desktop"; break;
|
||
|
+ case 1: result = "My Downloads"; break;
|
||
|
+ case 2:
|
||
|
+ prefs->GetCharPref(MozKey_DownloadDirExplicit, &explicitStr);
|
||
|
+ result = explicitStr;
|
||
|
+ break;
|
||
|
+ case 3: result = "Home"; break;
|
||
|
+ default:
|
||
|
+ NS_ERROR("Unknown download dir type");
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if (!result)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ gconf_client_set_string(aClient, GConfKey_DownloadFolder,
|
||
|
+ result, nsnull);
|
||
|
+ nsMemory::Free(explicitStr);
|
||
|
+ return NS_OK;
|
||
|
}
|
||
|
|
||
|
-/* void addObserver (in string aDomain, in nsIObserver aObserver, in boolean aHoldWeak); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::AddObserver(const char *aDomain, nsIObserver *aObserver, PRBool aHoldWeak)
|
||
|
-{
|
||
|
- nsresult rv;
|
||
|
-
|
||
|
- NS_ENSURE_ARG_POINTER(aDomain);
|
||
|
- NS_ENSURE_ARG_POINTER(aObserver);
|
||
|
-
|
||
|
- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||
|
-
|
||
|
- PRUint32 prefAtom;
|
||
|
- // make sure the pref name is supported
|
||
|
- rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom);
|
||
|
- NS_ENSURE_SUCCESS(rv, rv);
|
||
|
-
|
||
|
- if (!mObservers) {
|
||
|
- mObservers = new nsAutoVoidArray();
|
||
|
- if (mObservers == nsnull)
|
||
|
- return NS_ERROR_OUT_OF_MEMORY;
|
||
|
- }
|
||
|
-
|
||
|
- SysPrefCallbackData *pCallbackData = (SysPrefCallbackData *)
|
||
|
- nsMemory::Alloc(sizeof(SysPrefCallbackData));
|
||
|
- if (pCallbackData == nsnull)
|
||
|
- return NS_ERROR_OUT_OF_MEMORY;
|
||
|
-
|
||
|
- pCallbackData->bIsWeakRef = aHoldWeak;
|
||
|
- pCallbackData->prefAtom = prefAtom;
|
||
|
- // hold a weak reference to the observer if so requested
|
||
|
- nsCOMPtr<nsISupports> observerRef;
|
||
|
- if (aHoldWeak) {
|
||
|
- nsCOMPtr<nsISupportsWeakReference> weakRefFactory =
|
||
|
- do_QueryInterface(aObserver);
|
||
|
- if (!weakRefFactory) {
|
||
|
- // the caller didn't give us a object that supports weak reference.
|
||
|
- // ... tell them
|
||
|
- nsMemory::Free(pCallbackData);
|
||
|
- return NS_ERROR_INVALID_ARG;
|
||
|
- }
|
||
|
- nsCOMPtr<nsIWeakReference> tmp = do_GetWeakReference(weakRefFactory);
|
||
|
- observerRef = tmp;
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * "/apps/firefox/web/disable_cookies" is true if and only if
|
||
|
+ * "network.cookie.cookieBehavior" is 2 ('dontUse')
|
||
|
+ */
|
||
|
+static const char GConfKey_DisableCookies[] = "/apps/firefox/web/disable_cookies";
|
||
|
+static const char MozKey_CookieBehavior[] = "network.cookie.cookieBehavior";
|
||
|
+static const char MozKey_CookieExceptions[] = "network.cookie.honorExceptions";
|
||
|
+static const char MozKey_CookieViewExceptions[] = "pref.privacy.disable_button.cookie_exceptions";
|
||
|
+static nsresult ApplyDisableCookies(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableCookies, nsnull);
|
||
|
+ PRInt32 behavior = -1;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs =
|
||
|
+ aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ prefs->GetIntPref(MozKey_CookieBehavior, &behavior);
|
||
|
+ if (behavior < 0)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ if (disable) {
|
||
|
+ behavior = 2;
|
||
|
} else {
|
||
|
- observerRef = aObserver;
|
||
|
+ if (behavior == 2) {
|
||
|
+ behavior = 0;
|
||
|
+ }
|
||
|
}
|
||
|
+ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableCookies, nsnull);
|
||
|
+ nsresult rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_CookieExceptions, !lock, lock);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_CookieViewExceptions, lock, lock);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ return aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaIntPref(MozKey_CookieBehavior, behavior, lock);
|
||
|
+}
|
||
|
+static nsresult ReverseApplyDisableCookies(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ PRInt32 behavior = -1;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs =
|
||
|
+ aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ prefs->GetIntPref(MozKey_CookieBehavior, &behavior);
|
||
|
+ if (behavior < 0)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ gconf_client_set_bool(aClient, GConfKey_DisableCookies, behavior == 2, nsnull);
|
||
|
+ return NS_OK;
|
||
|
+}
|
||
|
|
||
|
- rv = mGConf->NotifyAdd(prefAtom, pCallbackData);
|
||
|
- if (NS_FAILED(rv)) {
|
||
|
- nsMemory::Free(pCallbackData);
|
||
|
- return rv;
|
||
|
+static char const* windowOpenFeatures[] = {
|
||
|
+ "dom.disable_window_open_feature.close",
|
||
|
+ "dom.disable_window_open_feature.directories",
|
||
|
+ "dom.disable_window_open_feature.location",
|
||
|
+ "dom.disable_window_open_feature.menubar",
|
||
|
+ "dom.disable_window_open_feature.minimizable",
|
||
|
+ "dom.disable_window_open_feature.personalbar",
|
||
|
+ "dom.disable_window_open_feature.resizable",
|
||
|
+ "dom.disable_window_open_feature.scrollbars",
|
||
|
+ "dom.disable_window_open_feature.status",
|
||
|
+ "dom.disable_window_open_feature.titlebar",
|
||
|
+ "dom.disable_window_open_feature.toolbar"
|
||
|
+};
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * "/apps/firefox/lockdown/disable_javascript_chrome" is true if and only if
|
||
|
+ * all of windowOpenFeatures are true
|
||
|
+ */
|
||
|
+static const char GConfKey_DisableJSChrome[] =
|
||
|
+ "/apps/firefox/lockdown/disable_javascript_chrome";
|
||
|
+static nsresult ApplyWindowOpen(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableJSChrome, nsnull);
|
||
|
+ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableJSChrome, nsnull);
|
||
|
+ PRBool curValues[NUM_ELEM(windowOpenFeatures)];
|
||
|
+ PRUint32 i;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ PRBool allDisabled = PR_TRUE;
|
||
|
+ for (i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) {
|
||
|
+ nsresult rv = prefs->GetBoolPref(windowOpenFeatures[i], &curValues[i]);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ if (!curValues[i]) {
|
||
|
+ allDisabled = PR_FALSE;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ for (i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) {
|
||
|
+ PRBool newVal = curValues[i];
|
||
|
+ if (disable) {
|
||
|
+ newVal = PR_TRUE;
|
||
|
+ } else if (allDisabled) {
|
||
|
+ // If all disable-window-open-feature prefs are currently
|
||
|
+ // PR_TRUE, then we need to set at least one of them to
|
||
|
+ // PR_FALSE. Set all of them to PR_FALSE.
|
||
|
+ newVal = PR_FALSE;
|
||
|
+ } // If at least one disable-window-open-feature pref is
|
||
|
+ // currently PR_FALSE, then we don't need to change anything
|
||
|
+ // when the gconf pref says don't disable
|
||
|
+ nsresult rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(windowOpenFeatures[i], newVal, lock);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
}
|
||
|
-
|
||
|
- pCallbackData->observer = observerRef;
|
||
|
- NS_ADDREF(pCallbackData->observer);
|
||
|
-
|
||
|
- mObservers->AppendElement(pCallbackData);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
-/* void removeObserver (in string aDomain, in nsIObserver aObserver); */
|
||
|
-NS_IMETHODIMP nsSystemPrefService::RemoveObserver(const char *aDomain, nsIObserver *aObserver)
|
||
|
+static nsresult ReverseApplyWindowOpen(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
{
|
||
|
- nsresult rv;
|
||
|
-
|
||
|
- NS_ENSURE_ARG_POINTER(aDomain);
|
||
|
- NS_ENSURE_ARG_POINTER(aObserver);
|
||
|
- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||
|
-
|
||
|
- if (!mObservers)
|
||
|
- return NS_OK;
|
||
|
-
|
||
|
- PRUint32 prefAtom;
|
||
|
- // make sure the pref name is supported
|
||
|
- rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom);
|
||
|
- NS_ENSURE_SUCCESS(rv, rv);
|
||
|
-
|
||
|
- // need to find the index of observer, so we can remove it
|
||
|
- PRIntn count = mObservers->Count();
|
||
|
- if (count <= 0)
|
||
|
- return NS_OK;
|
||
|
-
|
||
|
- PRIntn i;
|
||
|
- SysPrefCallbackData *pCallbackData;
|
||
|
- for (i = 0; i < count; ++i) {
|
||
|
- pCallbackData = (SysPrefCallbackData *)mObservers->ElementAt(i);
|
||
|
- if (pCallbackData) {
|
||
|
- nsCOMPtr<nsISupports> observerRef;
|
||
|
- if (pCallbackData->bIsWeakRef) {
|
||
|
- nsCOMPtr<nsISupportsWeakReference> weakRefFactory =
|
||
|
- do_QueryInterface(aObserver);
|
||
|
- if (weakRefFactory) {
|
||
|
- nsCOMPtr<nsIWeakReference> tmp =
|
||
|
- do_GetWeakReference(aObserver);
|
||
|
- observerRef = tmp;
|
||
|
- }
|
||
|
- }
|
||
|
- if (!observerRef)
|
||
|
- observerRef = aObserver;
|
||
|
-
|
||
|
- if (pCallbackData->observer == observerRef &&
|
||
|
- pCallbackData->prefAtom == prefAtom) {
|
||
|
- rv = mGConf->NotifyRemove(prefAtom, pCallbackData);
|
||
|
- if (NS_SUCCEEDED(rv)) {
|
||
|
- mObservers->RemoveElementAt(i);
|
||
|
- NS_RELEASE(pCallbackData->observer);
|
||
|
- nsMemory::Free(pCallbackData);
|
||
|
- }
|
||
|
- return rv;
|
||
|
- }
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ PRBool allDisabled = PR_TRUE;
|
||
|
+ PRBool curValues[NUM_ELEM(windowOpenFeatures)];
|
||
|
+ for (PRUint32 i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) {
|
||
|
+ nsresult rv = prefs->GetBoolPref(windowOpenFeatures[i], &curValues[i]);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ if (!curValues[i]) {
|
||
|
+ allDisabled = PR_FALSE;
|
||
|
}
|
||
|
}
|
||
|
+ gconf_client_set_bool(aClient, GConfKey_DisableJSChrome, allDisabled, nsnull);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
-void
|
||
|
-nsSystemPrefService::OnPrefChange(PRUint32 aPrefAtom, void *aData)
|
||
|
-{
|
||
|
- if (!mInitialized)
|
||
|
- return;
|
||
|
-
|
||
|
- SysPrefCallbackData *pData = (SysPrefCallbackData *)aData;
|
||
|
- if (pData->prefAtom != aPrefAtom)
|
||
|
- return;
|
||
|
-
|
||
|
- nsCOMPtr<nsIObserver> observer;
|
||
|
- if (pData->bIsWeakRef) {
|
||
|
- nsCOMPtr<nsIWeakReference> weakRef =
|
||
|
- do_QueryInterface(pData->observer);
|
||
|
- if(weakRef)
|
||
|
- observer = do_QueryReferent(weakRef);
|
||
|
- if (!observer) {
|
||
|
- // this weak referenced observer went away, remove it from the list
|
||
|
- nsresult rv = mGConf->NotifyRemove(aPrefAtom, pData);
|
||
|
- if (NS_SUCCEEDED(rv)) {
|
||
|
- mObservers->RemoveElement(pData);
|
||
|
- NS_RELEASE(pData->observer);
|
||
|
- nsMemory::Free(pData);
|
||
|
- }
|
||
|
- return;
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * If "/apps/firefox/lockdown/disable_unsafe_protocol" is true then
|
||
|
+ * -- "network.protocol-handler.blocked-default" is true
|
||
|
+ * -- "network.protocol-handler.blocked.XYZ" is false if and only if
|
||
|
+ * XYZ is a builtin non-disablable protocol or in
|
||
|
+ * "/apps/firefox/lockdown/additional_safe_protocols"
|
||
|
+ * AND if "/apps/firefox/lockdown/disable_unsafe_protocol" is false then
|
||
|
+ * -- "network.protocol-handler.blocked-default" is false
|
||
|
+ * -- if "network.protocol-handler.blocked.XYZ" exists then it is false
|
||
|
+ */
|
||
|
+static const char GConfKey_DisableUnsafeProtocols[] =
|
||
|
+ "/apps/firefox/lockdown/disable_unsafe_protocol";
|
||
|
+static const char GConfKey_AdditionalSafeProtocols[] =
|
||
|
+ "/apps/firefox/lockdown/additional_safe_protocols";
|
||
|
+static const char MozKey_BlockedDefault[] =
|
||
|
+ "network.protocol-handler.blocked-default";
|
||
|
+static const char MozKey_BlockedPrefix[] =
|
||
|
+ "network.protocol-handler.blocked.";
|
||
|
+static const char* nonDisablableBuiltinProtocols[] =
|
||
|
+ { "about", "data", "jar", "keyword", "resource", "viewsource",
|
||
|
+ "chrome", "moz-icon", "javascript", "file" };
|
||
|
+static PRBool FindString(const char** aList, PRInt32 aCount,
|
||
|
+ const char* aStr)
|
||
|
+{
|
||
|
+ for (PRInt32 i = 0; i < aCount; ++i) {
|
||
|
+ if (!strcmp(aStr, aList[i]))
|
||
|
+ return PR_TRUE;
|
||
|
+ }
|
||
|
+ return PR_FALSE;
|
||
|
+}
|
||
|
+typedef nsDataHashtable<nsCStringHashKey,int> StringSet;
|
||
|
+/** Collect the set of protocol names that we want to set preferences for */
|
||
|
+static nsresult AddAllProtocols(nsSystemPrefService* aPrefService,
|
||
|
+ const char* aSafeProtocols,
|
||
|
+ StringSet* aProtocolSet,
|
||
|
+ StringSet* aSafeSet)
|
||
|
+{
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ PRUint32 childCount;
|
||
|
+ char **childArray = nsnull;
|
||
|
+ nsresult rv = prefs->GetChildList(MozKey_BlockedPrefix, &childCount, &childArray);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ PRUint32 i;
|
||
|
+ for (i = 0; i < childCount; ++i) {
|
||
|
+ nsDependentCString tmp(childArray[i] + NUM_ELEM(MozKey_BlockedPrefix)-1);
|
||
|
+ aProtocolSet->Put(tmp, 1); // copies
|
||
|
+ }
|
||
|
+ for (i = 0; i < NUM_ELEM(nonDisablableBuiltinProtocols); ++i) {
|
||
|
+ nsDependentCString tmp(nonDisablableBuiltinProtocols[i]);
|
||
|
+ aProtocolSet->Put(tmp, 1);
|
||
|
+ }
|
||
|
+ i = 0;
|
||
|
+ while (aSafeProtocols[i]) {
|
||
|
+ const char* nextComma = strchr(aSafeProtocols+i, ',');
|
||
|
+ PRUint32 tokLen = nextComma ? nextComma - (aSafeProtocols+i)
|
||
|
+ : strlen(aSafeProtocols+i);
|
||
|
+ nsCAutoString tok(aSafeProtocols+i, tokLen);
|
||
|
+ aProtocolSet->Put(tok, 1);
|
||
|
+ aSafeSet->Put(tok, 1);
|
||
|
+ if (nextComma) {
|
||
|
+ i = nextComma - aSafeProtocols + 1;
|
||
|
+ } else {
|
||
|
+ break;
|
||
|
}
|
||
|
}
|
||
|
- else
|
||
|
- observer = do_QueryInterface(pData->observer);
|
||
|
-
|
||
|
- if (observer)
|
||
|
- observer->Observe(NS_STATIC_CAST(nsIPrefBranch *, this),
|
||
|
- NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID,
|
||
|
- NS_ConvertUTF8toUCS2(mGConf->GetMozKey(aPrefAtom)).
|
||
|
- get());
|
||
|
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray);
|
||
|
+ return NS_OK;
|
||
|
}
|
||
|
|
||
|
-/*************************************************************
|
||
|
- * GConfProxy
|
||
|
- *
|
||
|
- ************************************************************/
|
||
|
-
|
||
|
-struct GConfFuncListType {
|
||
|
- const char *FuncName;
|
||
|
- PRFuncPtr FuncPtr;
|
||
|
-};
|
||
|
-
|
||
|
-struct PrefNamePair {
|
||
|
- const char *mozPrefName;
|
||
|
- const char *gconfPrefName;
|
||
|
-};
|
||
|
-
|
||
|
-const char
|
||
|
-GConfProxy::sPrefGConfKey[] = "accessibility.unix.gconf2.shared-library";
|
||
|
-const char GConfProxy::sDefaultLibName1[] = "libgconf-2.so.4";
|
||
|
-const char GConfProxy::sDefaultLibName2[] = "libgconf-2.so";
|
||
|
-
|
||
|
-#define GCONF_FUNCS_POINTER_BEGIN \
|
||
|
- static GConfFuncListType sGConfFuncList[] = {
|
||
|
-#define GCONF_FUNCS_POINTER_ADD(func_name) \
|
||
|
- {func_name, nsnull},
|
||
|
-#define GCONF_FUNCS_POINTER_END \
|
||
|
- {nsnull, nsnull}, };
|
||
|
-
|
||
|
-GCONF_FUNCS_POINTER_BEGIN
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_client_get_default") // 0
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_client_get_bool") // 1
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_client_get_string") //2
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_client_get_int") //3
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_client_notify_add") //4
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_client_notify_remove") //5
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_client_add_dir") //6
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_client_remove_dir") //7
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_entry_get_value") //8
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_entry_get_key") //9
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_value_get_bool") //10
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_value_get_string") //11
|
||
|
- GCONF_FUNCS_POINTER_ADD("gconf_value_get_int") //12
|
||
|
-GCONF_FUNCS_POINTER_END
|
||
|
-
|
||
|
-/////////////////////////////////////////////////////////////////////////////
|
||
|
-// the list is the mapping table, between mozilla prefs and gconf prefs
|
||
|
-// It is expected to include all the pref pairs that are related in mozilla
|
||
|
-// and gconf.
|
||
|
-//
|
||
|
-// Note: the prefs listed here are not neccessarily be read from gconf, they
|
||
|
-// are the prefs that could be read from gconf. Mozilla has another
|
||
|
-// list (see sSysPrefList in nsSystemPref.cpp) that decide which prefs
|
||
|
-// are really read.
|
||
|
-//////////////////////////////////////////////////////////////////////////////
|
||
|
-
|
||
|
-static const PrefNamePair sPrefNameMapping[] = {
|
||
|
-#include "gconf_pref_list.inc"
|
||
|
- {nsnull, nsnull},
|
||
|
+struct ProtocolPrefClosure {
|
||
|
+ StringSet safeProtocolSet;
|
||
|
+ nsIPrefBranch2* prefs;
|
||
|
+ nsISystemPref* prefSetter;
|
||
|
+ PRPackedBool disableUnsafe;
|
||
|
+ PRPackedBool lock;
|
||
|
};
|
||
|
|
||
|
-PRBool PR_CALLBACK
|
||
|
-gconfDeleteObserver(void *aElement, void *aData) {
|
||
|
- nsMemory::Free(aElement);
|
||
|
- return PR_TRUE;
|
||
|
+static PLDHashOperator PR_CALLBACK SetProtocolPref(const nsACString& aKey,
|
||
|
+ int aItem,
|
||
|
+ void* aClosure)
|
||
|
+{
|
||
|
+ ProtocolPrefClosure* closure = NS_STATIC_CAST(ProtocolPrefClosure*, aClosure);
|
||
|
+ const nsCString& protocol = PromiseFlatCString(aKey);
|
||
|
+ PRBool blockProtocol = PR_FALSE;
|
||
|
+ if (closure->disableUnsafe &&
|
||
|
+ !FindString(nonDisablableBuiltinProtocols,
|
||
|
+ NUM_ELEM(nonDisablableBuiltinProtocols), protocol.get()) &&
|
||
|
+ !closure->safeProtocolSet.Get(aKey, nsnull)) {
|
||
|
+ blockProtocol = PR_TRUE;
|
||
|
+ }
|
||
|
+
|
||
|
+ nsCAutoString prefName;
|
||
|
+ prefName.Append(MozKey_BlockedPrefix);
|
||
|
+ prefName.Append(protocol);
|
||
|
+ closure->prefSetter->SetOverridingMozillaBoolPref(prefName.get(), blockProtocol,
|
||
|
+ closure->lock);
|
||
|
+ return PL_DHASH_NEXT;
|
||
|
+}
|
||
|
+static nsresult ApplyUnsafeProtocols(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableUnsafeProtocols, nsnull)
|
||
|
+ || !gconf_client_key_is_writable(aClient, GConfKey_AdditionalSafeProtocols, nsnull);
|
||
|
+ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableUnsafeProtocols, nsnull);
|
||
|
+ char* protocols = gconf_client_get_string(aClient, GConfKey_AdditionalSafeProtocols, nsnull);
|
||
|
+ if (!protocols)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ nsresult rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_BlockedDefault, disable, lock);
|
||
|
+ StringSet protocolSet;
|
||
|
+ ProtocolPrefClosure closure;
|
||
|
+ protocolSet.Init();
|
||
|
+ closure.safeProtocolSet.Init();
|
||
|
+ if (NS_SUCCEEDED(rv)) {
|
||
|
+ rv = AddAllProtocols(aPrefService, protocols, &protocolSet,
|
||
|
+ &closure.safeProtocolSet);
|
||
|
+ }
|
||
|
+ if (NS_SUCCEEDED(rv)) {
|
||
|
+ closure.disableUnsafe = disable;
|
||
|
+ closure.lock = lock;
|
||
|
+ closure.prefSetter = aPrefService->GetPrefs();
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ closure.prefs = prefs;
|
||
|
+ protocolSet.EnumerateRead(SetProtocolPref, &closure);
|
||
|
+ }
|
||
|
+ g_free(protocols);
|
||
|
+ return rv;
|
||
|
+}
|
||
|
+
|
||
|
+static nsresult ReverseApplyUnsafeProtocols(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ PRBool blockedDefault;
|
||
|
+ nsresult rv = prefs->GetBoolPref(MozKey_BlockedDefault, &blockedDefault);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ nsCAutoString enabledProtocols;
|
||
|
+ PRUint32 childCount;
|
||
|
+ char **childArray = nsnull;
|
||
|
+ rv = prefs->GetChildList(MozKey_BlockedPrefix, &childCount, &childArray);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ for (PRUint32 i = 0; i < childCount; ++i) {
|
||
|
+ PRBool val = PR_FALSE;
|
||
|
+ prefs->GetBoolPref(childArray[i], &val);
|
||
|
+ if (val) {
|
||
|
+ if (enabledProtocols.Length() > 0) {
|
||
|
+ enabledProtocols.Append(',');
|
||
|
+ }
|
||
|
+ enabledProtocols.Append(childArray[i] + NUM_ELEM(MozKey_BlockedPrefix)-1);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray);
|
||
|
+ gconf_client_set_bool(aClient, GConfKey_DisableUnsafeProtocols, blockedDefault, nsnull);
|
||
|
+ gconf_client_set_string(aClient, GConfKey_AdditionalSafeProtocols,
|
||
|
+ enabledProtocols.get(), nsnull);
|
||
|
+ return NS_OK;
|
||
|
}
|
||
|
|
||
|
-GConfProxy::GConfProxy(nsSystemPrefService *aSysPrefService):
|
||
|
- mGConfClient(nsnull),
|
||
|
- mGConfLib(nsnull),
|
||
|
- mInitialized(PR_FALSE),
|
||
|
- mSysPrefService(aSysPrefService),
|
||
|
- mObservers(nsnull)
|
||
|
-{
|
||
|
+/**
|
||
|
+ * Set config.lockdown.setwallpaper if and only if
|
||
|
+ * /desktop/gnome/background/picture_filename is write-only. Always
|
||
|
+ * lock it.
|
||
|
+ */
|
||
|
+static const char MozKey_LockdownWallpaper[] = "config.lockdown.setwallpaper";
|
||
|
+static const char GConfKey_WallpaperSetting[] =
|
||
|
+ "/desktop/gnome/background/picture_filename";
|
||
|
+static nsresult ApplyWallpaper(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ PRBool canSetWallpaper =
|
||
|
+ gconf_client_key_is_writable(aClient, GConfKey_WallpaperSetting, nsnull);
|
||
|
+ return aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_LockdownWallpaper,
|
||
|
+ !canSetWallpaper, PR_TRUE);
|
||
|
+}
|
||
|
+// No ReverseApplyWallpaper because this Mozilla pref can never be
|
||
|
+// modified
|
||
|
+
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * "signon.rememberSignons" is true if and only if "/apps/firefox/web/disable_save_password"
|
||
|
+ * is false.
|
||
|
+ */
|
||
|
+static const char MozKey_RememberSignons[] = "signon.rememberSignons";
|
||
|
+static const char GConfKey_DisableSavePassword[] = "/apps/firefox/web/disable_save_password";
|
||
|
+static nsresult ApplyDisableSavePassword(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisableSavePassword, nsnull);
|
||
|
+ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisableSavePassword, nsnull);
|
||
|
+ return aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_RememberSignons, !disable, lock);
|
||
|
+}
|
||
|
+
|
||
|
+static nsresult ReverseApplyDisableSavePassword(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ PRBool remember;
|
||
|
+ nsresult rv = prefs->GetBoolPref(MozKey_RememberSignons, &remember);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ gconf_client_set_bool(aClient, GConfKey_DisableSavePassword, !remember, nsnull);
|
||
|
+ return NS_OK;
|
||
|
}
|
||
|
|
||
|
-GConfProxy::~GConfProxy()
|
||
|
-{
|
||
|
- if (mGConfClient)
|
||
|
- g_object_unref(G_OBJECT(mGConfClient));
|
||
|
-
|
||
|
- if (mObservers) {
|
||
|
- (void)mObservers->EnumerateForwards(gconfDeleteObserver, nsnull);
|
||
|
- delete mObservers;
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * "permissions.default.image" is 1 (nsIPermissionManager::ALLOW_ACTION) if and only if
|
||
|
+ * "/apps/firefox/web/images_load" is 0, AND
|
||
|
+ * "permissions.default.image" is 2 (nsIPermissionManager::DENY_ACTION) if and only if
|
||
|
+ * "/apps/firefox/web/images_load" is 2, AND
|
||
|
+ * "permissions.default.image" is 3 if and only if "/apps/firefox/web/images_load" is 1
|
||
|
+ *
|
||
|
+ * Also, we set pref.advanced.images.disable_button.view_image iff
|
||
|
+ * /apps/firefox/web/images_load is read-only
|
||
|
+ * And we set permissions.default.honorExceptions iff
|
||
|
+ * /apps/firefox/web/images_load is not read-only
|
||
|
+ */
|
||
|
+static const char MozKey_ImagePermissions[] = "permissions.default.image";
|
||
|
+static const char MozKey_ImageExceptions[] = "permissions.honorExceptions.image";
|
||
|
+static const char MozKey_ImageViewExceptions[] = "pref.advanced.images.disable_button.view_image";
|
||
|
+static const char GConfKey_LoadImages[] = "/apps/firefox/web/images_load";
|
||
|
+static nsresult ApplyLoadImages(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_LoadImages, nsnull);
|
||
|
+ // 0 == accept, 1 == no-foreign, 2 == reject
|
||
|
+ gint setting = gconf_client_get_int(aClient, GConfKey_LoadImages, nsnull);
|
||
|
+ PRInt32 pref;
|
||
|
+ switch (setting) {
|
||
|
+ case 0: pref = nsIPermissionManager::ALLOW_ACTION; break;
|
||
|
+ case 2: pref = nsIPermissionManager::DENY_ACTION; break;
|
||
|
+ case 1: pref = 3; break;
|
||
|
+ default: return NS_ERROR_FAILURE;
|
||
|
}
|
||
|
+ nsresult rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_ImageExceptions, !lock, lock);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_ImageViewExceptions, lock, lock);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ return aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaIntPref(MozKey_ImagePermissions, pref, lock);
|
||
|
}
|
||
|
|
||
|
-PRBool
|
||
|
-GConfProxy::Init()
|
||
|
+static nsresult ReverseApplyLoadImages(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
{
|
||
|
- SYSPREF_LOG(("GConfProxy:: Init GConfProxy\n"));
|
||
|
- if (!mSysPrefService)
|
||
|
- return PR_FALSE;
|
||
|
- if (mInitialized)
|
||
|
- return PR_TRUE;
|
||
|
-
|
||
|
- nsCOMPtr<nsIPref> pref = do_GetService(NS_PREF_CONTRACTID);
|
||
|
- if (!pref)
|
||
|
- return PR_FALSE;
|
||
|
-
|
||
|
- nsXPIDLCString gconfLibName;
|
||
|
- nsresult rv;
|
||
|
-
|
||
|
- //check if gconf-2 library is given in prefs
|
||
|
- rv = pref->GetCharPref(sPrefGConfKey, getter_Copies(gconfLibName));
|
||
|
- if (NS_SUCCEEDED(rv)) {
|
||
|
- //use the library name in the preference
|
||
|
- SYSPREF_LOG(("GConf library in prefs is %s\n", gconfLibName.get()));
|
||
|
- mGConfLib = PR_LoadLibrary(gconfLibName.get());
|
||
|
- }
|
||
|
- else {
|
||
|
- SYSPREF_LOG(("GConf library not specified in prefs, try the default: "
|
||
|
- "%s and %s\n", sDefaultLibName1, sDefaultLibName2));
|
||
|
- mGConfLib = PR_LoadLibrary(sDefaultLibName1);
|
||
|
- if (!mGConfLib)
|
||
|
- mGConfLib = PR_LoadLibrary(sDefaultLibName2);
|
||
|
- }
|
||
|
-
|
||
|
- if (!mGConfLib) {
|
||
|
- SYSPREF_LOG(("Fail to load GConf library\n"));
|
||
|
- return PR_FALSE;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ PRInt32 pref;
|
||
|
+ nsresult rv = prefs->GetIntPref(MozKey_ImagePermissions, &pref);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ gint setting;
|
||
|
+ switch (pref) {
|
||
|
+ case nsIPermissionManager::ALLOW_ACTION: setting = 0; break;
|
||
|
+ case nsIPermissionManager::DENY_ACTION: setting = 2; break;
|
||
|
+ case 3: setting = 1; break;
|
||
|
+ default: return NS_ERROR_FAILURE;
|
||
|
}
|
||
|
+ gconf_client_set_int(aClient, GConfKey_LoadImages, setting, nsnull);
|
||
|
+ return NS_OK;
|
||
|
+}
|
||
|
|
||
|
- //check every func we need in the gconf library
|
||
|
- GConfFuncListType *funcList;
|
||
|
- PRFuncPtr func;
|
||
|
- for (funcList = sGConfFuncList; funcList->FuncName; ++funcList) {
|
||
|
- func = PR_FindFunctionSymbol(mGConfLib, funcList->FuncName);
|
||
|
- if (!func) {
|
||
|
- SYSPREF_LOG(("Check GConf Func Error: %s", funcList->FuncName));
|
||
|
- goto init_failed_unload;
|
||
|
+/**
|
||
|
+ * The relationship R is
|
||
|
+ * "/apps/firefox/web/disable_popups" is true if and only if
|
||
|
+ * "dom.disable_open_during_load" is true
|
||
|
+ * AND if "/apps/firefox/web/disable_popups" is true then
|
||
|
+ * "privacy.popups.showBrowserMessage" is false.
|
||
|
+ */
|
||
|
+static const char MozKey_DisablePopups[] = "dom.disable_open_during_load";
|
||
|
+static const char MozKey_DisableBrowserPopupMessage[] = "privacy.popups.showBrowserMessage";
|
||
|
+static const char GConfKey_DisablePopups[] = "/apps/firefox/web/disable_popups";
|
||
|
+static nsresult ApplyDisablePopups(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
+{
|
||
|
+ PRBool lock = !gconf_client_key_is_writable(aClient, GConfKey_DisablePopups, nsnull);
|
||
|
+ gboolean disable = gconf_client_get_bool(aClient, GConfKey_DisablePopups, nsnull);
|
||
|
+ nsresult rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_DisablePopups, disable, lock);
|
||
|
+ if (NS_SUCCEEDED(rv)) {
|
||
|
+ if (disable) {
|
||
|
+ rv = aPrefService->GetPrefs()->
|
||
|
+ SetOverridingMozillaBoolPref(MozKey_DisableBrowserPopupMessage, PR_TRUE, lock);
|
||
|
+ } else {
|
||
|
+ rv = aPrefService->GetPrefs()->
|
||
|
+ StopOverridingMozillaPref(MozKey_DisableBrowserPopupMessage);
|
||
|
}
|
||
|
- funcList->FuncPtr = func;
|
||
|
}
|
||
|
-
|
||
|
- InitFuncPtrs();
|
||
|
-
|
||
|
- mGConfClient = GConfClientGetDefault();
|
||
|
-
|
||
|
- // Don't unload past this point, since GConf's initialization of ORBit
|
||
|
- // causes atexit handlers to be registered.
|
||
|
-
|
||
|
- if (!mGConfClient) {
|
||
|
- SYSPREF_LOG(("Fail to Get default gconf client\n"));
|
||
|
- goto init_failed;
|
||
|
- }
|
||
|
- mInitialized = PR_TRUE;
|
||
|
- return PR_TRUE;
|
||
|
-
|
||
|
- init_failed_unload:
|
||
|
- PR_UnloadLibrary(mGConfLib);
|
||
|
- init_failed:
|
||
|
- mGConfLib = nsnull;
|
||
|
- return PR_FALSE;
|
||
|
+ return rv;
|
||
|
}
|
||
|
|
||
|
-nsresult
|
||
|
-GConfProxy::GetBoolPref(const char *aMozKey, PRBool *retval)
|
||
|
+static nsresult ReverseApplyDisablePopups(nsSystemPrefService* aPrefService,
|
||
|
+ GConfClient* aClient)
|
||
|
{
|
||
|
- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||
|
- *retval = GConfClientGetBool(mGConfClient, MozKey2GConfKey(aMozKey), NULL);
|
||
|
+ nsCOMPtr<nsIPrefBranch2> prefs = aPrefService->GetPrefs()->GetPrefUserBranch();
|
||
|
+ PRBool disabled;
|
||
|
+ nsresult rv = prefs->GetBoolPref(MozKey_DisablePopups, &disabled);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ gconf_client_set_bool(aClient, GConfKey_DisablePopups, disabled, nsnull);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
-nsresult
|
||
|
-GConfProxy::GetCharPref(const char *aMozKey, char **retval)
|
||
|
-{
|
||
|
- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||
|
+static ComplexGConfPrefMapping sComplexGConfPrefMappings[] = {
|
||
|
+ {GConfKey_TrustedURIs, ApplyTrustedURIs},
|
||
|
+ {GConfKey_DelegationURIs, ApplyDelegationURIs},
|
||
|
+ {GConfKey_IgnoreHosts, ApplyIgnoreHosts},
|
||
|
+ {GConfKey_ProxyMode, ApplyProxyMode},
|
||
|
+ {GConfKey_DownloadFolder, ApplyDownloadFolder},
|
||
|
+ {GConfKey_DisableCookies, ApplyDisableCookies},
|
||
|
+ {GConfKey_DisableJSChrome, ApplyWindowOpen},
|
||
|
+ {GConfKey_DisableUnsafeProtocols, ApplyUnsafeProtocols},
|
||
|
+ {GConfKey_AdditionalSafeProtocols, ApplyUnsafeProtocols},
|
||
|
+ {GConfKey_WallpaperSetting, ApplyWallpaper},
|
||
|
+ {GConfKey_DisableSavePassword, ApplyDisableSavePassword},
|
||
|
+ {GConfKey_LoadImages, ApplyLoadImages},
|
||
|
+ {GConfKey_DisablePopups, ApplyDisablePopups}
|
||
|
+};
|
||
|
+static ComplexMozPrefMapping sComplexMozPrefMappings[] = {
|
||
|
+ {MozKey_TrustedURIs, ReverseApplyTrustedURIs},
|
||
|
+ {MozKey_DelegationURIs, ReverseApplyDelegationURIs},
|
||
|
+ {MozKey_IgnoreHosts, ReverseApplyIgnoreHosts},
|
||
|
+ {MozKey_ProxyMode, ReverseApplyProxyMode},
|
||
|
+ {MozKey_UseDownloadDir, ReverseApplyDownloadFolder},
|
||
|
+ {MozKey_DownloadDirType, ReverseApplyDownloadFolder},
|
||
|
+ {MozKey_DownloadDirExplicit, ReverseApplyDownloadFolder},
|
||
|
+ {MozKey_CookieBehavior, ReverseApplyDisableCookies},
|
||
|
+ {MozKey_RememberSignons, ReverseApplyDisableSavePassword},
|
||
|
+ {MozKey_ImagePermissions, ReverseApplyLoadImages},
|
||
|
+ {MozKey_DisablePopups, ReverseApplyDisablePopups}
|
||
|
+};
|
||
|
+// The unsafe protocol preferences are handled specially because
|
||
|
+// they affect an unknown number of Mozilla preferences
|
||
|
+// Window opener permissions are also handled specially so we don't have to
|
||
|
+// repeat the windowOpenFeatures list.
|
||
|
+
|
||
|
+/* END preference mapping definition area */
|
||
|
+
|
||
|
+static PR_CALLBACK void GConfSimpleNotification(GConfClient* client,
|
||
|
+ guint cnxn_id,
|
||
|
+ GConfEntry *entry,
|
||
|
+ gpointer user_data)
|
||
|
+{
|
||
|
+ nsSystemPrefService* service = NS_STATIC_CAST(nsSystemPrefService*, user_data);
|
||
|
+ SimplePrefMapping* map = NS_STATIC_CAST(SimplePrefMapping*,
|
||
|
+ service->GetSimpleCallbackData(cnxn_id));
|
||
|
+ NS_ASSERTION(map, "Can't find mapping for callback");
|
||
|
+ if (!map)
|
||
|
+ return;
|
||
|
|
||
|
- gchar *str = GConfClientGetString(mGConfClient,
|
||
|
- MozKey2GConfKey(aMozKey), NULL);
|
||
|
- if (str) {
|
||
|
- *retval = PL_strdup(str);
|
||
|
- g_free(str);
|
||
|
- }
|
||
|
- return NS_OK;
|
||
|
+ ApplySimpleMapping(map, service->GetPrefs(), client);
|
||
|
}
|
||
|
|
||
|
-nsresult
|
||
|
-GConfProxy::GetIntPref(const char *aMozKey, PRInt32 *retval)
|
||
|
-{
|
||
|
- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||
|
- if (strcmp (aMozKey, "network.proxy.type") == 0) {
|
||
|
- gchar *str;
|
||
|
-
|
||
|
- str = GConfClientGetString(mGConfClient,
|
||
|
- MozKey2GConfKey (aMozKey), NULL);
|
||
|
-
|
||
|
- if (str) {
|
||
|
- if (strcmp (str, "manual") == 0)
|
||
|
- *retval = 1;
|
||
|
- else if (strcmp (str, "auto") == 0)
|
||
|
- *retval = 2;
|
||
|
- else
|
||
|
- *retval = 0;
|
||
|
-
|
||
|
- g_free (str);
|
||
|
- } else
|
||
|
- *retval = 0;
|
||
|
- } else {
|
||
|
- *retval = GConfClientGetInt(mGConfClient,
|
||
|
- MozKey2GConfKey(aMozKey), NULL);
|
||
|
- }
|
||
|
+static PR_CALLBACK void GConfComplexNotification(GConfClient* client,
|
||
|
+ guint cnxn_id,
|
||
|
+ GConfEntry *entry,
|
||
|
+ gpointer user_data)
|
||
|
+{
|
||
|
+ nsSystemPrefService* service = NS_STATIC_CAST(nsSystemPrefService*, user_data);
|
||
|
+ ComplexGConfPrefMapping* map = NS_STATIC_CAST(ComplexGConfPrefMapping*,
|
||
|
+ service->GetComplexCallbackData(cnxn_id));
|
||
|
+ NS_ASSERTION(map, "Can't find mapping for callback");
|
||
|
+ if (!map)
|
||
|
+ return;
|
||
|
|
||
|
- return NS_OK;
|
||
|
+ map->callback(service, GetGConf());
|
||
|
}
|
||
|
|
||
|
-nsresult
|
||
|
-GConfProxy::NotifyAdd (PRUint32 aAtom, void *aUserData)
|
||
|
+nsresult nsSystemPrefService::LoadSystemPreferences(nsISystemPref* aPrefs)
|
||
|
{
|
||
|
- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||
|
-
|
||
|
- const char *gconfKey = GetGConfKey(aAtom);
|
||
|
- if (!gconfKey)
|
||
|
- return NS_ERROR_FAILURE;
|
||
|
+ mPref = aPrefs;
|
||
|
|
||
|
- if (!mObservers) {
|
||
|
- mObservers = new nsAutoVoidArray();
|
||
|
- if (mObservers == nsnull)
|
||
|
- return NS_ERROR_OUT_OF_MEMORY;
|
||
|
+ GConfClient* client = GetGConf();
|
||
|
+ PRUint32 i;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> userPrefs = aPrefs->GetPrefUserBranch();
|
||
|
+
|
||
|
+ // Update gconf settings with any Mozilla settings that have
|
||
|
+ // changed from the default. Do it before we register our
|
||
|
+ // gconf notifications.
|
||
|
+ for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) {
|
||
|
+ gconf_client_add_dir(client, sSimplePrefMappings[i].gconfPrefName,
|
||
|
+ GCONF_CLIENT_PRELOAD_NONE, nsnull);
|
||
|
+
|
||
|
+ PRBool hasUserPref = PR_FALSE;
|
||
|
+ nsresult rv =
|
||
|
+ userPrefs->PrefHasUserValue(sSimplePrefMappings[i].mozPrefName,
|
||
|
+ &hasUserPref);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ if (hasUserPref && sSimplePrefMappings[i].allowWritesFromMozilla &&
|
||
|
+ gconf_client_key_is_writable(client,
|
||
|
+ sSimplePrefMappings[i].gconfPrefName,
|
||
|
+ nsnull)) {
|
||
|
+ rv = ReverseApplySimpleMapping(&sSimplePrefMappings[i],
|
||
|
+ aPrefs, client);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ for (i = 0; i < NUM_ELEM(sComplexGConfPrefMappings); ++i) {
|
||
|
+ gconf_client_add_dir(client, sComplexGConfPrefMappings[i].gconfPrefName,
|
||
|
+ GCONF_CLIENT_PRELOAD_NONE, nsnull);
|
||
|
+ }
|
||
|
+ ComplexMozPrefChanged lastMozCallback = nsnull;
|
||
|
+ for (i = 0; i < NUM_ELEM(sComplexMozPrefMappings); ++i) {
|
||
|
+ PRBool hasUserPref = PR_FALSE;
|
||
|
+ nsresult rv =
|
||
|
+ userPrefs->PrefHasUserValue(sComplexMozPrefMappings[i].mozPrefName,
|
||
|
+ &hasUserPref);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ if (hasUserPref) {
|
||
|
+ ComplexMozPrefChanged cb = sComplexMozPrefMappings[i].callback;
|
||
|
+ if (cb != lastMozCallback) {
|
||
|
+ cb(this, client);
|
||
|
+ lastMozCallback = cb;
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
- GConfCallbackData *pData = (GConfCallbackData *)
|
||
|
- nsMemory::Alloc(sizeof(GConfCallbackData));
|
||
|
- NS_ENSURE_TRUE(pData, NS_ERROR_OUT_OF_MEMORY);
|
||
|
-
|
||
|
- pData->proxy = this;
|
||
|
- pData->userData = aUserData;
|
||
|
- pData->atom = aAtom;
|
||
|
- mObservers->AppendElement(pData);
|
||
|
-
|
||
|
- GConfClientAddDir(mGConfClient, gconfKey,
|
||
|
- 0, // GCONF_CLIENT_PRELOAD_NONE, don't preload anything
|
||
|
- NULL);
|
||
|
-
|
||
|
- pData->notifyId = GConfClientNotifyAdd(mGConfClient, gconfKey,
|
||
|
- gconf_key_listener, pData,
|
||
|
- NULL, NULL);
|
||
|
+ // Register simple mappings and callbacks
|
||
|
+ for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) {
|
||
|
+ guint cx = gconf_client_notify_add(client,
|
||
|
+ sSimplePrefMappings[i].gconfPrefName,
|
||
|
+ GConfSimpleNotification, this,
|
||
|
+ nsnull, nsnull);
|
||
|
+ mGConfSimpleCallbacks.Put(cx, &sSimplePrefMappings[i]);
|
||
|
+ nsresult rv = ApplySimpleMapping(&sSimplePrefMappings[i], aPrefs, client);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ }
|
||
|
+
|
||
|
+ ComplexGConfPrefChanged lastCallback = nsnull;
|
||
|
+ for (i = 0; i < NUM_ELEM(sComplexGConfPrefMappings); ++i) {
|
||
|
+ guint cx = gconf_client_notify_add(client,
|
||
|
+ sComplexGConfPrefMappings[i].gconfPrefName,
|
||
|
+ GConfComplexNotification, this,
|
||
|
+ nsnull, nsnull);
|
||
|
+ mGConfComplexCallbacks.Put(cx, &sComplexGConfPrefMappings[i]);
|
||
|
+ ComplexGConfPrefChanged cb = sComplexGConfPrefMappings[i].callback;
|
||
|
+ if (cb != lastCallback) {
|
||
|
+ cb(this, client);
|
||
|
+ lastCallback = cb;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ ApplyUnsafeProtocols(this, client);
|
||
|
+
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
-nsresult
|
||
|
-GConfProxy::NotifyRemove (PRUint32 aAtom, const void *aUserData)
|
||
|
+nsresult nsSystemPrefService::NotifyMozillaPrefChanged(const char* aPrefName)
|
||
|
{
|
||
|
- NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||
|
+ PRUint32 i;
|
||
|
+ GConfClient* client = GetGConf();
|
||
|
|
||
|
- PRIntn count = mObservers->Count();
|
||
|
- if (count <= 0)
|
||
|
- return NS_OK;
|
||
|
-
|
||
|
- PRIntn i;
|
||
|
- GConfCallbackData *pData;
|
||
|
- for (i = 0; i < count; ++i) {
|
||
|
- pData = (GConfCallbackData *)mObservers->ElementAt(i);
|
||
|
- if (pData && pData->atom == aAtom && pData->userData == aUserData) {
|
||
|
- GConfClientNotifyRemove(mGConfClient, pData->notifyId);
|
||
|
- GConfClientRemoveDir(mGConfClient,
|
||
|
- GetGConfKey(pData->atom), NULL);
|
||
|
- mObservers->RemoveElementAt(i);
|
||
|
- nsMemory::Free(pData);
|
||
|
- break;
|
||
|
+ for (i = 0; i < NUM_ELEM(sSimplePrefMappings); ++i) {
|
||
|
+ if (!strcmp(aPrefName, sSimplePrefMappings[i].mozPrefName)) {
|
||
|
+ ReverseApplySimpleMapping(&sSimplePrefMappings[i],
|
||
|
+ mPref, client);
|
||
|
}
|
||
|
}
|
||
|
- return NS_OK;
|
||
|
-}
|
||
|
|
||
|
-void
|
||
|
-GConfProxy::InitFuncPtrs()
|
||
|
-{
|
||
|
- //gconf client funcs
|
||
|
- GConfClientGetDefault =
|
||
|
- (GConfClientGetDefaultType) sGConfFuncList[0].FuncPtr;
|
||
|
- GConfClientGetBool =
|
||
|
- (GConfClientGetBoolType) sGConfFuncList[1].FuncPtr;
|
||
|
- GConfClientGetString =
|
||
|
- (GConfClientGetStringType) sGConfFuncList[2].FuncPtr;
|
||
|
- GConfClientGetInt =
|
||
|
- (GConfClientGetIntType) sGConfFuncList[3].FuncPtr;
|
||
|
- GConfClientNotifyAdd =
|
||
|
- (GConfClientNotifyAddType) sGConfFuncList[4].FuncPtr;
|
||
|
- GConfClientNotifyRemove =
|
||
|
- (GConfClientNotifyRemoveType) sGConfFuncList[5].FuncPtr;
|
||
|
- GConfClientAddDir =
|
||
|
- (GConfClientAddDirType) sGConfFuncList[6].FuncPtr;
|
||
|
- GConfClientRemoveDir =
|
||
|
- (GConfClientRemoveDirType) sGConfFuncList[7].FuncPtr;
|
||
|
-
|
||
|
- //gconf entry funcs
|
||
|
- GConfEntryGetValue = (GConfEntryGetValueType) sGConfFuncList[8].FuncPtr;
|
||
|
- GConfEntryGetKey = (GConfEntryGetKeyType) sGConfFuncList[9].FuncPtr;
|
||
|
-
|
||
|
- //gconf value funcs
|
||
|
- GConfValueGetBool = (GConfValueGetBoolType) sGConfFuncList[10].FuncPtr;
|
||
|
- GConfValueGetString = (GConfValueGetStringType) sGConfFuncList[11].FuncPtr;
|
||
|
- GConfValueGetInt = (GConfValueGetIntType) sGConfFuncList[12].FuncPtr;
|
||
|
-}
|
||
|
-
|
||
|
-void
|
||
|
-GConfProxy::OnNotify(void *aClient, void * aEntry, PRUint32 aNotifyId,
|
||
|
- GConfCallbackData *aData)
|
||
|
-{
|
||
|
- if (!mInitialized || !aEntry || (mGConfClient != aClient) || !aData)
|
||
|
- return;
|
||
|
+ for (i = 0; i < NUM_ELEM(sComplexMozPrefMappings); ++i) {
|
||
|
+ if (!strcmp(aPrefName, sComplexMozPrefMappings[i].mozPrefName)) {
|
||
|
+ sComplexMozPrefMappings[i].callback(this, client);
|
||
|
+ }
|
||
|
+ }
|
||
|
|
||
|
- if (GConfEntryGetValue(aEntry) == NULL)
|
||
|
- return;
|
||
|
+ for (i = 0; i < NUM_ELEM(windowOpenFeatures); ++i) {
|
||
|
+ if (!strcmp(aPrefName, windowOpenFeatures[i])) {
|
||
|
+ ReverseApplyWindowOpen(this, client);
|
||
|
+ }
|
||
|
+ }
|
||
|
|
||
|
- PRUint32 prefAtom;
|
||
|
- nsresult rv = GetAtomForGConfKey(GConfEntryGetKey(aEntry), &prefAtom);
|
||
|
- if (NS_FAILED(rv))
|
||
|
- return;
|
||
|
+ ReverseApplyUnsafeProtocols(this, client);
|
||
|
|
||
|
- mSysPrefService->OnPrefChange(prefAtom, aData->userData);
|
||
|
+ return NS_OK;
|
||
|
}
|
||
|
|
||
|
-nsresult
|
||
|
-GConfProxy::GetAtom(const char *aKey, PRUint8 aNameType, PRUint32 *aAtom)
|
||
|
+static PLDHashOperator PR_CALLBACK UnregisterSimple(const PRUint32& aKey,
|
||
|
+ SimplePrefMapping* aData,
|
||
|
+ void* aClosure)
|
||
|
{
|
||
|
- if (!aKey)
|
||
|
- return NS_ERROR_FAILURE;
|
||
|
- PRUint32 prefSize = sizeof(sPrefNameMapping) / sizeof(sPrefNameMapping[0]);
|
||
|
- for (PRUint32 index = 0; index < prefSize; ++index) {
|
||
|
- if (!strcmp((aNameType == 0) ? sPrefNameMapping[index].mozPrefName :
|
||
|
- sPrefNameMapping[index].gconfPrefName, aKey)) {
|
||
|
- *aAtom = index;
|
||
|
- return NS_OK;
|
||
|
- }
|
||
|
- }
|
||
|
- return NS_ERROR_FAILURE;
|
||
|
+ GConfClient* client = GetGConf();
|
||
|
+ gconf_client_notify_remove(client, aKey);
|
||
|
+ gconf_client_remove_dir(client, aData->gconfPrefName, nsnull);
|
||
|
+ return PL_DHASH_NEXT;
|
||
|
}
|
||
|
|
||
|
-const char *
|
||
|
-GConfProxy::GetKey(PRUint32 aAtom, PRUint8 aNameType)
|
||
|
+static PLDHashOperator PR_CALLBACK UnregisterComplex(const PRUint32& aKey,
|
||
|
+ ComplexGConfPrefMapping* aData,
|
||
|
+ void* aClosure)
|
||
|
{
|
||
|
- PRUint32 mapSize = sizeof(sPrefNameMapping) / sizeof(sPrefNameMapping[0]);
|
||
|
- if (aAtom >= 0 && aAtom < mapSize)
|
||
|
- return (aNameType == 0) ? sPrefNameMapping[aAtom].mozPrefName :
|
||
|
- sPrefNameMapping[aAtom].gconfPrefName;
|
||
|
- return NULL;
|
||
|
+ GConfClient* client = GetGConf();
|
||
|
+ gconf_client_notify_remove(client, aKey);
|
||
|
+ gconf_client_remove_dir(client, aData->gconfPrefName, nsnull);
|
||
|
+ return PL_DHASH_NEXT;
|
||
|
}
|
||
|
|
||
|
-inline const char *
|
||
|
-GConfProxy::MozKey2GConfKey(const char *aMozKey)
|
||
|
+nsresult nsSystemPrefService::NotifyUnloadSystemPreferences()
|
||
|
{
|
||
|
- PRUint32 atom;
|
||
|
- nsresult rv = GetAtomForMozKey(aMozKey, &atom);
|
||
|
- if (NS_SUCCEEDED(rv))
|
||
|
- return GetGConfKey(atom);
|
||
|
- return NULL;
|
||
|
-}
|
||
|
+ // Unregister callbacks
|
||
|
+ mGConfSimpleCallbacks.EnumerateRead(UnregisterSimple, this);
|
||
|
+ mGConfSimpleCallbacks.Clear();
|
||
|
+ mGConfComplexCallbacks.EnumerateRead(UnregisterComplex, this);
|
||
|
+ mGConfComplexCallbacks.Clear();
|
||
|
|
||
|
-/* static */
|
||
|
-void gconf_key_listener (void* client, guint cnxn_id,
|
||
|
- void *entry, gpointer user_data)
|
||
|
-{
|
||
|
- SYSPREF_LOG(("...SYSPREF_LOG...key listener get called \n"));
|
||
|
- if (!user_data)
|
||
|
- return;
|
||
|
- GConfCallbackData *pData = NS_REINTERPRET_CAST(GConfCallbackData *,
|
||
|
- user_data);
|
||
|
- pData->proxy->OnNotify(client, entry, cnxn_id, pData);
|
||
|
+ return NS_OK;
|
||
|
}
|
||
|
+
|
||
|
+// Factory stuff
|
||
|
+
|
||
|
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPrefService, Init)
|
||
|
+
|
||
|
+static const nsModuleComponentInfo components[] = {
|
||
|
+ { NS_SYSTEMPREF_SERVICE_CLASSNAME,
|
||
|
+ NS_SYSTEMPREF_SERVICE_CID,
|
||
|
+ NS_SYSTEMPREF_SERVICE_CONTRACTID,
|
||
|
+ nsSystemPrefServiceConstructor,
|
||
|
+ },
|
||
|
+};
|
||
|
+
|
||
|
+NS_IMPL_NSGETMODULE(nsSystemPrefServiceModule, components)
|
||
|
--- extensions/pref/system-pref/src/nsISystemPrefService.h
|
||
|
+++ extensions/pref/system-pref/src/nsISystemPrefService.h
|
||
|
@@ -0,0 +1,107 @@
|
||
|
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||
|
+/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||
|
+ */
|
||
|
+/* ***** BEGIN LICENSE BLOCK *****
|
||
|
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||
|
+ *
|
||
|
+ *
|
||
|
+ * The contents of this file are subject to the Mozilla Public
|
||
|
+ * License Version 1.1 (the "License"); you may not use this file
|
||
|
+ * except in compliance with the License. You may obtain a copy of
|
||
|
+ * the License at http://www.mozilla.org/MPL/
|
||
|
+ *
|
||
|
+ * Software distributed under the License is distributed on an "AS
|
||
|
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||
|
+ * implied. See the License for the specific language governing
|
||
|
+ * rights and limitations under the License.
|
||
|
+ *
|
||
|
+ * The Original Code is mozilla.org code.
|
||
|
+ *
|
||
|
+ * The Initial Developer of the Original Code is Novell
|
||
|
+ * Portions created by Novell are Copyright (C) 2005 Novell,
|
||
|
+ * All Rights Reserved.
|
||
|
+ *
|
||
|
+ * Original Author: Robert O'Callahan (rocallahan@novell.com)
|
||
|
+ *
|
||
|
+ * Contributor(s):
|
||
|
+ *
|
||
|
+ * Alternatively, the contents of this file may be used under the terms of
|
||
|
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
|
||
|
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||
|
+ * in which case the provisions of the GPL or the LGPL are applicable instead
|
||
|
+ * of those above. If you wish to allow use of your version of this file only
|
||
|
+ * under the terms of either the GPL or the LGPL, and not to allow others to
|
||
|
+ * use your version of this file under the terms of the NPL, indicate your
|
||
|
+ * decision by deleting the provisions above and replace them with the notice
|
||
|
+ * and other provisions required by the GPL or the LGPL. If you do not delete
|
||
|
+ * the provisions above, a recipient may use your version of this file under
|
||
|
+ * the terms of any one of the NPL, the GPL or the LGPL.
|
||
|
+ *
|
||
|
+ * ***** END LICENSE BLOCK ***** */
|
||
|
+
|
||
|
+#ifndef nsISystemPrefService_h__
|
||
|
+#define nsISystemPrefService_h__
|
||
|
+
|
||
|
+#include "nsCOMPtr.h"
|
||
|
+#include "nsIPrefBranchInternal.h"
|
||
|
+
|
||
|
+#define NS_SYSTEMPREF_SERVICE_CONTRACTID "@mozilla.org/system-preferences-service;1"
|
||
|
+
|
||
|
+#define NS_ISYSTEMPREFSERVICE_IID \
|
||
|
+{ 0x006e1cfd, 0xd66a, 0x40b9, \
|
||
|
+ { 0x84, 0xa1, 0x84, 0xf3, 0xe6, 0xa2, 0xca, 0xbc } }
|
||
|
+
|
||
|
+class nsISystemPref {
|
||
|
+public:
|
||
|
+ /**
|
||
|
+ * Call one of these three methods to override a Mozilla
|
||
|
+ * preference with a system value. You can call it multiple
|
||
|
+ * times to change the value of a given preference to track
|
||
|
+ * the underlying system value.
|
||
|
+ *
|
||
|
+ * If aLocked is true then we set the default preference and
|
||
|
+ * lock it so the user value is ignored. If aLocked is false
|
||
|
+ * then we unlock the Mozilla preference and set the Mozilla
|
||
|
+ * user value.
|
||
|
+ */
|
||
|
+ virtual nsresult SetOverridingMozillaBoolPref(const char* aPrefName,
|
||
|
+ PRBool aValue, PRBool aLocked,
|
||
|
+ PRBool aPresent = PR_TRUE) = 0;
|
||
|
+ virtual nsresult SetOverridingMozillaIntPref(const char* aPrefName,
|
||
|
+ PRInt32 aValue, PRBool aLocked,
|
||
|
+ PRBool aPresent = PR_TRUE) = 0;
|
||
|
+ virtual nsresult SetOverridingMozillaStringPref(const char* aPrefName,
|
||
|
+ const char* aValue, PRBool aLocked,
|
||
|
+ PRBool aPresent = PR_TRUE) = 0;
|
||
|
+ virtual nsresult StopOverridingMozillaPref(const char* aPrefName) = 0;
|
||
|
+ virtual already_AddRefed<nsIPrefBranch2> GetPrefUserBranch() = 0;
|
||
|
+ virtual already_AddRefed<nsIPrefBranch> GetPrefDefaultBranch() = 0;
|
||
|
+};
|
||
|
+
|
||
|
+class nsISystemPrefService : public nsISupports {
|
||
|
+public:
|
||
|
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISYSTEMPREFSERVICE_IID)
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Load the system prefs from the store into their corresponding
|
||
|
+ * Mozilla prefs, calling SetOverridingMozillaPref on each
|
||
|
+ * such pref.
|
||
|
+ */
|
||
|
+ virtual nsresult LoadSystemPreferences(nsISystemPref* aPrefs) = 0;
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Notify that a Mozilla user pref that is being overridden by the
|
||
|
+ * store has changed. The new value of the Mozilla pref should be
|
||
|
+ * written back to the store.
|
||
|
+ */
|
||
|
+ virtual nsresult NotifyMozillaPrefChanged(const char* aPrefName) = 0;
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Notify that we're about to stop using the system prefs. After
|
||
|
+ * this, nsSystemPref will automatically stop overriding all
|
||
|
+ * Mozilla prefs that are being overridden.
|
||
|
+ */
|
||
|
+ virtual nsresult NotifyUnloadSystemPreferences() = 0;
|
||
|
+};
|
||
|
+
|
||
|
+#endif
|
||
|
--- extensions/pref/system-pref/src/nsSystemPref.cpp
|
||
|
+++ extensions/pref/system-pref/src/nsSystemPref.cpp
|
||
|
@@ -24,6 +24,7 @@
|
||
|
* Original Author: Bolian Yin (bolian.yin@sun.com)
|
||
|
*
|
||
|
* Contributor(s):
|
||
|
+ * Robert O'Callahan (rocallahan@novell.com)
|
||
|
*
|
||
|
* Alternatively, the contents of this file may be used under the terms of
|
||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||
|
@@ -41,66 +42,60 @@
|
||
|
|
||
|
#include "nsSystemPref.h"
|
||
|
#include "nsIObserverService.h"
|
||
|
+#include "nsIAppStartupNotifier.h"
|
||
|
+#include "nsIPrefService.h"
|
||
|
+#include "nsIPrefBranch.h"
|
||
|
+#include "nsICategoryManager.h"
|
||
|
+#include "nsIServiceManager.h"
|
||
|
|
||
|
#include "nsSystemPrefLog.h"
|
||
|
-#include "nsSystemPrefService.h"
|
||
|
#include "nsString.h"
|
||
|
|
||
|
-const char sSysPrefString[] = "config.use_system_prefs";
|
||
|
-union MozPrefValue {
|
||
|
- char * stringVal;
|
||
|
- PRInt32 intVal;
|
||
|
- PRBool boolVal;
|
||
|
-};
|
||
|
+#include <stdlib.h>
|
||
|
|
||
|
struct SysPrefItem {
|
||
|
- const char *prefName; // mozilla pref string name
|
||
|
- MozPrefValue defaultValue; // store the mozilla default value
|
||
|
- PRBool isLocked; // store the mozilla lock status
|
||
|
+ // Saved values on both branches
|
||
|
+ PRInt32 savedUserValueScalar;
|
||
|
+ char* savedUserValueString;
|
||
|
+ PRInt32 savedDefaultValueScalar;
|
||
|
+ char* savedDefaultValueString;
|
||
|
+ // When this is true, then the value was locked originally
|
||
|
+ PRPackedBool savedLocked;
|
||
|
+ // When this is true, then there was a user value
|
||
|
+ PRPackedBool savedUserPresent;
|
||
|
+ PRPackedBool ignore;
|
||
|
+
|
||
|
SysPrefItem() {
|
||
|
- prefName = nsnull;
|
||
|
- defaultValue.intVal = 0;
|
||
|
- defaultValue.stringVal = nsnull;
|
||
|
- defaultValue.boolVal = PR_FALSE;
|
||
|
- isLocked = PR_FALSE;
|
||
|
+ savedUserValueScalar = 0;
|
||
|
+ savedUserValueString = nsnull;
|
||
|
+ savedDefaultValueScalar = 0;
|
||
|
+ savedDefaultValueString = nsnull;
|
||
|
+ savedUserPresent = PR_FALSE;
|
||
|
+ savedLocked = PR_FALSE;
|
||
|
+ ignore = PR_FALSE;
|
||
|
}
|
||
|
- void SetPrefName(const char *aPrefName) {
|
||
|
- prefName = aPrefName;
|
||
|
+
|
||
|
+ virtual ~SysPrefItem() {
|
||
|
+ nsMemory::Free(savedUserValueString);
|
||
|
+ nsMemory::Free(savedDefaultValueString);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
-// all prefs that mozilla need to read from host system if they are available
|
||
|
-static const char *sSysPrefList[] = {
|
||
|
- "network.proxy.http",
|
||
|
- "network.proxy.http_port",
|
||
|
- "network.proxy.ftp",
|
||
|
- "network.proxy.ftp_port",
|
||
|
- "network.proxy.ssl",
|
||
|
- "network.proxy.ssl_port",
|
||
|
- "network.proxy.socks",
|
||
|
- "network.proxy.socks_port",
|
||
|
- "network.proxy.no_proxies_on",
|
||
|
- "network.proxy.autoconfig_url",
|
||
|
- "network.proxy.type",
|
||
|
- "config.use_system_prefs.accessibility",
|
||
|
-};
|
||
|
+static const char sSysPrefString[] = "config.use_system_prefs";
|
||
|
|
||
|
PRLogModuleInfo *gSysPrefLog = NULL;
|
||
|
|
||
|
NS_IMPL_ISUPPORTS2(nsSystemPref, nsIObserver, nsISupportsWeakReference)
|
||
|
|
||
|
-nsSystemPref::nsSystemPref():
|
||
|
- mSysPrefService(nsnull),
|
||
|
- mEnabled(PR_FALSE),
|
||
|
- mSysPrefs(nsnull)
|
||
|
+nsSystemPref::nsSystemPref() : mIgnorePrefSetting(PR_FALSE)
|
||
|
{
|
||
|
+ mSavedPrefs.Init();
|
||
|
+ mCachedUserPrefBranch = nsnull;
|
||
|
+ mCachedDefaultPrefBranch = nsnull;
|
||
|
}
|
||
|
|
||
|
nsSystemPref::~nsSystemPref()
|
||
|
{
|
||
|
- mSysPrefService = nsnull;
|
||
|
- mEnabled = PR_FALSE;
|
||
|
- delete [] mSysPrefs;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
@@ -131,6 +126,54 @@
|
||
|
return(rv);
|
||
|
}
|
||
|
|
||
|
+already_AddRefed<nsIPrefBranch2>
|
||
|
+nsSystemPref::GetPrefUserBranch()
|
||
|
+{
|
||
|
+ if (mCachedUserPrefBranch) {
|
||
|
+ NS_ADDREF(mCachedUserPrefBranch);
|
||
|
+ return mCachedUserPrefBranch;
|
||
|
+ }
|
||
|
+
|
||
|
+ nsresult rv;
|
||
|
+ nsCOMPtr<nsIPrefService> prefService =
|
||
|
+ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return nsnull;
|
||
|
+ nsCOMPtr<nsIPrefBranch> prefBranch;
|
||
|
+ rv = prefService->GetBranch(nsnull, getter_AddRefs(prefBranch));
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return nsnull;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> pb2(do_QueryInterface(prefBranch));
|
||
|
+ if (!pb2)
|
||
|
+ return nsnull;
|
||
|
+
|
||
|
+ nsIPrefBranch2* result = nsnull;
|
||
|
+ pb2.swap(result);
|
||
|
+ return result;
|
||
|
+}
|
||
|
+
|
||
|
+already_AddRefed<nsIPrefBranch>
|
||
|
+nsSystemPref::GetPrefDefaultBranch()
|
||
|
+{
|
||
|
+ if (mCachedDefaultPrefBranch) {
|
||
|
+ NS_ADDREF(mCachedDefaultPrefBranch);
|
||
|
+ return mCachedDefaultPrefBranch;
|
||
|
+ }
|
||
|
+
|
||
|
+ nsresult rv;
|
||
|
+ nsCOMPtr<nsIPrefService> prefService =
|
||
|
+ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return nsnull;
|
||
|
+ nsCOMPtr<nsIPrefBranch> prefBranch;
|
||
|
+ rv = prefService->GetDefaultBranch(nsnull, getter_AddRefs(prefBranch));
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return nsnull;
|
||
|
+ nsIPrefBranch* pb = nsnull;
|
||
|
+ prefBranch.swap(pb);
|
||
|
+ return pb;
|
||
|
+}
|
||
|
+
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// nsSystemPref::Observe
|
||
|
// Observe notifications from mozilla pref system and system prefs (if enabled)
|
||
|
@@ -145,330 +188,446 @@
|
||
|
if (!aTopic)
|
||
|
return NS_OK;
|
||
|
|
||
|
- // if we are notified by pref service
|
||
|
- // check the system pref settings
|
||
|
- if (!nsCRT::strcmp(aTopic, NS_PREFSERVICE_READ_TOPIC_ID)) {
|
||
|
- SYSPREF_LOG(("Observed: %s\n", aTopic));
|
||
|
-
|
||
|
- nsCOMPtr<nsIPrefBranch2> prefBranch =
|
||
|
- do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||
|
- if (NS_FAILED(rv))
|
||
|
- return rv;
|
||
|
+ nsCOMPtr<nsIPrefBranch2> userBranch = GetPrefUserBranch();
|
||
|
+ nsCOMPtr<nsIPrefBranch> defaultBranch = GetPrefDefaultBranch();
|
||
|
|
||
|
- rv = prefBranch->GetBoolPref(sSysPrefString, &mEnabled);
|
||
|
+ // Check the default branch first. If system prefs are enabled
|
||
|
+ // by default, then don't check the user prefs; we don't want
|
||
|
+ // to allow users to change the default.
|
||
|
+ PRBool defaultEnabled;
|
||
|
+ rv = defaultBranch->GetBoolPref(sSysPrefString, &defaultEnabled);
|
||
|
+ if (NS_FAILED(rv)) {
|
||
|
+ SYSPREF_LOG(("...Failed to Get %s\n", sSysPrefString));
|
||
|
+ return rv;
|
||
|
+ }
|
||
|
+ PRBool enabled = defaultEnabled;
|
||
|
+ if (!enabled) {
|
||
|
+ rv = userBranch->GetBoolPref(sSysPrefString, &enabled);
|
||
|
if (NS_FAILED(rv)) {
|
||
|
- SYSPREF_LOG(("...FAil to Get %s\n", sSysPrefString));
|
||
|
+ SYSPREF_LOG(("...Failed to Get %s\n", sSysPrefString));
|
||
|
return rv;
|
||
|
}
|
||
|
+ }
|
||
|
|
||
|
- // if there is no system pref service, assume nothing happen to us
|
||
|
- mSysPrefService = do_GetService(NS_SYSTEMPREF_SERVICE_CONTRACTID, &rv);
|
||
|
- if (NS_FAILED(rv) || !mSysPrefService) {
|
||
|
- SYSPREF_LOG(("...No System Pref Service\n"));
|
||
|
- return NS_OK;
|
||
|
- }
|
||
|
+ if (!nsCRT::strcmp(aTopic, NS_PREFSERVICE_READ_TOPIC_ID)) {
|
||
|
+ // The prefs have just loaded. This is the first thing that
|
||
|
+ // happens to us.
|
||
|
+ SYSPREF_LOG(("Observed: %s\n", aTopic));
|
||
|
|
||
|
- // listen on its changes
|
||
|
- rv = prefBranch->AddObserver(sSysPrefString, this, PR_TRUE);
|
||
|
+ // listen on changes to use_system_pref. It's OK to
|
||
|
+ // hold a strong reference because we don't keep a reference
|
||
|
+ // to the pref branch.
|
||
|
+ rv = userBranch->AddObserver(sSysPrefString, this, PR_TRUE);
|
||
|
if (NS_FAILED(rv)) {
|
||
|
- SYSPREF_LOG(("...FAil to add observer for %s\n", sSysPrefString));
|
||
|
+ SYSPREF_LOG(("...Failed to add observer for %s\n", sSysPrefString));
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
- if (!mEnabled) {
|
||
|
- SYSPREF_LOG(("%s is disabled\n", sSysPrefString));
|
||
|
+ NS_ASSERTION(!mSysPrefService, "Should not be already enabled");
|
||
|
+ if (!enabled) {
|
||
|
+ // Don't load the system pref service if the preference is
|
||
|
+ // not set.
|
||
|
return NS_OK;
|
||
|
}
|
||
|
- SYSPREF_LOG(("%s is enabled\n", sSysPrefString));
|
||
|
- rv = UseSystemPrefs();
|
||
|
|
||
|
- }
|
||
|
- // sSysPrefString value was changed, update ...
|
||
|
- else if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) &&
|
||
|
- NS_ConvertUTF8toUCS2(sSysPrefString).Equals(aData)) {
|
||
|
- SYSPREF_LOG(("++++++ Notify: topic=%s data=%s\n",
|
||
|
- aTopic, NS_ConvertUCS2toUTF8(aData).get()));
|
||
|
+ SYSPREF_LOG(("%s is enabled\n", sSysPrefString));
|
||
|
|
||
|
- nsCOMPtr<nsIPrefBranch> prefBranch =
|
||
|
- do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||
|
+ rv = LoadSystemPrefs();
|
||
|
if (NS_FAILED(rv))
|
||
|
return rv;
|
||
|
|
||
|
- PRBool enabled = mEnabled;
|
||
|
- rv = prefBranch->GetBoolPref(sSysPrefString, &mEnabled);
|
||
|
- if (enabled != mEnabled) {
|
||
|
- if (mEnabled)
|
||
|
- //read prefs from system
|
||
|
- rv = UseSystemPrefs();
|
||
|
- else
|
||
|
- //roll back to mozilla prefs
|
||
|
- rv = UseMozillaPrefs();
|
||
|
+ // Lock config.use_system_prefs so the user can't undo
|
||
|
+ // it. But only do this if it was set by in the default prefs;
|
||
|
+ // if it was not set by default, then locking it would actually
|
||
|
+ // unset the value! And the user should be allowed to turn off
|
||
|
+ // something they set themselves.
|
||
|
+ if (NS_SUCCEEDED(rv) && defaultEnabled) {
|
||
|
+ userBranch->LockPref(sSysPrefString);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- // if the system pref notify us that some pref has been changed by user
|
||
|
- // outside mozilla. We need to read it again.
|
||
|
- else if (!nsCRT::strcmp(aTopic, NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID) &&
|
||
|
- aData) {
|
||
|
- NS_ASSERTION(mEnabled == PR_TRUE, "Should not listen when disabled");
|
||
|
- SYSPREF_LOG(("====== System Pref Notify topic=%s data=%s\n",
|
||
|
- aTopic, (char*)aData));
|
||
|
- rv = ReadSystemPref(NS_LossyConvertUCS2toASCII(aData).get());
|
||
|
- return NS_OK;
|
||
|
- } else if (!nsCRT::strcmp(aTopic,"profile-before-change")) {
|
||
|
- //roll back to mozilla prefs
|
||
|
- if (mEnabled)
|
||
|
- UseMozillaPrefs();
|
||
|
- mEnabled = PR_FALSE;
|
||
|
- mSysPrefService = nsnull;
|
||
|
- delete [] mSysPrefs;
|
||
|
- mSysPrefs = nsnull;
|
||
|
- } else
|
||
|
- SYSPREF_LOG(("Not needed topic Received %s\n", aTopic));
|
||
|
- return rv;
|
||
|
-}
|
||
|
+ if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) &&
|
||
|
+ nsDependentString(aData).EqualsASCII(sSysPrefString)) {
|
||
|
+ // sSysPrefString value was changed, update...
|
||
|
+ SYSPREF_LOG(("++++++ Notify: topic=%s data=%s\n",
|
||
|
+ aTopic, NS_ConvertUCS2toUTF8(aData).get()));
|
||
|
+ if (mSysPrefService && !enabled)
|
||
|
+ return RestoreMozillaPrefs();
|
||
|
+ if (!mSysPrefService && enabled) {
|
||
|
+ // Don't lock it. If the user enabled use_system_prefs,
|
||
|
+ // they should be allowed to unlock it.
|
||
|
+ return LoadSystemPrefs();
|
||
|
+ }
|
||
|
|
||
|
-/* private */
|
||
|
+ // didn't change?
|
||
|
+ return NS_OK;
|
||
|
+ }
|
||
|
|
||
|
-////////////////////////////////////////////////////////////////
|
||
|
-// nsSystemPref::UseSystemPrefs
|
||
|
-// Read all the prefs in the table from system, listen for their
|
||
|
-// changes in system pref service.
|
||
|
-////////////////////////////////////////////////////////////////
|
||
|
-nsresult
|
||
|
-nsSystemPref::UseSystemPrefs()
|
||
|
-{
|
||
|
- SYSPREF_LOG(("\n====Now Use system prefs==\n"));
|
||
|
- nsresult rv = NS_OK;
|
||
|
- if (!mSysPrefService) {
|
||
|
- return NS_ERROR_FAILURE;
|
||
|
+ if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
|
||
|
+ // some other pref changed, tell the backend if there is one
|
||
|
+ if (mSysPrefService && !mIgnorePrefSetting) {
|
||
|
+ NS_LossyConvertUTF16toASCII tmp(aData);
|
||
|
+#ifdef DEBUG
|
||
|
+ PRBool isLocked;
|
||
|
+ userBranch->PrefIsLocked(tmp.get(), &isLocked);
|
||
|
+ NS_ASSERTION(!isLocked, "Locked pref is changing?");
|
||
|
+#endif
|
||
|
+ SysPrefItem* item;
|
||
|
+ if (!mSavedPrefs.Get(tmp, &item)) {
|
||
|
+ NS_ERROR("Notified about pref change that we didn't ask about?");
|
||
|
+ } else {
|
||
|
+ if (!item->ignore) {
|
||
|
+ mSysPrefService->NotifyMozillaPrefChanged(tmp.get());
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ return NS_OK;
|
||
|
}
|
||
|
|
||
|
- PRIntn sysPrefCount= sizeof(sSysPrefList) / sizeof(sSysPrefList[0]);
|
||
|
+ if (!nsCRT::strcmp(aTopic,"profile-before-change"))
|
||
|
+ return RestoreMozillaPrefs();
|
||
|
|
||
|
- if (!mSysPrefs) {
|
||
|
- mSysPrefs = new SysPrefItem[sysPrefCount];
|
||
|
- if (!mSysPrefs)
|
||
|
- return NS_ERROR_OUT_OF_MEMORY;
|
||
|
- for (PRIntn index = 0; index < sysPrefCount; ++index)
|
||
|
- mSysPrefs[index].SetPrefName(sSysPrefList[index]);
|
||
|
- }
|
||
|
+ SYSPREF_LOG(("Not needed topic Received %s\n", aTopic));
|
||
|
|
||
|
- for (PRIntn index = 0; index < sysPrefCount; ++index) {
|
||
|
- // save mozilla prefs
|
||
|
- SaveMozDefaultPref(mSysPrefs[index].prefName,
|
||
|
- &mSysPrefs[index].defaultValue,
|
||
|
- &mSysPrefs[index].isLocked);
|
||
|
-
|
||
|
- // get the system prefs
|
||
|
- ReadSystemPref(mSysPrefs[index].prefName);
|
||
|
- SYSPREF_LOG(("Add Listener on %s\n", mSysPrefs[index].prefName));
|
||
|
- mSysPrefService->AddObserver(mSysPrefs[index].prefName,
|
||
|
- this, PR_TRUE);
|
||
|
- }
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
-//////////////////////////////////////////////////////////////////////
|
||
|
-// nsSystemPref::ReadSystemPref
|
||
|
-// Read a pref value from system pref service, and lock it in mozilla.
|
||
|
-//////////////////////////////////////////////////////////////////////
|
||
|
nsresult
|
||
|
-nsSystemPref::ReadSystemPref(const char *aPrefName)
|
||
|
+nsSystemPref::SetOverridingMozillaBoolPref(const char* aPrefName,
|
||
|
+ PRBool aValue, PRBool aLock, PRBool aPresent)
|
||
|
{
|
||
|
- if (!mSysPrefService)
|
||
|
- return NS_ERROR_FAILURE;
|
||
|
- nsresult rv;
|
||
|
-
|
||
|
- nsCOMPtr<nsIPrefBranch> prefBranch
|
||
|
- (do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||
|
- if (NS_FAILED(rv))
|
||
|
- return rv;
|
||
|
-
|
||
|
- SYSPREF_LOG(("about to read aPrefName %s\n", aPrefName));
|
||
|
+ return OverridePref(aPrefName, nsIPrefBranch::PREF_BOOL,
|
||
|
+ (void*)aValue, aLock, aPresent);
|
||
|
+}
|
||
|
|
||
|
- prefBranch->UnlockPref(aPrefName);
|
||
|
+nsresult
|
||
|
+nsSystemPref::SetOverridingMozillaIntPref(const char* aPrefName,
|
||
|
+ PRInt32 aValue, PRBool aLock, PRBool aPresent)
|
||
|
+{
|
||
|
+ return OverridePref(aPrefName, nsIPrefBranch::PREF_INT,
|
||
|
+ (void*)aValue, aLock, aPresent);
|
||
|
+}
|
||
|
|
||
|
- PRInt32 prefType = nsIPrefBranch::PREF_INVALID;
|
||
|
- nsXPIDLCString strValue;
|
||
|
- PRInt32 intValue = 0;
|
||
|
- PRBool boolValue = PR_FALSE;
|
||
|
+nsresult
|
||
|
+nsSystemPref::SetOverridingMozillaStringPref(const char* aPrefName,
|
||
|
+ const char* aValue, PRBool aLock, PRBool aPresent)
|
||
|
+{
|
||
|
+ return OverridePref(aPrefName, nsIPrefBranch::PREF_STRING,
|
||
|
+ (void*)aValue, aLock, aPresent);
|
||
|
+}
|
||
|
|
||
|
- rv = prefBranch->GetPrefType(aPrefName, &prefType);
|
||
|
- if (NS_FAILED(rv))
|
||
|
- return rv;
|
||
|
- switch (prefType) {
|
||
|
+static nsresult RestorePrefValue(PRInt32 aPrefType,
|
||
|
+ const char* aPrefName,
|
||
|
+ SysPrefItem* aItem,
|
||
|
+ nsIPrefBranch* aUser,
|
||
|
+ nsIPrefBranch* aDefault)
|
||
|
+{
|
||
|
+ switch (aPrefType) {
|
||
|
case nsIPrefBranch::PREF_STRING:
|
||
|
- mSysPrefService->GetCharPref(aPrefName, getter_Copies(strValue));
|
||
|
- SYSPREF_LOG(("system value is %s\n", strValue.get()));
|
||
|
-
|
||
|
- prefBranch->SetCharPref(aPrefName, strValue.get());
|
||
|
+ aDefault->SetCharPref(aPrefName,
|
||
|
+ aItem->savedDefaultValueString);
|
||
|
+ if (aItem->savedUserPresent) {
|
||
|
+ aUser->SetCharPref(aPrefName, aItem->savedUserValueString);
|
||
|
+ }
|
||
|
break;
|
||
|
case nsIPrefBranch::PREF_INT:
|
||
|
- mSysPrefService->GetIntPref(aPrefName, &intValue);
|
||
|
- SYSPREF_LOG(("system value is %d\n", intValue));
|
||
|
-
|
||
|
- prefBranch->SetIntPref(aPrefName, intValue);
|
||
|
+ aDefault->SetIntPref(aPrefName, aItem->savedDefaultValueScalar);
|
||
|
+ if (aItem->savedUserPresent) {
|
||
|
+ aUser->SetIntPref(aPrefName, aItem->savedUserValueScalar);
|
||
|
+ }
|
||
|
break;
|
||
|
case nsIPrefBranch::PREF_BOOL:
|
||
|
- mSysPrefService->GetBoolPref(aPrefName, &boolValue);
|
||
|
- SYSPREF_LOG(("system value is %s\n", boolValue ? "TRUE" : "FALSE"));
|
||
|
-
|
||
|
- prefBranch->SetBoolPref(aPrefName, boolValue);
|
||
|
+ aDefault->SetBoolPref(aPrefName, aItem->savedDefaultValueScalar);
|
||
|
+ if (aItem->savedUserPresent) {
|
||
|
+ aUser->SetBoolPref(aPrefName, aItem->savedUserValueScalar);
|
||
|
+ }
|
||
|
break;
|
||
|
default:
|
||
|
- SYSPREF_LOG(("Fail to system value for it\n"));
|
||
|
+ NS_ERROR("Unknown preference type");
|
||
|
return NS_ERROR_FAILURE;
|
||
|
}
|
||
|
- prefBranch->LockPref(aPrefName);
|
||
|
+
|
||
|
+ if (!aItem->savedUserPresent) {
|
||
|
+ aUser->DeleteBranch(aPrefName);
|
||
|
+ }
|
||
|
+
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
-//////////////////////////////////////////////////////////////////////
|
||
|
-// nsSystemPref::UseMozillaPrefs
|
||
|
-// Restore mozilla default prefs, remove system pref listeners
|
||
|
-/////////////////////////////////////////////////////////////////////
|
||
|
-nsresult
|
||
|
-nsSystemPref::UseMozillaPrefs()
|
||
|
+static PLDHashOperator PR_CALLBACK RestorePref(const nsACString& aKey,
|
||
|
+ SysPrefItem* aItem,
|
||
|
+ void* aClosure)
|
||
|
{
|
||
|
- nsresult rv = NS_OK;
|
||
|
- SYSPREF_LOG(("\n====Now rollback to Mozilla prefs==\n"));
|
||
|
+ nsSystemPref* prefs = NS_STATIC_CAST(nsSystemPref*, aClosure);
|
||
|
+ nsCOMPtr<nsIPrefBranch2> userBranch = prefs->GetPrefUserBranch();
|
||
|
+ const nsCString& prefName = PromiseFlatCString(aKey);
|
||
|
+
|
||
|
+ PRInt32 prefType = nsIPrefBranch::PREF_INVALID;
|
||
|
+ nsresult rv = userBranch->GetPrefType(prefName.get(), &prefType);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return PL_DHASH_NEXT;
|
||
|
+ PRBool isLocked;
|
||
|
+ userBranch->PrefIsLocked(prefName.get(), &isLocked);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return PL_DHASH_NEXT;
|
||
|
|
||
|
- // if we did not use system prefs, do nothing
|
||
|
- if (!mSysPrefService)
|
||
|
- return NS_OK;
|
||
|
+ // Remove our observer before we change the value
|
||
|
+ userBranch->RemoveObserver(prefName.get(), prefs);
|
||
|
+ // Remember to ignore this item. Because some prefs start with "config.use_system_prefs",
|
||
|
+ // which we always observe, even after we remove the observer, changes to the pref will
|
||
|
+ // still be observed by us. We must ignore them.
|
||
|
+ aItem->ignore = PR_TRUE;
|
||
|
|
||
|
- PRIntn sysPrefCount= sizeof(sSysPrefList) / sizeof(sSysPrefList[0]);
|
||
|
- for (PRIntn index = 0; index < sysPrefCount; ++index) {
|
||
|
- // restore mozilla default value and free string memory if needed
|
||
|
- RestoreMozDefaultPref(mSysPrefs[index].prefName,
|
||
|
- &mSysPrefs[index].defaultValue,
|
||
|
- mSysPrefs[index].isLocked);
|
||
|
- SYSPREF_LOG(("stop listening on %s\n", mSysPrefs[index].prefName));
|
||
|
- mSysPrefService->RemoveObserver(mSysPrefs[index].prefName,
|
||
|
- this);
|
||
|
+ // Unlock the pref so we can set it
|
||
|
+ if (isLocked) {
|
||
|
+ userBranch->UnlockPref(prefName.get());
|
||
|
}
|
||
|
- return rv;
|
||
|
+
|
||
|
+ nsCOMPtr<nsIPrefBranch> defaultBranch = prefs->GetPrefDefaultBranch();
|
||
|
+
|
||
|
+ RestorePrefValue(prefType, prefName.get(), aItem,
|
||
|
+ userBranch, defaultBranch);
|
||
|
+
|
||
|
+ if (aItem->savedLocked) {
|
||
|
+ userBranch->LockPref(prefName.get());
|
||
|
+ }
|
||
|
+
|
||
|
+ return PL_DHASH_NEXT;
|
||
|
}
|
||
|
|
||
|
-////////////////////////////////////////////////////////////////////////////
|
||
|
-// nsSystemPref::RestoreMozDefaultPref
|
||
|
-// Save the saved mozilla default value.
|
||
|
-// It is also responsible for allocate the string memory when needed, because
|
||
|
-// this method know what type of value is stored.
|
||
|
-/////////////////////////////////////////////////////////////////////////////
|
||
|
nsresult
|
||
|
-nsSystemPref::SaveMozDefaultPref(const char *aPrefName,
|
||
|
- MozPrefValue *aPrefValue,
|
||
|
- PRBool *aLocked)
|
||
|
-{
|
||
|
- NS_ENSURE_ARG_POINTER(aPrefName);
|
||
|
- NS_ENSURE_ARG_POINTER(aPrefValue);
|
||
|
- NS_ENSURE_ARG_POINTER(aLocked);
|
||
|
-
|
||
|
- nsresult rv;
|
||
|
+nsSystemPref::StopOverridingMozillaPref(const char* aPrefName)
|
||
|
+{
|
||
|
+ SysPrefItem* item;
|
||
|
+ nsDependentCString prefNameStr(aPrefName);
|
||
|
+ if (!mSavedPrefs.Get(prefNameStr, &item))
|
||
|
+ return NS_OK;
|
||
|
|
||
|
- nsCOMPtr<nsIPrefBranch> prefBranch =
|
||
|
- do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||
|
- if (NS_FAILED(rv))
|
||
|
- return rv;
|
||
|
+ RestorePref(prefNameStr, item, this);
|
||
|
+ mSavedPrefs.Remove(prefNameStr);
|
||
|
+ delete item;
|
||
|
+ return NS_OK;
|
||
|
+}
|
||
|
|
||
|
- SYSPREF_LOG(("Save Mozilla value for %s\n", aPrefName));
|
||
|
+/* private */
|
||
|
|
||
|
+nsresult
|
||
|
+nsSystemPref::OverridePref(const char* aPrefName, PRInt32 aType,
|
||
|
+ void* aValue, PRBool aLock, PRBool aPresent)
|
||
|
+{
|
||
|
+ nsCOMPtr<nsIPrefBranch2> userBranch = GetPrefUserBranch();
|
||
|
+ nsCOMPtr<nsIPrefBranch> defaultBranch = GetPrefDefaultBranch();
|
||
|
PRInt32 prefType = nsIPrefBranch::PREF_INVALID;
|
||
|
- nsXPIDLCString strValue;
|
||
|
-
|
||
|
- rv = prefBranch->GetPrefType(aPrefName, &prefType);
|
||
|
+ nsresult rv = userBranch->GetPrefType(aPrefName, &prefType);
|
||
|
if (NS_FAILED(rv))
|
||
|
return rv;
|
||
|
- switch (prefType) {
|
||
|
- case nsIPrefBranch::PREF_STRING:
|
||
|
- prefBranch->GetCharPref(aPrefName,
|
||
|
- getter_Copies(strValue));
|
||
|
- SYSPREF_LOG(("Mozilla value is %s", strValue.get()));
|
||
|
-
|
||
|
- if (aPrefValue->stringVal)
|
||
|
- PL_strfree(aPrefValue->stringVal);
|
||
|
- aPrefValue->stringVal = PL_strdup(strValue.get());
|
||
|
- break;
|
||
|
- case nsIPrefBranch::PREF_INT:
|
||
|
- prefBranch->GetIntPref(aPrefName, &aPrefValue->intVal);
|
||
|
- SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue->intVal));
|
||
|
|
||
|
- break;
|
||
|
- case nsIPrefBranch::PREF_BOOL:
|
||
|
- prefBranch->GetBoolPref(aPrefName, &aPrefValue->boolVal);
|
||
|
- SYSPREF_LOG(("Mozilla value is %s\n",
|
||
|
- aPrefValue->boolVal ? "TRUE" : "FALSE"));
|
||
|
+ PRBool isLocked;
|
||
|
+ rv = userBranch->PrefIsLocked(aPrefName, &isLocked);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ PRBool hasUserValue;
|
||
|
+ rv = userBranch->PrefHasUserValue(aPrefName, &hasUserValue);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
|
||
|
- break;
|
||
|
- default:
|
||
|
- SYSPREF_LOG(("Fail to Read Mozilla value for it\n"));
|
||
|
- return NS_ERROR_FAILURE;
|
||
|
+ if (prefType == 0) {
|
||
|
+ // Preference does not exist. Allow the system prefs to
|
||
|
+ // set it.
|
||
|
+ } else {
|
||
|
+ NS_ASSERTION(aType == prefType,
|
||
|
+ "System pref engine passed incorrect type for Mozilla pref");
|
||
|
+ if (aType != prefType)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (prefType != 0) {
|
||
|
+ nsDependentCString prefNameStr(aPrefName);
|
||
|
+ SysPrefItem* item = nsnull;
|
||
|
+ if (!mSavedPrefs.Get(prefNameStr, &item)) {
|
||
|
+ // Need to save the existing value away
|
||
|
+ item = new SysPrefItem();
|
||
|
+ if (!item)
|
||
|
+ return NS_ERROR_OUT_OF_MEMORY;
|
||
|
+
|
||
|
+ item->savedLocked = isLocked;
|
||
|
+ item->savedUserPresent = hasUserValue;
|
||
|
+
|
||
|
+ switch (prefType) {
|
||
|
+ case nsIPrefBranch::PREF_STRING:
|
||
|
+ if (hasUserValue) {
|
||
|
+ userBranch->GetCharPref(aPrefName, &item->savedUserValueString);
|
||
|
+ }
|
||
|
+ defaultBranch->GetCharPref(aPrefName, &item->savedDefaultValueString);
|
||
|
+ break;
|
||
|
+ case nsIPrefBranch::PREF_INT:
|
||
|
+ if (hasUserValue) {
|
||
|
+ userBranch->GetIntPref(aPrefName, &item->savedUserValueScalar);
|
||
|
+ }
|
||
|
+ defaultBranch->GetIntPref(aPrefName, &item->savedDefaultValueScalar);
|
||
|
+ break;
|
||
|
+ case nsIPrefBranch::PREF_BOOL:
|
||
|
+ if (hasUserValue) {
|
||
|
+ userBranch->GetBoolPref(aPrefName, &item->savedUserValueScalar);
|
||
|
+ }
|
||
|
+ defaultBranch->GetBoolPref(aPrefName, &item->savedDefaultValueScalar);
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ NS_ERROR("Unknown preference type");
|
||
|
+ delete item;
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ }
|
||
|
+
|
||
|
+ mSavedPrefs.Put(prefNameStr, item);
|
||
|
+
|
||
|
+ // Watch the user value in case it changes on the Mozilla side
|
||
|
+ // If 'aLock' is true then it shouldn't change and we don't
|
||
|
+ // need the observer, but don't bother optimizing for that.
|
||
|
+ userBranch->AddObserver(aPrefName, this, PR_TRUE);
|
||
|
+ } else {
|
||
|
+ if (isLocked != aLock) {
|
||
|
+ // restore pref value on user and default branches
|
||
|
+ RestorePrefValue(prefType, aPrefName, item,
|
||
|
+ userBranch, defaultBranch);
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|
||
|
- rv = prefBranch->PrefIsLocked(aPrefName, aLocked);
|
||
|
- SYSPREF_LOG((" (%s).\n", aLocked ? "Locked" : "NOT Locked"));
|
||
|
- return rv;
|
||
|
-}
|
||
|
|
||
|
-////////////////////////////////////////////////////////////////////////////
|
||
|
-// nsSystemPref::RestoreMozDefaultPref
|
||
|
-// Restore the saved mozilla default value to pref service.
|
||
|
-// It is also responsible for free the string memory when needed, because
|
||
|
-// this method know what type of value is stored.
|
||
|
-/////////////////////////////////////////////////////////////////////////////
|
||
|
-nsresult
|
||
|
-nsSystemPref::RestoreMozDefaultPref(const char *aPrefName,
|
||
|
- MozPrefValue *aPrefValue,
|
||
|
- PRBool aLocked)
|
||
|
-{
|
||
|
- NS_ENSURE_ARG_POINTER(aPrefName);
|
||
|
+ // We need to ignore pref changes due to our own calls here
|
||
|
+ mIgnorePrefSetting = PR_TRUE;
|
||
|
|
||
|
- nsresult rv;
|
||
|
+ // Unlock it if it's locked, so we can set it
|
||
|
+ if (isLocked) {
|
||
|
+ rv = userBranch->UnlockPref(aPrefName);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ }
|
||
|
|
||
|
- nsCOMPtr<nsIPrefBranch> prefBranch =
|
||
|
- do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||
|
+ // Set the pref on the default branch if we're locking it, because
|
||
|
+ // only the default branch gets used when the pref is locked.
|
||
|
+ // Set the pref on the user branch if we're not locking it, because
|
||
|
+ // that's where the user change will go.
|
||
|
+ nsIPrefBranch* settingBranch =
|
||
|
+ aLock ? defaultBranch.get() : NS_STATIC_CAST(nsIPrefBranch*, userBranch.get());
|
||
|
+
|
||
|
+ if (!aPresent) {
|
||
|
+ rv = settingBranch->DeleteBranch(aPrefName);
|
||
|
+ } else {
|
||
|
+ switch (aType) {
|
||
|
+ case nsIPrefBranch::PREF_STRING:
|
||
|
+ rv = settingBranch->SetCharPref(aPrefName, (const char*)aValue);
|
||
|
+ break;
|
||
|
+ case nsIPrefBranch::PREF_INT:
|
||
|
+ rv = settingBranch->SetIntPref(aPrefName, (PRInt32)(NS_PTR_TO_INT32(aValue)));
|
||
|
+ break;
|
||
|
+ case nsIPrefBranch::PREF_BOOL:
|
||
|
+ rv = settingBranch->SetBoolPref(aPrefName, (PRBool)(NS_PTR_TO_INT32(aValue)));
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ NS_ERROR("Unknown preference type");
|
||
|
+ mIgnorePrefSetting = PR_FALSE;
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
+ }
|
||
|
+ }
|
||
|
if (NS_FAILED(rv))
|
||
|
return rv;
|
||
|
+ if (aLock) {
|
||
|
+ rv = userBranch->LockPref(aPrefName);
|
||
|
+ }
|
||
|
|
||
|
- SYSPREF_LOG(("Restore Mozilla value for %s\n", aPrefName));
|
||
|
+ mIgnorePrefSetting = PR_FALSE;
|
||
|
+ return rv;
|
||
|
+}
|
||
|
|
||
|
- PRInt32 prefType = nsIPrefBranch::PREF_INVALID;
|
||
|
- rv = prefBranch->GetPrefType(aPrefName, &prefType);
|
||
|
+nsresult
|
||
|
+nsSystemPref::FixupLockdownPrefs()
|
||
|
+{
|
||
|
+ nsCOMPtr<nsIPrefBranch2> userPrefs = GetPrefUserBranch();
|
||
|
+ nsCOMPtr<nsIPrefBranch2> defaultPrefs = GetPrefUserBranch();
|
||
|
+ PRUint32 childCount;
|
||
|
+ char **childArray = nsnull;
|
||
|
+ nsresult rv = userPrefs->GetChildList("config.lockdown.",
|
||
|
+ &childCount, &childArray);
|
||
|
if (NS_FAILED(rv))
|
||
|
return rv;
|
||
|
+ for (PRUint32 i = 0; i < childCount; ++i) {
|
||
|
+ PRInt32 type;
|
||
|
+ rv = defaultPrefs->GetPrefType(childArray[i], &type);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ NS_ASSERTION(type == nsIPrefBranch2::PREF_BOOL,
|
||
|
+ "All config.lockdown.* prefs should be boolean");
|
||
|
+ if (type == nsIPrefBranch2::PREF_BOOL) {
|
||
|
+ rv = defaultPrefs->SetBoolPref(childArray[i], PR_FALSE);
|
||
|
+ if (NS_FAILED(rv))
|
||
|
+ return rv;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(childCount, childArray);
|
||
|
+ return NS_OK;
|
||
|
+}
|
||
|
|
||
|
- // unlock, if it is locked
|
||
|
- prefBranch->UnlockPref(aPrefName);
|
||
|
+nsresult
|
||
|
+nsSystemPref::LoadSystemPrefs()
|
||
|
+{
|
||
|
+ SYSPREF_LOG(("\n====Now Use system prefs==\n"));
|
||
|
+ NS_ASSERTION(!mSysPrefService,
|
||
|
+ "Shouldn't have the pref service here");
|
||
|
+ nsresult rv;
|
||
|
+ mSysPrefService = do_GetService(NS_SYSTEMPREF_SERVICE_CONTRACTID, &rv);
|
||
|
+ if (NS_FAILED(rv) || !mSysPrefService) {
|
||
|
+ FixupLockdownPrefs();
|
||
|
+ SYSPREF_LOG(("...No System Pref Service\n"));
|
||
|
+ return NS_OK;
|
||
|
+ }
|
||
|
|
||
|
- switch (prefType) {
|
||
|
- case nsIPrefBranch::PREF_STRING:
|
||
|
- prefBranch->SetCharPref(aPrefName,
|
||
|
- aPrefValue->stringVal);
|
||
|
- SYSPREF_LOG(("Mozilla value is %s\n", aPrefValue->stringVal));
|
||
|
+ // Cache the pref-branch while we load up the system prefs.
|
||
|
+ NS_ASSERTION(!mCachedUserPrefBranch,
|
||
|
+ "Shouldn't have a cache here");
|
||
|
+ nsCOMPtr<nsIPrefBranch2> userBranch = GetPrefUserBranch();
|
||
|
+ nsCOMPtr<nsIPrefBranch> defaultBranch = GetPrefDefaultBranch();
|
||
|
+ mCachedDefaultPrefBranch = defaultBranch;
|
||
|
+ mCachedUserPrefBranch = userBranch;
|
||
|
+ rv = mSysPrefService->LoadSystemPreferences(this);
|
||
|
+ mCachedDefaultPrefBranch = nsnull;
|
||
|
+ mCachedUserPrefBranch = nsnull;
|
||
|
+
|
||
|
+ if (NS_FAILED(rv)) {
|
||
|
+ // Restore all modified preferences to their original values
|
||
|
+ mSavedPrefs.EnumerateRead(RestorePref, this);
|
||
|
+ mSavedPrefs.Clear();
|
||
|
+ mSysPrefService = nsnull;
|
||
|
+ }
|
||
|
+
|
||
|
+ return rv;
|
||
|
+}
|
||
|
|
||
|
- PL_strfree(aPrefValue->stringVal);
|
||
|
- aPrefValue->stringVal = nsnull;
|
||
|
+nsresult
|
||
|
+nsSystemPref::RestoreMozillaPrefs()
|
||
|
+{
|
||
|
+ SYSPREF_LOG(("\n====Now rollback to Mozilla prefs==\n"));
|
||
|
|
||
|
- break;
|
||
|
- case nsIPrefBranch::PREF_INT:
|
||
|
- prefBranch->SetIntPref(aPrefName, aPrefValue->intVal);
|
||
|
- SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue->intVal));
|
||
|
+ NS_ASSERTION(mSysPrefService,
|
||
|
+ "Should have the pref service here");
|
||
|
+ if (!mSysPrefService)
|
||
|
+ return NS_ERROR_FAILURE;
|
||
|
|
||
|
- break;
|
||
|
- case nsIPrefBranch::PREF_BOOL:
|
||
|
- prefBranch->SetBoolPref(aPrefName, aPrefValue->boolVal);
|
||
|
- SYSPREF_LOG(("Mozilla value is %s\n",
|
||
|
- aPrefValue->boolVal ? "TRUE" : "FALSE"));
|
||
|
+ nsCOMPtr<nsIPrefBranch2> userBranch = GetPrefUserBranch();
|
||
|
+ nsCOMPtr<nsIPrefBranch> defaultBranch = GetPrefDefaultBranch();
|
||
|
+ mCachedDefaultPrefBranch = defaultBranch;
|
||
|
+ mCachedUserPrefBranch = userBranch;
|
||
|
+
|
||
|
+ mSysPrefService->NotifyUnloadSystemPreferences();
|
||
|
+ // Restore all modified preferences to their original values
|
||
|
+ mSavedPrefs.EnumerateRead(RestorePref, this);
|
||
|
+ mSavedPrefs.Clear();
|
||
|
+
|
||
|
+ mCachedDefaultPrefBranch = nsnull;
|
||
|
+ mCachedUserPrefBranch = nsnull;
|
||
|
+
|
||
|
+ mSysPrefService = nsnull;
|
||
|
|
||
|
- break;
|
||
|
- default:
|
||
|
- SYSPREF_LOG(("Fail to Restore Mozilla value for it\n"));
|
||
|
- return NS_ERROR_FAILURE;
|
||
|
- }
|
||
|
+ FixupLockdownPrefs();
|
||
|
|
||
|
- // restore its old lock status
|
||
|
- if (aLocked)
|
||
|
- prefBranch->LockPref(aPrefName);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
--- extensions/pref/system-pref/src/nsSystemPref.h
|
||
|
+++ extensions/pref/system-pref/src/nsSystemPref.h
|
||
|
@@ -23,7 +23,7 @@
|
||
|
*
|
||
|
* Original Author: Bolian Yin (bolian.yin@sun.com)
|
||
|
*
|
||
|
- * Contributor(s):
|
||
|
+ * Contributor(s): Robert O'Callahan/Novell (rocallahan@novell.com)
|
||
|
*
|
||
|
* Alternatively, the contents of this file may be used under the terms of
|
||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||
|
@@ -45,16 +45,14 @@
|
||
|
#include "nsCOMPtr.h"
|
||
|
#include "nsXPCOM.h"
|
||
|
#include "nsCRT.h"
|
||
|
-#include "nsIAppStartupNotifier.h"
|
||
|
-#include "nsICategoryManager.h"
|
||
|
-#include "nsIServiceManager.h"
|
||
|
#include "nsWeakReference.h"
|
||
|
-#include "nsIPrefService.h"
|
||
|
-#include "nsIPrefBranch2.h"
|
||
|
+#include "nsClassHashtable.h"
|
||
|
+#include "nsHashKeys.h"
|
||
|
+#include "nsMemory.h"
|
||
|
|
||
|
-#include <nsIObserver.h>
|
||
|
+#include "nsISystemPrefService.h"
|
||
|
+#include "nsIObserver.h"
|
||
|
|
||
|
-union MozPrefValue;
|
||
|
struct SysPrefItem;
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
@@ -62,18 +60,34 @@
|
||
|
// nsSystemPref, as an extension of mozilla pref service, reads some mozilla
|
||
|
// prefs from host system when the feature is enabled ("config.system-pref").
|
||
|
//
|
||
|
-// nsSystemPref listens on NS_PREFSERVICE_READ_TOPIC_ID. When notified,
|
||
|
-// nsSystemPref will start the nsSystemPrefService (platform specific) to
|
||
|
-// read all the interested prefs (listed in sSysPrefList table) from system
|
||
|
-// and lock these prefs from user's modification.
|
||
|
-//
|
||
|
-// This feature will make mozilla integrated better into host platforms. If
|
||
|
-// users want to change the prefs read from system, the system provided pref
|
||
|
-// editor (i.e. gconf-editor in gnome) should be used.
|
||
|
+// nsSystemPref listens on NS_PREFSERVICE_READ_TOPIC_ID. When
|
||
|
+// notified, nsSystemPref will start the nsSystemPrefService (platform
|
||
|
+// specific) and tell it to override Mozilla prefs with its own
|
||
|
+// settings.
|
||
|
+//
|
||
|
+// When overriding a Mozilla preference the prefservice can request the
|
||
|
+// pref be locked or unlocked. If the pref is locked then we set the default
|
||
|
+// value and lock it in Mozilla so the user value is ignored and the user cannot
|
||
|
+// change the value. If the pref is unlocked then we set the user value
|
||
|
+// and unlock it in Mozilla so the user can change it. If the user changes it,
|
||
|
+// then the prefservice is notified so it can copy the value back to its
|
||
|
+// underlying store.
|
||
|
+//
|
||
|
+// We detect changes to Mozilla prefs by observing pref changes in the
|
||
|
+// user branch.
|
||
|
+//
|
||
|
+// For testing purposes, if the user toggles on
|
||
|
+// config.use_system_prefs then we save the current preferences before
|
||
|
+// overriding them from gconf, and if the user toggles off
|
||
|
+// config.use_system_prefs *in the same session* then we restore the
|
||
|
+// preferences. If the user exits without turning off use_system_prefs
|
||
|
+// then the saved values are lost and the new values are permanent.
|
||
|
+//
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
class nsSystemPref : public nsIObserver,
|
||
|
- public nsSupportsWeakReference
|
||
|
+ public nsSupportsWeakReference,
|
||
|
+ public nsISystemPref
|
||
|
{
|
||
|
public:
|
||
|
NS_DECL_ISUPPORTS
|
||
|
@@ -83,23 +97,39 @@
|
||
|
virtual ~nsSystemPref();
|
||
|
nsresult Init(void);
|
||
|
|
||
|
+ // nsISystemPref
|
||
|
+ virtual nsresult SetOverridingMozillaBoolPref(const char* aPrefName,
|
||
|
+ PRBool aValue, PRBool aLocked,
|
||
|
+ PRBool aPresent = PR_TRUE);
|
||
|
+ virtual nsresult SetOverridingMozillaIntPref(const char* aPrefName,
|
||
|
+ PRInt32 aValue, PRBool aLocked,
|
||
|
+ PRBool aPresent = PR_TRUE);
|
||
|
+ virtual nsresult SetOverridingMozillaStringPref(const char* aPrefName,
|
||
|
+ const char* aValue, PRBool aLocked,
|
||
|
+ PRBool aPresent = PR_TRUE);
|
||
|
+ virtual nsresult StopOverridingMozillaPref(const char* aPrefName);
|
||
|
+ virtual already_AddRefed<nsIPrefBranch2> GetPrefUserBranch();
|
||
|
+ virtual already_AddRefed<nsIPrefBranch> GetPrefDefaultBranch();
|
||
|
+
|
||
|
private:
|
||
|
- // funcs used to load system prefs and save mozilla default prefs
|
||
|
- nsresult UseSystemPrefs();
|
||
|
- nsresult ReadSystemPref(const char *aPrefName);
|
||
|
- nsresult SaveMozDefaultPref(const char *aPrefName,
|
||
|
- MozPrefValue *aPrefVal,
|
||
|
- PRBool *aLocked);
|
||
|
-
|
||
|
- // funcs used to load mozilla default prefs
|
||
|
- nsresult UseMozillaPrefs();
|
||
|
- nsresult RestoreMozDefaultPref(const char *aPrefName,
|
||
|
- MozPrefValue *aPrefVal,
|
||
|
- PRBool aLocked);
|
||
|
-
|
||
|
- nsCOMPtr<nsIPrefBranch2> mSysPrefService;
|
||
|
- PRBool mEnabled; // system pref is enabled or not
|
||
|
- SysPrefItem *mSysPrefs;
|
||
|
+ // If we don't load the system prefs for any reason, then
|
||
|
+ // set all config.lockdown.* preferences to PR_FALSE so that
|
||
|
+ // residual lockdown settings are removed.
|
||
|
+ nsresult FixupLockdownPrefs();
|
||
|
+
|
||
|
+ nsresult LoadSystemPrefs();
|
||
|
+
|
||
|
+ nsresult RestoreMozillaPrefs();
|
||
|
+
|
||
|
+ nsresult OverridePref(const char* aPrefName, PRInt32 aType,
|
||
|
+ void* aValue, PRBool aLock, PRBool aPresent);
|
||
|
+
|
||
|
+ nsCOMPtr<nsISystemPrefService> mSysPrefService;
|
||
|
+ nsClassHashtable<nsCStringHashKey,SysPrefItem> mSavedPrefs;
|
||
|
+ // weak pointers to cached prefbranches
|
||
|
+ nsIPrefBranch2* mCachedUserPrefBranch;
|
||
|
+ nsIPrefBranch* mCachedDefaultPrefBranch;
|
||
|
+ PRPackedBool mIgnorePrefSetting;
|
||
|
};
|
||
|
|
||
|
#define NS_SYSTEMPREF_CID \
|
||
|
--- extensions/pref/system-pref/src/nsSystemPrefFactory.cpp
|
||
|
+++ extensions/pref/system-pref/src/nsSystemPrefFactory.cpp
|
||
|
@@ -42,10 +42,10 @@
|
||
|
#include "nsICategoryManager.h"
|
||
|
#include "nsIGenericFactory.h"
|
||
|
#include "nsSystemPref.h"
|
||
|
-#include "nsSystemPrefService.h"
|
||
|
+#include "nsIServiceManager.h"
|
||
|
+#include "nsIAppStartupNotifier.h"
|
||
|
|
||
|
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPref, Init)
|
||
|
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPrefService, Init)
|
||
|
|
||
|
// Registering nsSystemPref module as part of the app-startup category to get
|
||
|
// it instantiated.
|
||
|
@@ -96,11 +96,6 @@
|
||
|
RegisterSystemPref,
|
||
|
UnRegisterSystemPref,
|
||
|
},
|
||
|
- { NS_SYSTEMPREF_SERVICE_CLASSNAME,
|
||
|
- NS_SYSTEMPREF_SERVICE_CID,
|
||
|
- NS_SYSTEMPREF_SERVICE_CONTRACTID,
|
||
|
- nsSystemPrefServiceConstructor,
|
||
|
- },
|
||
|
};
|
||
|
|
||
|
NS_IMPL_NSGETMODULE(nsSystemPrefModule, components)
|