2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** 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 Communicator client code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Alec Flett <alecf@netscape.com>
|
2009-11-03 11:05:31 -08:00
|
|
|
* Mats Palmgren <matspal@gmail.com>
|
2007-03-22 10:30:00 -07:00
|
|
|
*
|
|
|
|
* 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 MPL, 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 MPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
2010-09-27 14:23:35 -07:00
|
|
|
#include "mozilla/dom/ContentChild.h"
|
2011-10-10 22:50:08 -07:00
|
|
|
|
|
|
|
#include "mozilla/Util.h"
|
|
|
|
|
2010-05-26 12:30:03 -07:00
|
|
|
#include "nsXULAppAPI.h"
|
|
|
|
|
2011-05-23 07:54:03 -07:00
|
|
|
#include "mozilla/Preferences.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsAppDirectoryServiceDefs.h"
|
|
|
|
#include "nsDirectoryServiceDefs.h"
|
|
|
|
#include "nsICategoryManager.h"
|
|
|
|
#include "nsCategoryManagerUtils.h"
|
|
|
|
#include "nsNetUtil.h"
|
|
|
|
#include "nsIFile.h"
|
2010-09-08 20:38:12 -07:00
|
|
|
#include "nsIInputStream.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsILocalFile.h"
|
|
|
|
#include "nsIObserverService.h"
|
2010-09-08 20:38:12 -07:00
|
|
|
#include "nsIStringEnumerator.h"
|
|
|
|
#include "nsIZipReader.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsPrefBranch.h"
|
|
|
|
#include "nsXPIDLString.h"
|
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "nsCOMArray.h"
|
|
|
|
#include "nsXPCOMCID.h"
|
2008-04-01 23:41:23 -07:00
|
|
|
#include "nsAutoPtr.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsQuickSort.h"
|
|
|
|
#include "prmem.h"
|
|
|
|
#include "pldhash.h"
|
|
|
|
|
|
|
|
#include "prefapi.h"
|
|
|
|
#include "prefread.h"
|
|
|
|
#include "prefapi_private_data.h"
|
2010-10-19 13:35:08 -07:00
|
|
|
#include "PrefTuple.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-06-02 14:49:33 -07:00
|
|
|
#include "mozilla/Omnijar.h"
|
|
|
|
#include "nsZipArchive.h"
|
|
|
|
|
2011-05-28 16:42:57 -07:00
|
|
|
#include "nsTArray.h"
|
|
|
|
#include "nsRefPtrHashtable.h"
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
namespace mozilla {
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Definitions
|
|
|
|
#define INITIAL_PREF_FILES 10
|
2010-09-08 20:38:12 -07:00
|
|
|
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Prototypes
|
|
|
|
static nsresult openPrefFile(nsIFile* aFile);
|
|
|
|
static nsresult pref_InitInitialObjects(void);
|
2010-07-02 09:45:20 -07:00
|
|
|
static nsresult pref_LoadPrefsInDirList(const char *listId);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-05-23 07:54:03 -07:00
|
|
|
Preferences* Preferences::sPreferences = nsnull;
|
2011-06-21 23:39:10 -07:00
|
|
|
nsIPrefBranch2* Preferences::sRootBranch = nsnull;
|
|
|
|
nsIPrefBranch* Preferences::sDefaultRootBranch = nsnull;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool Preferences::sShutdown = false;
|
2011-05-23 07:54:03 -07:00
|
|
|
|
2011-05-28 16:42:57 -07:00
|
|
|
class ValueObserverHashKey : public PLDHashEntryHdr {
|
|
|
|
public:
|
|
|
|
typedef ValueObserverHashKey* KeyType;
|
|
|
|
typedef const ValueObserverHashKey* KeyTypePointer;
|
|
|
|
|
|
|
|
static const ValueObserverHashKey* KeyToPointer(ValueObserverHashKey *aKey)
|
|
|
|
{
|
|
|
|
return aKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
static PLDHashNumber HashKey(const ValueObserverHashKey *aKey)
|
|
|
|
{
|
|
|
|
PRUint32 strHash = nsCRT::HashCode(aKey->mPrefName.BeginReading(),
|
|
|
|
aKey->mPrefName.Length());
|
|
|
|
return PR_ROTATE_LEFT32(strHash, 4) ^ NS_PTR_TO_UINT32(aKey->mCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
ValueObserverHashKey(const char *aPref, PrefChangedFunc aCallback) :
|
|
|
|
mPrefName(aPref), mCallback(aCallback) { }
|
|
|
|
|
|
|
|
ValueObserverHashKey(const ValueObserverHashKey *aOther) :
|
|
|
|
mPrefName(aOther->mPrefName), mCallback(aOther->mCallback)
|
|
|
|
{ }
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool KeyEquals(const ValueObserverHashKey *aOther) const
|
2011-05-28 16:42:57 -07:00
|
|
|
{
|
|
|
|
return mCallback == aOther->mCallback && mPrefName == aOther->mPrefName;
|
|
|
|
}
|
|
|
|
|
|
|
|
ValueObserverHashKey *GetKey() const
|
|
|
|
{
|
|
|
|
return const_cast<ValueObserverHashKey*>(this);
|
|
|
|
}
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
enum { ALLOW_MEMMOVE = true };
|
2011-05-28 16:42:57 -07:00
|
|
|
|
|
|
|
nsCString mPrefName;
|
|
|
|
PrefChangedFunc mCallback;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ValueObserver : public nsIObserver,
|
|
|
|
public ValueObserverHashKey
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSIOBSERVER
|
|
|
|
|
|
|
|
ValueObserver(const char *aPref, PrefChangedFunc aCallback)
|
|
|
|
: ValueObserverHashKey(aPref, aCallback) { }
|
|
|
|
|
|
|
|
~ValueObserver() {
|
|
|
|
Preferences::RemoveObserver(this, mPrefName.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
void AppendClosure(void *aClosure) {
|
|
|
|
mClosures.AppendElement(aClosure);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemoveClosure(void *aClosure) {
|
|
|
|
mClosures.RemoveElement(aClosure);
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool HasNoClosures() {
|
2011-05-28 16:42:57 -07:00
|
|
|
return mClosures.Length() == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTArray<void*> mClosures;
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS1(ValueObserver, nsIObserver)
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
ValueObserver::Observe(nsISupports *aSubject,
|
|
|
|
const char *aTopic,
|
|
|
|
const PRUnichar *aData)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID),
|
|
|
|
"invalid topic");
|
|
|
|
NS_ConvertUTF16toUTF8 data(aData);
|
|
|
|
for (PRUint32 i = 0; i < mClosures.Length(); i++) {
|
|
|
|
mCallback(data.get(), mClosures.ElementAt(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct CacheData {
|
|
|
|
void* cacheLocation;
|
|
|
|
union {
|
2011-09-28 23:19:26 -07:00
|
|
|
bool defaultValueBool;
|
2011-05-28 16:42:57 -07:00
|
|
|
PRInt32 defaultValueInt;
|
|
|
|
PRUint32 defaultValueUint;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
static nsTArray<nsAutoPtr<CacheData> >* gCacheData = nsnull;
|
|
|
|
static nsRefPtrHashtable<ValueObserverHashKey,
|
|
|
|
ValueObserver>* gObserverTable = nsnull;
|
|
|
|
|
2011-05-23 07:54:03 -07:00
|
|
|
// static
|
|
|
|
Preferences*
|
2011-06-11 19:30:15 -07:00
|
|
|
Preferences::GetInstanceForService()
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
|
|
|
if (sPreferences) {
|
|
|
|
NS_ADDREF(sPreferences);
|
|
|
|
return sPreferences;
|
|
|
|
}
|
|
|
|
|
2011-06-02 23:01:02 -07:00
|
|
|
NS_ENSURE_TRUE(!sShutdown, nsnull);
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
InitStaticMembers(true);
|
2011-05-23 07:54:03 -07:00
|
|
|
NS_IF_ADDREF(sPreferences);
|
|
|
|
return sPreferences;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
|
|
|
Preferences::InitStaticMembers(bool aForService)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
|
|
|
if (sShutdown || sPreferences) {
|
|
|
|
return sPreferences != nsnull;
|
|
|
|
}
|
|
|
|
|
2011-06-11 19:30:15 -07:00
|
|
|
// If InitStaticMembers() isn't called for getting nsIPrefService,
|
|
|
|
// some global components needed by Preferences::Init() may not have been
|
|
|
|
// initialized yet. Therefore, we must create the singleton instance via
|
|
|
|
// service manager.
|
|
|
|
if (!aForService) {
|
|
|
|
nsCOMPtr<nsIPrefService> prefService =
|
|
|
|
do_GetService(NS_PREFSERVICE_CONTRACTID);
|
|
|
|
return sPreferences != nsnull;
|
|
|
|
}
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
sRootBranch = new nsPrefBranch("", false);
|
2011-06-21 23:39:10 -07:00
|
|
|
NS_ADDREF(sRootBranch);
|
2011-10-17 07:59:28 -07:00
|
|
|
sDefaultRootBranch = new nsPrefBranch("", true);
|
2011-06-21 23:39:10 -07:00
|
|
|
NS_ADDREF(sDefaultRootBranch);
|
|
|
|
|
2011-05-23 07:54:03 -07:00
|
|
|
sPreferences = new Preferences();
|
|
|
|
NS_ADDREF(sPreferences);
|
2011-06-21 23:39:10 -07:00
|
|
|
|
|
|
|
if (NS_FAILED(sPreferences->Init())) {
|
|
|
|
// The singleton instance will delete sRootBranch and sDefaultRootBranch.
|
2011-05-23 07:54:03 -07:00
|
|
|
NS_RELEASE(sPreferences);
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
2011-05-28 16:42:57 -07:00
|
|
|
|
|
|
|
gCacheData = new nsTArray<nsAutoPtr<CacheData> >();
|
|
|
|
|
|
|
|
gObserverTable = new nsRefPtrHashtable<ValueObserverHashKey, ValueObserver>();
|
|
|
|
gObserverTable->Init();
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
return true;
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
void
|
|
|
|
Preferences::Shutdown()
|
|
|
|
{
|
2011-06-02 23:01:02 -07:00
|
|
|
if (!sShutdown ) {
|
2011-10-17 07:59:28 -07:00
|
|
|
sShutdown = true; // Don't create the singleton instance after here.
|
2011-06-02 23:01:02 -07:00
|
|
|
|
|
|
|
// Don't set NULL to sPreferences here. The instance may be grabbed by
|
|
|
|
// other modules. The utility methods of Preferences should be available
|
|
|
|
// until the singleton instance actually released.
|
|
|
|
if (sPreferences) {
|
|
|
|
sPreferences->Release();
|
|
|
|
}
|
|
|
|
}
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Constructor/Destructor
|
|
|
|
*/
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
Preferences::Preferences()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
Preferences::~Preferences()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2011-06-02 23:01:02 -07:00
|
|
|
NS_ASSERTION(sPreferences == this, "Isn't this the singleton instance?");
|
|
|
|
|
|
|
|
delete gObserverTable;
|
|
|
|
gObserverTable = nsnull;
|
|
|
|
|
|
|
|
delete gCacheData;
|
|
|
|
gCacheData = nsnull;
|
|
|
|
|
2011-06-21 23:39:10 -07:00
|
|
|
NS_RELEASE(sRootBranch);
|
|
|
|
NS_RELEASE(sDefaultRootBranch);
|
|
|
|
|
2011-06-02 23:01:02 -07:00
|
|
|
sPreferences = nsnull;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
PREF_Cleanup();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* nsISupports Implementation
|
|
|
|
*/
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
NS_IMPL_THREADSAFE_ADDREF(Preferences)
|
|
|
|
NS_IMPL_THREADSAFE_RELEASE(Preferences)
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
NS_INTERFACE_MAP_BEGIN(Preferences)
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrefService)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIPrefService)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIPrefBranch)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIPrefBranch2)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIPrefBranchInternal)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* nsIPrefService Implementation
|
|
|
|
*/
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
nsresult
|
|
|
|
Preferences::Init()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
rv = PREF_Init();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
rv = pref_InitInitialObjects();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2010-09-27 14:23:35 -07:00
|
|
|
using mozilla::dom::ContentChild;
|
|
|
|
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
2010-11-08 18:49:00 -08:00
|
|
|
InfallibleTArray<PrefTuple> array;
|
2010-10-19 13:35:08 -07:00
|
|
|
ContentChild::GetSingleton()->SendReadPrefsArray(&array);
|
2010-09-27 14:23:35 -07:00
|
|
|
|
2010-10-19 13:35:08 -07:00
|
|
|
// Store the array
|
|
|
|
nsTArray<PrefTuple>::size_type index = array.Length();
|
|
|
|
while (index-- > 0) {
|
2011-10-17 07:59:28 -07:00
|
|
|
pref_SetPrefTuple(array[index], true);
|
2010-10-19 13:35:08 -07:00
|
|
|
}
|
|
|
|
return NS_OK;
|
2010-09-27 14:23:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsXPIDLCString lockFileName;
|
2007-03-22 10:30:00 -07:00
|
|
|
/*
|
|
|
|
* The following is a small hack which will allow us to only load the library
|
|
|
|
* which supports the netscape.cfg file if the preference is defined. We
|
|
|
|
* test for the existence of the pref, set in the all.js (mozilla) or
|
|
|
|
* all-ns.js (netscape 6), and if it exists we startup the pref config
|
|
|
|
* category which will do the rest.
|
|
|
|
*/
|
|
|
|
|
2011-06-21 23:39:10 -07:00
|
|
|
rv = sRootBranch->GetCharPref("general.config.filename", getter_Copies(lockFileName));
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_SUCCEEDED(rv))
|
|
|
|
NS_CreateServicesFromCategory("pref-config-startup",
|
2007-07-08 00:08:04 -07:00
|
|
|
static_cast<nsISupports *>(static_cast<void *>(this)),
|
2007-03-22 10:30:00 -07:00
|
|
|
"pref-config-startup");
|
|
|
|
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 09:59:13 -07:00
|
|
|
nsCOMPtr<nsIObserverService> observerService =
|
|
|
|
mozilla::services::GetObserverService();
|
|
|
|
if (!observerService)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
rv = observerService->AddObserver(this, "profile-before-change", true);
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 09:59:13 -07:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv))
|
2011-10-17 07:59:28 -07:00
|
|
|
rv = observerService->AddObserver(this, "profile-do-change", true);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
observerService->AddObserver(this, "load-extension-defaults", true);
|
2010-07-02 09:45:20 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return(rv);
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
Preferences::Observe(nsISupports *aSubject, const char *aTopic,
|
|
|
|
const PRUnichar *someData)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-09-08 20:38:12 -07:00
|
|
|
if (XRE_GetProcessType() == GeckoProcessType_Content)
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
|
|
|
|
if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) {
|
|
|
|
if (mCurrentFile) {
|
2011-10-17 07:59:28 -07:00
|
|
|
mCurrentFile->Remove(false);
|
2007-03-22 10:30:00 -07:00
|
|
|
mCurrentFile = nsnull;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rv = SavePrefFile(nsnull);
|
|
|
|
}
|
|
|
|
} else if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
|
2008-12-04 06:31:53 -08:00
|
|
|
ResetUserPrefs();
|
|
|
|
rv = ReadUserPrefs(nsnull);
|
2010-07-02 09:45:20 -07:00
|
|
|
} else if (!strcmp(aTopic, "load-extension-defaults")) {
|
|
|
|
pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST);
|
2007-05-02 13:13:33 -07:00
|
|
|
} else if (!nsCRT::strcmp(aTopic, "reload-default-prefs")) {
|
|
|
|
// Reload the default prefs from file.
|
|
|
|
pref_InitInitialObjects();
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
Preferences::ReadUserPrefs(nsIFile *aFile)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-05-26 12:30:03 -07:00
|
|
|
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
|
|
|
NS_ERROR("cannot load prefs from content process");
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (nsnull == aFile) {
|
|
|
|
rv = UseDefaultPrefFile();
|
|
|
|
UseUserPrefFile();
|
|
|
|
|
|
|
|
NotifyServiceObservers(NS_PREFSERVICE_READ_TOPIC_ID);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
rv = ReadAndOwnUserPrefFile(aFile);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
Preferences::ResetPrefs()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-05-26 12:30:03 -07:00
|
|
|
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
|
|
|
NS_ERROR("cannot set prefs from content process");
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NotifyServiceObservers(NS_PREFSERVICE_RESET_TOPIC_ID);
|
|
|
|
PREF_CleanupPrefs();
|
|
|
|
|
|
|
|
nsresult rv = PREF_Init();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
return pref_InitInitialObjects();
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
Preferences::ResetUserPrefs()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-05-26 12:30:03 -07:00
|
|
|
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
|
|
|
NS_ERROR("cannot set prefs from content process");
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
PREF_ClearAllUserPrefs();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
Preferences::SavePrefFile(nsIFile *aFile)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-05-26 12:30:03 -07:00
|
|
|
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
|
|
|
NS_ERROR("cannot save prefs from content process");
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return SavePrefFileInternal(aFile);
|
|
|
|
}
|
|
|
|
|
2011-11-02 07:51:39 -07:00
|
|
|
nsresult
|
|
|
|
Preferences::ReadExtensionPrefs(nsIFile *aFile)
|
2010-09-08 20:38:12 -07:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIZipReader> reader = do_CreateInstance(kZipReaderCID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
rv = reader->Open(aFile);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIUTF8StringEnumerator> files;
|
2011-09-28 16:14:45 -07:00
|
|
|
rv = reader->FindEntries(nsDependentCString("defaults/preferences/*.(J|j)(S|s)$"),
|
2010-09-08 20:38:12 -07:00
|
|
|
getter_AddRefs(files));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
char buffer[4096];
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool more;
|
2010-09-08 20:38:12 -07:00
|
|
|
while (NS_SUCCEEDED(rv = files->HasMore(&more)) && more) {
|
|
|
|
nsCAutoString entry;
|
|
|
|
rv = files->GetNext(entry);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIInputStream> stream;
|
2011-09-28 16:14:45 -07:00
|
|
|
rv = reader->GetInputStream(entry, getter_AddRefs(stream));
|
2010-09-08 20:38:12 -07:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
PRUint32 avail, read;
|
|
|
|
|
|
|
|
PrefParseState ps;
|
|
|
|
PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
|
|
|
|
while (NS_SUCCEEDED(rv = stream->Available(&avail)) && avail) {
|
|
|
|
rv = stream->Read(buffer, 4096, &read);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_WARNING("Pref stream read failed");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = PREF_ParseBuf(&ps, buffer, read);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_WARNING("Pref stream parse failed");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PREF_FinalizeParseState(&ps);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-11-02 07:51:39 -07:00
|
|
|
void
|
2011-05-23 07:54:02 -07:00
|
|
|
Preferences::SetPreference(const PrefTuple *aPref)
|
2010-09-27 14:23:35 -07:00
|
|
|
{
|
2011-11-02 07:51:39 -07:00
|
|
|
pref_SetPrefTuple(*aPref, true);
|
2010-09-27 14:23:35 -07:00
|
|
|
}
|
|
|
|
|
2011-11-02 07:51:39 -07:00
|
|
|
void
|
|
|
|
Preferences::ClearContentPref(const char *aPref)
|
2011-01-05 20:54:47 -08:00
|
|
|
{
|
2011-11-02 07:51:39 -07:00
|
|
|
PREF_ClearUserPref(aPref);
|
2011-01-05 20:54:47 -08:00
|
|
|
}
|
|
|
|
|
2011-11-02 07:51:39 -07:00
|
|
|
bool
|
|
|
|
Preferences::MirrorPreference(const char *aPref, PrefTuple *aTuple)
|
2010-09-28 10:02:37 -07:00
|
|
|
{
|
2011-11-02 07:51:39 -07:00
|
|
|
PrefHashEntry *entry = pref_HashTableLookup(aPref);
|
|
|
|
if (!entry)
|
|
|
|
return false;
|
2010-09-28 10:02:37 -07:00
|
|
|
|
2011-11-02 07:51:39 -07:00
|
|
|
pref_GetTupleFromEntry(entry, aTuple);
|
|
|
|
return true;
|
2010-09-28 10:02:37 -07:00
|
|
|
}
|
|
|
|
|
2011-11-02 07:51:39 -07:00
|
|
|
void
|
2011-05-23 07:54:02 -07:00
|
|
|
Preferences::MirrorPreferences(nsTArray<PrefTuple,
|
|
|
|
nsTArrayInfallibleAllocator> *aArray)
|
2010-09-28 10:02:37 -07:00
|
|
|
{
|
2010-10-19 13:35:08 -07:00
|
|
|
aArray->SetCapacity(PL_DHASH_TABLE_SIZE(&gHashTable));
|
|
|
|
PL_DHashTableEnumerate(&gHashTable, pref_MirrorPrefs, aArray);
|
2010-09-28 10:02:37 -07:00
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
Preferences::GetBranch(const char *aPrefRoot, nsIPrefBranch **_retval)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if ((nsnull != aPrefRoot) && (*aPrefRoot != '\0')) {
|
|
|
|
// TODO: - cache this stuff and allow consumers to share branches (hold weak references I think)
|
2011-10-17 07:59:28 -07:00
|
|
|
nsPrefBranch* prefBranch = new nsPrefBranch(aPrefRoot, false);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (!prefBranch)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
rv = CallQueryInterface(prefBranch, _retval);
|
|
|
|
} else {
|
|
|
|
// special case caching the default root
|
2011-06-21 23:39:10 -07:00
|
|
|
rv = CallQueryInterface(sRootBranch, _retval);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
Preferences::GetDefaultBranch(const char *aPrefRoot, nsIPrefBranch **_retval)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2011-06-21 23:39:10 -07:00
|
|
|
if (!aPrefRoot || !aPrefRoot[0]) {
|
|
|
|
return CallQueryInterface(sDefaultRootBranch, _retval);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// TODO: - cache this stuff and allow consumers to share branches (hold weak references I think)
|
2011-10-17 07:59:28 -07:00
|
|
|
nsPrefBranch* prefBranch = new nsPrefBranch(aPrefRoot, true);
|
2007-03-22 10:30:00 -07:00
|
|
|
if (!prefBranch)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2011-06-21 23:39:10 -07:00
|
|
|
return CallQueryInterface(prefBranch, _retval);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
nsresult
|
|
|
|
Preferences::NotifyServiceObservers(const char *aTopic)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIObserverService> observerService =
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 09:59:13 -07:00
|
|
|
mozilla::services::GetObserverService();
|
|
|
|
if (!observerService)
|
|
|
|
return NS_ERROR_FAILURE;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsISupports *subject = (nsISupports *)((nsIPrefService *)this);
|
|
|
|
observerService->NotifyObservers(subject, aTopic, nsnull);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
nsresult
|
|
|
|
Preferences::UseDefaultPrefFile()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
nsresult rv, rv2;
|
|
|
|
nsCOMPtr<nsIFile> aFile;
|
|
|
|
|
|
|
|
rv = NS_GetSpecialDirectory(NS_APP_PREFS_50_FILE, getter_AddRefs(aFile));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = ReadAndOwnUserPrefFile(aFile);
|
|
|
|
// Most likely cause of failure here is that the file didn't
|
|
|
|
// exist, so save a new one. mUserPrefReadFailed will be
|
|
|
|
// used to catch an error in actually reading the file.
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
rv2 = SavePrefFileInternal(aFile);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv2), "Failed to save new shared pref file");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
nsresult
|
|
|
|
Preferences::UseUserPrefFile()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIFile> aFile;
|
|
|
|
nsDependentCString prefsDirProp(NS_APP_PREFS_50_DIR);
|
|
|
|
|
|
|
|
rv = NS_GetSpecialDirectory(prefsDirProp.get(), getter_AddRefs(aFile));
|
|
|
|
if (NS_SUCCEEDED(rv) && aFile) {
|
|
|
|
rv = aFile->AppendNative(NS_LITERAL_CSTRING("user.js"));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2011-09-28 23:19:26 -07:00
|
|
|
bool exists = false;
|
2007-09-15 12:32:51 -07:00
|
|
|
aFile->Exists(&exists);
|
|
|
|
if (exists) {
|
|
|
|
rv = openPrefFile(aFile);
|
|
|
|
} else {
|
|
|
|
rv = NS_ERROR_FILE_NOT_FOUND;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
nsresult
|
|
|
|
Preferences::MakeBackupPrefFile(nsIFile *aFile)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
// Example: this copies "prefs.js" to "Invalidprefs.js" in the same directory.
|
2009-11-03 11:05:31 -08:00
|
|
|
// "Invalidprefs.js" is removed if it exists, prior to making the copy.
|
2007-03-22 10:30:00 -07:00
|
|
|
nsAutoString newFilename;
|
|
|
|
nsresult rv = aFile->GetLeafName(newFilename);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
newFilename.Insert(NS_LITERAL_STRING("Invalid"), 0);
|
2009-11-03 11:05:31 -08:00
|
|
|
nsCOMPtr<nsIFile> newFile;
|
|
|
|
rv = aFile->GetParent(getter_AddRefs(newFile));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = newFile->Append(newFilename);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2011-09-28 23:19:26 -07:00
|
|
|
bool exists = false;
|
2009-11-03 11:05:31 -08:00
|
|
|
newFile->Exists(&exists);
|
|
|
|
if (exists) {
|
2011-10-17 07:59:28 -07:00
|
|
|
rv = newFile->Remove(false);
|
2009-11-03 11:05:31 -08:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
rv = aFile->CopyTo(nsnull, newFilename);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
nsresult
|
|
|
|
Preferences::ReadAndOwnUserPrefFile(nsIFile *aFile)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_ARG(aFile);
|
|
|
|
|
|
|
|
if (mCurrentFile == aFile)
|
|
|
|
return NS_OK;
|
|
|
|
mCurrentFile = aFile;
|
|
|
|
|
2007-12-04 17:05:55 -08:00
|
|
|
nsresult rv = NS_OK;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool exists = false;
|
2007-12-04 17:05:55 -08:00
|
|
|
mCurrentFile->Exists(&exists);
|
|
|
|
if (exists) {
|
|
|
|
rv = openPrefFile(mCurrentFile);
|
|
|
|
if (NS_FAILED(rv)) {
|
2009-11-03 11:05:31 -08:00
|
|
|
// Save a backup copy of the current (invalid) prefs file, since all prefs
|
|
|
|
// from the error line to the end of the file will be lost (bug 361102).
|
|
|
|
// TODO we should notify the user about it (bug 523725).
|
|
|
|
MakeBackupPrefFile(mCurrentFile);
|
2007-12-04 17:05:55 -08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rv = NS_ERROR_FILE_NOT_FOUND;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
nsresult
|
|
|
|
Preferences::SavePrefFileInternal(nsIFile *aFile)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
if (nsnull == aFile) {
|
|
|
|
// the gDirty flag tells us if we should write to mCurrentFile
|
|
|
|
// we only check this flag when the caller wants to write to the default
|
|
|
|
if (!gDirty)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// It's possible that we never got a prefs file.
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (mCurrentFile)
|
|
|
|
rv = WritePrefFile(mCurrentFile);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
} else {
|
|
|
|
return WritePrefFile(aFile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
nsresult
|
|
|
|
Preferences::WritePrefFile(nsIFile* aFile)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
const char outHeader[] =
|
|
|
|
"# Mozilla User Preferences"
|
|
|
|
NS_LINEBREAK
|
|
|
|
NS_LINEBREAK
|
|
|
|
"/* Do not edit this file."
|
|
|
|
NS_LINEBREAK
|
|
|
|
" *"
|
|
|
|
NS_LINEBREAK
|
|
|
|
" * If you make changes to this file while the application is running,"
|
|
|
|
NS_LINEBREAK
|
|
|
|
" * the changes will be overwritten when the application exits."
|
|
|
|
NS_LINEBREAK
|
|
|
|
" *"
|
|
|
|
NS_LINEBREAK
|
|
|
|
" * To make a manual change to preferences, you can visit the URL about:config"
|
|
|
|
NS_LINEBREAK
|
|
|
|
" * For more information, see http://www.mozilla.org/unix/customizing.html#prefs"
|
|
|
|
NS_LINEBREAK
|
|
|
|
" */"
|
|
|
|
NS_LINEBREAK
|
|
|
|
NS_LINEBREAK;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIOutputStream> outStreamSink;
|
|
|
|
nsCOMPtr<nsIOutputStream> outStream;
|
|
|
|
PRUint32 writeAmount;
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
if (!gHashTable.ops)
|
|
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
|
|
|
|
|
|
// execute a "safe" save by saving through a tempfile
|
|
|
|
rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(outStreamSink),
|
|
|
|
aFile,
|
|
|
|
-1,
|
|
|
|
0600);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
rv = NS_NewBufferedOutputStream(getter_AddRefs(outStream), outStreamSink, 4096);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
char** valueArray = (char **)PR_Calloc(sizeof(char *), gHashTable.entryCount);
|
|
|
|
if (!valueArray)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
pref_saveArgs saveArgs;
|
|
|
|
saveArgs.prefArray = valueArray;
|
|
|
|
saveArgs.saveTypes = SAVE_ALL;
|
|
|
|
|
|
|
|
// get the lines that we're supposed to be writing to the file
|
|
|
|
PL_DHashTableEnumerate(&gHashTable, pref_savePref, &saveArgs);
|
|
|
|
|
|
|
|
/* Sort the preferences to make a readable file on disk */
|
|
|
|
NS_QuickSort(valueArray, gHashTable.entryCount, sizeof(char *), pref_CompareStrings, NULL);
|
|
|
|
|
|
|
|
// write out the file header
|
|
|
|
outStream->Write(outHeader, sizeof(outHeader) - 1, &writeAmount);
|
|
|
|
|
|
|
|
char** walker = valueArray;
|
|
|
|
for (PRUint32 valueIdx = 0; valueIdx < gHashTable.entryCount; valueIdx++, walker++) {
|
|
|
|
if (*walker) {
|
|
|
|
outStream->Write(*walker, strlen(*walker), &writeAmount);
|
|
|
|
outStream->Write(NS_LINEBREAK, NS_LINEBREAK_LEN, &writeAmount);
|
2009-03-29 04:45:19 -07:00
|
|
|
NS_Free(*walker);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
PR_Free(valueArray);
|
|
|
|
|
|
|
|
// tell the safe output stream to overwrite the real prefs file
|
|
|
|
// (it'll abort if there were any errors during writing)
|
|
|
|
nsCOMPtr<nsISafeOutputStream> safeStream = do_QueryInterface(outStream);
|
|
|
|
NS_ASSERTION(safeStream, "expected a safe output stream!");
|
|
|
|
if (safeStream) {
|
|
|
|
rv = safeStream->Finish();
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_WARNING("failed to save prefs file! possible dataloss");
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
gDirty = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-09-13 08:36:23 -07:00
|
|
|
static nsresult openPrefFile(nsIFile* aFile)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIInputStream> inStr;
|
|
|
|
|
|
|
|
nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), aFile);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2009-10-04 03:44:52 -07:00
|
|
|
PRUint32 fileSize;
|
|
|
|
rv = inStr->Available(&fileSize);
|
2008-04-01 23:41:23 -07:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
nsAutoArrayPtr<char> fileBuffer(new char[fileSize]);
|
|
|
|
if (fileBuffer == nsnull)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
PrefParseState ps;
|
|
|
|
PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
|
2008-04-01 23:41:23 -07:00
|
|
|
|
|
|
|
// Read is not guaranteed to return a buf the size of fileSize,
|
|
|
|
// but usually will.
|
2008-01-30 15:39:42 -08:00
|
|
|
nsresult rv2 = NS_OK;
|
|
|
|
for (;;) {
|
|
|
|
PRUint32 amtRead = 0;
|
2009-09-13 08:36:23 -07:00
|
|
|
rv = inStr->Read((char*)fileBuffer, fileSize, &amtRead);
|
2008-01-30 15:39:42 -08:00
|
|
|
if (NS_FAILED(rv) || amtRead == 0)
|
|
|
|
break;
|
2008-04-01 23:41:23 -07:00
|
|
|
if (!PREF_ParseBuf(&ps, fileBuffer, amtRead))
|
2008-01-30 15:39:42 -08:00
|
|
|
rv2 = NS_ERROR_FILE_CORRUPTED;
|
|
|
|
}
|
2008-04-01 23:41:23 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
PREF_FinalizeParseState(&ps);
|
2008-04-01 23:41:23 -07:00
|
|
|
|
|
|
|
return NS_FAILED(rv) ? rv : rv2;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* some stuff that gets called from Pref_Init()
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int
|
|
|
|
pref_CompareFileNames(nsIFile* aFile1, nsIFile* aFile2, void* /*unused*/)
|
|
|
|
{
|
|
|
|
nsCAutoString filename1, filename2;
|
|
|
|
aFile1->GetNativeLeafName(filename1);
|
|
|
|
aFile2->GetNativeLeafName(filename2);
|
|
|
|
|
|
|
|
return Compare(filename2, filename1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load default pref files from a directory. The files in the
|
|
|
|
* directory are sorted reverse-alphabetically; a set of "special file
|
|
|
|
* names" may be specified which are loaded after all the others.
|
|
|
|
*/
|
|
|
|
static nsresult
|
|
|
|
pref_LoadPrefsInDir(nsIFile* aDir, char const *const *aSpecialFiles, PRUint32 aSpecialFilesCount)
|
|
|
|
{
|
|
|
|
nsresult rv, rv2;
|
2011-09-28 23:19:26 -07:00
|
|
|
bool hasMoreElements;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> dirIterator;
|
|
|
|
|
|
|
|
// this may fail in some normal cases, such as embedders who do not use a GRE
|
|
|
|
rv = aDir->GetDirectoryEntries(getter_AddRefs(dirIterator));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
// If the directory doesn't exist, then we have no reason to complain. We
|
|
|
|
// loaded everything (and nothing) successfully.
|
|
|
|
if (rv == NS_ERROR_FILE_NOT_FOUND)
|
|
|
|
rv = NS_OK;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = dirIterator->HasMoreElements(&hasMoreElements);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMArray<nsIFile> prefFiles(INITIAL_PREF_FILES);
|
|
|
|
nsCOMArray<nsIFile> specialFiles(aSpecialFilesCount);
|
|
|
|
nsCOMPtr<nsIFile> prefFile;
|
|
|
|
|
|
|
|
while (hasMoreElements && NS_SUCCEEDED(rv)) {
|
|
|
|
nsCAutoString leafName;
|
|
|
|
|
|
|
|
rv = dirIterator->GetNext(getter_AddRefs(prefFile));
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
prefFile->GetNativeLeafName(leafName);
|
|
|
|
NS_ASSERTION(!leafName.IsEmpty(), "Failure in default prefs: directory enumerator returned empty file?");
|
|
|
|
|
|
|
|
// Skip non-js files
|
|
|
|
if (StringEndsWith(leafName, NS_LITERAL_CSTRING(".js"),
|
|
|
|
nsCaseInsensitiveCStringComparator())) {
|
2011-09-28 23:19:26 -07:00
|
|
|
bool shouldParse = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
// separate out special files
|
|
|
|
for (PRUint32 i = 0; i < aSpecialFilesCount; ++i) {
|
|
|
|
if (leafName.Equals(nsDependentCString(aSpecialFiles[i]))) {
|
2011-10-17 07:59:28 -07:00
|
|
|
shouldParse = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
// special files should be process in order; we put them into
|
|
|
|
// the array by index; this can make the array sparse
|
|
|
|
specialFiles.ReplaceObjectAt(prefFile, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldParse) {
|
|
|
|
prefFiles.AppendObject(prefFile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = dirIterator->HasMoreElements(&hasMoreElements);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prefFiles.Count() + specialFiles.Count() == 0) {
|
|
|
|
NS_WARNING("No default pref files found.");
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = NS_SUCCESS_FILE_DIRECTORY_EMPTY;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
prefFiles.Sort(pref_CompareFileNames, nsnull);
|
|
|
|
|
|
|
|
PRUint32 arrayCount = prefFiles.Count();
|
|
|
|
PRUint32 i;
|
|
|
|
for (i = 0; i < arrayCount; ++i) {
|
|
|
|
rv2 = openPrefFile(prefFiles[i]);
|
|
|
|
if (NS_FAILED(rv2)) {
|
|
|
|
NS_ERROR("Default pref file not parsed successfully.");
|
|
|
|
rv = rv2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
arrayCount = specialFiles.Count();
|
|
|
|
for (i = 0; i < arrayCount; ++i) {
|
|
|
|
// this may be a sparse array; test before parsing
|
|
|
|
nsIFile* file = specialFiles[i];
|
|
|
|
if (file) {
|
|
|
|
rv2 = openPrefFile(file);
|
|
|
|
if (NS_FAILED(rv2)) {
|
|
|
|
NS_ERROR("Special default pref file not parsed successfully.");
|
|
|
|
rv = rv2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2007-08-31 19:16:47 -07:00
|
|
|
static nsresult pref_LoadPrefsInDirList(const char *listId)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIProperties> dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> dirList;
|
|
|
|
dirSvc->Get(listId,
|
|
|
|
NS_GET_IID(nsISimpleEnumerator),
|
|
|
|
getter_AddRefs(dirList));
|
|
|
|
if (dirList) {
|
2011-09-28 23:19:26 -07:00
|
|
|
bool hasMore;
|
2007-08-31 19:16:47 -07:00
|
|
|
while (NS_SUCCEEDED(dirList->HasMoreElements(&hasMore)) && hasMore) {
|
|
|
|
nsCOMPtr<nsISupports> elem;
|
|
|
|
dirList->GetNext(getter_AddRefs(elem));
|
|
|
|
if (elem) {
|
|
|
|
nsCOMPtr<nsIFile> dir = do_QueryInterface(elem);
|
|
|
|
if (dir) {
|
|
|
|
// Do we care if a file provided by this process fails to load?
|
|
|
|
pref_LoadPrefsInDir(dir, nsnull, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-06-02 14:49:33 -07:00
|
|
|
static nsresult pref_ReadPrefFromJar(nsZipArchive* jarReader, const char *name)
|
|
|
|
{
|
|
|
|
nsZipItemPtr<char> manifest(jarReader, name, true);
|
|
|
|
NS_ENSURE_TRUE(manifest.Buffer(), NS_ERROR_NOT_AVAILABLE);
|
|
|
|
|
|
|
|
PrefParseState ps;
|
|
|
|
PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
|
|
|
|
nsresult rv = PREF_ParseBuf(&ps, manifest, manifest.Length());
|
|
|
|
PREF_FinalizeParseState(&ps);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-02-25 03:53:36 -08:00
|
|
|
//----------------------------------------------------------------------------------------
|
|
|
|
// Initialize default preference JavaScript buffers from
|
|
|
|
// appropriate TEXT resources
|
|
|
|
//----------------------------------------------------------------------------------------
|
|
|
|
static nsresult pref_InitInitialObjects()
|
2010-06-02 14:49:33 -07:00
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
2011-02-25 03:53:36 -08:00
|
|
|
// In omni.jar case, we load the following prefs:
|
|
|
|
// - jar:$gre/omni.jar!/greprefs.js
|
|
|
|
// - jar:$gre/omni.jar!/defaults/pref/*.js
|
|
|
|
// In non omni.jar case, we load:
|
|
|
|
// - $gre/greprefs.js
|
|
|
|
//
|
2011-07-28 00:04:08 -07:00
|
|
|
// In both cases, we also load:
|
2011-02-25 03:53:36 -08:00
|
|
|
// - $gre/defaults/pref/*.js
|
2011-07-28 00:04:08 -07:00
|
|
|
// This is kept for bug 591866 (channel-prefs.js should not be in omni.jar)
|
|
|
|
// on $app == $gre case ; we load all files instead of channel-prefs.js only
|
|
|
|
// to have the same behaviour as $app != $gre, where this is required as
|
|
|
|
// a supported location for GRE preferences.
|
2011-02-25 03:53:36 -08:00
|
|
|
//
|
|
|
|
// When $app != $gre, we additionally load, in omni.jar case:
|
|
|
|
// - jar:$app/omni.jar!/defaults/preferences/*.js
|
|
|
|
// - $app/defaults/preferences/*.js
|
|
|
|
// and in non omni.jar case:
|
|
|
|
// - $app/defaults/preferences/*.js
|
2010-06-02 14:49:33 -07:00
|
|
|
|
2010-08-11 18:10:11 -07:00
|
|
|
nsZipFind *findPtr;
|
2011-02-25 03:53:36 -08:00
|
|
|
nsAutoPtr<nsZipFind> find;
|
2010-11-10 00:20:52 -08:00
|
|
|
nsTArray<nsCString> prefEntries;
|
2010-08-11 18:10:11 -07:00
|
|
|
const char *entryName;
|
|
|
|
PRUint16 entryNameLen;
|
2010-11-10 00:20:52 -08:00
|
|
|
|
2011-02-25 03:53:36 -08:00
|
|
|
nsZipArchive* jarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
|
|
|
|
if (jarReader) {
|
|
|
|
// Load jar:$gre/omni.jar!/greprefs.js
|
|
|
|
rv = pref_ReadPrefFromJar(jarReader, "greprefs.js");
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2011-02-25 03:53:36 -08:00
|
|
|
|
2011-02-25 03:53:36 -08:00
|
|
|
// Load jar:$gre/omni.jar!/defaults/pref/*.js
|
|
|
|
rv = jarReader->FindInit("defaults/pref/*.js$", &findPtr);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2011-02-25 03:53:36 -08:00
|
|
|
|
2011-02-25 03:53:36 -08:00
|
|
|
find = findPtr;
|
|
|
|
while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) {
|
|
|
|
prefEntries.AppendElement(Substring(entryName, entryName + entryNameLen));
|
|
|
|
}
|
2011-05-10 18:27:51 -07:00
|
|
|
|
2011-02-25 03:53:36 -08:00
|
|
|
prefEntries.Sort();
|
|
|
|
for (PRUint32 i = prefEntries.Length(); i--; ) {
|
|
|
|
rv = pref_ReadPrefFromJar(jarReader, prefEntries[i].get());
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
NS_WARNING("Error parsing preferences.");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Load $gre/greprefs.js
|
|
|
|
nsCOMPtr<nsIFile> greprefsFile;
|
|
|
|
rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(greprefsFile));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2011-05-10 18:27:51 -07:00
|
|
|
|
2011-02-25 03:53:36 -08:00
|
|
|
rv = greprefsFile->AppendNative(NS_LITERAL_CSTRING("greprefs.js"));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
rv = openPrefFile(greprefsFile);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
NS_WARNING("Error parsing GRE default preferences. Is this an old-style embedding app?");
|
|
|
|
}
|
|
|
|
|
2011-07-28 00:04:08 -07:00
|
|
|
// Load $gre/defaults/pref/*.js
|
|
|
|
nsCOMPtr<nsIFile> defaultPrefDir;
|
2011-02-25 03:53:36 -08:00
|
|
|
|
2011-07-28 00:04:08 -07:00
|
|
|
rv = NS_GetSpecialDirectory(NS_APP_PREF_DEFAULTS_50_DIR, getter_AddRefs(defaultPrefDir));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2011-02-08 10:54:52 -08:00
|
|
|
|
2011-07-28 00:04:08 -07:00
|
|
|
/* these pref file names should not be used: we process them after all other application pref files for backwards compatibility */
|
|
|
|
static const char* specialFiles[] = {
|
2011-05-10 11:24:48 -07:00
|
|
|
#if defined(XP_MACOSX)
|
2011-07-28 00:04:08 -07:00
|
|
|
"macprefs.js"
|
2011-02-08 10:54:52 -08:00
|
|
|
#elif defined(XP_WIN)
|
2011-07-28 00:04:08 -07:00
|
|
|
"winpref.js"
|
2011-02-08 10:54:52 -08:00
|
|
|
#elif defined(XP_UNIX)
|
2011-07-28 00:04:08 -07:00
|
|
|
"unix.js"
|
2011-02-25 03:53:36 -08:00
|
|
|
#if defined(VMS)
|
2011-07-28 00:04:08 -07:00
|
|
|
, "openvms.js"
|
2011-02-25 03:53:36 -08:00
|
|
|
#elif defined(_AIX)
|
2011-07-28 00:04:08 -07:00
|
|
|
, "aix.js"
|
2011-02-08 10:54:52 -08:00
|
|
|
#endif
|
|
|
|
#elif defined(XP_OS2)
|
2011-07-28 00:04:08 -07:00
|
|
|
"os2pref.js"
|
2011-02-25 03:53:36 -08:00
|
|
|
#elif defined(XP_BEOS)
|
2011-07-28 00:04:08 -07:00
|
|
|
"beos.js"
|
2011-02-08 10:54:52 -08:00
|
|
|
#endif
|
2011-07-28 00:04:08 -07:00
|
|
|
};
|
2011-02-08 10:54:52 -08:00
|
|
|
|
2011-10-10 22:50:08 -07:00
|
|
|
rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, ArrayLength(specialFiles));
|
2011-07-28 00:04:08 -07:00
|
|
|
if (NS_FAILED(rv))
|
|
|
|
NS_WARNING("Error parsing application default preferences.");
|
2011-02-25 03:53:36 -08:00
|
|
|
|
|
|
|
// Load jar:$app/omni.jar!/defaults/preferences/*.js
|
|
|
|
nsZipArchive *appJarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP);
|
|
|
|
if (appJarReader) {
|
|
|
|
rv = appJarReader->FindInit("defaults/preferences/*.js$", &findPtr);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
find = findPtr;
|
|
|
|
prefEntries.Clear();
|
|
|
|
while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) {
|
|
|
|
prefEntries.AppendElement(Substring(entryName, entryName + entryNameLen));
|
|
|
|
}
|
|
|
|
prefEntries.Sort();
|
|
|
|
for (PRUint32 i = prefEntries.Length(); i--; ) {
|
|
|
|
rv = pref_ReadPrefFromJar(appJarReader, prefEntries[i].get());
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
NS_WARNING("Error parsing preferences.");
|
|
|
|
}
|
2011-02-08 10:54:52 -08:00
|
|
|
}
|
|
|
|
|
2007-08-31 19:16:47 -07:00
|
|
|
rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-08-31 19:16:47 -07:00
|
|
|
NS_CreateServicesFromCategory(NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID,
|
|
|
|
nsnull, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
Bug 560095 - Use mozilla::services::GetObserverService(). r=biesi,dveditz,gavin,josh,jst,mrbkap,roc,sdwilsh,shaver,sicking,smontagu,surkov
2010-04-29 09:59:13 -07:00
|
|
|
nsCOMPtr<nsIObserverService> observerService =
|
|
|
|
mozilla::services::GetObserverService();
|
|
|
|
if (!observerService)
|
|
|
|
return NS_ERROR_FAILURE;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-08-31 19:16:47 -07:00
|
|
|
observerService->NotifyObservers(nsnull, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID, nsnull);
|
|
|
|
|
|
|
|
return pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2011-05-23 07:54:02 -07:00
|
|
|
|
2011-05-23 07:54:03 -07:00
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* static utilities
|
|
|
|
*
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
2011-09-28 23:19:26 -07:00
|
|
|
Preferences::GetBool(const char* aPref, bool* aResult)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-06-21 23:39:10 -07:00
|
|
|
return sRootBranch->GetBoolPref(aPref, aResult);
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::GetInt(const char* aPref, PRInt32* aResult)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-06-21 23:39:10 -07:00
|
|
|
return sRootBranch->GetIntPref(aPref, aResult);
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
2011-05-28 00:03:00 -07:00
|
|
|
// static
|
|
|
|
nsAdoptingCString
|
|
|
|
Preferences::GetCString(const char* aPref)
|
|
|
|
{
|
|
|
|
nsAdoptingCString result;
|
|
|
|
GetCString(aPref, &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsAdoptingString
|
|
|
|
Preferences::GetString(const char* aPref)
|
|
|
|
{
|
|
|
|
nsAdoptingString result;
|
|
|
|
GetString(aPref, &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:03 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
2011-05-28 00:03:00 -07:00
|
|
|
Preferences::GetCString(const char* aPref, nsACString* aResult)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-05-28 00:03:00 -07:00
|
|
|
nsCAutoString result;
|
2011-06-21 23:39:10 -07:00
|
|
|
nsresult rv = sRootBranch->GetCharPref(aPref, getter_Copies(result));
|
2011-05-23 07:54:03 -07:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
*aResult = result;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
2011-05-28 00:03:00 -07:00
|
|
|
Preferences::GetString(const char* aPref, nsAString* aResult)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-05-28 00:03:00 -07:00
|
|
|
nsCAutoString result;
|
2011-06-21 23:39:10 -07:00
|
|
|
nsresult rv = sRootBranch->GetCharPref(aPref, getter_Copies(result));
|
2011-05-23 07:54:03 -07:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
CopyUTF8toUTF16(result, *aResult);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-05-28 00:03:00 -07:00
|
|
|
// static
|
|
|
|
nsAdoptingCString
|
|
|
|
Preferences::GetLocalizedCString(const char* aPref)
|
|
|
|
{
|
|
|
|
nsAdoptingCString result;
|
|
|
|
GetLocalizedCString(aPref, &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsAdoptingString
|
|
|
|
Preferences::GetLocalizedString(const char* aPref)
|
|
|
|
{
|
|
|
|
nsAdoptingString result;
|
|
|
|
GetLocalizedString(aPref, &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-05-26 21:53:03 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
2011-05-28 00:03:00 -07:00
|
|
|
Preferences::GetLocalizedCString(const char* aPref, nsACString* aResult)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
|
|
|
nsAutoString result;
|
|
|
|
nsresult rv = GetLocalizedString(aPref, &result);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
CopyUTF16toUTF8(result, *aResult);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::GetLocalizedString(const char* aPref, nsAString* aResult)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(aResult, "aResult must not be NULL");
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
|
|
|
nsCOMPtr<nsIPrefLocalizedString> prefLocalString;
|
2011-06-21 23:39:10 -07:00
|
|
|
nsresult rv = sRootBranch->GetComplexValue(aPref,
|
2011-05-23 07:54:03 -07:00
|
|
|
NS_GET_IID(nsIPrefLocalizedString),
|
|
|
|
getter_AddRefs(prefLocalString));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2011-05-28 00:03:00 -07:00
|
|
|
NS_ASSERTION(prefLocalString, "Succeeded but the result is NULL");
|
|
|
|
prefLocalString->GetData(getter_Copies(*aResult));
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2011-06-11 19:30:15 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::GetComplex(const char* aPref, const nsIID &aType, void** aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-06-21 23:39:10 -07:00
|
|
|
return sRootBranch->GetComplexValue(aPref, aType, aResult);
|
2011-06-11 19:30:15 -07:00
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:03 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
2011-05-28 00:03:00 -07:00
|
|
|
Preferences::SetCString(const char* aPref, const char* aValue)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
2011-06-02 23:01:02 -07:00
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-06-21 23:39:10 -07:00
|
|
|
return sRootBranch->SetCharPref(aPref, aValue);
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
2011-05-28 00:03:00 -07:00
|
|
|
Preferences::SetCString(const char* aPref, const nsACString &aValue)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
2011-05-28 00:03:00 -07:00
|
|
|
return SetCString(aPref, PromiseFlatCString(aValue).get());
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
2011-05-28 00:03:00 -07:00
|
|
|
Preferences::SetString(const char* aPref, const PRUnichar* aValue)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
|
|
|
NS_ConvertUTF16toUTF8 utf8(aValue);
|
2011-05-28 00:03:00 -07:00
|
|
|
return SetCString(aPref, utf8.get());
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
2011-05-28 00:03:00 -07:00
|
|
|
Preferences::SetString(const char* aPref, const nsAString &aValue)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
|
|
|
NS_ConvertUTF16toUTF8 utf8(aValue);
|
2011-05-28 00:03:00 -07:00
|
|
|
return SetCString(aPref, utf8.get());
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
2011-09-28 23:19:26 -07:00
|
|
|
Preferences::SetBool(const char* aPref, bool aValue)
|
2011-05-23 07:54:03 -07:00
|
|
|
{
|
2011-06-02 23:01:02 -07:00
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-06-21 23:39:10 -07:00
|
|
|
return sRootBranch->SetBoolPref(aPref, aValue);
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::SetInt(const char* aPref, PRInt32 aValue)
|
|
|
|
{
|
2011-06-02 23:01:02 -07:00
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-06-21 23:39:10 -07:00
|
|
|
return sRootBranch->SetIntPref(aPref, aValue);
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
2011-06-11 19:30:15 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::SetComplex(const char* aPref, const nsIID &aType,
|
|
|
|
nsISupports* aValue)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-06-21 23:39:10 -07:00
|
|
|
return sRootBranch->SetComplexValue(aPref, aType, aValue);
|
2011-06-11 19:30:15 -07:00
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:03 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::ClearUser(const char* aPref)
|
|
|
|
{
|
2011-06-02 23:01:02 -07:00
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-06-21 23:39:10 -07:00
|
|
|
return sRootBranch->ClearUserPref(aPref);
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
2011-06-02 23:01:02 -07:00
|
|
|
// static
|
2011-09-28 23:19:26 -07:00
|
|
|
bool
|
2011-06-02 23:01:02 -07:00
|
|
|
Preferences::HasUserValue(const char* aPref)
|
|
|
|
{
|
2011-10-17 07:59:28 -07:00
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), false);
|
2011-09-28 23:19:26 -07:00
|
|
|
bool hasUserValue;
|
2011-06-21 23:39:10 -07:00
|
|
|
nsresult rv = sRootBranch->PrefHasUserValue(aPref, &hasUserValue);
|
2011-06-02 23:01:02 -07:00
|
|
|
if (NS_FAILED(rv)) {
|
2011-10-17 07:59:28 -07:00
|
|
|
return false;
|
2011-06-02 23:01:02 -07:00
|
|
|
}
|
|
|
|
return hasUserValue;
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:03 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::AddStrongObserver(nsIObserver* aObserver,
|
|
|
|
const char* aPref)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-10-17 07:59:28 -07:00
|
|
|
return sRootBranch->AddObserver(aPref, aObserver, false);
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::AddWeakObserver(nsIObserver* aObserver,
|
|
|
|
const char* aPref)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
2011-10-17 07:59:28 -07:00
|
|
|
return sRootBranch->AddObserver(aPref, aObserver, true);
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::RemoveObserver(nsIObserver* aObserver,
|
|
|
|
const char* aPref)
|
|
|
|
{
|
2011-06-02 23:01:02 -07:00
|
|
|
if (!sPreferences && sShutdown) {
|
|
|
|
return NS_OK; // Observers have been released automatically.
|
|
|
|
}
|
|
|
|
NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE);
|
2011-06-21 23:39:10 -07:00
|
|
|
return sRootBranch->RemoveObserver(aPref, aObserver);
|
2011-05-23 07:54:03 -07:00
|
|
|
}
|
|
|
|
|
2011-05-28 16:39:27 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::AddStrongObservers(nsIObserver* aObserver,
|
|
|
|
const char** aPrefs)
|
|
|
|
{
|
|
|
|
for (PRUint32 i = 0; aPrefs[i]; i++) {
|
|
|
|
nsresult rv = AddStrongObserver(aObserver, aPrefs[i]);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::AddWeakObservers(nsIObserver* aObserver,
|
|
|
|
const char** aPrefs)
|
|
|
|
{
|
|
|
|
for (PRUint32 i = 0; aPrefs[i]; i++) {
|
|
|
|
nsresult rv = AddWeakObserver(aObserver, aPrefs[i]);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::RemoveObservers(nsIObserver* aObserver,
|
|
|
|
const char** aPrefs)
|
|
|
|
{
|
2011-06-02 23:01:02 -07:00
|
|
|
if (!sPreferences && sShutdown) {
|
|
|
|
return NS_OK; // Observers have been released automatically.
|
|
|
|
}
|
|
|
|
NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE);
|
|
|
|
|
2011-05-28 16:39:27 -07:00
|
|
|
for (PRUint32 i = 0; aPrefs[i]; i++) {
|
|
|
|
nsresult rv = RemoveObserver(aObserver, aPrefs[i]);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-05-28 16:42:57 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::RegisterCallback(PrefChangedFunc aCallback,
|
|
|
|
const char* aPref,
|
|
|
|
void* aClosure)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
|
|
|
|
|
|
|
ValueObserverHashKey hashKey(aPref, aCallback);
|
|
|
|
nsRefPtr<ValueObserver> observer;
|
|
|
|
gObserverTable->Get(&hashKey, getter_AddRefs(observer));
|
|
|
|
if (observer) {
|
|
|
|
observer->AppendClosure(aClosure);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
observer = new ValueObserver(aPref, aCallback);
|
|
|
|
observer->AppendClosure(aClosure);
|
|
|
|
nsresult rv = AddStrongObserver(observer, aPref);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return gObserverTable->Put(observer, observer) ? NS_OK :
|
|
|
|
NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::UnregisterCallback(PrefChangedFunc aCallback,
|
|
|
|
const char* aPref,
|
|
|
|
void* aClosure)
|
|
|
|
{
|
2011-06-02 23:01:02 -07:00
|
|
|
if (!sPreferences && sShutdown) {
|
|
|
|
return NS_OK; // Observers have been released automatically.
|
|
|
|
}
|
|
|
|
NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE);
|
2011-05-28 16:42:57 -07:00
|
|
|
|
|
|
|
ValueObserverHashKey hashKey(aPref, aCallback);
|
|
|
|
nsRefPtr<ValueObserver> observer;
|
|
|
|
gObserverTable->Get(&hashKey, getter_AddRefs(observer));
|
|
|
|
if (!observer) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
observer->RemoveClosure(aClosure);
|
|
|
|
if (observer->HasNoClosures()) {
|
|
|
|
// Delete the callback since its list of closures is empty.
|
|
|
|
gObserverTable->Remove(observer);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int BoolVarChanged(const char* aPref, void* aClosure)
|
|
|
|
{
|
|
|
|
CacheData* cache = static_cast<CacheData*>(aClosure);
|
2011-09-28 23:19:26 -07:00
|
|
|
*((bool*)cache->cacheLocation) =
|
2011-05-28 16:42:57 -07:00
|
|
|
Preferences::GetBool(aPref, cache->defaultValueBool);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
2011-09-28 23:19:26 -07:00
|
|
|
Preferences::AddBoolVarCache(bool* aCache,
|
2011-05-28 16:42:57 -07:00
|
|
|
const char* aPref,
|
2011-09-28 23:19:26 -07:00
|
|
|
bool aDefault)
|
2011-05-28 16:42:57 -07:00
|
|
|
{
|
|
|
|
NS_ASSERTION(aCache, "aCache must not be NULL");
|
|
|
|
*aCache = GetBool(aPref, aDefault);
|
|
|
|
CacheData* data = new CacheData();
|
|
|
|
data->cacheLocation = aCache;
|
|
|
|
data->defaultValueBool = aDefault;
|
|
|
|
gCacheData->AppendElement(data);
|
|
|
|
return RegisterCallback(BoolVarChanged, aPref, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int IntVarChanged(const char* aPref, void* aClosure)
|
|
|
|
{
|
|
|
|
CacheData* cache = static_cast<CacheData*>(aClosure);
|
|
|
|
*((PRInt32*)cache->cacheLocation) =
|
|
|
|
Preferences::GetInt(aPref, cache->defaultValueInt);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::AddIntVarCache(PRInt32* aCache,
|
|
|
|
const char* aPref,
|
|
|
|
PRInt32 aDefault)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aCache, "aCache must not be NULL");
|
|
|
|
*aCache = Preferences::GetInt(aPref, aDefault);
|
|
|
|
CacheData* data = new CacheData();
|
|
|
|
data->cacheLocation = aCache;
|
|
|
|
data->defaultValueInt = aDefault;
|
|
|
|
gCacheData->AppendElement(data);
|
|
|
|
return RegisterCallback(IntVarChanged, aPref, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int UintVarChanged(const char* aPref, void* aClosure)
|
|
|
|
{
|
|
|
|
CacheData* cache = static_cast<CacheData*>(aClosure);
|
|
|
|
*((PRUint32*)cache->cacheLocation) =
|
|
|
|
Preferences::GetUint(aPref, cache->defaultValueUint);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::AddUintVarCache(PRUint32* aCache,
|
|
|
|
const char* aPref,
|
|
|
|
PRUint32 aDefault)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aCache, "aCache must not be NULL");
|
|
|
|
*aCache = Preferences::GetUint(aPref, aDefault);
|
|
|
|
CacheData* data = new CacheData();
|
|
|
|
data->cacheLocation = aCache;
|
|
|
|
data->defaultValueUint = aDefault;
|
|
|
|
gCacheData->AppendElement(data);
|
|
|
|
return RegisterCallback(UintVarChanged, aPref, data);
|
|
|
|
}
|
|
|
|
|
2011-06-21 23:39:10 -07:00
|
|
|
// static
|
|
|
|
nsresult
|
2011-09-28 23:19:26 -07:00
|
|
|
Preferences::GetDefaultBool(const char* aPref, bool* aResult)
|
2011-06-21 23:39:10 -07:00
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
|
|
|
return sDefaultRootBranch->GetBoolPref(aPref, aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::GetDefaultInt(const char* aPref, PRInt32* aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
|
|
|
return sDefaultRootBranch->GetIntPref(aPref, aResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::GetDefaultCString(const char* aPref, nsACString* aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
|
|
|
nsCAutoString result;
|
|
|
|
nsresult rv = sDefaultRootBranch->GetCharPref(aPref, getter_Copies(result));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
*aResult = result;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::GetDefaultString(const char* aPref, nsAString* aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
|
|
|
nsCAutoString result;
|
|
|
|
nsresult rv = sDefaultRootBranch->GetCharPref(aPref, getter_Copies(result));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
CopyUTF8toUTF16(result, *aResult);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::GetDefaultLocalizedCString(const char* aPref,
|
|
|
|
nsACString* aResult)
|
|
|
|
{
|
|
|
|
nsAutoString result;
|
|
|
|
nsresult rv = GetDefaultLocalizedString(aPref, &result);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
CopyUTF16toUTF8(result, *aResult);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::GetDefaultLocalizedString(const char* aPref,
|
|
|
|
nsAString* aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
|
|
|
nsCOMPtr<nsIPrefLocalizedString> prefLocalString;
|
|
|
|
nsresult rv =
|
|
|
|
sDefaultRootBranch->GetComplexValue(aPref,
|
|
|
|
NS_GET_IID(nsIPrefLocalizedString),
|
|
|
|
getter_AddRefs(prefLocalString));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
NS_ASSERTION(prefLocalString, "Succeeded but the result is NULL");
|
|
|
|
prefLocalString->GetData(getter_Copies(*aResult));
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsAdoptingString
|
|
|
|
Preferences::GetDefaultString(const char* aPref)
|
|
|
|
{
|
|
|
|
nsAdoptingString result;
|
|
|
|
GetDefaultString(aPref, &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsAdoptingCString
|
|
|
|
Preferences::GetDefaultCString(const char* aPref)
|
|
|
|
{
|
|
|
|
nsAdoptingCString result;
|
|
|
|
GetDefaultCString(aPref, &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsAdoptingString
|
|
|
|
Preferences::GetDefaultLocalizedString(const char* aPref)
|
|
|
|
{
|
|
|
|
nsAdoptingString result;
|
|
|
|
GetDefaultLocalizedString(aPref, &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsAdoptingCString
|
|
|
|
Preferences::GetDefaultLocalizedCString(const char* aPref)
|
|
|
|
{
|
|
|
|
nsAdoptingCString result;
|
|
|
|
GetDefaultLocalizedCString(aPref, &result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
Preferences::GetDefaultComplex(const char* aPref, const nsIID &aType,
|
|
|
|
void** aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
|
|
|
|
return sDefaultRootBranch->GetComplexValue(aPref, aType, aResult);
|
|
|
|
}
|
|
|
|
|
2011-05-23 07:54:02 -07:00
|
|
|
} // namespace mozilla
|