LCOV - code coverage report
Current view: directory - modules/libpref/src - Preferences.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 714 417 58.4 %
Date: 2012-06-02 Functions: 96 63 65.6 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Communicator client code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Alec Flett <alecf@netscape.com>
      24                 :  *   Mats Palmgren <matspal@gmail.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include "mozilla/dom/ContentChild.h"
      41                 : 
      42                 : #include "mozilla/Util.h"
      43                 : #include "mozilla/HashFunctions.h"
      44                 : 
      45                 : #include "nsXULAppAPI.h"
      46                 : 
      47                 : #include "mozilla/Preferences.h"
      48                 : #include "nsAppDirectoryServiceDefs.h"
      49                 : #include "nsDirectoryServiceDefs.h"
      50                 : #include "nsICategoryManager.h"
      51                 : #include "nsCategoryManagerUtils.h"
      52                 : #include "nsNetUtil.h"
      53                 : #include "nsIFile.h"
      54                 : #include "nsIInputStream.h"
      55                 : #include "nsILocalFile.h"
      56                 : #include "nsIObserverService.h"
      57                 : #include "nsIStringEnumerator.h"
      58                 : #include "nsIZipReader.h"
      59                 : #include "nsPrefBranch.h"
      60                 : #include "nsXPIDLString.h"
      61                 : #include "nsCRT.h"
      62                 : #include "nsCOMArray.h"
      63                 : #include "nsXPCOMCID.h"
      64                 : #include "nsAutoPtr.h"
      65                 : 
      66                 : #include "nsQuickSort.h"
      67                 : #include "prmem.h"
      68                 : #include "pldhash.h"
      69                 : 
      70                 : #include "prefapi.h"
      71                 : #include "prefread.h"
      72                 : #include "prefapi_private_data.h"
      73                 : #include "PrefTuple.h"
      74                 : 
      75                 : #include "mozilla/Omnijar.h"
      76                 : #include "nsZipArchive.h"
      77                 : 
      78                 : #include "nsTArray.h"
      79                 : #include "nsRefPtrHashtable.h"
      80                 : 
      81                 : namespace mozilla {
      82                 : 
      83                 : // Definitions
      84                 : #define INITIAL_PREF_FILES 10
      85                 : static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
      86                 : 
      87                 : // Prototypes
      88                 : static nsresult openPrefFile(nsIFile* aFile);
      89                 : static nsresult pref_InitInitialObjects(void);
      90                 : static nsresult pref_LoadPrefsInDirList(const char *listId);
      91                 : static nsresult ReadExtensionPrefs(nsIFile *aFile);
      92                 : 
      93                 : Preferences* Preferences::sPreferences = nsnull;
      94                 : nsIPrefBranch* Preferences::sRootBranch = nsnull;
      95                 : nsIPrefBranch* Preferences::sDefaultRootBranch = nsnull;
      96                 : bool Preferences::sShutdown = false;
      97                 : 
      98          148339 : class ValueObserverHashKey : public PLDHashEntryHdr {
      99                 : public:
     100                 :   typedef ValueObserverHashKey* KeyType;
     101                 :   typedef const ValueObserverHashKey* KeyTypePointer;
     102                 : 
     103          101231 :   static const ValueObserverHashKey* KeyToPointer(ValueObserverHashKey *aKey)
     104                 :   {
     105          101231 :     return aKey;
     106                 :   }
     107                 : 
     108          101231 :   static PLDHashNumber HashKey(const ValueObserverHashKey *aKey)
     109                 :   {
     110          101231 :     PLDHashNumber hash = HashString(aKey->mPrefName);
     111          101231 :     return AddToHash(hash, aKey->mCallback);
     112                 :   }
     113                 : 
     114           99828 :   ValueObserverHashKey(const char *aPref, PrefChangedFunc aCallback) :
     115           99828 :     mPrefName(aPref), mCallback(aCallback) { }
     116                 : 
     117           48511 :   ValueObserverHashKey(const ValueObserverHashKey *aOther) :
     118           48511 :     mPrefName(aOther->mPrefName), mCallback(aOther->mCallback)
     119           48511 :   { }
     120                 : 
     121            2806 :   bool KeyEquals(const ValueObserverHashKey *aOther) const
     122                 :   {
     123            2806 :     return mCallback == aOther->mCallback && mPrefName == aOther->mPrefName;
     124                 :   }
     125                 : 
     126                 :   ValueObserverHashKey *GetKey() const
     127                 :   {
     128                 :     return const_cast<ValueObserverHashKey*>(this);
     129                 :   }
     130                 : 
     131                 :   enum { ALLOW_MEMMOVE = true };
     132                 : 
     133                 :   nsCString mPrefName;
     134                 :   PrefChangedFunc mCallback;
     135                 : };
     136                 : 
     137                 : class ValueObserver : public nsIObserver,
     138                 :                       public ValueObserverHashKey
     139                 : {
     140                 : public:
     141                 :   NS_DECL_ISUPPORTS
     142                 :   NS_DECL_NSIOBSERVER
     143                 : 
     144           48511 :   ValueObserver(const char *aPref, PrefChangedFunc aCallback)
     145           48511 :     : ValueObserverHashKey(aPref, aCallback) { }
     146                 : 
     147           97022 :   ~ValueObserver() {
     148           48511 :     Preferences::RemoveObserver(this, mPrefName.get());
     149           48511 :   }
     150                 : 
     151           48511 :   void AppendClosure(void *aClosure) {
     152           48511 :     mClosures.AppendElement(aClosure);
     153           48511 :   }
     154                 : 
     155            1403 :   void RemoveClosure(void *aClosure) {
     156            1403 :     mClosures.RemoveElement(aClosure);
     157            1403 :   }
     158                 : 
     159            1403 :   bool HasNoClosures() {
     160            1403 :     return mClosures.Length() == 0;
     161                 :   }
     162                 : 
     163                 :   nsTArray<void*> mClosures;
     164                 : };
     165                 : 
     166         1109805 : NS_IMPL_ISUPPORTS1(ValueObserver, nsIObserver)
     167                 : 
     168                 : NS_IMETHODIMP
     169              22 : ValueObserver::Observe(nsISupports     *aSubject,
     170                 :                        const char      *aTopic,
     171                 :                        const PRUnichar *aData)
     172                 : {
     173              22 :   NS_ASSERTION(!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID),
     174                 :                "invalid topic");
     175              44 :   NS_ConvertUTF16toUTF8 data(aData);
     176              44 :   for (PRUint32 i = 0; i < mClosures.Length(); i++) {
     177              22 :     mCallback(data.get(), mClosures.ElementAt(i));
     178                 :   }
     179                 : 
     180              22 :   return NS_OK;
     181                 : }
     182                 : 
     183                 : struct CacheData {
     184                 :   void* cacheLocation;
     185                 :   union {
     186                 :     bool defaultValueBool;
     187                 :     PRInt32 defaultValueInt;
     188                 :     PRUint32 defaultValueUint;
     189                 :   };
     190                 : };
     191                 : 
     192                 : static nsTArray<nsAutoPtr<CacheData> >* gCacheData = nsnull;
     193                 : static nsRefPtrHashtable<ValueObserverHashKey,
     194                 :                          ValueObserver>* gObserverTable = nsnull;
     195                 : 
     196                 : // static
     197                 : Preferences*
     198            1419 : Preferences::GetInstanceForService()
     199                 : {
     200            1419 :   if (sPreferences) {
     201               0 :     NS_ADDREF(sPreferences);
     202               0 :     return sPreferences;
     203                 :   }
     204                 : 
     205            1419 :   NS_ENSURE_TRUE(!sShutdown, nsnull);
     206                 : 
     207            1419 :   sRootBranch = new nsPrefBranch("", false);
     208            1419 :   NS_ADDREF(sRootBranch);
     209            1419 :   sDefaultRootBranch = new nsPrefBranch("", true);
     210            1419 :   NS_ADDREF(sDefaultRootBranch);
     211                 : 
     212            1419 :   sPreferences = new Preferences();
     213            1419 :   NS_ADDREF(sPreferences);
     214                 : 
     215            1419 :   if (NS_FAILED(sPreferences->Init())) {
     216                 :     // The singleton instance will delete sRootBranch and sDefaultRootBranch.
     217               0 :     NS_RELEASE(sPreferences);
     218               0 :     return nsnull;
     219                 :   }
     220                 : 
     221            1419 :   gCacheData = new nsTArray<nsAutoPtr<CacheData> >();
     222                 : 
     223            1419 :   gObserverTable = new nsRefPtrHashtable<ValueObserverHashKey, ValueObserver>();
     224            1419 :   gObserverTable->Init();
     225                 : 
     226            1419 :   NS_ADDREF(sPreferences);
     227            1419 :   return sPreferences;
     228                 : }
     229                 : 
     230                 : // static
     231                 : bool
     232          192732 : Preferences::InitStaticMembers()
     233                 : {
     234          192732 :   if (!sShutdown && !sPreferences) {
     235                 :     nsCOMPtr<nsIPrefService> prefService =
     236               0 :       do_GetService(NS_PREFSERVICE_CONTRACTID);
     237                 :   }
     238                 : 
     239          192732 :   return sPreferences != nsnull;
     240                 : }
     241                 : 
     242                 : // static
     243                 : void
     244            1419 : Preferences::Shutdown()
     245                 : {
     246            1419 :   if (!sShutdown) {
     247            1419 :     sShutdown = true; // Don't create the singleton instance after here.
     248                 : 
     249                 :     // Don't set NULL to sPreferences here.  The instance may be grabbed by
     250                 :     // other modules.  The utility methods of Preferences should be available
     251                 :     // until the singleton instance actually released.
     252            1419 :     if (sPreferences) {
     253            1419 :       sPreferences->Release();
     254                 :     }
     255                 :   }
     256            1419 : }
     257                 : 
     258                 : //-----------------------------------------------------------------------------
     259                 : 
     260                 : /*
     261                 :  * Constructor/Destructor
     262                 :  */
     263                 : 
     264            1419 : Preferences::Preferences()
     265                 : {
     266            1419 : }
     267                 : 
     268            4257 : Preferences::~Preferences()
     269                 : {
     270            1419 :   NS_ASSERTION(sPreferences == this, "Isn't this the singleton instance?");
     271                 : 
     272            1419 :   delete gObserverTable;
     273            1419 :   gObserverTable = nsnull;
     274                 : 
     275            1419 :   delete gCacheData;
     276            1419 :   gCacheData = nsnull;
     277                 : 
     278            1419 :   NS_RELEASE(sRootBranch);
     279            1419 :   NS_RELEASE(sDefaultRootBranch);
     280                 : 
     281            1419 :   sPreferences = nsnull;
     282                 : 
     283            1419 :   PREF_Cleanup();
     284            5676 : }
     285                 : 
     286                 : 
     287                 : /*
     288                 :  * nsISupports Implementation
     289                 :  */
     290                 : 
     291           99849 : NS_IMPL_THREADSAFE_ADDREF(Preferences)
     292           99849 : NS_IMPL_THREADSAFE_RELEASE(Preferences)
     293                 : 
     294           81222 : NS_INTERFACE_MAP_BEGIN(Preferences)
     295           81222 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrefService)
     296           76772 :     NS_INTERFACE_MAP_ENTRY(nsIPrefService)
     297           70131 :     NS_INTERFACE_MAP_ENTRY(nsIObserver)
     298           68499 :     NS_INTERFACE_MAP_ENTRY(nsIPrefBranch)
     299           21292 :     NS_INTERFACE_MAP_ENTRY(nsIPrefBranch2)
     300           21292 :     NS_INTERFACE_MAP_ENTRY(nsIPrefBranchInternal)
     301           21292 :     NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     302           18454 : NS_INTERFACE_MAP_END
     303                 : 
     304                 : 
     305                 : /*
     306                 :  * nsIPrefService Implementation
     307                 :  */
     308                 : 
     309                 : nsresult
     310            1419 : Preferences::Init()
     311                 : {
     312                 :   nsresult rv;
     313                 : 
     314            1419 :   rv = PREF_Init();
     315            1419 :   NS_ENSURE_SUCCESS(rv, rv);
     316                 : 
     317            1419 :   rv = pref_InitInitialObjects();
     318            1419 :   NS_ENSURE_SUCCESS(rv, rv);
     319                 : 
     320                 :   using mozilla::dom::ContentChild;
     321            1419 :   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     322               0 :     InfallibleTArray<PrefTuple> array;
     323               0 :     ContentChild::GetSingleton()->SendReadPrefsArray(&array);
     324                 : 
     325                 :     // Store the array
     326               0 :     nsTArray<PrefTuple>::size_type index = array.Length();
     327               0 :     while (index-- > 0) {
     328               0 :       pref_SetPrefTuple(array[index], true);
     329                 :     }
     330               0 :     return NS_OK;
     331                 :   }
     332                 : 
     333            2838 :   nsXPIDLCString lockFileName;
     334                 :   /*
     335                 :    * The following is a small hack which will allow us to only load the library
     336                 :    * which supports the netscape.cfg file if the preference is defined. We
     337                 :    * test for the existence of the pref, set in the all.js (mozilla) or
     338                 :    * all-ns.js (netscape 6), and if it exists we startup the pref config
     339                 :    * category which will do the rest.
     340                 :    */
     341                 : 
     342            1419 :   rv = PREF_CopyCharPref("general.config.filename", getter_Copies(lockFileName), false);
     343            1419 :   if (NS_SUCCEEDED(rv))
     344                 :     NS_CreateServicesFromCategory("pref-config-startup",
     345                 :                                   static_cast<nsISupports *>(static_cast<void *>(this)),
     346               0 :                                   "pref-config-startup");    
     347                 : 
     348                 :   nsCOMPtr<nsIObserverService> observerService =
     349            2838 :     mozilla::services::GetObserverService();
     350            1419 :   if (!observerService)
     351               0 :     return NS_ERROR_FAILURE;
     352                 : 
     353            1419 :   rv = observerService->AddObserver(this, "profile-before-change", true);
     354                 : 
     355            1419 :   observerService->AddObserver(this, "load-extension-defaults", true);
     356                 : 
     357            1419 :   return(rv);
     358                 : }
     359                 : 
     360                 : // static
     361                 : nsresult
     362               0 : Preferences::ResetAndReadUserPrefs()
     363                 : {
     364               0 :   sPreferences->ResetUserPrefs();
     365               0 :   return sPreferences->ReadUserPrefs(nsnull);
     366                 : }
     367                 : 
     368                 : NS_IMETHODIMP
     369             816 : Preferences::Observe(nsISupports *aSubject, const char *aTopic,
     370                 :                      const PRUnichar *someData)
     371                 : {
     372             816 :   if (XRE_GetProcessType() == GeckoProcessType_Content)
     373               0 :     return NS_ERROR_NOT_AVAILABLE;
     374                 : 
     375             816 :   nsresult rv = NS_OK;
     376                 : 
     377             816 :   if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
     378             814 :     if (!nsCRT::strcmp(someData, NS_LITERAL_STRING("shutdown-cleanse").get())) {
     379               0 :       if (mCurrentFile) {
     380               0 :         mCurrentFile->Remove(false);
     381               0 :         mCurrentFile = nsnull;
     382                 :       }
     383                 :     } else {
     384             814 :       rv = SavePrefFile(nsnull);
     385                 :     }
     386               2 :   } else if (!strcmp(aTopic, "load-extension-defaults")) {
     387               1 :     pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST);
     388               1 :   } else if (!nsCRT::strcmp(aTopic, "reload-default-prefs")) {
     389                 :     // Reload the default prefs from file.
     390               1 :     pref_InitInitialObjects();
     391                 :   }
     392             816 :   return rv;
     393                 : }
     394                 : 
     395                 : 
     396                 : NS_IMETHODIMP
     397               4 : Preferences::ReadUserPrefs(nsIFile *aFile)
     398                 : {
     399               4 :   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     400               0 :     NS_ERROR("cannot load prefs from content process");
     401               0 :     return NS_ERROR_NOT_AVAILABLE;
     402                 :   }
     403                 : 
     404                 :   nsresult rv;
     405                 : 
     406               4 :   if (nsnull == aFile) {
     407               0 :     rv = UseDefaultPrefFile();
     408               0 :     UseUserPrefFile();
     409                 : 
     410               0 :     NotifyServiceObservers(NS_PREFSERVICE_READ_TOPIC_ID);
     411                 : 
     412                 :   } else {
     413               4 :     rv = ReadAndOwnUserPrefFile(aFile);
     414                 :   }
     415               4 :   return rv;
     416                 : }
     417                 : 
     418                 : NS_IMETHODIMP
     419               1 : Preferences::ResetPrefs()
     420                 : {
     421               1 :   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     422               0 :     NS_ERROR("cannot set prefs from content process");
     423               0 :     return NS_ERROR_NOT_AVAILABLE;
     424                 :   }
     425                 : 
     426               1 :   NotifyServiceObservers(NS_PREFSERVICE_RESET_TOPIC_ID);
     427               1 :   PREF_CleanupPrefs();
     428                 : 
     429               1 :   nsresult rv = PREF_Init();
     430               1 :   NS_ENSURE_SUCCESS(rv, rv);
     431                 : 
     432               1 :   return pref_InitInitialObjects();
     433                 : }
     434                 : 
     435                 : NS_IMETHODIMP
     436               0 : Preferences::ResetUserPrefs()
     437                 : {
     438               0 :   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     439               0 :     NS_ERROR("cannot set prefs from content process");
     440               0 :     return NS_ERROR_NOT_AVAILABLE;
     441                 :   }
     442                 : 
     443               0 :   PREF_ClearAllUserPrefs();
     444               0 :   return NS_OK;    
     445                 : }
     446                 : 
     447                 : NS_IMETHODIMP
     448            2117 : Preferences::SavePrefFile(nsIFile *aFile)
     449                 : {
     450            2117 :   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     451               0 :     NS_ERROR("cannot save prefs from content process");
     452               0 :     return NS_ERROR_NOT_AVAILABLE;
     453                 :   }
     454                 : 
     455            2117 :   return SavePrefFileInternal(aFile);
     456                 : }
     457                 : 
     458                 : static nsresult
     459               0 : ReadExtensionPrefs(nsIFile *aFile)
     460                 : {
     461                 :   nsresult rv;
     462               0 :   nsCOMPtr<nsIZipReader> reader = do_CreateInstance(kZipReaderCID, &rv);
     463               0 :   NS_ENSURE_SUCCESS(rv, rv);
     464                 : 
     465               0 :   rv = reader->Open(aFile);
     466               0 :   NS_ENSURE_SUCCESS(rv, rv);
     467                 : 
     468               0 :   nsCOMPtr<nsIUTF8StringEnumerator> files;
     469               0 :   rv = reader->FindEntries(nsDependentCString("defaults/preferences/*.(J|j)(S|s)$"),
     470               0 :                            getter_AddRefs(files));
     471               0 :   NS_ENSURE_SUCCESS(rv, rv);
     472                 : 
     473                 :   char buffer[4096];
     474                 : 
     475                 :   bool more;
     476               0 :   while (NS_SUCCEEDED(rv = files->HasMore(&more)) && more) {
     477               0 :     nsCAutoString entry;
     478               0 :     rv = files->GetNext(entry);
     479               0 :     NS_ENSURE_SUCCESS(rv, rv);
     480                 : 
     481               0 :     nsCOMPtr<nsIInputStream> stream;
     482               0 :     rv = reader->GetInputStream(entry, getter_AddRefs(stream));
     483               0 :     NS_ENSURE_SUCCESS(rv, rv);
     484                 : 
     485                 :     PRUint32 avail, read;
     486                 : 
     487                 :     PrefParseState ps;
     488               0 :     PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
     489               0 :     while (NS_SUCCEEDED(rv = stream->Available(&avail)) && avail) {
     490               0 :       rv = stream->Read(buffer, 4096, &read);
     491               0 :       if (NS_FAILED(rv)) {
     492               0 :         NS_WARNING("Pref stream read failed");
     493               0 :         break;
     494                 :       }
     495                 : 
     496               0 :       rv = PREF_ParseBuf(&ps, buffer, read);
     497               0 :       if (NS_FAILED(rv)) {
     498               0 :         NS_WARNING("Pref stream parse failed");
     499               0 :         break;
     500                 :       }
     501                 :     }
     502               0 :     PREF_FinalizeParseState(&ps);
     503                 :   }
     504               0 :   return rv;
     505                 : }
     506                 : 
     507                 : void
     508               0 : Preferences::SetPreference(const PrefTuple *aPref)
     509                 : {
     510               0 :   pref_SetPrefTuple(*aPref, true);
     511               0 : }
     512                 : 
     513                 : void
     514               0 : Preferences::ClearContentPref(const char *aPref)
     515                 : {
     516               0 :   PREF_ClearUserPref(aPref);
     517               0 : }
     518                 : 
     519                 : bool
     520               0 : Preferences::MirrorPreference(const char *aPref, PrefTuple *aTuple)
     521                 : {
     522               0 :   PrefHashEntry *entry = pref_HashTableLookup(aPref);
     523               0 :   if (!entry)
     524               0 :     return false;
     525                 : 
     526               0 :   pref_GetTupleFromEntry(entry, aTuple);
     527               0 :   return true;
     528                 : }
     529                 : 
     530                 : void
     531               0 : Preferences::MirrorPreferences(nsTArray<PrefTuple,
     532                 :                                         nsTArrayInfallibleAllocator> *aArray)
     533                 : {
     534               0 :   aArray->SetCapacity(PL_DHASH_TABLE_SIZE(&gHashTable));
     535               0 :   PL_DHashTableEnumerate(&gHashTable, pref_MirrorPrefs, aArray);
     536               0 : }
     537                 : 
     538                 : NS_IMETHODIMP
     539            2939 : Preferences::GetBranch(const char *aPrefRoot, nsIPrefBranch **_retval)
     540                 : {
     541                 :   nsresult rv;
     542                 : 
     543            2939 :   if ((nsnull != aPrefRoot) && (*aPrefRoot != '\0')) {
     544                 :     // TODO: - cache this stuff and allow consumers to share branches (hold weak references I think)
     545            2874 :     nsPrefBranch* prefBranch = new nsPrefBranch(aPrefRoot, false);
     546            2874 :     if (!prefBranch)
     547               0 :       return NS_ERROR_OUT_OF_MEMORY;
     548                 : 
     549            2874 :     rv = CallQueryInterface(prefBranch, _retval);
     550                 :   } else {
     551                 :     // special case caching the default root
     552              65 :     rv = CallQueryInterface(sRootBranch, _retval);
     553                 :   }
     554            2939 :   return rv;
     555                 : }
     556                 : 
     557                 : NS_IMETHODIMP
     558            2745 : Preferences::GetDefaultBranch(const char *aPrefRoot, nsIPrefBranch **_retval)
     559                 : {
     560            2745 :   if (!aPrefRoot || !aPrefRoot[0]) {
     561            2732 :     return CallQueryInterface(sDefaultRootBranch, _retval);
     562                 :   }
     563                 : 
     564                 :   // TODO: - cache this stuff and allow consumers to share branches (hold weak references I think)
     565              13 :   nsPrefBranch* prefBranch = new nsPrefBranch(aPrefRoot, true);
     566              13 :   if (!prefBranch)
     567               0 :     return NS_ERROR_OUT_OF_MEMORY;
     568                 : 
     569              13 :   return CallQueryInterface(prefBranch, _retval);
     570                 : }
     571                 : 
     572                 : 
     573                 : nsresult
     574               1 : Preferences::NotifyServiceObservers(const char *aTopic)
     575                 : {
     576                 :   nsCOMPtr<nsIObserverService> observerService = 
     577               2 :     mozilla::services::GetObserverService();  
     578               1 :   if (!observerService)
     579               0 :     return NS_ERROR_FAILURE;
     580                 : 
     581               1 :   nsISupports *subject = (nsISupports *)((nsIPrefService *)this);
     582               1 :   observerService->NotifyObservers(subject, aTopic, nsnull);
     583                 :   
     584               1 :   return NS_OK;
     585                 : }
     586                 : 
     587                 : nsresult
     588               0 : Preferences::UseDefaultPrefFile()
     589                 : {
     590                 :   nsresult rv, rv2;
     591               0 :   nsCOMPtr<nsIFile> aFile;
     592                 : 
     593               0 :   rv = NS_GetSpecialDirectory(NS_APP_PREFS_50_FILE, getter_AddRefs(aFile));
     594               0 :   if (NS_SUCCEEDED(rv)) {
     595               0 :     rv = ReadAndOwnUserPrefFile(aFile);
     596                 :     // Most likely cause of failure here is that the file didn't
     597                 :     // exist, so save a new one. mUserPrefReadFailed will be
     598                 :     // used to catch an error in actually reading the file.
     599               0 :     if (NS_FAILED(rv)) {
     600               0 :       rv2 = SavePrefFileInternal(aFile);
     601               0 :       NS_ASSERTION(NS_SUCCEEDED(rv2), "Failed to save new shared pref file");
     602                 :     }
     603                 :   }
     604                 :   
     605               0 :   return rv;
     606                 : }
     607                 : 
     608                 : nsresult
     609               0 : Preferences::UseUserPrefFile()
     610                 : {
     611               0 :   nsresult rv = NS_OK;
     612               0 :   nsCOMPtr<nsIFile> aFile;
     613               0 :   nsDependentCString prefsDirProp(NS_APP_PREFS_50_DIR);
     614                 : 
     615               0 :   rv = NS_GetSpecialDirectory(prefsDirProp.get(), getter_AddRefs(aFile));
     616               0 :   if (NS_SUCCEEDED(rv) && aFile) {
     617               0 :     rv = aFile->AppendNative(NS_LITERAL_CSTRING("user.js"));
     618               0 :     if (NS_SUCCEEDED(rv)) {
     619               0 :       bool exists = false;
     620               0 :       aFile->Exists(&exists);
     621               0 :       if (exists) {
     622               0 :         rv = openPrefFile(aFile);
     623                 :       } else {
     624               0 :         rv = NS_ERROR_FILE_NOT_FOUND;
     625                 :       }
     626                 :     }
     627                 :   }
     628               0 :   return rv;
     629                 : }
     630                 : 
     631                 : nsresult
     632               0 : Preferences::MakeBackupPrefFile(nsIFile *aFile)
     633                 : {
     634                 :   // Example: this copies "prefs.js" to "Invalidprefs.js" in the same directory.
     635                 :   // "Invalidprefs.js" is removed if it exists, prior to making the copy.
     636               0 :   nsAutoString newFilename;
     637               0 :   nsresult rv = aFile->GetLeafName(newFilename);
     638               0 :   NS_ENSURE_SUCCESS(rv, rv);
     639               0 :   newFilename.Insert(NS_LITERAL_STRING("Invalid"), 0);
     640               0 :   nsCOMPtr<nsIFile> newFile;
     641               0 :   rv = aFile->GetParent(getter_AddRefs(newFile));
     642               0 :   NS_ENSURE_SUCCESS(rv, rv);
     643               0 :   rv = newFile->Append(newFilename);
     644               0 :   NS_ENSURE_SUCCESS(rv, rv);
     645               0 :   bool exists = false;
     646               0 :   newFile->Exists(&exists);
     647               0 :   if (exists) {
     648               0 :     rv = newFile->Remove(false);
     649               0 :     NS_ENSURE_SUCCESS(rv, rv);
     650                 :   }
     651               0 :   rv = aFile->CopyTo(nsnull, newFilename);
     652               0 :   NS_ENSURE_SUCCESS(rv, rv);
     653               0 :   return rv;
     654                 : }
     655                 : 
     656                 : nsresult
     657               4 : Preferences::ReadAndOwnUserPrefFile(nsIFile *aFile)
     658                 : {
     659               4 :   NS_ENSURE_ARG(aFile);
     660                 :   
     661               4 :   if (mCurrentFile == aFile)
     662               0 :     return NS_OK;
     663               4 :   mCurrentFile = aFile;
     664                 : 
     665               4 :   nsresult rv = NS_OK;
     666               4 :   bool exists = false;
     667               4 :   mCurrentFile->Exists(&exists);
     668               4 :   if (exists) {
     669               4 :     rv = openPrefFile(mCurrentFile);
     670               4 :     if (NS_FAILED(rv)) {
     671                 :       // Save a backup copy of the current (invalid) prefs file, since all prefs
     672                 :       // from the error line to the end of the file will be lost (bug 361102).
     673                 :       // TODO we should notify the user about it (bug 523725).
     674               0 :       MakeBackupPrefFile(mCurrentFile);
     675                 :     }
     676                 :   } else {
     677               0 :     rv = NS_ERROR_FILE_NOT_FOUND;
     678                 :   }
     679                 : 
     680               4 :   return rv;
     681                 : }
     682                 : 
     683                 : nsresult
     684            2117 : Preferences::SavePrefFileInternal(nsIFile *aFile)
     685                 : {
     686            2117 :   if (nsnull == aFile) {
     687                 :     // the gDirty flag tells us if we should write to mCurrentFile
     688                 :     // we only check this flag when the caller wants to write to the default
     689            2115 :     if (!gDirty)
     690               0 :       return NS_OK;
     691                 :     
     692                 :     // It's possible that we never got a prefs file.
     693            2115 :     nsresult rv = NS_OK;
     694            2115 :     if (mCurrentFile)
     695               1 :       rv = WritePrefFile(mCurrentFile);
     696                 : 
     697            2115 :     return rv;
     698                 :   } else {
     699               2 :     return WritePrefFile(aFile);
     700                 :   }
     701                 : }
     702                 : 
     703                 : nsresult
     704               3 : Preferences::WritePrefFile(nsIFile* aFile)
     705                 : {
     706                 :   const char                outHeader[] =
     707                 :     "# Mozilla User Preferences"
     708                 :     NS_LINEBREAK
     709                 :     NS_LINEBREAK
     710                 :     "/* Do not edit this file."
     711                 :     NS_LINEBREAK
     712                 :     " *"
     713                 :     NS_LINEBREAK
     714                 :     " * If you make changes to this file while the application is running,"
     715                 :     NS_LINEBREAK
     716                 :     " * the changes will be overwritten when the application exits."
     717                 :     NS_LINEBREAK
     718                 :     " *"
     719                 :     NS_LINEBREAK
     720                 :     " * To make a manual change to preferences, you can visit the URL about:config"
     721                 :     NS_LINEBREAK
     722                 :     " */"
     723                 :     NS_LINEBREAK
     724               3 :     NS_LINEBREAK;
     725                 : 
     726               6 :   nsCOMPtr<nsIOutputStream> outStreamSink;
     727               6 :   nsCOMPtr<nsIOutputStream> outStream;
     728                 :   PRUint32                  writeAmount;
     729                 :   nsresult                  rv;
     730                 : 
     731               3 :   if (!gHashTable.ops)
     732               0 :     return NS_ERROR_NOT_INITIALIZED;
     733                 : 
     734                 :   // execute a "safe" save by saving through a tempfile
     735               3 :   rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(outStreamSink),
     736                 :                                        aFile,
     737                 :                                        -1,
     738               3 :                                        0600);
     739               3 :   if (NS_FAILED(rv)) 
     740               0 :       return rv;
     741               3 :   rv = NS_NewBufferedOutputStream(getter_AddRefs(outStream), outStreamSink, 4096);
     742               3 :   if (NS_FAILED(rv)) 
     743               0 :       return rv;  
     744                 : 
     745               3 :   char** valueArray = (char **)PR_Calloc(sizeof(char *), gHashTable.entryCount);
     746               3 :   if (!valueArray)
     747               0 :     return NS_ERROR_OUT_OF_MEMORY;
     748                 :   
     749                 :   pref_saveArgs saveArgs;
     750               3 :   saveArgs.prefArray = valueArray;
     751               3 :   saveArgs.saveTypes = SAVE_ALL;
     752                 :   
     753                 :   // get the lines that we're supposed to be writing to the file
     754               3 :   PL_DHashTableEnumerate(&gHashTable, pref_savePref, &saveArgs);
     755                 :     
     756                 :   /* Sort the preferences to make a readable file on disk */
     757               3 :   NS_QuickSort(valueArray, gHashTable.entryCount, sizeof(char *), pref_CompareStrings, NULL);
     758                 :   
     759                 :   // write out the file header
     760               3 :   outStream->Write(outHeader, sizeof(outHeader) - 1, &writeAmount);
     761                 : 
     762               3 :   char** walker = valueArray;
     763            4868 :   for (PRUint32 valueIdx = 0; valueIdx < gHashTable.entryCount; valueIdx++, walker++) {
     764            4865 :     if (*walker) {
     765              15 :       outStream->Write(*walker, strlen(*walker), &writeAmount);
     766              15 :       outStream->Write(NS_LINEBREAK, NS_LINEBREAK_LEN, &writeAmount);
     767              15 :       NS_Free(*walker);
     768                 :     }
     769                 :   }
     770               3 :   PR_Free(valueArray);
     771                 : 
     772                 :   // tell the safe output stream to overwrite the real prefs file
     773                 :   // (it'll abort if there were any errors during writing)
     774               6 :   nsCOMPtr<nsISafeOutputStream> safeStream = do_QueryInterface(outStream);
     775               3 :   NS_ASSERTION(safeStream, "expected a safe output stream!");
     776               3 :   if (safeStream) {
     777               3 :     rv = safeStream->Finish();
     778               3 :     if (NS_FAILED(rv)) {
     779               0 :       NS_WARNING("failed to save prefs file! possible dataloss");
     780               0 :       return rv;
     781                 :     }
     782                 :   }
     783                 : 
     784               3 :   gDirty = false;
     785               3 :   return NS_OK;
     786                 : }
     787                 : 
     788            8531 : static nsresult openPrefFile(nsIFile* aFile)
     789                 : {
     790           17062 :   nsCOMPtr<nsIInputStream> inStr;
     791                 : 
     792            8531 :   nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), aFile);
     793            8531 :   if (NS_FAILED(rv)) 
     794               0 :     return rv;        
     795                 : 
     796                 :   PRUint32 fileSize;
     797            8531 :   rv = inStr->Available(&fileSize);
     798            8531 :   if (NS_FAILED(rv))
     799               0 :     return rv;
     800                 : 
     801           25593 :   nsAutoArrayPtr<char> fileBuffer(new char[fileSize]);
     802            8531 :   if (fileBuffer == nsnull)
     803               0 :     return NS_ERROR_OUT_OF_MEMORY;
     804                 : 
     805                 :   PrefParseState ps;
     806            8531 :   PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
     807                 : 
     808                 :   // Read is not guaranteed to return a buf the size of fileSize,
     809                 :   // but usually will.
     810            8531 :   nsresult rv2 = NS_OK;
     811            8531 :   for (;;) {
     812           17062 :     PRUint32 amtRead = 0;
     813           17062 :     rv = inStr->Read((char*)fileBuffer, fileSize, &amtRead);
     814           17062 :     if (NS_FAILED(rv) || amtRead == 0)
     815                 :       break;
     816            8531 :     if (!PREF_ParseBuf(&ps, fileBuffer, amtRead))
     817               0 :       rv2 = NS_ERROR_FILE_CORRUPTED;
     818                 :   }
     819                 : 
     820            8531 :   PREF_FinalizeParseState(&ps);
     821                 : 
     822            8531 :   return NS_FAILED(rv) ? rv : rv2;
     823                 : }
     824                 : 
     825                 : /*
     826                 :  * some stuff that gets called from Pref_Init()
     827                 :  */
     828                 : 
     829                 : static int
     830           14210 : pref_CompareFileNames(nsIFile* aFile1, nsIFile* aFile2, void* /*unused*/)
     831                 : {
     832           28420 :   nsCAutoString filename1, filename2;
     833           14210 :   aFile1->GetNativeLeafName(filename1);
     834           14210 :   aFile2->GetNativeLeafName(filename2);
     835                 : 
     836           14210 :   return Compare(filename2, filename1);
     837                 : }
     838                 : 
     839                 : /**
     840                 :  * Load default pref files from a directory. The files in the
     841                 :  * directory are sorted reverse-alphabetically; a set of "special file
     842                 :  * names" may be specified which are loaded after all the others.
     843                 :  */
     844                 : static nsresult
     845            2811 : pref_LoadPrefsInDir(nsIFile* aDir, char const *const *aSpecialFiles, PRUint32 aSpecialFilesCount)
     846                 : {
     847                 :   nsresult rv, rv2;
     848                 :   bool hasMoreElements;
     849                 : 
     850            5622 :   nsCOMPtr<nsISimpleEnumerator> dirIterator;
     851                 : 
     852                 :   // this may fail in some normal cases, such as embedders who do not use a GRE
     853            2811 :   rv = aDir->GetDirectoryEntries(getter_AddRefs(dirIterator));
     854            2811 :   if (NS_FAILED(rv)) {
     855                 :     // If the directory doesn't exist, then we have no reason to complain.  We
     856                 :     // loaded everything (and nothing) successfully.
     857            1389 :     if (rv == NS_ERROR_FILE_NOT_FOUND)
     858               0 :       rv = NS_OK;
     859            1389 :     return rv;
     860                 :   }
     861                 : 
     862            1422 :   rv = dirIterator->HasMoreElements(&hasMoreElements);
     863            1422 :   NS_ENSURE_SUCCESS(rv, rv);
     864                 : 
     865            2844 :   nsCOMArray<nsIFile> prefFiles(INITIAL_PREF_FILES);
     866            2844 :   nsCOMArray<nsIFile> specialFiles(aSpecialFilesCount);
     867            2844 :   nsCOMPtr<nsIFile> prefFile;
     868                 : 
     869            9950 :   while (hasMoreElements && NS_SUCCEEDED(rv)) {
     870           14212 :     nsCAutoString leafName;
     871                 : 
     872            7106 :     rv = dirIterator->GetNext(getter_AddRefs(prefFile));
     873            7106 :     if (NS_FAILED(rv)) {
     874                 :       break;
     875                 :     }
     876                 : 
     877            7106 :     prefFile->GetNativeLeafName(leafName);
     878            7106 :     NS_ASSERTION(!leafName.IsEmpty(), "Failure in default prefs: directory enumerator returned empty file?");
     879                 : 
     880                 :     // Skip non-js files
     881            7106 :     if (StringEndsWith(leafName, NS_LITERAL_CSTRING(".js"),
     882            7106 :                        nsCaseInsensitiveCStringComparator())) {
     883            7106 :       bool shouldParse = true;
     884                 :       // separate out special files
     885           14211 :       for (PRUint32 i = 0; i < aSpecialFilesCount; ++i) {
     886            7105 :         if (leafName.Equals(nsDependentCString(aSpecialFiles[i]))) {
     887               0 :           shouldParse = false;
     888                 :           // special files should be process in order; we put them into
     889                 :           // the array by index; this can make the array sparse
     890               0 :           specialFiles.ReplaceObjectAt(prefFile, i);
     891                 :         }
     892                 :       }
     893                 : 
     894            7106 :       if (shouldParse) {
     895            7106 :         prefFiles.AppendObject(prefFile);
     896                 :       }
     897                 :     }
     898                 : 
     899           14212 :     rv = dirIterator->HasMoreElements(&hasMoreElements);
     900                 :   }
     901                 : 
     902            1422 :   if (prefFiles.Count() + specialFiles.Count() == 0) {
     903               0 :     NS_WARNING("No default pref files found.");
     904               0 :     if (NS_SUCCEEDED(rv)) {
     905               0 :       rv = NS_SUCCESS_FILE_DIRECTORY_EMPTY;
     906                 :     }
     907               0 :     return rv;
     908                 :   }
     909                 : 
     910            1422 :   prefFiles.Sort(pref_CompareFileNames, nsnull);
     911                 :   
     912            1422 :   PRUint32 arrayCount = prefFiles.Count();
     913                 :   PRUint32 i;
     914            8528 :   for (i = 0; i < arrayCount; ++i) {
     915            7106 :     rv2 = openPrefFile(prefFiles[i]);
     916            7106 :     if (NS_FAILED(rv2)) {
     917               0 :       NS_ERROR("Default pref file not parsed successfully.");
     918               0 :       rv = rv2;
     919                 :     }
     920                 :   }
     921                 : 
     922            1422 :   arrayCount = specialFiles.Count();
     923            1422 :   for (i = 0; i < arrayCount; ++i) {
     924                 :     // this may be a sparse array; test before parsing
     925               0 :     nsIFile* file = specialFiles[i];
     926               0 :     if (file) {
     927               0 :       rv2 = openPrefFile(file);
     928               0 :       if (NS_FAILED(rv2)) {
     929               0 :         NS_ERROR("Special default pref file not parsed successfully.");
     930               0 :         rv = rv2;
     931                 :       }
     932                 :     }
     933                 :   }
     934                 : 
     935            1422 :   return rv;
     936                 : }
     937                 : 
     938            2843 : static nsresult pref_LoadPrefsInDirList(const char *listId)
     939                 : {
     940                 :   nsresult rv;
     941            5686 :   nsCOMPtr<nsIProperties> dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
     942            2843 :   if (NS_FAILED(rv))
     943               0 :     return rv;
     944                 : 
     945            5686 :   nsCOMPtr<nsISimpleEnumerator> list;
     946            2843 :   dirSvc->Get(listId,
     947                 :               NS_GET_IID(nsISimpleEnumerator),
     948            2843 :               getter_AddRefs(list));
     949            2843 :   if (!list)
     950            1453 :     return NS_OK;
     951                 : 
     952                 :   bool hasMore;
     953            4170 :   while (NS_SUCCEEDED(list->HasMoreElements(&hasMore)) && hasMore) {
     954            2780 :     nsCOMPtr<nsISupports> elem;
     955            1390 :     list->GetNext(getter_AddRefs(elem));
     956            1390 :     if (!elem)
     957               0 :       continue;
     958                 : 
     959            2780 :     nsCOMPtr<nsIFile> path = do_QueryInterface(elem);
     960            1390 :     if (!path)
     961               0 :       continue;
     962                 : 
     963            4170 :     nsCAutoString leaf;
     964            1390 :     path->GetNativeLeafName(leaf);
     965                 : 
     966                 :     // Do we care if a file provided by this process fails to load?
     967            1390 :     if (Substring(leaf, leaf.Length() - 4).Equals(NS_LITERAL_CSTRING(".xpi")))
     968               0 :       ReadExtensionPrefs(path);
     969                 :     else
     970            1390 :       pref_LoadPrefsInDir(path, nsnull, 0);
     971                 :   }
     972            1390 :   return NS_OK;
     973                 : }
     974                 : 
     975               0 : static nsresult pref_ReadPrefFromJar(nsZipArchive* jarReader, const char *name)
     976                 : {
     977               0 :   nsZipItemPtr<char> manifest(jarReader, name, true);
     978               0 :   NS_ENSURE_TRUE(manifest.Buffer(), NS_ERROR_NOT_AVAILABLE);
     979                 : 
     980                 :   PrefParseState ps;
     981               0 :   PREF_InitParseState(&ps, PREF_ReaderCallback, NULL);
     982               0 :   nsresult rv = PREF_ParseBuf(&ps, manifest, manifest.Length());
     983               0 :   PREF_FinalizeParseState(&ps);
     984                 : 
     985               0 :   return rv;
     986                 : }
     987                 : 
     988                 : //----------------------------------------------------------------------------------------
     989                 : // Initialize default preference JavaScript buffers from
     990                 : // appropriate TEXT resources
     991                 : //----------------------------------------------------------------------------------------
     992            1421 : static nsresult pref_InitInitialObjects()
     993                 : {
     994                 :   nsresult rv;
     995                 : 
     996                 :   // In omni.jar case, we load the following prefs:
     997                 :   // - jar:$gre/omni.jar!/greprefs.js
     998                 :   // - jar:$gre/omni.jar!/defaults/pref/*.js
     999                 :   // In non omni.jar case, we load:
    1000                 :   // - $gre/greprefs.js
    1001                 :   //
    1002                 :   // In both cases, we also load:
    1003                 :   // - $gre/defaults/pref/*.js
    1004                 :   // This is kept for bug 591866 (channel-prefs.js should not be in omni.jar)
    1005                 :   // on $app == $gre case ; we load all files instead of channel-prefs.js only
    1006                 :   // to have the same behaviour as $app != $gre, where this is required as
    1007                 :   // a supported location for GRE preferences.
    1008                 :   //
    1009                 :   // When $app != $gre, we additionally load, in omni.jar case:
    1010                 :   // - jar:$app/omni.jar!/defaults/preferences/*.js
    1011                 :   // - $app/defaults/preferences/*.js
    1012                 :   // and in non omni.jar case:
    1013                 :   // - $app/defaults/preferences/*.js
    1014                 : 
    1015                 :   nsZipFind *findPtr;
    1016            2842 :   nsAutoPtr<nsZipFind> find;
    1017            2842 :   nsTArray<nsCString> prefEntries;
    1018                 :   const char *entryName;
    1019                 :   PRUint16 entryNameLen;
    1020                 : 
    1021            2842 :   nsRefPtr<nsZipArchive> jarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
    1022            1421 :   if (jarReader) {
    1023                 :     // Load jar:$gre/omni.jar!/greprefs.js
    1024               0 :     rv = pref_ReadPrefFromJar(jarReader, "greprefs.js");
    1025               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1026                 : 
    1027                 :     // Load jar:$gre/omni.jar!/defaults/pref/*.js
    1028               0 :     rv = jarReader->FindInit("defaults/pref/*.js$", &findPtr);
    1029               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1030                 : 
    1031               0 :     find = findPtr;
    1032               0 :     while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) {
    1033               0 :       prefEntries.AppendElement(Substring(entryName, entryNameLen));
    1034                 :     }
    1035                 : 
    1036               0 :     prefEntries.Sort();
    1037               0 :     for (PRUint32 i = prefEntries.Length(); i--; ) {
    1038               0 :       rv = pref_ReadPrefFromJar(jarReader, prefEntries[i].get());
    1039               0 :       if (NS_FAILED(rv))
    1040               0 :         NS_WARNING("Error parsing preferences.");
    1041                 :     }
    1042                 :   } else {
    1043                 :     // Load $gre/greprefs.js
    1044            2842 :     nsCOMPtr<nsIFile> greprefsFile;
    1045            1421 :     rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(greprefsFile));
    1046            1421 :     NS_ENSURE_SUCCESS(rv, rv);
    1047                 : 
    1048            1421 :     rv = greprefsFile->AppendNative(NS_LITERAL_CSTRING("greprefs.js"));
    1049            1421 :     NS_ENSURE_SUCCESS(rv, rv);
    1050                 : 
    1051            1421 :     rv = openPrefFile(greprefsFile);
    1052            1421 :     if (NS_FAILED(rv))
    1053               0 :       NS_WARNING("Error parsing GRE default preferences. Is this an old-style embedding app?");
    1054                 :   }
    1055                 : 
    1056                 :   // Load $gre/defaults/pref/*.js
    1057            2842 :   nsCOMPtr<nsIFile> defaultPrefDir;
    1058                 : 
    1059            1421 :   rv = NS_GetSpecialDirectory(NS_APP_PREF_DEFAULTS_50_DIR, getter_AddRefs(defaultPrefDir));
    1060            1421 :   NS_ENSURE_SUCCESS(rv, rv);
    1061                 : 
    1062                 :   /* these pref file names should not be used: we process them after all other application pref files for backwards compatibility */
    1063                 :   static const char* specialFiles[] = {
    1064                 : #if defined(XP_MACOSX)
    1065                 :     "macprefs.js"
    1066                 : #elif defined(XP_WIN)
    1067                 :     "winpref.js"
    1068                 : #elif defined(XP_UNIX)
    1069                 :     "unix.js"
    1070                 : #if defined(VMS)
    1071                 :     , "openvms.js"
    1072                 : #elif defined(_AIX)
    1073                 :     , "aix.js"
    1074                 : #endif
    1075                 : #elif defined(XP_OS2)
    1076                 :     "os2pref.js"
    1077                 : #elif defined(XP_BEOS)
    1078                 :     "beos.js"
    1079                 : #endif
    1080                 :   };
    1081                 : 
    1082            1421 :   rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, ArrayLength(specialFiles));
    1083            1421 :   if (NS_FAILED(rv))
    1084               0 :     NS_WARNING("Error parsing application default preferences.");
    1085                 : 
    1086                 :   // Load jar:$app/omni.jar!/defaults/preferences/*.js
    1087            2842 :   nsRefPtr<nsZipArchive> appJarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP);
    1088            1421 :   if (appJarReader) {
    1089               0 :     rv = appJarReader->FindInit("defaults/preferences/*.js$", &findPtr);
    1090               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1091               0 :     find = findPtr;
    1092               0 :     prefEntries.Clear();
    1093               0 :     while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) {
    1094               0 :       prefEntries.AppendElement(Substring(entryName, entryNameLen));
    1095                 :     }
    1096               0 :     prefEntries.Sort();
    1097               0 :     for (PRUint32 i = prefEntries.Length(); i--; ) {
    1098               0 :       rv = pref_ReadPrefFromJar(appJarReader, prefEntries[i].get());
    1099               0 :       if (NS_FAILED(rv))
    1100               0 :         NS_WARNING("Error parsing preferences.");
    1101                 :     }
    1102                 :   }
    1103                 : 
    1104            1421 :   rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST);
    1105            1421 :   NS_ENSURE_SUCCESS(rv, rv);
    1106                 : 
    1107                 :   NS_CreateServicesFromCategory(NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID,
    1108            1421 :                                 nsnull, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID);
    1109                 : 
    1110                 :   nsCOMPtr<nsIObserverService> observerService =
    1111            2842 :     mozilla::services::GetObserverService();
    1112            1421 :   if (!observerService)
    1113               0 :     return NS_ERROR_FAILURE;
    1114                 : 
    1115            1421 :   observerService->NotifyObservers(nsnull, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID, nsnull);
    1116                 : 
    1117            1421 :   return pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST);
    1118                 : }
    1119                 : 
    1120                 : 
    1121                 : /******************************************************************************
    1122                 :  *
    1123                 :  * static utilities
    1124                 :  *
    1125                 :  ******************************************************************************/
    1126                 : 
    1127                 : // static
    1128                 : nsresult
    1129           33717 : Preferences::GetBool(const char* aPref, bool* aResult)
    1130                 : {
    1131           33717 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1132           33717 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1133           33717 :   return PREF_GetBoolPref(aPref, aResult, false);
    1134                 : }
    1135                 : 
    1136                 : // static
    1137                 : nsresult
    1138           36949 : Preferences::GetInt(const char* aPref, PRInt32* aResult)
    1139                 : {
    1140           36949 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1141           36949 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1142           36949 :   return PREF_GetIntPref(aPref, aResult, false);
    1143                 : }
    1144                 : 
    1145                 : // static
    1146                 : nsAdoptingCString
    1147             261 : Preferences::GetCString(const char* aPref)
    1148                 : {
    1149             261 :   nsAdoptingCString result;
    1150             261 :   PREF_CopyCharPref(aPref, getter_Copies(result), false);
    1151                 :   return result;
    1152                 : }
    1153                 : 
    1154                 : // static
    1155                 : nsAdoptingString
    1156            1405 : Preferences::GetString(const char* aPref)
    1157                 : {
    1158            1405 :   nsAdoptingString result;
    1159            1405 :   GetString(aPref, &result);
    1160                 :   return result;
    1161                 : }
    1162                 : 
    1163                 : // static
    1164                 : nsresult
    1165               0 : Preferences::GetCString(const char* aPref, nsACString* aResult)
    1166                 : {
    1167               0 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1168               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1169               0 :   nsCAutoString result;
    1170               0 :   nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), false);
    1171               0 :   if (NS_SUCCEEDED(rv)) {
    1172               0 :     *aResult = result;
    1173                 :   }
    1174               0 :   return rv;
    1175                 : }
    1176                 : 
    1177                 : // static
    1178                 : nsresult
    1179            1647 : Preferences::GetString(const char* aPref, nsAString* aResult)
    1180                 : {
    1181            1647 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1182            1647 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1183            3294 :   nsCAutoString result;
    1184            1647 :   nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), false);
    1185            1647 :   if (NS_SUCCEEDED(rv)) {
    1186            1647 :     CopyUTF8toUTF16(result, *aResult);
    1187                 :   }
    1188            1647 :   return rv;
    1189                 : }
    1190                 : 
    1191                 : // static
    1192                 : nsAdoptingCString
    1193               0 : Preferences::GetLocalizedCString(const char* aPref)
    1194                 : {
    1195               0 :   nsAdoptingCString result;
    1196               0 :   GetLocalizedCString(aPref, &result);
    1197                 :   return result;
    1198                 : }
    1199                 : 
    1200                 : // static
    1201                 : nsAdoptingString
    1202               0 : Preferences::GetLocalizedString(const char* aPref)
    1203                 : {
    1204               0 :   nsAdoptingString result;
    1205               0 :   GetLocalizedString(aPref, &result);
    1206                 :   return result;
    1207                 : }
    1208                 : 
    1209                 : // static
    1210                 : nsresult
    1211               0 : Preferences::GetLocalizedCString(const char* aPref, nsACString* aResult)
    1212                 : {
    1213               0 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1214               0 :   nsAutoString result;
    1215               0 :   nsresult rv = GetLocalizedString(aPref, &result);
    1216               0 :   if (NS_SUCCEEDED(rv)) {
    1217               0 :     CopyUTF16toUTF8(result, *aResult);
    1218                 :   }
    1219               0 :   return rv;
    1220                 : }
    1221                 : 
    1222                 : // static
    1223                 : nsresult
    1224               0 : Preferences::GetLocalizedString(const char* aPref, nsAString* aResult)
    1225                 : {
    1226               0 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1227               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1228               0 :   nsCOMPtr<nsIPrefLocalizedString> prefLocalString;
    1229                 :   nsresult rv = sRootBranch->GetComplexValue(aPref,
    1230                 :                                              NS_GET_IID(nsIPrefLocalizedString),
    1231               0 :                                              getter_AddRefs(prefLocalString));
    1232               0 :   if (NS_SUCCEEDED(rv)) {
    1233               0 :     NS_ASSERTION(prefLocalString, "Succeeded but the result is NULL");
    1234               0 :     prefLocalString->GetData(getter_Copies(*aResult));
    1235                 :   }
    1236               0 :   return rv;
    1237                 : }
    1238                 : 
    1239                 : // static
    1240                 : nsresult
    1241               0 : Preferences::GetComplex(const char* aPref, const nsIID &aType, void** aResult)
    1242                 : {
    1243               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1244               0 :   return sRootBranch->GetComplexValue(aPref, aType, aResult);
    1245                 : }
    1246                 : 
    1247                 : // static
    1248                 : nsresult
    1249               0 : Preferences::SetCString(const char* aPref, const char* aValue)
    1250                 : {
    1251               0 :   NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default, NS_ERROR_NOT_AVAILABLE);
    1252               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1253               0 :   return PREF_SetCharPref(aPref, aValue, false);
    1254                 : }
    1255                 : 
    1256                 : // static
    1257                 : nsresult
    1258               0 : Preferences::SetCString(const char* aPref, const nsACString &aValue)
    1259                 : {
    1260               0 :   NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default, NS_ERROR_NOT_AVAILABLE);
    1261               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1262               0 :   return PREF_SetCharPref(aPref, PromiseFlatCString(aValue).get(), false);
    1263                 : }
    1264                 : 
    1265                 : // static
    1266                 : nsresult
    1267               0 : Preferences::SetString(const char* aPref, const PRUnichar* aValue)
    1268                 : {
    1269               0 :   NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default, NS_ERROR_NOT_AVAILABLE);
    1270               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1271               0 :   return PREF_SetCharPref(aPref, NS_ConvertUTF16toUTF8(aValue).get(), false);
    1272                 : }
    1273                 : 
    1274                 : // static
    1275                 : nsresult
    1276               0 : Preferences::SetString(const char* aPref, const nsAString &aValue)
    1277                 : {
    1278               0 :   NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default, NS_ERROR_NOT_AVAILABLE);
    1279               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1280               0 :   return PREF_SetCharPref(aPref, NS_ConvertUTF16toUTF8(aValue).get(), false);
    1281                 : }
    1282                 : 
    1283                 : // static
    1284                 : nsresult
    1285               0 : Preferences::SetBool(const char* aPref, bool aValue)
    1286                 : {
    1287               0 :   NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default, NS_ERROR_NOT_AVAILABLE);
    1288               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1289               0 :   return PREF_SetBoolPref(aPref, aValue, false);
    1290                 : }
    1291                 : 
    1292                 : // static
    1293                 : nsresult
    1294              16 : Preferences::SetInt(const char* aPref, PRInt32 aValue)
    1295                 : {
    1296              16 :   NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default, NS_ERROR_NOT_AVAILABLE);
    1297              16 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1298              16 :   return PREF_SetIntPref(aPref, aValue, false);
    1299                 : }
    1300                 : 
    1301                 : // static
    1302                 : nsresult
    1303               0 : Preferences::SetComplex(const char* aPref, const nsIID &aType,
    1304                 :                         nsISupports* aValue)
    1305                 : {
    1306               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1307               0 :   return sRootBranch->SetComplexValue(aPref, aType, aValue);
    1308                 : }
    1309                 : 
    1310                 : // static
    1311                 : nsresult
    1312             113 : Preferences::ClearUser(const char* aPref)
    1313                 : {
    1314             113 :   NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default, NS_ERROR_NOT_AVAILABLE);
    1315             113 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1316             113 :   return PREF_ClearUserPref(aPref);
    1317                 : }
    1318                 : 
    1319                 : // static
    1320                 : bool
    1321             288 : Preferences::HasUserValue(const char* aPref)
    1322                 : {
    1323             288 :   NS_ENSURE_TRUE(InitStaticMembers(), false);
    1324             288 :   return PREF_HasUserPref(aPref);
    1325                 : }
    1326                 : 
    1327                 : // static
    1328                 : nsresult
    1329           56944 : Preferences::AddStrongObserver(nsIObserver* aObserver,
    1330                 :                                const char* aPref)
    1331                 : {
    1332           56944 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1333           56944 :   return sRootBranch->AddObserver(aPref, aObserver, false);
    1334                 : }
    1335                 : 
    1336                 : // static
    1337                 : nsresult
    1338           11474 : Preferences::AddWeakObserver(nsIObserver* aObserver,
    1339                 :                              const char* aPref)
    1340                 : {
    1341           11474 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1342           11474 :   return sRootBranch->AddObserver(aPref, aObserver, true);
    1343                 : }
    1344                 : 
    1345                 : // static
    1346                 : nsresult
    1347           54127 : Preferences::RemoveObserver(nsIObserver* aObserver,
    1348                 :                             const char* aPref)
    1349                 : {
    1350           54127 :   if (!sPreferences && sShutdown) {
    1351               3 :     return NS_OK; // Observers have been released automatically.
    1352                 :   }
    1353           54124 :   NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE);
    1354           54124 :   return sRootBranch->RemoveObserver(aPref, aObserver);
    1355                 : }
    1356                 : 
    1357                 : // static
    1358                 : nsresult
    1359            2811 : Preferences::AddStrongObservers(nsIObserver* aObserver,
    1360                 :                                 const char** aPrefs)
    1361                 : {
    1362           11244 :   for (PRUint32 i = 0; aPrefs[i]; i++) {
    1363            8433 :     nsresult rv = AddStrongObserver(aObserver, aPrefs[i]);
    1364            8433 :     NS_ENSURE_SUCCESS(rv, rv);
    1365                 :   }
    1366            2811 :   return NS_OK;
    1367                 : }
    1368                 : 
    1369                 : // static
    1370                 : nsresult
    1371            1666 : Preferences::AddWeakObservers(nsIObserver* aObserver,
    1372                 :                               const char** aPrefs)
    1373                 : {
    1374           13046 :   for (PRUint32 i = 0; aPrefs[i]; i++) {
    1375           11380 :     nsresult rv = AddWeakObserver(aObserver, aPrefs[i]);
    1376           11380 :     NS_ENSURE_SUCCESS(rv, rv);
    1377                 :   }
    1378            1666 :   return NS_OK;
    1379                 : }
    1380                 : 
    1381                 : // static
    1382                 : nsresult
    1383            4213 : Preferences::RemoveObservers(nsIObserver* aObserver,
    1384                 :                              const char** aPrefs)
    1385                 : {
    1386            4213 :   if (!sPreferences && sShutdown) {
    1387            2810 :     return NS_OK; // Observers have been released automatically.
    1388                 :   }
    1389            1403 :   NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE);
    1390                 : 
    1391            7015 :   for (PRUint32 i = 0; aPrefs[i]; i++) {
    1392            5612 :     nsresult rv = RemoveObserver(aObserver, aPrefs[i]);
    1393            5612 :     NS_ENSURE_SUCCESS(rv, rv);
    1394                 :   }
    1395            1403 :   return NS_OK;
    1396                 : }
    1397                 : 
    1398                 : // static
    1399                 : nsresult
    1400           48511 : Preferences::RegisterCallback(PrefChangedFunc aCallback,
    1401                 :                               const char* aPref,
    1402                 :                               void* aClosure)
    1403                 : {
    1404           48511 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1405                 : 
    1406           97022 :   ValueObserverHashKey hashKey(aPref, aCallback);
    1407           97022 :   nsRefPtr<ValueObserver> observer;
    1408           48511 :   gObserverTable->Get(&hashKey, getter_AddRefs(observer));
    1409           48511 :   if (observer) {
    1410               0 :     observer->AppendClosure(aClosure);
    1411               0 :     return NS_OK;
    1412                 :   }
    1413                 : 
    1414           48511 :   observer = new ValueObserver(aPref, aCallback);
    1415           48511 :   observer->AppendClosure(aClosure);
    1416           48511 :   nsresult rv = AddStrongObserver(observer, aPref);
    1417           48511 :   NS_ENSURE_SUCCESS(rv, rv);
    1418           48511 :   return gObserverTable->Put(observer, observer) ? NS_OK :
    1419           48511 :                                                    NS_ERROR_OUT_OF_MEMORY;
    1420                 : }
    1421                 : 
    1422                 : // static
    1423                 : nsresult
    1424            2806 : Preferences::UnregisterCallback(PrefChangedFunc aCallback,
    1425                 :                                 const char* aPref,
    1426                 :                                 void* aClosure)
    1427                 : {
    1428            2806 :   if (!sPreferences && sShutdown) {
    1429               0 :     return NS_OK; // Observers have been released automatically.
    1430                 :   }
    1431            2806 :   NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE);
    1432                 : 
    1433            5612 :   ValueObserverHashKey hashKey(aPref, aCallback);
    1434            5612 :   nsRefPtr<ValueObserver> observer;
    1435            2806 :   gObserverTable->Get(&hashKey, getter_AddRefs(observer));
    1436            2806 :   if (!observer) {
    1437            1403 :     return NS_OK;
    1438                 :   }
    1439                 : 
    1440            1403 :   observer->RemoveClosure(aClosure);
    1441            1403 :   if (observer->HasNoClosures()) {
    1442                 :     // Delete the callback since its list of closures is empty.
    1443            1403 :     gObserverTable->Remove(observer);
    1444                 :   }
    1445            1403 :   return NS_OK;
    1446                 : }
    1447                 : 
    1448              12 : static int BoolVarChanged(const char* aPref, void* aClosure)
    1449                 : {
    1450              12 :   CacheData* cache = static_cast<CacheData*>(aClosure);
    1451                 :   *((bool*)cache->cacheLocation) =
    1452              12 :     Preferences::GetBool(aPref, cache->defaultValueBool);
    1453              12 :   return 0;
    1454                 : }
    1455                 : 
    1456                 : // static
    1457                 : nsresult
    1458           19805 : Preferences::AddBoolVarCache(bool* aCache,
    1459                 :                              const char* aPref,
    1460                 :                              bool aDefault)
    1461                 : {
    1462           19805 :   NS_ASSERTION(aCache, "aCache must not be NULL");
    1463           19805 :   *aCache = GetBool(aPref, aDefault);
    1464           19805 :   CacheData* data = new CacheData();
    1465           19805 :   data->cacheLocation = aCache;
    1466           19805 :   data->defaultValueBool = aDefault;
    1467           19805 :   gCacheData->AppendElement(data);
    1468           19805 :   return RegisterCallback(BoolVarChanged, aPref, data);
    1469                 : }
    1470                 : 
    1471               3 : static int IntVarChanged(const char* aPref, void* aClosure)
    1472                 : {
    1473               3 :   CacheData* cache = static_cast<CacheData*>(aClosure);
    1474                 :   *((PRInt32*)cache->cacheLocation) =
    1475               3 :     Preferences::GetInt(aPref, cache->defaultValueInt);
    1476               3 :   return 0;
    1477                 : }
    1478                 : 
    1479                 : // static
    1480                 : nsresult
    1481           18307 : Preferences::AddIntVarCache(PRInt32* aCache,
    1482                 :                             const char* aPref,
    1483                 :                             PRInt32 aDefault)
    1484                 : {
    1485           18307 :   NS_ASSERTION(aCache, "aCache must not be NULL");
    1486           18307 :   *aCache = Preferences::GetInt(aPref, aDefault);
    1487           18307 :   CacheData* data = new CacheData();
    1488           18307 :   data->cacheLocation = aCache;
    1489           18307 :   data->defaultValueInt = aDefault;
    1490           18307 :   gCacheData->AppendElement(data);
    1491           18307 :   return RegisterCallback(IntVarChanged, aPref, data);
    1492                 : }
    1493                 : 
    1494               5 : static int UintVarChanged(const char* aPref, void* aClosure)
    1495                 : {
    1496               5 :   CacheData* cache = static_cast<CacheData*>(aClosure);
    1497                 :   *((PRUint32*)cache->cacheLocation) =
    1498               5 :     Preferences::GetUint(aPref, cache->defaultValueUint);
    1499               5 :   return 0;
    1500                 : }
    1501                 : 
    1502                 : // static
    1503                 : nsresult
    1504            7035 : Preferences::AddUintVarCache(PRUint32* aCache,
    1505                 :                              const char* aPref,
    1506                 :                              PRUint32 aDefault)
    1507                 : {
    1508            7035 :   NS_ASSERTION(aCache, "aCache must not be NULL");
    1509            7035 :   *aCache = Preferences::GetUint(aPref, aDefault);
    1510            7035 :   CacheData* data = new CacheData();
    1511            7035 :   data->cacheLocation = aCache;
    1512            7035 :   data->defaultValueUint = aDefault;
    1513            7035 :   gCacheData->AppendElement(data);
    1514            7035 :   return RegisterCallback(UintVarChanged, aPref, data);
    1515                 : }
    1516                 : 
    1517                 : // static
    1518                 : nsresult
    1519               0 : Preferences::GetDefaultBool(const char* aPref, bool* aResult)
    1520                 : {
    1521               0 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1522               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1523               0 :   return PREF_GetBoolPref(aPref, aResult, true);
    1524                 : }
    1525                 : 
    1526                 : // static
    1527                 : nsresult
    1528            1404 : Preferences::GetDefaultInt(const char* aPref, PRInt32* aResult)
    1529                 : {
    1530            1404 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1531            1404 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1532            1404 :   return PREF_GetIntPref(aPref, aResult, true);
    1533                 : }
    1534                 : 
    1535                 : // static
    1536                 : nsresult
    1537               0 : Preferences::GetDefaultCString(const char* aPref, nsACString* aResult)
    1538                 : {
    1539               0 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1540               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1541               0 :   nsCAutoString result;
    1542               0 :   nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), true);
    1543               0 :   if (NS_SUCCEEDED(rv)) {
    1544               0 :     *aResult = result;
    1545                 :   }
    1546               0 :   return rv;
    1547                 : }
    1548                 : 
    1549                 : // static
    1550                 : nsresult
    1551               0 : Preferences::GetDefaultString(const char* aPref, nsAString* aResult)
    1552                 : {
    1553               0 :   NS_PRECONDITION(aResult, "aResult must not be NULL");
    1554               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1555               0 :   nsCAutoString result;
    1556               0 :   nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), true);
    1557               0 :   if (NS_SUCCEEDED(rv)) {
    1558               0 :     CopyUTF8toUTF16(result, *aResult);
    1559                 :   }
    1560               0 :   return rv;
    1561                 : }
    1562                 : 
    1563                 : // static
    1564                 : nsresult
    1565               0 : Preferences::GetDefaultLocalizedCString(const char* aPref,
    1566                 :                                         nsACString* aResult)
    1567                 : {
    1568               0 :   nsAutoString result;
    1569               0 :   nsresult rv = GetDefaultLocalizedString(aPref, &result);
    1570               0 :   if (NS_SUCCEEDED(rv)) {
    1571               0 :     CopyUTF16toUTF8(result, *aResult);
    1572                 :   }
    1573               0 :   return rv;
    1574                 : }
    1575                 : 
    1576                 : // static
    1577                 : nsresult
    1578               0 : Preferences::GetDefaultLocalizedString(const char* aPref,
    1579                 :                                        nsAString* aResult)
    1580                 : {
    1581               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1582               0 :   nsCOMPtr<nsIPrefLocalizedString> prefLocalString;
    1583                 :   nsresult rv =
    1584                 :     sDefaultRootBranch->GetComplexValue(aPref,
    1585                 :                                         NS_GET_IID(nsIPrefLocalizedString),
    1586               0 :                                         getter_AddRefs(prefLocalString));
    1587               0 :   if (NS_SUCCEEDED(rv)) {
    1588               0 :     NS_ASSERTION(prefLocalString, "Succeeded but the result is NULL");
    1589               0 :     prefLocalString->GetData(getter_Copies(*aResult));
    1590                 :   }
    1591               0 :   return rv;
    1592                 : }
    1593                 : 
    1594                 : // static
    1595                 : nsAdoptingString
    1596               0 : Preferences::GetDefaultString(const char* aPref)
    1597                 : {
    1598               0 :   nsAdoptingString result;
    1599               0 :   GetDefaultString(aPref, &result);
    1600                 :   return result;
    1601                 : }
    1602                 : 
    1603                 : // static
    1604                 : nsAdoptingCString
    1605               0 : Preferences::GetDefaultCString(const char* aPref)
    1606                 : {
    1607               0 :   nsAdoptingCString result;
    1608               0 :   PREF_CopyCharPref(aPref, getter_Copies(result), true);
    1609                 :   return result;
    1610                 : }
    1611                 : 
    1612                 : // static
    1613                 : nsAdoptingString
    1614               0 : Preferences::GetDefaultLocalizedString(const char* aPref)
    1615                 : {
    1616               0 :   nsAdoptingString result;
    1617               0 :   GetDefaultLocalizedString(aPref, &result);
    1618                 :   return result;
    1619                 : }
    1620                 : 
    1621                 : // static
    1622                 : nsAdoptingCString
    1623               0 : Preferences::GetDefaultLocalizedCString(const char* aPref)
    1624                 : {
    1625               0 :   nsAdoptingCString result;
    1626               0 :   GetDefaultLocalizedCString(aPref, &result);
    1627                 :   return result;
    1628                 : }
    1629                 : 
    1630                 : // static
    1631                 : nsresult
    1632               0 : Preferences::GetDefaultComplex(const char* aPref, const nsIID &aType,
    1633                 :                                void** aResult)
    1634                 : {
    1635               0 :   NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
    1636               0 :   return sDefaultRootBranch->GetComplexValue(aPref, aType, aResult);
    1637                 : }
    1638                 : 
    1639                 : } // namespace mozilla

Generated by: LCOV version 1.7