From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- modules/libpref/Preferences.cpp | 2023 +++++++ modules/libpref/Preferences.h | 408 ++ modules/libpref/greprefs.js | 12 + modules/libpref/init/all.js | 5583 ++++++++++++++++++++ modules/libpref/moz.build | 48 + modules/libpref/nsIPrefBranch.idl | 409 ++ modules/libpref/nsIPrefBranch2.idl | 16 + modules/libpref/nsIPrefBranchInternal.idl | 17 + modules/libpref/nsIPrefLocalizedString.idl | 64 + modules/libpref/nsIPrefService.idl | 160 + modules/libpref/nsIRelativeFilePref.idl | 69 + modules/libpref/nsPrefBranch.cpp | 901 ++++ modules/libpref/nsPrefBranch.h | 269 + modules/libpref/nsPrefsFactory.cpp | 54 + modules/libpref/prefapi.cpp | 1013 ++++ modules/libpref/prefapi.h | 258 + modules/libpref/prefapi_private_data.h | 40 + modules/libpref/prefread.cpp | 657 +++ modules/libpref/prefread.h | 118 + modules/libpref/test/unit/data/testPref.js | 6 + modules/libpref/test/unit/data/testPrefSticky.js | 2 + .../libpref/test/unit/data/testPrefStickyUser.js | 5 + modules/libpref/test/unit/extdata/testExt.js | 2 + modules/libpref/test/unit/head_libPrefs.js | 45 + modules/libpref/test/unit/test_bug345529.js | 34 + modules/libpref/test/unit/test_bug506224.js | 29 + modules/libpref/test/unit/test_bug577950.js | 28 + modules/libpref/test/unit/test_bug790374.js | 55 + modules/libpref/test/unit/test_changeType.js | 63 + modules/libpref/test/unit/test_dirtyPrefs.js | 75 + modules/libpref/test/unit/test_extprefs.js | 70 + modules/libpref/test/unit/test_libPrefs.js | 392 ++ modules/libpref/test/unit/test_stickyprefs.js | 170 + modules/libpref/test/unit/test_warnings.js | 69 + modules/libpref/test/unit/xpcshell.ini | 18 + .../libpref/test/unit_ipc/test_existing_prefs.js | 21 + .../libpref/test/unit_ipc/test_initial_prefs.js | 18 + modules/libpref/test/unit_ipc/test_large_pref.js | 98 + .../libpref/test/unit_ipc/test_observed_prefs.js | 16 + modules/libpref/test/unit_ipc/test_update_prefs.js | 38 + .../test/unit_ipc/test_user_default_prefs.js | 76 + modules/libpref/test/unit_ipc/xpcshell.ini | 11 + 42 files changed, 13460 insertions(+) create mode 100644 modules/libpref/Preferences.cpp create mode 100644 modules/libpref/Preferences.h create mode 100644 modules/libpref/greprefs.js create mode 100644 modules/libpref/init/all.js create mode 100644 modules/libpref/moz.build create mode 100644 modules/libpref/nsIPrefBranch.idl create mode 100644 modules/libpref/nsIPrefBranch2.idl create mode 100644 modules/libpref/nsIPrefBranchInternal.idl create mode 100644 modules/libpref/nsIPrefLocalizedString.idl create mode 100644 modules/libpref/nsIPrefService.idl create mode 100644 modules/libpref/nsIRelativeFilePref.idl create mode 100644 modules/libpref/nsPrefBranch.cpp create mode 100644 modules/libpref/nsPrefBranch.h create mode 100644 modules/libpref/nsPrefsFactory.cpp create mode 100644 modules/libpref/prefapi.cpp create mode 100644 modules/libpref/prefapi.h create mode 100644 modules/libpref/prefapi_private_data.h create mode 100644 modules/libpref/prefread.cpp create mode 100644 modules/libpref/prefread.h create mode 100644 modules/libpref/test/unit/data/testPref.js create mode 100644 modules/libpref/test/unit/data/testPrefSticky.js create mode 100644 modules/libpref/test/unit/data/testPrefStickyUser.js create mode 100644 modules/libpref/test/unit/extdata/testExt.js create mode 100644 modules/libpref/test/unit/head_libPrefs.js create mode 100644 modules/libpref/test/unit/test_bug345529.js create mode 100644 modules/libpref/test/unit/test_bug506224.js create mode 100644 modules/libpref/test/unit/test_bug577950.js create mode 100644 modules/libpref/test/unit/test_bug790374.js create mode 100644 modules/libpref/test/unit/test_changeType.js create mode 100644 modules/libpref/test/unit/test_dirtyPrefs.js create mode 100644 modules/libpref/test/unit/test_extprefs.js create mode 100644 modules/libpref/test/unit/test_libPrefs.js create mode 100644 modules/libpref/test/unit/test_stickyprefs.js create mode 100644 modules/libpref/test/unit/test_warnings.js create mode 100644 modules/libpref/test/unit/xpcshell.ini create mode 100644 modules/libpref/test/unit_ipc/test_existing_prefs.js create mode 100644 modules/libpref/test/unit_ipc/test_initial_prefs.js create mode 100644 modules/libpref/test/unit_ipc/test_large_pref.js create mode 100644 modules/libpref/test/unit_ipc/test_observed_prefs.js create mode 100644 modules/libpref/test/unit_ipc/test_update_prefs.js create mode 100644 modules/libpref/test/unit_ipc/test_user_default_prefs.js create mode 100644 modules/libpref/test/unit_ipc/xpcshell.ini (limited to 'modules/libpref') diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp new file mode 100644 index 000000000..f36819236 --- /dev/null +++ b/modules/libpref/Preferences.cpp @@ -0,0 +1,2023 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/MemoryReporting.h" +#include "mozilla/dom/ContentChild.h" + +#include "mozilla/ArrayUtils.h" +#include "mozilla/Attributes.h" +#include "mozilla/HashFunctions.h" +#include "mozilla/UniquePtrExtensions.h" + +#include "nsXULAppAPI.h" + +#include "mozilla/Preferences.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsDataHashtable.h" +#include "nsDirectoryServiceDefs.h" +#include "nsICategoryManager.h" +#include "nsCategoryManagerUtils.h" +#include "nsNetUtil.h" +#include "nsIFile.h" +#include "nsIInputStream.h" +#include "nsIObserverService.h" +#include "nsIOutputStream.h" +#include "nsISafeOutputStream.h" +#include "nsISimpleEnumerator.h" +#include "nsIStringEnumerator.h" +#include "nsIZipReader.h" +#include "nsPrefBranch.h" +#include "nsXPIDLString.h" +#include "nsCRT.h" +#include "nsCOMArray.h" +#include "nsXPCOMCID.h" +#include "nsAutoPtr.h" +#include "nsPrintfCString.h" + +#include "nsQuickSort.h" +#include "PLDHashTable.h" + +#include "prefapi.h" +#include "prefread.h" +#include "prefapi_private_data.h" + +#include "mozilla/Omnijar.h" +#include "nsZipArchive.h" + +#include "nsTArray.h" +#include "nsRefPtrHashtable.h" +#include "nsIMemoryReporter.h" +#include "nsThreadUtils.h" + +#ifdef DEBUG +#define ENSURE_MAIN_PROCESS(message, pref) do { \ + if (MOZ_UNLIKELY(!XRE_IsParentProcess())) { \ + nsPrintfCString msg("ENSURE_MAIN_PROCESS failed. %s %s", message, pref); \ + NS_WARNING(msg.get()); \ + return NS_ERROR_NOT_AVAILABLE; \ + } \ +} while (0); +#else +#define ENSURE_MAIN_PROCESS(message, pref) \ + if (MOZ_UNLIKELY(!XRE_IsParentProcess())) { \ + return NS_ERROR_NOT_AVAILABLE; \ + } +#endif + +class PrefCallback; + +namespace mozilla { + +// Definitions +#define INITIAL_PREF_FILES 10 +static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID); + +void +Preferences::DirtyCallback() +{ + if (gHashTable && sPreferences && !sPreferences->mDirty) { + sPreferences->mDirty = true; + } +} + +// Prototypes +static nsresult openPrefFile(nsIFile* aFile); +static nsresult pref_InitInitialObjects(void); +static nsresult pref_LoadPrefsInDirList(const char *listId); +static nsresult ReadExtensionPrefs(nsIFile *aFile); + +static const char kTelemetryPref[] = "toolkit.telemetry.enabled"; +static const char kOldTelemetryPref[] = "toolkit.telemetry.enabledPreRelease"; +static const char kChannelPref[] = "app.update.channel"; + +static const char kPrefFileHeader[] = + "# 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 + " */" + NS_LINEBREAK + NS_LINEBREAK; + +Preferences* Preferences::sPreferences = nullptr; +nsIPrefBranch* Preferences::sRootBranch = nullptr; +nsIPrefBranch* Preferences::sDefaultRootBranch = nullptr; +bool Preferences::sShutdown = false; + +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) + { + PLDHashNumber hash = HashString(aKey->mPrefName); + hash = AddToHash(hash, aKey->mMatchKind); + return AddToHash(hash, aKey->mCallback); + } + + ValueObserverHashKey(const char *aPref, PrefChangedFunc aCallback, Preferences::MatchKind aMatchKind) : + mPrefName(aPref), mCallback(aCallback), mMatchKind(aMatchKind) { } + + explicit ValueObserverHashKey(const ValueObserverHashKey *aOther) : + mPrefName(aOther->mPrefName), + mCallback(aOther->mCallback), + mMatchKind(aOther->mMatchKind) + { } + + bool KeyEquals(const ValueObserverHashKey *aOther) const + { + return mCallback == aOther->mCallback && + mPrefName == aOther->mPrefName && + mMatchKind == aOther->mMatchKind; + } + + ValueObserverHashKey *GetKey() const + { + return const_cast(this); + } + + enum { ALLOW_MEMMOVE = true }; + + nsCString mPrefName; + PrefChangedFunc mCallback; + Preferences::MatchKind mMatchKind; +}; + +class ValueObserver final : public nsIObserver, + public ValueObserverHashKey +{ + ~ValueObserver() { + Preferences::RemoveObserver(this, mPrefName.get()); + } + +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + ValueObserver(const char *aPref, PrefChangedFunc aCallback, Preferences::MatchKind aMatchKind) + : ValueObserverHashKey(aPref, aCallback, aMatchKind) { } + + void AppendClosure(void *aClosure) { + mClosures.AppendElement(aClosure); + } + + void RemoveClosure(void *aClosure) { + mClosures.RemoveElement(aClosure); + } + + bool HasNoClosures() { + return mClosures.Length() == 0; + } + + nsTArray mClosures; +}; + +NS_IMPL_ISUPPORTS(ValueObserver, nsIObserver) + +NS_IMETHODIMP +ValueObserver::Observe(nsISupports *aSubject, + const char *aTopic, + const char16_t *aData) +{ + NS_ASSERTION(!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID), + "invalid topic"); + NS_ConvertUTF16toUTF8 data(aData); + if (mMatchKind == Preferences::ExactMatch && !mPrefName.EqualsASCII(data.get())) { + return NS_OK; + } + for (uint32_t i = 0; i < mClosures.Length(); i++) { + mCallback(data.get(), mClosures.ElementAt(i)); + } + + return NS_OK; +} + +struct CacheData { + void* cacheLocation; + union { + bool defaultValueBool; + int32_t defaultValueInt; + uint32_t defaultValueUint; + float defaultValueFloat; + }; +}; + +static nsTArray >* gCacheData = nullptr; +static nsRefPtrHashtable* gObserverTable = nullptr; + +#ifdef DEBUG +static bool +HaveExistingCacheFor(void* aPtr) +{ + MOZ_ASSERT(NS_IsMainThread()); + if (gCacheData) { + for (size_t i = 0, count = gCacheData->Length(); i < count; ++i) { + if ((*gCacheData)[i]->cacheLocation == aPtr) { + return true; + } + } + } + return false; +} + +static void +AssertNotAlreadyCached(const char* aPrefType, + const char* aPref, + void* aPtr) +{ + if (HaveExistingCacheFor(aPtr)) { + fprintf_stderr(stderr, + "Attempt to add a %s pref cache for preference '%s' at address '%p'" + "was made. However, a pref was already cached at this address.\n", + aPrefType, aPref, aPtr); + MOZ_ASSERT(false, "Should not have an existing pref cache for this address"); + } +} +#endif + +static void +ReportToConsole(const char* aMessage, int aLine, bool aError) +{ + nsPrintfCString message("** Preference parsing %s (line %d) = %s **\n", + (aError ? "error" : "warning"), aLine, aMessage); + nsPrefBranch::ReportToConsole(NS_ConvertUTF8toUTF16(message.get())); +} + +// Although this is a member of Preferences, it measures sPreferences and +// several other global structures. +/* static */ int64_t +Preferences::SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeOf) +{ + NS_ENSURE_TRUE(InitStaticMembers(), 0); + + size_t n = aMallocSizeOf(sPreferences); + if (gHashTable) { + // pref keys are allocated in a private arena, which we count elsewhere. + // pref stringvals are allocated out of the same private arena. + n += gHashTable->ShallowSizeOfIncludingThis(aMallocSizeOf); + } + if (gCacheData) { + n += gCacheData->ShallowSizeOfIncludingThis(aMallocSizeOf); + for (uint32_t i = 0, count = gCacheData->Length(); i < count; ++i) { + n += aMallocSizeOf((*gCacheData)[i]); + } + } + if (gObserverTable) { + n += gObserverTable->ShallowSizeOfIncludingThis(aMallocSizeOf); + for (auto iter = gObserverTable->Iter(); !iter.Done(); iter.Next()) { + n += iter.Key()->mPrefName.SizeOfExcludingThisIfUnshared(aMallocSizeOf); + n += iter.Data()->mClosures.ShallowSizeOfExcludingThis(aMallocSizeOf); + } + } + if (sRootBranch) { + n += reinterpret_cast(sRootBranch)->SizeOfIncludingThis(aMallocSizeOf); + } + if (sDefaultRootBranch) { + n += reinterpret_cast(sDefaultRootBranch)->SizeOfIncludingThis(aMallocSizeOf); + } + n += pref_SizeOfPrivateData(aMallocSizeOf); + return n; +} + +class PreferenceServiceReporter final : public nsIMemoryReporter +{ + ~PreferenceServiceReporter() {} + +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIMEMORYREPORTER + +protected: + static const uint32_t kSuspectReferentCount = 1000; +}; + +NS_IMPL_ISUPPORTS(PreferenceServiceReporter, nsIMemoryReporter) + +MOZ_DEFINE_MALLOC_SIZE_OF(PreferenceServiceMallocSizeOf) + +NS_IMETHODIMP +PreferenceServiceReporter::CollectReports( + nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize) +{ + MOZ_COLLECT_REPORT( + "explicit/preferences", KIND_HEAP, UNITS_BYTES, + Preferences::SizeOfIncludingThisAndOtherStuff(PreferenceServiceMallocSizeOf), + "Memory used by the preferences system."); + + nsPrefBranch* rootBranch = + static_cast(Preferences::GetRootBranch()); + if (!rootBranch) { + return NS_OK; + } + + size_t numStrong = 0; + size_t numWeakAlive = 0; + size_t numWeakDead = 0; + nsTArray suspectPreferences; + // Count of the number of referents for each preference. + nsDataHashtable prefCounter; + + for (auto iter = rootBranch->mObservers.Iter(); !iter.Done(); iter.Next()) { + nsAutoPtr& callback = iter.Data(); + nsPrefBranch* prefBranch = callback->GetPrefBranch(); + const char* pref = prefBranch->getPrefName(callback->GetDomain().get()); + + if (callback->IsWeak()) { + nsCOMPtr callbackRef = do_QueryReferent(callback->mWeakRef); + if (callbackRef) { + numWeakAlive++; + } else { + numWeakDead++; + } + } else { + numStrong++; + } + + nsDependentCString prefString(pref); + uint32_t oldCount = 0; + prefCounter.Get(prefString, &oldCount); + uint32_t currentCount = oldCount + 1; + prefCounter.Put(prefString, currentCount); + + // Keep track of preferences that have a suspiciously large number of + // referents (a symptom of a leak). + if (currentCount == kSuspectReferentCount) { + suspectPreferences.AppendElement(prefString); + } + } + + for (uint32_t i = 0; i < suspectPreferences.Length(); i++) { + nsCString& suspect = suspectPreferences[i]; + uint32_t totalReferentCount = 0; + prefCounter.Get(suspect, &totalReferentCount); + + nsPrintfCString suspectPath("preference-service-suspect/" + "referent(pref=%s)", suspect.get()); + + aHandleReport->Callback( + /* process = */ EmptyCString(), + suspectPath, KIND_OTHER, UNITS_COUNT, totalReferentCount, + NS_LITERAL_CSTRING( + "A preference with a suspiciously large number referents (symptom of a " + "leak)."), + aData); + } + + MOZ_COLLECT_REPORT( + "preference-service/referent/strong", KIND_OTHER, UNITS_COUNT, + numStrong, + "The number of strong referents held by the preference service."); + + MOZ_COLLECT_REPORT( + "preference-service/referent/weak/alive", KIND_OTHER, UNITS_COUNT, + numWeakAlive, + "The number of weak referents held by the preference service that are " + "still alive."); + + MOZ_COLLECT_REPORT( + "preference-service/referent/weak/dead", KIND_OTHER, UNITS_COUNT, + numWeakDead, + "The number of weak referents held by the preference service that are " + "dead."); + + return NS_OK; +} + +namespace { +class AddPreferencesMemoryReporterRunnable : public Runnable +{ + NS_IMETHOD Run() override + { + return RegisterStrongMemoryReporter(new PreferenceServiceReporter()); + } +}; +} // namespace + +// static +Preferences* +Preferences::GetInstanceForService() +{ + if (sPreferences) { + NS_ADDREF(sPreferences); + return sPreferences; + } + + NS_ENSURE_TRUE(!sShutdown, nullptr); + + sRootBranch = new nsPrefBranch("", false); + NS_ADDREF(sRootBranch); + sDefaultRootBranch = new nsPrefBranch("", true); + NS_ADDREF(sDefaultRootBranch); + + sPreferences = new Preferences(); + NS_ADDREF(sPreferences); + + if (NS_FAILED(sPreferences->Init())) { + // The singleton instance will delete sRootBranch and sDefaultRootBranch. + NS_RELEASE(sPreferences); + return nullptr; + } + + gCacheData = new nsTArray >(); + + gObserverTable = new nsRefPtrHashtable(); + + // Preferences::GetInstanceForService() can be called from GetService(), and + // RegisterStrongMemoryReporter calls GetService(nsIMemoryReporter). To + // avoid a potential recursive GetService() call, we can't register the + // memory reporter here; instead, do it off a runnable. + RefPtr runnable = + new AddPreferencesMemoryReporterRunnable(); + NS_DispatchToMainThread(runnable); + + NS_ADDREF(sPreferences); + return sPreferences; +} + +// static +bool +Preferences::IsServiceAvailable() +{ + return !!sPreferences; +} + +// static +bool +Preferences::InitStaticMembers() +{ +#ifndef MOZ_B2G + MOZ_ASSERT(NS_IsMainThread()); +#endif + + if (!sShutdown && !sPreferences) { + nsCOMPtr prefService = + do_GetService(NS_PREFSERVICE_CONTRACTID); + } + + return sPreferences != nullptr; +} + +// static +void +Preferences::Shutdown() +{ + if (!sShutdown) { + sShutdown = true; // Don't create the singleton instance after here. + + // Don't set sPreferences to nullptr 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(); + } + } +} + +//----------------------------------------------------------------------------- + +/* + * Constructor/Destructor + */ + +Preferences::Preferences() + : mDirty(false) +{ +} + +Preferences::~Preferences() +{ + NS_ASSERTION(sPreferences == this, "Isn't this the singleton instance?"); + + delete gObserverTable; + gObserverTable = nullptr; + + delete gCacheData; + gCacheData = nullptr; + + NS_RELEASE(sRootBranch); + NS_RELEASE(sDefaultRootBranch); + + sPreferences = nullptr; + + PREF_Cleanup(); +} + + +/* + * nsISupports Implementation + */ + +NS_IMPL_ADDREF(Preferences) +NS_IMPL_RELEASE(Preferences) + +NS_INTERFACE_MAP_BEGIN(Preferences) + 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 + */ + +nsresult +Preferences::Init() +{ + nsresult rv; + + PREF_SetDirtyCallback(&DirtyCallback); + PREF_Init(); + + rv = pref_InitInitialObjects(); + NS_ENSURE_SUCCESS(rv, rv); + + using mozilla::dom::ContentChild; + if (XRE_IsContentProcess()) { + InfallibleTArray prefs; + ContentChild::GetSingleton()->SendReadPrefsArray(&prefs); + + // Store the array + for (uint32_t i = 0; i < prefs.Length(); ++i) { + pref_SetPref(prefs[i]); + } + return NS_OK; + } + + nsXPIDLCString lockFileName; + /* + * 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. + */ + + rv = PREF_CopyCharPref("general.config.filename", getter_Copies(lockFileName), false); + if (NS_SUCCEEDED(rv)) + NS_CreateServicesFromCategory("pref-config-startup", + static_cast(static_cast(this)), + "pref-config-startup"); + + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (!observerService) + return NS_ERROR_FAILURE; + + rv = observerService->AddObserver(this, "profile-before-change", true); + + observerService->AddObserver(this, "load-extension-defaults", true); + observerService->AddObserver(this, "suspend_process_notification", true); + + return(rv); +} + +// static +nsresult +Preferences::ResetAndReadUserPrefs() +{ + sPreferences->ResetUserPrefs(); + return sPreferences->ReadUserPrefs(nullptr); +} + +NS_IMETHODIMP +Preferences::Observe(nsISupports *aSubject, const char *aTopic, + const char16_t *someData) +{ + if (XRE_IsContentProcess()) + return NS_ERROR_NOT_AVAILABLE; + + nsresult rv = NS_OK; + + if (!nsCRT::strcmp(aTopic, "profile-before-change")) { + rv = SavePrefFile(nullptr); + } else if (!strcmp(aTopic, "load-extension-defaults")) { + pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST); + } else if (!nsCRT::strcmp(aTopic, "reload-default-prefs")) { + // Reload the default prefs from file. + pref_InitInitialObjects(); + } else if (!nsCRT::strcmp(aTopic, "suspend_process_notification")) { + // Our process is being suspended. The OS may wake our process later, + // or it may kill the process. In case our process is going to be killed + // from the suspended state, we save preferences before suspending. + rv = SavePrefFile(nullptr); + } + return rv; +} + + +NS_IMETHODIMP +Preferences::ReadUserPrefs(nsIFile *aFile) +{ + if (XRE_IsContentProcess()) { + NS_ERROR("cannot load prefs from content process"); + return NS_ERROR_NOT_AVAILABLE; + } + + nsresult rv; + + if (nullptr == aFile) { + rv = UseDefaultPrefFile(); + // A user pref file is optional. + // Ignore all errors related to it, so we retain 'rv' value :-| + (void) UseUserPrefFile(); + + // Migrate the old prerelease telemetry pref + if (!Preferences::GetBool(kOldTelemetryPref, true)) { + Preferences::SetBool(kTelemetryPref, false); + Preferences::ClearUser(kOldTelemetryPref); + } + + NotifyServiceObservers(NS_PREFSERVICE_READ_TOPIC_ID); + } else { + rv = ReadAndOwnUserPrefFile(aFile); + } + + return rv; +} + +NS_IMETHODIMP +Preferences::ResetPrefs() +{ + if (XRE_IsContentProcess()) { + NS_ERROR("cannot reset prefs from content process"); + return NS_ERROR_NOT_AVAILABLE; + } + + NotifyServiceObservers(NS_PREFSERVICE_RESET_TOPIC_ID); + PREF_CleanupPrefs(); + + PREF_Init(); + + return pref_InitInitialObjects(); +} + +NS_IMETHODIMP +Preferences::ResetUserPrefs() +{ + if (XRE_IsContentProcess()) { + NS_ERROR("cannot reset user prefs from content process"); + return NS_ERROR_NOT_AVAILABLE; + } + + PREF_ClearAllUserPrefs(); + return NS_OK; +} + +NS_IMETHODIMP +Preferences::SavePrefFile(nsIFile *aFile) +{ + if (XRE_IsContentProcess()) { + NS_ERROR("cannot save pref file from content process"); + return NS_ERROR_NOT_AVAILABLE; + } + + return SavePrefFileInternal(aFile); +} + +static nsresult +ReadExtensionPrefs(nsIFile *aFile) +{ + nsresult rv; + nsCOMPtr reader = do_CreateInstance(kZipReaderCID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = reader->Open(aFile); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr files; + rv = reader->FindEntries(nsDependentCString("defaults/preferences/*.(J|j)(S|s)$"), + getter_AddRefs(files)); + NS_ENSURE_SUCCESS(rv, rv); + + char buffer[4096]; + + bool more; + while (NS_SUCCEEDED(rv = files->HasMore(&more)) && more) { + nsAutoCString entry; + rv = files->GetNext(entry); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr stream; + rv = reader->GetInputStream(entry, getter_AddRefs(stream)); + NS_ENSURE_SUCCESS(rv, rv); + + uint64_t avail; + uint32_t read; + + PrefParseState ps; + PREF_InitParseState(&ps, PREF_ReaderCallback, ReportToConsole, nullptr); + 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; + } + + PREF_ParseBuf(&ps, buffer, read); + } + PREF_FinalizeParseState(&ps); + } + return rv; +} + +void +Preferences::SetPreference(const PrefSetting& aPref) +{ + pref_SetPref(aPref); +} + +void +Preferences::GetPreference(PrefSetting* aPref) +{ + PrefHashEntry *entry = pref_HashTableLookup(aPref->name().get()); + if (!entry) + return; + + if (pref_EntryHasAdvisablySizedValues(entry)) { + pref_GetPrefFromEntry(entry, aPref); + } +} + +void +Preferences::GetPreferences(InfallibleTArray* aPrefs) +{ + aPrefs->SetCapacity(gHashTable->Capacity()); + for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) { + auto entry = static_cast(iter.Get()); + + if (!pref_EntryHasAdvisablySizedValues(entry)) { + continue; + } + + dom::PrefSetting *pref = aPrefs->AppendElement(); + pref_GetPrefFromEntry(entry, pref); + } +} + +NS_IMETHODIMP +Preferences::GetBranch(const char *aPrefRoot, nsIPrefBranch **_retval) +{ + nsresult rv; + + if ((nullptr != aPrefRoot) && (*aPrefRoot != '\0')) { + // TODO: - cache this stuff and allow consumers to share branches (hold weak references I think) + RefPtr prefBranch = new nsPrefBranch(aPrefRoot, false); + prefBranch.forget(_retval); + rv = NS_OK; + } else { + // special case caching the default root + nsCOMPtr root(sRootBranch); + root.forget(_retval); + rv = NS_OK; + } + return rv; +} + +NS_IMETHODIMP +Preferences::GetDefaultBranch(const char *aPrefRoot, nsIPrefBranch **_retval) +{ + if (!aPrefRoot || !aPrefRoot[0]) { + nsCOMPtr root(sDefaultRootBranch); + root.forget(_retval); + return NS_OK; + } + + // TODO: - cache this stuff and allow consumers to share branches (hold weak references I think) + RefPtr prefBranch = new nsPrefBranch(aPrefRoot, true); + if (!prefBranch) + return NS_ERROR_OUT_OF_MEMORY; + + prefBranch.forget(_retval); + return NS_OK; +} + +NS_IMETHODIMP +Preferences::GetDirty(bool *_retval) { + *_retval = mDirty; + return NS_OK; +} + +nsresult +Preferences::NotifyServiceObservers(const char *aTopic) +{ + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (!observerService) + return NS_ERROR_FAILURE; + + nsISupports *subject = (nsISupports *)((nsIPrefService *)this); + observerService->NotifyObservers(subject, aTopic, nullptr); + + return NS_OK; +} + +nsresult +Preferences::UseDefaultPrefFile() +{ + nsCOMPtr aFile; + nsresult 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)) { + if (NS_FAILED(SavePrefFileInternal(aFile))) + NS_ERROR("Failed to save new shared pref file"); + else + rv = NS_OK; + } + } + + return rv; +} + +nsresult +Preferences::UseUserPrefFile() +{ + nsresult rv = NS_OK; + nsCOMPtr 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)) { + bool exists = false; + aFile->Exists(&exists); + if (exists) { + rv = openPrefFile(aFile); + } else { + rv = NS_ERROR_FILE_NOT_FOUND; + } + } + } + return rv; +} + +nsresult +Preferences::MakeBackupPrefFile(nsIFile *aFile) +{ + // Example: this copies "prefs.js" to "Invalidprefs.js" in the same directory. + // "Invalidprefs.js" is removed if it exists, prior to making the copy. + nsAutoString newFilename; + nsresult rv = aFile->GetLeafName(newFilename); + NS_ENSURE_SUCCESS(rv, rv); + newFilename.Insert(NS_LITERAL_STRING("Invalid"), 0); + nsCOMPtr newFile; + rv = aFile->GetParent(getter_AddRefs(newFile)); + NS_ENSURE_SUCCESS(rv, rv); + rv = newFile->Append(newFilename); + NS_ENSURE_SUCCESS(rv, rv); + bool exists = false; + newFile->Exists(&exists); + if (exists) { + rv = newFile->Remove(false); + NS_ENSURE_SUCCESS(rv, rv); + } + rv = aFile->CopyTo(nullptr, newFilename); + NS_ENSURE_SUCCESS(rv, rv); + return rv; +} + +nsresult +Preferences::ReadAndOwnUserPrefFile(nsIFile *aFile) +{ + NS_ENSURE_ARG(aFile); + + if (mCurrentFile == aFile) + return NS_OK; + mCurrentFile = aFile; + + nsresult rv = NS_OK; + bool exists = false; + mCurrentFile->Exists(&exists); + if (exists) { + rv = openPrefFile(mCurrentFile); + if (NS_FAILED(rv)) { + // 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); + } + } else { + rv = NS_ERROR_FILE_NOT_FOUND; + } + + return rv; +} + +nsresult +Preferences::SavePrefFileInternal(nsIFile *aFile) +{ + if (nullptr == aFile) { + // the mDirty flag tells us if we should write to mCurrentFile + // we only check this flag when the caller wants to write to the default + if (!mDirty) { + 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); + } +} + +nsresult +Preferences::WritePrefFile(nsIFile* aFile) +{ + nsCOMPtr outStreamSink; + nsCOMPtr outStream; + uint32_t writeAmount; + nsresult rv; + + if (!gHashTable) + 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; + + // get the lines that we're supposed to be writing to the file + uint32_t prefCount; + UniquePtr valueArray = pref_savePrefs(gHashTable, &prefCount); + + /* Sort the preferences to make a readable file on disk */ + NS_QuickSort(valueArray.get(), prefCount, sizeof(char *), + pref_CompareStrings, nullptr); + + // write out the file header + outStream->Write(kPrefFileHeader, sizeof(kPrefFileHeader) - 1, &writeAmount); + + for (uint32_t valueIdx = 0; valueIdx < prefCount; valueIdx++) { + char*& pref = valueArray[valueIdx]; + MOZ_ASSERT(pref); + outStream->Write(pref, strlen(pref), &writeAmount); + outStream->Write(NS_LINEBREAK, NS_LINEBREAK_LEN, &writeAmount); + free(pref); + pref = nullptr; + } + + // tell the safe output stream to overwrite the real prefs file + // (it'll abort if there were any errors during writing) + nsCOMPtr 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 data loss"); + return rv; + } + } + + mDirty = false; + return NS_OK; +} + +static nsresult openPrefFile(nsIFile* aFile) +{ + nsCOMPtr inStr; + + nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), aFile); + if (NS_FAILED(rv)) + return rv; + + int64_t fileSize64; + rv = aFile->GetFileSize(&fileSize64); + if (NS_FAILED(rv)) + return rv; + NS_ENSURE_TRUE(fileSize64 <= UINT32_MAX, NS_ERROR_FILE_TOO_BIG); + + uint32_t fileSize = (uint32_t)fileSize64; + auto fileBuffer = MakeUniqueFallible(fileSize); + if (fileBuffer == nullptr) + return NS_ERROR_OUT_OF_MEMORY; + + PrefParseState ps; + PREF_InitParseState(&ps, PREF_ReaderCallback, ReportToConsole, nullptr); + + // Read is not guaranteed to return a buf the size of fileSize, + // but usually will. + nsresult rv2 = NS_OK; + uint32_t offset = 0; + for (;;) { + uint32_t amtRead = 0; + rv = inStr->Read(fileBuffer.get(), fileSize, &amtRead); + if (NS_FAILED(rv) || amtRead == 0) + break; + if (!PREF_ParseBuf(&ps, fileBuffer.get(), amtRead)) + rv2 = NS_ERROR_FILE_CORRUPTED; + offset += amtRead; + if (offset == fileSize) { + break; + } + } + + PREF_FinalizeParseState(&ps); + + return NS_FAILED(rv) ? rv : rv2; +} + +/* + * some stuff that gets called from Pref_Init() + */ + +static int +pref_CompareFileNames(nsIFile* aFile1, nsIFile* aFile2, void* /*unused*/) +{ + nsAutoCString 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, uint32_t aSpecialFilesCount) +{ + nsresult rv, rv2; + bool hasMoreElements; + + nsCOMPtr 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_ERROR_FILE_TARGET_DOES_NOT_EXIST) + rv = NS_OK; + return rv; + } + + rv = dirIterator->HasMoreElements(&hasMoreElements); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMArray prefFiles(INITIAL_PREF_FILES); + nsCOMArray specialFiles(aSpecialFilesCount); + nsCOMPtr prefFile; + + while (hasMoreElements && NS_SUCCEEDED(rv)) { + nsAutoCString leafName; + + nsCOMPtr supports; + rv = dirIterator->GetNext(getter_AddRefs(supports)); + prefFile = do_QueryInterface(supports); + 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())) { + bool shouldParse = true; + // separate out special files + for (uint32_t i = 0; i < aSpecialFilesCount; ++i) { + if (leafName.Equals(nsDependentCString(aSpecialFiles[i]))) { + shouldParse = false; + // 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, nullptr); + + uint32_t arrayCount = prefFiles.Count(); + uint32_t 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; +} + +static nsresult pref_LoadPrefsInDirList(const char *listId) +{ + nsresult rv; + nsCOMPtr dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr list; + dirSvc->Get(listId, + NS_GET_IID(nsISimpleEnumerator), + getter_AddRefs(list)); + if (!list) + return NS_OK; + + bool hasMore; + while (NS_SUCCEEDED(list->HasMoreElements(&hasMore)) && hasMore) { + nsCOMPtr elem; + list->GetNext(getter_AddRefs(elem)); + if (!elem) + continue; + + nsCOMPtr path = do_QueryInterface(elem); + if (!path) + continue; + + nsAutoCString leaf; + path->GetNativeLeafName(leaf); + + // Do we care if a file provided by this process fails to load? + if (Substring(leaf, leaf.Length() - 4).EqualsLiteral(".xpi")) + ReadExtensionPrefs(path); + else + pref_LoadPrefsInDir(path, nullptr, 0); + } + return NS_OK; +} + +static nsresult pref_ReadPrefFromJar(nsZipArchive* jarReader, const char *name) +{ + nsZipItemPtr manifest(jarReader, name, true); + NS_ENSURE_TRUE(manifest.Buffer(), NS_ERROR_NOT_AVAILABLE); + + PrefParseState ps; + PREF_InitParseState(&ps, PREF_ReaderCallback, ReportToConsole, nullptr); + PREF_ParseBuf(&ps, manifest, manifest.Length()); + PREF_FinalizeParseState(&ps); + + return NS_OK; +} + +//---------------------------------------------------------------------------------------- +// Initialize default preference JavaScript buffers from +// appropriate TEXT resources +//---------------------------------------------------------------------------------------- +static nsresult pref_InitInitialObjects() +{ + nsresult rv; + + // 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 + // + // In both cases, we also load: + // - $gre/defaults/pref/*.js + // 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. + // + // 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 + // When $app == $gre, we additionally load, in omni.jar case: + // - jar:$gre/omni.jar!/defaults/preferences/*.js + // Thus, in omni.jar case, we always load app-specific default preferences + // from omni.jar, whether or not $app == $gre. + + nsZipFind *findPtr; + nsAutoPtr find; + nsTArray prefEntries; + const char *entryName; + uint16_t entryNameLen; + + RefPtr 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); + + // Load jar:$gre/omni.jar!/defaults/pref/*.js + rv = jarReader->FindInit("defaults/pref/*.js$", &findPtr); + NS_ENSURE_SUCCESS(rv, rv); + + find = findPtr; + while (NS_SUCCEEDED(find->FindNext(&entryName, &entryNameLen))) { + prefEntries.AppendElement(Substring(entryName, entryNameLen)); + } + + prefEntries.Sort(); + for (uint32_t 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 greprefsFile; + rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(greprefsFile)); + NS_ENSURE_SUCCESS(rv, rv); + + 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?"); + } + + // Load $gre/defaults/pref/*.js + nsCOMPtr defaultPrefDir; + + rv = NS_GetSpecialDirectory(NS_APP_PREF_DEFAULTS_50_DIR, getter_AddRefs(defaultPrefDir)); + NS_ENSURE_SUCCESS(rv, rv); + + /* these pref file names should not be used: we process them after all other application pref files for backwards compatibility */ + static const char* specialFiles[] = { +#if defined(XP_MACOSX) + "macprefs.js" +#elif defined(XP_WIN) + "winpref.js" +#elif defined(XP_UNIX) + "unix.js" +#if defined(_AIX) + , "aix.js" +#endif +#elif defined(XP_BEOS) + "beos.js" +#endif + }; + + rv = pref_LoadPrefsInDir(defaultPrefDir, specialFiles, ArrayLength(specialFiles)); + if (NS_FAILED(rv)) + NS_WARNING("Error parsing application default preferences."); + + // Load jar:$app/omni.jar!/defaults/preferences/*.js + // or jar:$gre/omni.jar!/defaults/preferences/*.js. + RefPtr appJarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP); + // GetReader(mozilla::Omnijar::APP) returns null when $app == $gre, in which + // case we look for app-specific default preferences in $gre. + if (!appJarReader) + appJarReader = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE); + 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, entryNameLen)); + } + prefEntries.Sort(); + for (uint32_t i = prefEntries.Length(); i--; ) { + rv = pref_ReadPrefFromJar(appJarReader, prefEntries[i].get()); + if (NS_FAILED(rv)) + NS_WARNING("Error parsing preferences."); + } + } + + rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST); + NS_ENSURE_SUCCESS(rv, rv); + + // Set up the correct default for toolkit.telemetry.enabled. + // If this build has MOZ_TELEMETRY_ON_BY_DEFAULT *or* we're on the beta + // channel, telemetry is on by default, otherwise not. This is necessary + // so that beta users who are testing final release builds don't flipflop + // defaults. + if (Preferences::GetDefaultType(kTelemetryPref) == nsIPrefBranch::PREF_INVALID) { + bool prerelease = false; +#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT + prerelease = true; +#else + if (Preferences::GetDefaultCString(kChannelPref).EqualsLiteral("beta")) { + prerelease = true; + } +#endif + PREF_SetBoolPref(kTelemetryPref, prerelease, true); + } + + NS_CreateServicesFromCategory(NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID, + nullptr, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID); + + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (!observerService) + return NS_ERROR_FAILURE; + + observerService->NotifyObservers(nullptr, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID, nullptr); + + return pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST); +} + + +/****************************************************************************** + * + * static utilities + * + ******************************************************************************/ + +// static +nsresult +Preferences::GetBool(const char* aPref, bool* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_GetBoolPref(aPref, aResult, false); +} + +// static +nsresult +Preferences::GetInt(const char* aPref, int32_t* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_GetIntPref(aPref, aResult, false); +} + +// static +nsresult +Preferences::GetFloat(const char* aPref, float* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsAutoCString result; + nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), false); + if (NS_SUCCEEDED(rv)) { + *aResult = result.ToFloat(&rv); + } + + return rv; +} + +// static +nsAdoptingCString +Preferences::GetCString(const char* aPref) +{ + nsAdoptingCString result; + PREF_CopyCharPref(aPref, getter_Copies(result), false); + return result; +} + +// static +nsAdoptingString +Preferences::GetString(const char* aPref) +{ + nsAdoptingString result; + GetString(aPref, &result); + return result; +} + +// static +nsresult +Preferences::GetCString(const char* aPref, nsACString* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsAutoCString result; + nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), false); + if (NS_SUCCEEDED(rv)) { + *aResult = result; + } + return rv; +} + +// static +nsresult +Preferences::GetString(const char* aPref, nsAString* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsAutoCString result; + nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), false); + if (NS_SUCCEEDED(rv)) { + CopyUTF8toUTF16(result, *aResult); + } + return rv; +} + +// 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; +} + +// static +nsresult +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) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsCOMPtr prefLocalString; + nsresult rv = sRootBranch->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 +nsresult +Preferences::GetComplex(const char* aPref, const nsIID &aType, void** aResult) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sRootBranch->GetComplexValue(aPref, aType, aResult); +} + +// static +nsresult +Preferences::SetCString(const char* aPref, const char* aValue) +{ + ENSURE_MAIN_PROCESS("Cannot SetCString from content process:", aPref); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_SetCharPref(aPref, aValue, false); +} + +// static +nsresult +Preferences::SetCString(const char* aPref, const nsACString &aValue) +{ + ENSURE_MAIN_PROCESS("Cannot SetCString from content process:", aPref); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_SetCharPref(aPref, PromiseFlatCString(aValue).get(), false); +} + +// static +nsresult +Preferences::SetString(const char* aPref, const char16ptr_t aValue) +{ + ENSURE_MAIN_PROCESS("Cannot SetString from content process:", aPref); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_SetCharPref(aPref, NS_ConvertUTF16toUTF8(aValue).get(), false); +} + +// static +nsresult +Preferences::SetString(const char* aPref, const nsAString &aValue) +{ + ENSURE_MAIN_PROCESS("Cannot SetString from content process:", aPref); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_SetCharPref(aPref, NS_ConvertUTF16toUTF8(aValue).get(), false); +} + +// static +nsresult +Preferences::SetBool(const char* aPref, bool aValue) +{ + ENSURE_MAIN_PROCESS("Cannot SetBool from content process:", aPref); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_SetBoolPref(aPref, aValue, false); +} + +// static +nsresult +Preferences::SetInt(const char* aPref, int32_t aValue) +{ + ENSURE_MAIN_PROCESS("Cannot SetInt from content process:", aPref); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_SetIntPref(aPref, aValue, false); +} + +// static +nsresult +Preferences::SetFloat(const char* aPref, float aValue) +{ + return SetCString(aPref, nsPrintfCString("%f", aValue).get()); +} + +// static +nsresult +Preferences::SetComplex(const char* aPref, const nsIID &aType, + nsISupports* aValue) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sRootBranch->SetComplexValue(aPref, aType, aValue); +} + +// static +nsresult +Preferences::ClearUser(const char* aPref) +{ + ENSURE_MAIN_PROCESS("Cannot ClearUser from content process:", aPref); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_ClearUserPref(aPref); +} + +// static +bool +Preferences::HasUserValue(const char* aPref) +{ + NS_ENSURE_TRUE(InitStaticMembers(), false); + return PREF_HasUserPref(aPref); +} + +// static +int32_t +Preferences::GetType(const char* aPref) +{ + NS_ENSURE_TRUE(InitStaticMembers(), nsIPrefBranch::PREF_INVALID); + int32_t result; + return NS_SUCCEEDED(sRootBranch->GetPrefType(aPref, &result)) ? + result : nsIPrefBranch::PREF_INVALID; +} + +// static +nsresult +Preferences::AddStrongObserver(nsIObserver* aObserver, + const char* aPref) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sRootBranch->AddObserver(aPref, aObserver, false); +} + +// static +nsresult +Preferences::AddWeakObserver(nsIObserver* aObserver, + const char* aPref) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return sRootBranch->AddObserver(aPref, aObserver, true); +} + +// static +nsresult +Preferences::RemoveObserver(nsIObserver* aObserver, + const char* aPref) +{ + if (!sPreferences && sShutdown) { + return NS_OK; // Observers have been released automatically. + } + NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE); + return sRootBranch->RemoveObserver(aPref, aObserver); +} + +// static +nsresult +Preferences::AddStrongObservers(nsIObserver* aObserver, + const char** aPrefs) +{ + for (uint32_t 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 (uint32_t 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) +{ + if (!sPreferences && sShutdown) { + return NS_OK; // Observers have been released automatically. + } + NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE); + + for (uint32_t i = 0; aPrefs[i]; i++) { + nsresult rv = RemoveObserver(aObserver, aPrefs[i]); + NS_ENSURE_SUCCESS(rv, rv); + } + return NS_OK; +} + +// static +nsresult +Preferences::RegisterCallback(PrefChangedFunc aCallback, + const char* aPref, + void* aClosure, + MatchKind aMatchKind) +{ + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + + ValueObserverHashKey hashKey(aPref, aCallback, aMatchKind); + RefPtr observer; + gObserverTable->Get(&hashKey, getter_AddRefs(observer)); + if (observer) { + observer->AppendClosure(aClosure); + return NS_OK; + } + + observer = new ValueObserver(aPref, aCallback, aMatchKind); + observer->AppendClosure(aClosure); + nsresult rv = AddStrongObserver(observer, aPref); + NS_ENSURE_SUCCESS(rv, rv); + gObserverTable->Put(observer, observer); + return NS_OK; +} + +// static +nsresult +Preferences::RegisterCallbackAndCall(PrefChangedFunc aCallback, + const char* aPref, + void* aClosure, + MatchKind aMatchKind) +{ + nsresult rv = RegisterCallback(aCallback, aPref, aClosure, aMatchKind); + if (NS_SUCCEEDED(rv)) { + (*aCallback)(aPref, aClosure); + } + return rv; +} + +// static +nsresult +Preferences::UnregisterCallback(PrefChangedFunc aCallback, + const char* aPref, + void* aClosure, + MatchKind aMatchKind) +{ + if (!sPreferences && sShutdown) { + return NS_OK; // Observers have been released automatically. + } + NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE); + + ValueObserverHashKey hashKey(aPref, aCallback, aMatchKind); + RefPtr 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 void BoolVarChanged(const char* aPref, void* aClosure) +{ + CacheData* cache = static_cast(aClosure); + *((bool*)cache->cacheLocation) = + Preferences::GetBool(aPref, cache->defaultValueBool); +} + +// static +nsresult +Preferences::AddBoolVarCache(bool* aCache, + const char* aPref, + bool aDefault) +{ + NS_ASSERTION(aCache, "aCache must not be NULL"); +#ifdef DEBUG + AssertNotAlreadyCached("bool", aPref, aCache); +#endif + *aCache = GetBool(aPref, aDefault); + CacheData* data = new CacheData(); + data->cacheLocation = aCache; + data->defaultValueBool = aDefault; + gCacheData->AppendElement(data); + return RegisterCallback(BoolVarChanged, aPref, data, ExactMatch); +} + +static void IntVarChanged(const char* aPref, void* aClosure) +{ + CacheData* cache = static_cast(aClosure); + *((int32_t*)cache->cacheLocation) = + Preferences::GetInt(aPref, cache->defaultValueInt); +} + +// static +nsresult +Preferences::AddIntVarCache(int32_t* aCache, + const char* aPref, + int32_t aDefault) +{ + NS_ASSERTION(aCache, "aCache must not be NULL"); +#ifdef DEBUG + AssertNotAlreadyCached("int", aPref, aCache); +#endif + *aCache = Preferences::GetInt(aPref, aDefault); + CacheData* data = new CacheData(); + data->cacheLocation = aCache; + data->defaultValueInt = aDefault; + gCacheData->AppendElement(data); + return RegisterCallback(IntVarChanged, aPref, data, ExactMatch); +} + +static void UintVarChanged(const char* aPref, void* aClosure) +{ + CacheData* cache = static_cast(aClosure); + *((uint32_t*)cache->cacheLocation) = + Preferences::GetUint(aPref, cache->defaultValueUint); +} + +// static +nsresult +Preferences::AddUintVarCache(uint32_t* aCache, + const char* aPref, + uint32_t aDefault) +{ + NS_ASSERTION(aCache, "aCache must not be NULL"); +#ifdef DEBUG + AssertNotAlreadyCached("uint", aPref, aCache); +#endif + *aCache = Preferences::GetUint(aPref, aDefault); + CacheData* data = new CacheData(); + data->cacheLocation = aCache; + data->defaultValueUint = aDefault; + gCacheData->AppendElement(data); + return RegisterCallback(UintVarChanged, aPref, data, ExactMatch); +} + +template +static void AtomicUintVarChanged(const char* aPref, void* aClosure) +{ + CacheData* cache = static_cast(aClosure); + *((Atomic*)cache->cacheLocation) = + Preferences::GetUint(aPref, cache->defaultValueUint); +} + +template +// static +nsresult +Preferences::AddAtomicUintVarCache(Atomic* aCache, + const char* aPref, + uint32_t aDefault) +{ + NS_ASSERTION(aCache, "aCache must not be NULL"); +#ifdef DEBUG + AssertNotAlreadyCached("uint", aPref, aCache); +#endif + *aCache = Preferences::GetUint(aPref, aDefault); + CacheData* data = new CacheData(); + data->cacheLocation = aCache; + data->defaultValueUint = aDefault; + gCacheData->AppendElement(data); + return RegisterCallback(AtomicUintVarChanged, aPref, data, ExactMatch); +} + +// Since the definition of this template function is not in a header file, +// we need to explicitly specify the instantiations that are required. +// Currently only the order=Relaxed variant is needed. +template +nsresult Preferences::AddAtomicUintVarCache(Atomic*, + const char*, uint32_t); + +static void FloatVarChanged(const char* aPref, void* aClosure) +{ + CacheData* cache = static_cast(aClosure); + *((float*)cache->cacheLocation) = + Preferences::GetFloat(aPref, cache->defaultValueFloat); +} + +// static +nsresult +Preferences::AddFloatVarCache(float* aCache, + const char* aPref, + float aDefault) +{ + NS_ASSERTION(aCache, "aCache must not be NULL"); +#ifdef DEBUG + AssertNotAlreadyCached("float", aPref, aCache); +#endif + *aCache = Preferences::GetFloat(aPref, aDefault); + CacheData* data = new CacheData(); + data->cacheLocation = aCache; + data->defaultValueFloat = aDefault; + gCacheData->AppendElement(data); + return RegisterCallback(FloatVarChanged, aPref, data, ExactMatch); +} + +// static +nsresult +Preferences::GetDefaultBool(const char* aPref, bool* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_GetBoolPref(aPref, aResult, true); +} + +// static +nsresult +Preferences::GetDefaultInt(const char* aPref, int32_t* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + return PREF_GetIntPref(aPref, aResult, true); +} + +// static +nsresult +Preferences::GetDefaultCString(const char* aPref, nsACString* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsAutoCString result; + nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), true); + if (NS_SUCCEEDED(rv)) { + *aResult = result; + } + return rv; +} + +// static +nsresult +Preferences::GetDefaultString(const char* aPref, nsAString* aResult) +{ + NS_PRECONDITION(aResult, "aResult must not be NULL"); + NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + nsAutoCString result; + nsresult rv = PREF_CopyCharPref(aPref, getter_Copies(result), true); + 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 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; + PREF_CopyCharPref(aPref, getter_Copies(result), true); + 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); +} + +// static +int32_t +Preferences::GetDefaultType(const char* aPref) +{ + NS_ENSURE_TRUE(InitStaticMembers(), nsIPrefBranch::PREF_INVALID); + int32_t result; + return NS_SUCCEEDED(sDefaultRootBranch->GetPrefType(aPref, &result)) ? + result : nsIPrefBranch::PREF_INVALID; +} + +} // namespace mozilla + +#undef ENSURE_MAIN_PROCESS diff --git a/modules/libpref/Preferences.h b/modules/libpref/Preferences.h new file mode 100644 index 000000000..255d2a8d2 --- /dev/null +++ b/modules/libpref/Preferences.h @@ -0,0 +1,408 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_Preferences_h +#define mozilla_Preferences_h + +#ifndef MOZILLA_INTERNAL_API +#error "This header is only usable from within libxul (MOZILLA_INTERNAL_API)." +#endif + +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" +#include "nsIPrefBranchInternal.h" +#include "nsIObserver.h" +#include "nsCOMPtr.h" +#include "nsTArray.h" +#include "nsWeakReference.h" +#include "mozilla/MemoryReporting.h" + +class nsIFile; +class nsAdoptingString; +class nsAdoptingCString; + +#ifndef have_PrefChangedFunc_typedef +typedef void (*PrefChangedFunc)(const char *, void *); +#define have_PrefChangedFunc_typedef +#endif + +namespace mozilla { + +namespace dom { +class PrefSetting; +} // namespace dom + +class Preferences final : public nsIPrefService, + public nsIObserver, + public nsIPrefBranchInternal, + public nsSupportsWeakReference +{ +public: + typedef mozilla::dom::PrefSetting PrefSetting; + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIPREFSERVICE + NS_FORWARD_NSIPREFBRANCH(sRootBranch->) + NS_DECL_NSIOBSERVER + + Preferences(); + + nsresult Init(); + + /** + * Returns true if the Preferences service is available, false otherwise. + */ + static bool IsServiceAvailable(); + + /** + * Reset loaded user prefs then read them + */ + static nsresult ResetAndReadUserPrefs(); + + /** + * Returns the singleton instance which is addreffed. + */ + static Preferences* GetInstanceForService(); + + /** + * Finallizes global members. + */ + static void Shutdown(); + + /** + * Returns shared pref service instance + * NOTE: not addreffed. + */ + static nsIPrefService* GetService() + { + NS_ENSURE_TRUE(InitStaticMembers(), nullptr); + return sPreferences; + } + + /** + * Returns shared pref branch instance. + * NOTE: not addreffed. + */ + static nsIPrefBranch* GetRootBranch() + { + NS_ENSURE_TRUE(InitStaticMembers(), nullptr); + return sRootBranch; + } + + /** + * Returns shared default pref branch instance. + * NOTE: not addreffed. + */ + static nsIPrefBranch* GetDefaultRootBranch() + { + NS_ENSURE_TRUE(InitStaticMembers(), nullptr); + return sDefaultRootBranch; + } + + /** + * Gets int or bool type pref value with default value if failed to get + * the pref. + */ + static bool GetBool(const char* aPref, bool aDefault = false) + { + bool result = aDefault; + GetBool(aPref, &result); + return result; + } + + static int32_t GetInt(const char* aPref, int32_t aDefault = 0) + { + int32_t result = aDefault; + GetInt(aPref, &result); + return result; + } + + static uint32_t GetUint(const char* aPref, uint32_t aDefault = 0) + { + uint32_t result = aDefault; + GetUint(aPref, &result); + return result; + } + + static float GetFloat(const char* aPref, float aDefault = 0) + { + float result = aDefault; + GetFloat(aPref, &result); + return result; + } + + /** + * Gets char type pref value directly. If failed, the get() of result + * returns nullptr. Even if succeeded but the result was empty string, the + * get() does NOT return nullptr. So, you can check whether the method + * succeeded or not by: + * + * nsAdoptingString value = Prefereces::GetString("foo.bar"); + * if (!value) { + * // failed + * } + * + * Be aware. If you wrote as: + * + * nsAutoString value = Preferences::GetString("foo.bar"); + * if (!value.get()) { + * // the condition is always FALSE!! + * } + * + * The value.get() doesn't return nullptr. You must use nsAdoptingString + * when you need to check whether it was failure or not. + */ + static nsAdoptingCString GetCString(const char* aPref); + static nsAdoptingString GetString(const char* aPref); + static nsAdoptingCString GetLocalizedCString(const char* aPref); + static nsAdoptingString GetLocalizedString(const char* aPref); + + /** + * Gets int, float, or bool type pref value with raw return value of + * nsIPrefBranch. + * + * @param aPref A pref name. + * @param aResult Must not be nullptr. The value is never modified + * when these methods fail. + */ + static nsresult GetBool(const char* aPref, bool* aResult); + static nsresult GetInt(const char* aPref, int32_t* aResult); + static nsresult GetFloat(const char* aPref, float* aResult); + static nsresult GetUint(const char* aPref, uint32_t* aResult) + { + int32_t result; + nsresult rv = GetInt(aPref, &result); + if (NS_SUCCEEDED(rv)) { + *aResult = static_cast(result); + } + return rv; + } + + /** + * Gets string type pref value with raw return value of nsIPrefBranch. + * + * @param aPref A pref name. + * @param aResult Must not be nullptr. The value is never modified + * when these methods fail. + */ + static nsresult GetCString(const char* aPref, nsACString* aResult); + static nsresult GetString(const char* aPref, nsAString* aResult); + static nsresult GetLocalizedCString(const char* aPref, nsACString* aResult); + static nsresult GetLocalizedString(const char* aPref, nsAString* aResult); + + static nsresult GetComplex(const char* aPref, const nsIID &aType, + void** aResult); + + /** + * Sets various type pref values. + */ + static nsresult SetBool(const char* aPref, bool aValue); + static nsresult SetInt(const char* aPref, int32_t aValue); + static nsresult SetUint(const char* aPref, uint32_t aValue) + { + return SetInt(aPref, static_cast(aValue)); + } + static nsresult SetFloat(const char* aPref, float aValue); + static nsresult SetCString(const char* aPref, const char* aValue); + static nsresult SetCString(const char* aPref, const nsACString &aValue); + static nsresult SetString(const char* aPref, const char16ptr_t aValue); + static nsresult SetString(const char* aPref, const nsAString &aValue); + + static nsresult SetComplex(const char* aPref, const nsIID &aType, + nsISupports* aValue); + + /** + * Clears user set pref. + */ + static nsresult ClearUser(const char* aPref); + + /** + * Whether the pref has a user value or not. + */ + static bool HasUserValue(const char* aPref); + + /** + * Gets the type of the pref. + */ + static int32_t GetType(const char* aPref); + + /** + * Adds/Removes the observer for the root pref branch. + * The observer is referenced strongly if AddStrongObserver is used. On the + * other hand, it is referenced weakly, if AddWeakObserver is used. + * See nsIPrefBranch.idl for details. + */ + static nsresult AddStrongObserver(nsIObserver* aObserver, const char* aPref); + static nsresult AddWeakObserver(nsIObserver* aObserver, const char* aPref); + static nsresult RemoveObserver(nsIObserver* aObserver, const char* aPref); + + /** + * Adds/Removes two or more observers for the root pref branch. + * Pass to aPrefs an array of const char* whose last item is nullptr. + */ + static nsresult AddStrongObservers(nsIObserver* aObserver, + const char** aPrefs); + static nsresult AddWeakObservers(nsIObserver* aObserver, + const char** aPrefs); + static nsresult RemoveObservers(nsIObserver* aObserver, + const char** aPrefs); + + /** + * Registers/Unregisters the callback function for the aPref. + * + * Pass ExactMatch for aMatchKind to only get callbacks for + * exact matches and not prefixes. + */ + enum MatchKind { + PrefixMatch, + ExactMatch, + }; + static nsresult RegisterCallback(PrefChangedFunc aCallback, + const char* aPref, + void* aClosure = nullptr, + MatchKind aMatchKind = PrefixMatch); + static nsresult UnregisterCallback(PrefChangedFunc aCallback, + const char* aPref, + void* aClosure = nullptr, + MatchKind aMatchKind = PrefixMatch); + // Like RegisterCallback, but also calls the callback immediately for + // initialization. + static nsresult RegisterCallbackAndCall(PrefChangedFunc aCallback, + const char* aPref, + void* aClosure = nullptr, + MatchKind aMatchKind = PrefixMatch); + + /** + * Adds the aVariable to cache table. aVariable must be a pointer for a + * static variable. The value will be modified when the pref value is + * changed but note that even if you modified it, the value isn't assigned to + * the pref. + */ + static nsresult AddBoolVarCache(bool* aVariable, + const char* aPref, + bool aDefault = false); + static nsresult AddIntVarCache(int32_t* aVariable, + const char* aPref, + int32_t aDefault = 0); + static nsresult AddUintVarCache(uint32_t* aVariable, + const char* aPref, + uint32_t aDefault = 0); + template + static nsresult AddAtomicUintVarCache(Atomic* aVariable, + const char* aPref, + uint32_t aDefault = 0); + static nsresult AddFloatVarCache(float* aVariable, + const char* aPref, + float aDefault = 0.0f); + + /** + * Gets the default bool, int or uint value of the pref. + * The result is raw result of nsIPrefBranch::Get*Pref(). + * If the pref could have any value, you needed to use these methods. + * If not so, you could use below methods. + */ + static nsresult GetDefaultBool(const char* aPref, bool* aResult); + static nsresult GetDefaultInt(const char* aPref, int32_t* aResult); + static nsresult GetDefaultUint(const char* aPref, uint32_t* aResult) + { + return GetDefaultInt(aPref, reinterpret_cast(aResult)); + } + + /** + * Gets the default bool, int or uint value of the pref directly. + * You can set an invalid value of the pref to aFailedResult. If these + * methods failed to get the default value, they would return the + * aFailedResult value. + */ + static bool GetDefaultBool(const char* aPref, bool aFailedResult) + { + bool result; + return NS_SUCCEEDED(GetDefaultBool(aPref, &result)) ? result : + aFailedResult; + } + static int32_t GetDefaultInt(const char* aPref, int32_t aFailedResult) + { + int32_t result; + return NS_SUCCEEDED(GetDefaultInt(aPref, &result)) ? result : aFailedResult; + } + static uint32_t GetDefaultUint(const char* aPref, uint32_t aFailedResult) + { + return static_cast( + GetDefaultInt(aPref, static_cast(aFailedResult))); + } + + /** + * Gets the default value of the char type pref. + * If the get() of the result returned nullptr, that meant the value didn't + * have default value. + * + * See the comment at definition at GetString() and GetCString() for more + * details of the result. + */ + static nsAdoptingString GetDefaultString(const char* aPref); + static nsAdoptingCString GetDefaultCString(const char* aPref); + static nsAdoptingString GetDefaultLocalizedString(const char* aPref); + static nsAdoptingCString GetDefaultLocalizedCString(const char* aPref); + + static nsresult GetDefaultCString(const char* aPref, nsACString* aResult); + static nsresult GetDefaultString(const char* aPref, nsAString* aResult); + static nsresult GetDefaultLocalizedCString(const char* aPref, + nsACString* aResult); + static nsresult GetDefaultLocalizedString(const char* aPref, + nsAString* aResult); + + static nsresult GetDefaultComplex(const char* aPref, const nsIID &aType, + void** aResult); + + /** + * Gets the type of the pref. + */ + static int32_t GetDefaultType(const char* aPref); + + // Used to synchronise preferences between chrome and content processes. + static void GetPreferences(InfallibleTArray* aPrefs); + static void GetPreference(PrefSetting* aPref); + static void SetPreference(const PrefSetting& aPref); + + static int64_t SizeOfIncludingThisAndOtherStuff(mozilla::MallocSizeOf aMallocSizeOf); + + static void DirtyCallback(); + +protected: + virtual ~Preferences(); + + nsresult NotifyServiceObservers(const char *aSubject); + /** + * Reads the default pref file or, if that failed, try to save a new one. + * + * @return NS_OK if either action succeeded, + * or the error code related to the read attempt. + */ + nsresult UseDefaultPrefFile(); + nsresult UseUserPrefFile(); + nsresult ReadAndOwnUserPrefFile(nsIFile *aFile); + nsresult ReadAndOwnSharedUserPrefFile(nsIFile *aFile); + nsresult SavePrefFileInternal(nsIFile* aFile); + nsresult WritePrefFile(nsIFile* aFile); + nsresult MakeBackupPrefFile(nsIFile *aFile); + +private: + nsCOMPtr mCurrentFile; + bool mDirty; + + static Preferences* sPreferences; + static nsIPrefBranch* sRootBranch; + static nsIPrefBranch* sDefaultRootBranch; + static bool sShutdown; + + /** + * Init static members. TRUE if it succeeded. Otherwise, FALSE. + */ + static bool InitStaticMembers(); +}; + +} // namespace mozilla + +#endif // mozilla_Preferences_h diff --git a/modules/libpref/greprefs.js b/modules/libpref/greprefs.js new file mode 100644 index 000000000..d59110b6a --- /dev/null +++ b/modules/libpref/greprefs.js @@ -0,0 +1,12 @@ +#include ../../netwerk/base/security-prefs.js +#include init/all.js +#ifdef MOZ_DATA_REPORTING +#include ../../toolkit/components/telemetry/datareporting-prefs.js +#endif +#ifdef MOZ_SERVICES_HEALTHREPORT +#if MOZ_WIDGET_TOOLKIT == android +#include ../../mobile/android/chrome/content/healthreport-prefs.js +#else +#include ../../toolkit/components/telemetry/healthreport-prefs.js +#endif +#endif diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js new file mode 100644 index 000000000..1cb9e1921 --- /dev/null +++ b/modules/libpref/init/all.js @@ -0,0 +1,5583 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* The prefs in this file are shipped with the GRE and should apply to all + * embedding situations. Application-specific preferences belong somewhere else, + * for example xpfe/bootstrap/browser-prefs.js + * + * Platform-specific #ifdefs at the end of this file override the generic + * entries at the top. + */ + +/* + * SYNTAX HINTS: + * + * - Dashes are delimiters; use underscores instead. + * - The first character after a period must be alphabetic. + * - Computed values (e.g. 50 * 1024) don't work. + */ + +pref("keyword.enabled", false); +pref("general.useragent.locale", "chrome://global/locale/intl.properties"); +pref("general.useragent.compatMode.firefox", false); + +// This pref exists only for testing purposes. In order to disable all +// overrides by default, don't initialize UserAgentOverrides.jsm. +pref("general.useragent.site_specific_overrides", true); + +pref("general.config.obscure_value", 13); // for MCD .cfg files + +pref("general.warnOnAboutConfig", true); + +// maximum number of dated backups to keep at any time +pref("browser.bookmarks.max_backups", 5); + +// Delete HTTP cache v1 data +pref("browser.cache.auto_delete_cache_version", 0); +// Preference for switching the cache backend, can be changed freely at runtime +// 0 - use the old (Darin's) cache +// 1 - use the new cache back-end (cache v2) +pref("browser.cache.use_new_backend", 0); +pref("browser.cache.use_new_backend_temp", true); + +pref("browser.cache.disk.enable", true); +// Is this the first-time smartsizing has been introduced? +pref("browser.cache.disk.smart_size.first_run", true); +// Does the user want smart-sizing? +pref("browser.cache.disk.smart_size.enabled", true); +// Which max value should we use for smart-sizing? +pref("browser.cache.disk.smart_size.use_old_max", true); +// Size (in KB) explicitly set by the user. Used when smart_size.enabled == false +pref("browser.cache.disk.capacity", 256000); +// When smartsizing is disabled we could potentially fill all disk space by +// cache data when the disk capacity is not set correctly. To avoid that we +// check the free space every time we write some data to the cache. The free +// space is checked against two limits. Once the soft limit is reached we start +// evicting the least useful entries, when we reach the hard limit writing to +// the entry fails. +pref("browser.cache.disk.free_space_soft_limit", 5120); // 5MB +pref("browser.cache.disk.free_space_hard_limit", 1024); // 1MB +// Max-size (in KB) for entries in disk cache. Set to -1 for no limit. +// (Note: entries bigger than 1/8 of disk-cache are never cached) +pref("browser.cache.disk.max_entry_size", 51200); // 50 MB +pref("browser.cache.memory.enable", true); +// -1 = determine dynamically, 0 = none, n = memory capacity in kilobytes +//pref("browser.cache.memory.capacity", -1); +// Max-size (in KB) for entries in memory cache. Set to -1 for no limit. +// (Note: entries bigger than than 90% of the mem-cache are never cached) +pref("browser.cache.memory.max_entry_size", 5120); +// Memory limit (in kB) for new cache data not yet written to disk. Writes to +// the cache are buffered and written to disk on background with low priority. +// With a slow persistent storage these buffers may grow when data is coming +// fast from the network. When the amount of unwritten data is exceeded, new +// writes will simply fail. We have two buckets, one for important data +// (priority) like html, css, fonts and js, and one for other data like images, +// video, etc. +// Note: 0 means no limit. +pref("browser.cache.disk.max_chunks_memory_usage", 10240); +pref("browser.cache.disk.max_priority_chunks_memory_usage", 10240); + +pref("browser.cache.disk_cache_ssl", true); +// 0 = once-per-session, 1 = each-time, 2 = never, 3 = when-appropriate/automatically +pref("browser.cache.check_doc_frequency", 3); +// Limit of recent metadata we keep in memory for faster access, in Kb +pref("browser.cache.disk.metadata_memory_limit", 250); // 0.25 MB +// The number of chunks we preload ahead of read. One chunk has currently 256kB. +pref("browser.cache.disk.preload_chunk_count", 4); // 1 MB of read ahead +// The half life used to re-compute cache entries frecency in hours. +pref("browser.cache.frecency_half_life_hours", 6); + +// Number of seconds the cache spends writting pending data and closing files +// after the shutdown has been signalled. Past that time data are never written +// and files are left open given up to the OS to do the cleanup. +pref("browser.cache.max_shutdown_io_lag", 2); + +pref("browser.cache.offline.enable", true); +// enable offline apps by default, disable prompt +pref("offline-apps.allow_by_default", true); + +// offline cache capacity in kilobytes +pref("browser.cache.offline.capacity", 512000); + +// the user should be warned if offline app disk usage exceeds this amount +// (in kilobytes) +pref("offline-apps.quota.warn", 51200); + +// zlib compression level used for cache compression: +// 0 => disable compression +// 1 => best speed +// 9 => best compression +// cache compression turned off for now - see bug #715198 +pref("browser.cache.compression_level", 0); + +// Don't show "Open with" option on download dialog if true. +pref("browser.download.forbid_open_with", false); + +// Whether or not testing features are enabled. +pref("dom.quotaManager.testing", false); + +// Whether or not indexedDB is enabled. +pref("dom.indexedDB.enabled", true); +// Whether or not indexedDB experimental features are enabled. +pref("dom.indexedDB.experimental", false); +// Enable indexedDB logging. +pref("dom.indexedDB.logging.enabled", true); +// Detailed output in log messages. +pref("dom.indexedDB.logging.details", true); +// Enable profiler marks for indexedDB events. +pref("dom.indexedDB.logging.profiler-marks", false); + +// Whether or not File Handle is enabled. +pref("dom.fileHandle.enabled", true); + +// Whether window.onappinstalled from "W3C Web Manifest" is enabled +pref("dom.manifest.onappinstalled", false); + +// Whether or not selection events are enabled +pref("dom.select_events.enabled", true); + +// Whether or not selection events on text controls are enabled +#ifdef NIGHTLY_BUILD +pref("dom.select_events.textcontrols.enabled", true); +#else +pref("dom.select_events.textcontrols.enabled", false); +#endif + +// Whether or not Web Workers are enabled. +pref("dom.workers.enabled", true); + +// The number of workers per domain allowed to run concurrently. +// We're going for effectively infinite, while preventing abuse. +pref("dom.workers.maxPerDomain", 512); + +pref("dom.serviceWorkers.enabled", false); + +// The amount of time (milliseconds) service workers keep running after each event. +pref("dom.serviceWorkers.idle_timeout", 30000); + +// The amount of time (milliseconds) service workers can be kept running using waitUntil promises. +pref("dom.serviceWorkers.idle_extended_timeout", 300000); + +// Enable test for 24 hours update, service workers will always treat last update check time is over 24 hours +pref("dom.serviceWorkers.testUpdateOverOneDay", false); + +// Whether nonzero values can be returned from performance.timing.* +pref("dom.enable_performance", true); + +// Whether resource timing will be gathered and returned by performance.GetEntries* +pref("dom.enable_resource_timing", true); + +// Enable high-resolution timing markers for users +pref("dom.enable_user_timing", true); + +// Enable printing performance marks/measures to log +pref("dom.performance.enable_user_timing_logging", false); + +// Enable notification of performance timing +pref("dom.performance.enable_notify_performance_timing", false); + +// Enable Permission API's .revoke() method +pref("dom.permissions.revoke.enable", false); + +// Enable Performance Observer API +#ifdef NIGHTLY_BUILD +pref("dom.enable_performance_observer", true); +#else +pref("dom.enable_performance_observer", false); +#endif + +// Enable requestIdleCallback API +#ifdef NIGHTLY_BUILD +pref("dom.requestIdleCallback.enabled", true); +#else +pref("dom.requestIdleCallback.enabled", false); +#endif + +// Whether the Gamepad API is enabled +pref("dom.gamepad.enabled", true); +pref("dom.gamepad.test.enabled", false); +#ifdef RELEASE_OR_BETA +pref("dom.gamepad.non_standard_events.enabled", false); +#else +pref("dom.gamepad.non_standard_events.enabled", true); +#endif +pref("dom.gamepad.extensions.enabled", false); + +// Whether the KeyboardEvent.code is enabled +pref("dom.keyboardevent.code.enabled", true); + +// If this is true, TextEventDispatcher dispatches keydown and keyup events +// even during composition (keypress events are never fired during composition +// even if this is true). +pref("dom.keyboardevent.dispatch_during_composition", false); + +// Whether URL,Location,Link::GetHash should be percent encoded +// in setter and percent decoded in getter (old behaviour = true) +pref("dom.url.encode_decode_hash", true); +// Whether ::GetHash should do percent decoding (old behaviour = true) +pref("dom.url.getters_decode_hash", false); + +// Whether to run add-on code in different compartments from browser code. This +// causes a separate compartment for each (addon, global) combination, which may +// significantly increase the number of compartments in the system. +pref("dom.compartment_per_addon", true); + +// Fastback caching - if this pref is negative, then we calculate the number +// of content viewers to cache based on the amount of available memory. +pref("browser.sessionhistory.max_total_viewers", -1); + +pref("ui.use_native_colors", true); +pref("ui.click_hold_context_menus", false); +// Duration of timeout of incremental search in menus (ms). 0 means infinite. +pref("ui.menu.incremental_search.timeout", 1000); +// If true, all popups won't hide automatically on blur +pref("ui.popup.disable_autohide", false); + +pref("browser.display.use_document_fonts", 1); // 0 = never, 1 = quick, 2 = always +// 0 = default: always, except in high contrast mode +// 1 = always +// 2 = never +pref("browser.display.document_color_use", 0); +pref("browser.display.use_system_colors", false); +pref("browser.display.foreground_color", "#000000"); +pref("browser.display.background_color", "#FFFFFF"); +pref("browser.display.force_inline_alttext", false); // true = force ALT text for missing images to be layed out inline +// 0 = no external leading, +// 1 = use external leading only when font provides, +// 2 = add extra leading both internal leading and external leading are zero +pref("browser.display.normal_lineheight_calc_control", 2); +// enable showing image placeholders while image is loading or when image is broken +pref("browser.display.show_image_placeholders", true); +// if browser.display.show_image_placeholders is true then this controls whether the loading image placeholder and border is shown or not +pref("browser.display.show_loading_image_placeholder", false); +// min font device pixel size at which to turn on high quality +pref("browser.display.auto_quality_min_font_size", 20); +pref("browser.anchor_color", "#0000EE"); +pref("browser.active_color", "#EE0000"); +pref("browser.visited_color", "#551A8B"); +pref("browser.underline_anchors", true); +pref("browser.enable_automatic_image_resizing", false); +pref("browser.enable_click_image_resizing", true); + +// See http://dev.w3.org/html5/spec/forms.html#attr-fe-autofocus +pref("browser.autofocus", true); + +// See http://whatwg.org/specs/web-apps/current-work/#ping +pref("browser.send_pings", false); +pref("browser.send_pings.max_per_link", 1); // limit the number of pings that are sent per link click +pref("browser.send_pings.require_same_host", false); // only send pings to the same host if this is true + +pref("browser.display.use_focus_colors", false); +pref("browser.display.focus_background_color", "#117722"); +pref("browser.display.focus_text_color", "#ffffff"); +pref("browser.display.focus_ring_width", 1); +pref("browser.display.focus_ring_on_anything", false); +// focus ring border style. +// 0 = solid border, 1 = dotted border +pref("browser.display.focus_ring_style", 1); + +pref("browser.helperApps.alwaysAsk.force", false); +pref("browser.helperApps.neverAsk.saveToDisk", ""); +pref("browser.helperApps.neverAsk.openFile", ""); +pref("browser.helperApps.deleteTempFileOnExit", false); + +// xxxbsmedberg: where should prefs for the toolkit go? +pref("browser.chrome.toolbar_tips", true); +// 0 = Pictures Only, 1 = Text Only, 2 = Pictures and Text +pref("browser.chrome.toolbar_style", 2); +// max image size for which it is placed in the tab icon for tabbrowser. +// if 0, no images are used for tab icons for image documents. +pref("browser.chrome.image_icons.max_size", 1024); + +pref("browser.triple_click_selects_paragraph", true); + +// Print/Preview Shrink-To-Fit won't shrink below 20% for text-ish documents. +pref("print.shrink-to-fit.scale-limit-percent", 20); + +// Whether we should display simplify page checkbox on print preview UI +pref("print.use_simplify_page", false); + +// Disable support for MathML +pref("mathml.disabled", false); + +// Enable scale transform for stretchy MathML operators. See bug 414277. +pref("mathml.scale_stretchy_operators.enabled", true); + +// Enabled on nightly only until we fix mochitest failures. +#ifdef NIGHTLY_BUILD +pref("media.dormant-on-pause-timeout-ms", 5000); +#else +pref("media.dormant-on-pause-timeout-ms", -1); +#endif + +// Media cache size in kilobytes +pref("media.cache_size", 512000); +// When a network connection is suspended, don't resume it until the +// amount of buffered data falls below this threshold (in seconds). +pref("media.cache_resume_threshold", 999999); +// Stop reading ahead when our buffered data is this many seconds ahead +// of the current playback position. This limit can stop us from using arbitrary +// amounts of network bandwidth prefetching huge videos. +pref("media.cache_readahead_limit", 999999); + +// Master HTML5 media volume scale. +pref("media.volume_scale", "1.0"); + +// Timeout for wakelock release +pref("media.wakelock_timeout", 2000); + +// Whether we should play videos opened in a "video document", i.e. videos +// opened as top-level documents, as opposed to inside a media element. +pref("media.play-stand-alone", true); + +pref("media.hardware-video-decoding.enabled", true); +pref("media.hardware-video-decoding.force-enabled", false); + +#ifdef MOZ_DIRECTSHOW +pref("media.directshow.enabled", true); +#endif +#ifdef MOZ_FMP4 +pref("media.mp4.enabled", true); +// Specifies whether the PDMFactory can create a test decoder that +#endif +// just outputs blank frames/audio instead of actually decoding. The blank +// decoder works on all platforms. +pref("media.use-blank-decoder", false); +#ifdef MOZ_WMF +pref("media.wmf.enabled", true); +pref("media.wmf.decoder.thread-count", -1); +pref("media.wmf.low-latency.enabled", false); +pref("media.wmf.skip-blacklist", false); +#ifdef NIGHTLY_BUILD +pref("media.wmf.vp9.enabled", true); +#else +pref("media.wmf.vp9.enabled", false); +#endif +pref("media.windows-media-foundation.allow-d3d11-dxva", true); +pref("media.wmf.disable-d3d11-for-dlls", "igd11dxva64.dll: 20.19.15.4463, 20.19.15.4454, 20.19.15.4444, 20.19.15.4416, 20.19.15.4404, 20.19.15.4390, 20.19.15.4380, 20.19.15.4377, 20.19.15.4364, 20.19.15.4360, 20.19.15.4352, 20.19.15.4331, 20.19.15.4326, 20.19.15.4300; igd10iumd32.dll: 20.19.15.4444, 20.19.15.4424, 20.19.15.4409, 20.19.15.4390, 20.19.15.4380, 20.19.15.4360, 10.18.10.4358, 20.19.15.4331, 20.19.15.4312, 20.19.15.4300, 10.18.15.4281, 10.18.15.4279, 10.18.10.4276, 10.18.15.4268, 10.18.15.4256, 10.18.10.4252, 10.18.15.4248, 10.18.14.4112, 10.18.10.3958, 10.18.10.3496, 10.18.10.3431, 10.18.10.3412, 10.18.10.3355, 9.18.10.3234, 9.18.10.3071, 9.18.10.3055, 9.18.10.3006; igd10umd32.dll: 9.17.10.4229, 9.17.10.3040, 9.17.10.2857, 8.15.10.2274, 8.15.10.2272, 8.15.10.2246, 8.15.10.1840, 8.15.10.1808; igd10umd64.dll: 9.17.10.4229, 9.17.10.2857, 10.18.10.3496; isonyvideoprocessor.dll: 4.1.2247.8090, 4.1.2153.6200; tosqep.dll: 1.2.15.526, 1.1.12.201, 1.0.11.318, 1.0.11.215, 1.0.10.1224; tosqep64.dll: 1.1.12.201, 1.0.11.215; nvwgf2um.dll: 22.21.13.8253, 22.21.13.8233, 22.21.13.8205, 22.21.13.8189, 22.21.13.8178, 22.21.13.8165, 21.21.13.7892, 21.21.13.7878, 21.21.13.7866, 21.21.13.7849, 21.21.13.7654, 21.21.13.7653, 21.21.13.7633, 21.21.13.7619, 21.21.13.7563, 21.21.13.7306, 21.21.13.7290, 21.21.13.7270, 21.21.13.7254, 21.21.13.6939, 21.21.13.6926, 21.21.13.6909, 21.21.13.4201, 21.21.13.4200, 10.18.13.6881, 10.18.13.6839, 10.18.13.6510, 10.18.13.6472, 10.18.13.6143, 10.18.13.5946, 10.18.13.5923, 10.18.13.5921, 10.18.13.5891, 10.18.13.5887, 10.18.13.5582, 10.18.13.5445, 10.18.13.5382, 10.18.13.5362, 9.18.13.4788, 9.18.13.4752, 9.18.13.4725, 9.18.13.4709, 9.18.13.4195, 9.18.13.4192, 9.18.13.4144, 9.18.13.4052, 9.18.13.3788, 9.18.13.3523, 9.18.13.3235, 9.18.13.3165, 9.18.13.2723, 9.18.13.2702, 9.18.13.1422, 9.18.13.1407, 9.18.13.1106, 9.18.13.546; atidxx32.dll: 21.19.151.3, 21.19.142.257, 21.19.137.514, 21.19.137.1, 21.19.134.1, 21.19.128.7, 21.19.128.4, 20.19.0.32837, 20.19.0.32832, 8.17.10.682, 8.17.10.671, 8.17.10.661, 8.17.10.648, 8.17.10.644, 8.17.10.625, 8.17.10.605, 8.17.10.581, 8.17.10.569, 8.17.10.560, 8.17.10.545, 8.17.10.539, 8.17.10.531, 8.17.10.525, 8.17.10.520, 8.17.10.519, 8.17.10.514, 8.17.10.511, 8.17.10.494, 8.17.10.489, 8.17.10.483, 8.17.10.453, 8.17.10.451, 8.17.10.441, 8.17.10.436, 8.17.10.432, 8.17.10.425, 8.17.10.418, 8.17.10.414, 8.17.10.401, 8.17.10.395, 8.17.10.385, 8.17.10.378, 8.17.10.362, 8.17.10.355, 8.17.10.342, 8.17.10.331, 8.17.10.318, 8.17.10.310, 8.17.10.286, 8.17.10.269, 8.17.10.261, 8.17.10.247, 8.17.10.240, 8.15.10.212; atidxx64.dll: 21.19.151.3, 21.19.142.257, 21.19.137.514, 21.19.137.1, 21.19.134.1, 21.19.128.7, 21.19.128.4, 20.19.0.32832, 8.17.10.682, 8.17.10.661, 8.17.10.644, 8.17.10.625; nvumdshim.dll: 10.18.13.6822"); +pref("media.wmf.disable-d3d9-for-dlls", "igdumd64.dll: 8.15.10.2189, 8.15.10.2119, 8.15.10.2104, 8.15.10.2102, 8.771.1.0; atiumd64.dll: 7.14.10.833, 7.14.10.867, 7.14.10.885, 7.14.10.903, 7.14.10.911, 8.14.10.768, 9.14.10.1001, 9.14.10.1017, 9.14.10.1080, 9.14.10.1128, 9.14.10.1162, 9.14.10.1171, 9.14.10.1183, 9.14.10.1197, 9.14.10.945, 9.14.10.972, 9.14.10.984, 9.14.10.996"); +#endif +#if defined(MOZ_FFMPEG) +#if defined(XP_MACOSX) +pref("media.ffmpeg.enabled", false); +#else +pref("media.ffmpeg.enabled", true); +#endif +pref("media.libavcodec.allow-obsolete", false); +#endif +#if defined(MOZ_FFVPX) +pref("media.ffvpx.enabled", true); +#endif +pref("media.gmp.decoder.enabled", false); +pref("media.gmp.decoder.aac", 0); +pref("media.gmp.decoder.h264", 0); +#ifdef MOZ_RAW +pref("media.raw.enabled", true); +#endif +pref("media.ogg.enabled", true); +pref("media.opus.enabled", true); +pref("media.wave.enabled", true); +pref("media.webm.enabled", true); + +#ifdef MOZ_APPLEMEDIA +#ifdef MOZ_WIDGET_UIKIT +pref("media.mp3.enabled", true); +#endif +pref("media.apple.mp3.enabled", true); +pref("media.apple.mp4.enabled", true); +#endif + +// GMP storage version number. At startup we check the version against +// media.gmp.storage.version.observed, and if the versions don't match, +// we clear storage and set media.gmp.storage.version.observed=expected. +// This provides a mechanism to clear GMP storage when non-compatible +// changes are made. +pref("media.gmp.storage.version.expected", 1); + +// Filter what triggers user notifications. +// See DecoderDoctorDocumentWatcher::ReportAnalysis for details. +pref("media.decoder-doctor.notifications-allowed", "MediaWMFNeeded,MediaWidevineNoWMFNoSilverlight,MediaCannotInitializePulseAudio,MediaCannotPlayNoDecoders,MediaUnsupportedLibavcodec"); +// Whether we report partial failures. +pref("media.decoder-doctor.verbose", false); +// Whether DD should consider WMF-disabled a WMF failure, useful for testing. +pref("media.decoder-doctor.wmf-disabled-is-failure", false); + +// Whether to suspend decoding of videos in background tabs. +#ifdef NIGHTLY_BUILD +pref("media.suspend-bkgnd-video.enabled", true); +#else +pref("media.suspend-bkgnd-video.enabled", false); +#endif +// Delay, in ms, from time window goes to background to suspending +// video decoders. Defaults to 10 seconds. +pref("media.suspend-bkgnd-video.delay-ms", 10000); + +#ifdef MOZ_WEBRTC +pref("media.navigator.enabled", true); +pref("media.navigator.video.enabled", true); +pref("media.navigator.load_adapt", true); +pref("media.navigator.load_adapt.encoder_only", true); +pref("media.navigator.load_adapt.measure_interval",1000); +pref("media.navigator.load_adapt.avg_seconds",3); +pref("media.navigator.load_adapt.high_load","0.90"); +pref("media.navigator.load_adapt.low_load","0.40"); +pref("media.navigator.video.default_fps",30); +pref("media.navigator.video.default_minfps",10); +pref("media.navigator.video.use_remb", true); +pref("media.navigator.video.use_tmmbr", false); +pref("media.navigator.audio.use_fec", true); +pref("media.navigator.video.red_ulpfec_enabled", false); + +pref("media.peerconnection.dtmf.enabled", true); + +pref("media.webrtc.debug.trace_mask", 0); +pref("media.webrtc.debug.multi_log", false); +pref("media.webrtc.debug.aec_log_dir", ""); +pref("media.webrtc.debug.log_file", ""); +pref("media.webrtc.debug.aec_dump_max_size", 4194304); // 4MB + +#ifdef MOZ_WIDGET_GONK +pref("media.navigator.video.default_width", 320); +pref("media.navigator.video.default_height", 240); +pref("media.peerconnection.enabled", true); +pref("media.peerconnection.video.enabled", true); +pref("media.navigator.video.max_fs", 1200); // 640x480 == 1200mb +pref("media.navigator.video.max_fr", 30); +pref("media.navigator.video.h264.level", 12); // 0x42E00C - level 1.2 +pref("media.navigator.video.h264.max_br", 700); // 8x10 +pref("media.navigator.video.h264.max_mbps", 11880); // CIF@30fps +pref("media.peerconnection.video.h264_enabled", false); +pref("media.peerconnection.video.vp9_enabled", false); +pref("media.getusermedia.aec", 4); +#else +pref("media.navigator.video.default_width",0); // adaptive default +pref("media.navigator.video.default_height",0); // adaptive default +pref("media.peerconnection.enabled", true); +pref("media.peerconnection.video.enabled", true); +pref("media.navigator.video.max_fs", 12288); // Enough for 2048x1536 +pref("media.navigator.video.max_fr", 60); +pref("media.navigator.video.h264.level", 31); // 0x42E01f - level 3.1 +pref("media.navigator.video.h264.max_br", 0); +pref("media.navigator.video.h264.max_mbps", 0); +pref("media.peerconnection.video.h264_enabled", false); +pref("media.peerconnection.video.vp9_enabled", true); +pref("media.getusermedia.aec", 1); +pref("media.getusermedia.browser.enabled", true); +#endif +// Gonk typically captures at QVGA, and so min resolution is QQVGA or +// 160x120; 100Kbps is plenty for that. +// Desktop is typically VGA capture or more; and qm_select will not drop resolution +// below 1/2 in each dimension (or so), so QVGA (320x200) is the lowest here usually. +pref("media.peerconnection.video.min_bitrate", 0); +pref("media.peerconnection.video.start_bitrate", 0); +pref("media.peerconnection.video.max_bitrate", 0); +pref("media.peerconnection.video.min_bitrate_estimate", 0); +pref("media.navigator.audio.fake_frequency", 1000); +pref("media.navigator.permission.disabled", false); +pref("media.peerconnection.simulcast", true); +pref("media.peerconnection.default_iceservers", "[]"); +pref("media.peerconnection.ice.loopback", false); // Set only for testing in offline environments. +pref("media.peerconnection.ice.tcp", false); +pref("media.peerconnection.ice.tcp_so_sock_count", 0); // Disable SO gathering +pref("media.peerconnection.ice.link_local", false); // Set only for testing IPV6 in networks that don't assign IPV6 addresses +pref("media.peerconnection.ice.force_interface", ""); // Limit to only a single interface +pref("media.peerconnection.ice.relay_only", false); // Limit candidates to TURN +pref("media.peerconnection.use_document_iceservers", true); +pref("media.peerconnection.identity.enabled", true); +pref("media.peerconnection.identity.timeout", 10000); +pref("media.peerconnection.ice.stun_client_maximum_transmits", 7); +pref("media.peerconnection.ice.trickle_grace_period", 5000); +pref("media.peerconnection.ice.no_host", false); +pref("media.peerconnection.ice.default_address_only", false); +pref("media.peerconnection.ice.proxy_only", false); + +// These values (aec, agc, and noice) are from media/webrtc/trunk/webrtc/common_types.h +// kXxxUnchanged = 0, kXxxDefault = 1, and higher values are specific to each +// setting (for Xxx = Ec, Agc, or Ns). Defaults are all set to kXxxDefault here. +pref("media.peerconnection.turn.disable", false); +#if defined(MOZ_WEBRTC_HARDWARE_AEC_NS) +pref("media.getusermedia.aec_enabled", false); +pref("media.getusermedia.noise_enabled", false); +#else +pref("media.getusermedia.aec_enabled", true); +pref("media.getusermedia.noise_enabled", true); +#endif +pref("media.getusermedia.aec_extended_filter", true); +pref("media.getusermedia.aec_delay_agnostic", true); +pref("media.getusermedia.noise", 1); +pref("media.getusermedia.agc_enabled", false); +pref("media.getusermedia.agc", 1); +// capture_delay: Adjustments for OS-specific input delay (lower bound) +// playout_delay: Adjustments for OS-specific AudioStream+cubeb+output delay (lower bound) +// full_duplex: enable cubeb full-duplex capture/playback +#if defined(XP_MACOSX) +pref("media.peerconnection.capture_delay", 50); +pref("media.getusermedia.playout_delay", 10); +pref("media.navigator.audio.full_duplex", false); +#elif defined(XP_WIN) +pref("media.peerconnection.capture_delay", 50); +pref("media.getusermedia.playout_delay", 40); +pref("media.navigator.audio.full_duplex", false); +#elif defined(ANDROID) +pref("media.peerconnection.capture_delay", 100); +pref("media.getusermedia.playout_delay", 100); +pref("media.navigator.audio.full_duplex", false); +// Whether to enable Webrtc Hardware acceleration support +pref("media.navigator.hardware.vp8_encode.acceleration_enabled", false); +pref("media.navigator.hardware.vp8_decode.acceleration_enabled", false); +#elif defined(XP_LINUX) +pref("media.peerconnection.capture_delay", 70); +pref("media.getusermedia.playout_delay", 50); +pref("media.navigator.audio.full_duplex", true); +#else +// *BSD, others - merely a guess for now +pref("media.peerconnection.capture_delay", 50); +pref("media.getusermedia.playout_delay", 50); +pref("media.navigator.audio.full_duplex", false); +#endif +#endif + +pref("dom.webaudio.enabled", true); + +#if !defined(ANDROID) +pref("media.getusermedia.screensharing.enabled", true); +#endif + +#ifdef RELEASE_OR_BETA +pref("media.getusermedia.screensharing.allowed_domains", "webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org,*.circuit.com,*.yourcircuit.com,circuit.siemens.com,yourcircuit.siemens.com,circuitsandbox.net,*.unify.com,tandi.circuitsandbox.net,*.ericsson.net,*.cct.ericsson.net,*.opentok.com,*.conf.meetecho.com,meet.jit.si,*.meet.jit.si,web.stage.speakeasyapp.net,web.speakeasyapp.net,*.hipchat.me,*.beta-wspbx.com,*.wspbx.com,*.unifiedcloudit.com,*.smartboxuc.com,*.smartbox-uc.com,*.panterranetworks.com,pexipdemo.com,*.pexipdemo.com,pex.me,*.pex.me,*.rd.pexip.com,1click.io,*.1click.io,*.fuze.com,*.fuzemeeting.com,*.thinkingphones.com,gotomeeting.com,*.gotomeeting.com,gotowebinar.com,*.gotowebinar.com,gototraining.com,*.gototraining.com,citrix.com,*.citrix.com,expertcity.com,*.expertcity.com,citrixonline.com,*.citrixonline.com,g2m.me,*.g2m.me,gotomeet.me,*.gotomeet.me,gotomeet.at,*.gotomeet.at,miriadaxdes.miriadax.net,certificacion.miriadax.net,miriadax.net,*.wire.com,sylaps.com,*.sylaps.com,bluejeans.com,*.bluejeans.com,*.a.bluejeans.com,*.bbcollab.com"); +#else + // includes Mozilla's test domain: mozilla.github.io (not intended for release) +pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io,webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org,*.circuit.com,*.yourcircuit.com,circuit.siemens.com,yourcircuit.siemens.com,circuitsandbox.net,*.unify.com,tandi.circuitsandbox.net,*.ericsson.net,*.cct.ericsson.net,*.opentok.com,*.conf.meetecho.com,meet.jit.si,*.meet.jit.si,web.stage.speakeasyapp.net,web.speakeasyapp.net,*.hipchat.me,*.beta-wspbx.com,*.wspbx.com,*.unifiedcloudit.com,*.smartboxuc.com,*.smartbox-uc.com,*.panterranetworks.com,pexipdemo.com,*.pexipdemo.com,pex.me,*.pex.me,*.rd.pexip.com,1click.io,*.1click.io,*.fuze.com,*.fuzemeeting.com,*.thinkingphones.com,gotomeeting.com,*.gotomeeting.com,gotowebinar.com,*.gotowebinar.com,gototraining.com,*.gototraining.com,citrix.com,*.citrix.com,expertcity.com,*.expertcity.com,citrixonline.com,*.citrixonline.com,g2m.me,*.g2m.me,gotomeet.me,*.gotomeet.me,gotomeet.at,*.gotomeet.at,miriadaxdes.miriadax.net,certificacion.miriadax.net,miriadax.net,*.wire.com,sylaps.com,*.sylaps.com,bluejeans.com,*.bluejeans.com,*.a.bluejeans.com,*.bbcollab.com"); +#endif +// OS/X 10.6 and XP have screen/window sharing off by default due to various issues - Caveat emptor +pref("media.getusermedia.screensharing.allow_on_old_platforms", false); + +pref("media.getusermedia.audiocapture.enabled", false); + +// TextTrack WebVTT Region extension support. +pref("media.webvtt.regions.enabled", false); + +// AudioTrack and VideoTrack support +pref("media.track.enabled", false); + +// Whether to enable MediaSource support. +pref("media.mediasource.enabled", true); + +pref("media.mediasource.mp4.enabled", true); + +#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID) +pref("media.mediasource.webm.enabled", false); +#else +pref("media.mediasource.webm.enabled", true); +#endif +pref("media.mediasource.webm.audio.enabled", true); + +// Use new MediaFormatReader architecture for plain ogg. +pref("media.flac.enabled", true); +pref("media.ogg.flac.enabled", true); + +pref("media.benchmark.vp9.threshold", 150); +pref("media.benchmark.frames", 300); +pref("media.benchmark.timeout", 1000); + +#ifdef MOZ_WEBSPEECH +pref("media.webspeech.recognition.enable", false); +pref("media.webspeech.synth.enabled", false); +#endif +#ifdef MOZ_WEBM_ENCODER +pref("media.encoder.webm.enabled", true); +#endif + +// Whether to autostart a media element with an |autoplay| attribute +pref("media.autoplay.enabled", true); + +// The default number of decoded video frames that are enqueued in +// MediaDecoderReader's mVideoQueue. +pref("media.video-queue.default-size", 10); + +// The maximum number of queued frames to send to the compositor. +// By default, send all of them. +pref("media.video-queue.send-to-compositor-size", 9999); + +// Whether to disable the video stats to prevent fingerprinting +pref("media.video_stats.enabled", true); + +// Weather we allow AMD switchable graphics +pref("layers.amd-switchable-gfx.enabled", true); + +// Whether to use async panning and zooming +pref("layers.async-pan-zoom.enabled", true); + +// Whether to enable event region building during painting +pref("layout.event-regions.enabled", false); + +// APZ preferences. For documentation/details on what these prefs do, check +// gfx/layers/apz/src/AsyncPanZoomController.cpp. +pref("apz.allow_checkerboarding", true); +pref("apz.allow_immediate_handoff", true); +pref("apz.allow_zooming", false); + +// Whether to lock touch scrolling to one axis at a time +// 0 = FREE (No locking at all) +// 1 = STANDARD (Once locked, remain locked until scrolling ends) +// 2 = STICKY (Allow lock to be broken, with hysteresis) +pref("apz.axis_lock.mode", 0); +pref("apz.axis_lock.lock_angle", "0.5235987"); // PI / 6 (30 degrees) +pref("apz.axis_lock.breakout_threshold", "0.03125"); // 1/32 inches +pref("apz.axis_lock.breakout_angle", "0.3926991"); // PI / 8 (22.5 degrees) +pref("apz.axis_lock.direct_pan_angle", "1.047197"); // PI / 3 (60 degrees) +pref("apz.content_response_timeout", 400); +pref("apz.drag.enabled", false); +pref("apz.danger_zone_x", 50); +pref("apz.danger_zone_y", 100); +pref("apz.disable_for_scroll_linked_effects", false); +pref("apz.displayport_expiry_ms", 15000); +pref("apz.enlarge_displayport_when_clipped", false); +pref("apz.fling_accel_base_mult", "1.0"); +pref("apz.fling_accel_interval_ms", 500); +pref("apz.fling_accel_min_velocity", "1.5"); +pref("apz.fling_accel_supplemental_mult", "1.0"); +pref("apz.fling_curve_function_x1", "0.0"); +pref("apz.fling_curve_function_y1", "0.0"); +pref("apz.fling_curve_function_x2", "1.0"); +pref("apz.fling_curve_function_y2", "1.0"); +pref("apz.fling_curve_threshold_inches_per_ms", "-1.0"); +pref("apz.fling_friction", "0.002"); +pref("apz.fling_min_velocity_threshold", "0.5"); +pref("apz.fling_stop_on_tap_threshold", "0.05"); +pref("apz.fling_stopped_threshold", "0.01"); +pref("apz.highlight_checkerboarded_areas", false); +pref("apz.max_velocity_inches_per_ms", "-1.0"); +pref("apz.max_velocity_queue_size", 5); +pref("apz.min_skate_speed", "1.0"); +pref("apz.minimap.enabled", false); +pref("apz.minimap.visibility.enabled", false); +pref("apz.overscroll.enabled", false); +pref("apz.overscroll.min_pan_distance_ratio", "1.0"); +pref("apz.overscroll.spring_friction", "0.015"); +pref("apz.overscroll.spring_stiffness", "0.0018"); +pref("apz.overscroll.stop_distance_threshold", "5.0"); +pref("apz.overscroll.stop_velocity_threshold", "0.01"); +pref("apz.overscroll.stretch_factor", "0.35"); +pref("apz.paint_skipping.enabled", true); +// Fetch displayport updates early from the message queue +pref("apz.peek_messages.enabled", true); + +// Whether to print the APZC tree for debugging +pref("apz.printtree", false); + +#ifdef NIGHTLY_BUILD +pref("apz.record_checkerboarding", true); +#else +pref("apz.record_checkerboarding", false); +#endif +pref("apz.test.logging_enabled", false); +pref("apz.touch_start_tolerance", "0.1"); +pref("apz.touch_move_tolerance", "0.03"); +pref("apz.velocity_bias", "0.0"); +pref("apz.velocity_relevance_time_ms", 150); +pref("apz.x_skate_highmem_adjust", "0.0"); +pref("apz.y_skate_highmem_adjust", "0.0"); +pref("apz.x_skate_size_multiplier", "1.25"); +pref("apz.y_skate_size_multiplier", "3.5"); +pref("apz.x_stationary_size_multiplier", "1.5"); +pref("apz.y_stationary_size_multiplier", "3.5"); +pref("apz.zoom_animation_duration_ms", 250); +pref("apz.scale_repaint_delay_ms", 500); + +#if defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID) +// Mobile prefs +pref("apz.allow_zooming", true); +pref("apz.enlarge_displayport_when_clipped", true); +pref("apz.y_skate_size_multiplier", "1.5"); +pref("apz.y_stationary_size_multiplier", "1.5"); +#endif + +#ifdef XP_MACOSX +// Whether to run in native HiDPI mode on machines with "Retina"/HiDPI display; +// <= 0 : hidpi mode disabled, display will just use pixel-based upscaling +// == 1 : hidpi supported if all screens share the same backingScaleFactor +// >= 2 : hidpi supported even with mixed backingScaleFactors (somewhat broken) +pref("gfx.hidpi.enabled", 2); +#endif + +#if !defined(MOZ_WIDGET_GONK) && !defined(MOZ_WIDGET_ANDROID) +// Use containerless scrolling for now on desktop. +pref("layout.scroll.root-frame-containers", false); +#endif + +// Whether to enable LayerScope tool and default listening port +pref("gfx.layerscope.enabled", false); +pref("gfx.layerscope.port", 23456); + +// Log severe performance warnings to the error console and profiles. +// This should be use to quickly find which slow paths are used by test cases. +pref("gfx.perf-warnings.enabled", false); + +// 0 = Off, 1 = Full, 2 = Tagged Images Only. +// See eCMSMode in gfx/thebes/gfxPlatform.h +pref("gfx.color_management.mode", 2); +pref("gfx.color_management.display_profile", ""); +pref("gfx.color_management.rendering_intent", 0); +pref("gfx.color_management.enablev4", false); + +pref("gfx.downloadable_fonts.enabled", true); +pref("gfx.downloadable_fonts.fallback_delay", 3000); +pref("gfx.downloadable_fonts.fallback_delay_short", 100); + +// disable downloadable font cache so that behavior is consistently +// the uncached load behavior across pages (useful for testing reflow problems) +pref("gfx.downloadable_fonts.disable_cache", false); + +pref("gfx.downloadable_fonts.woff2.enabled", true); + +#ifdef ANDROID +pref("gfx.bundled_fonts.enabled", true); +pref("gfx.bundled_fonts.force-enabled", false); +#endif + +// Do we fire a notification about missing fonts, so the front-end can decide +// whether to try and do something about it (e.g. download additional fonts)? +pref("gfx.missing_fonts.notify", false); + +// prefs controlling the font (name/cmap) loader that runs shortly after startup +pref("gfx.font_loader.families_per_slice", 3); // read in info 3 families at a time +#ifdef XP_WIN +pref("gfx.font_loader.delay", 120000); // 2 minutes after startup +pref("gfx.font_loader.interval", 1000); // every 1 second until complete +#else +pref("gfx.font_loader.delay", 8000); // 8 secs after startup +pref("gfx.font_loader.interval", 50); // run every 50 ms +#endif + +// whether to always search all font cmaps during system font fallback +pref("gfx.font_rendering.fallback.always_use_cmaps", false); + +// cache shaped word results +pref("gfx.font_rendering.wordcache.charlimit", 32); + +// cache shaped word results +pref("gfx.font_rendering.wordcache.maxentries", 10000); + +pref("gfx.font_rendering.graphite.enabled", true); + +#ifdef XP_WIN +pref("gfx.font_rendering.directwrite.force-enabled", false); +pref("gfx.font_rendering.directwrite.use_gdi_table_loading", true); +#endif + +pref("gfx.font_rendering.opentype_svg.enabled", true); + +#ifdef XP_WIN +// comma separated list of backends to use in order of preference +// e.g., pref("gfx.canvas.azure.backends", "direct2d,skia,cairo"); +pref("gfx.canvas.azure.backends", "direct2d1.1,skia,cairo"); +pref("gfx.content.azure.backends", "direct2d1.1,skia,cairo"); +#else +#ifdef XP_MACOSX +pref("gfx.content.azure.backends", "skia"); +pref("gfx.canvas.azure.backends", "skia"); +// Accelerated cg canvas where available (10.7+) +pref("gfx.canvas.azure.accelerated", true); +#else +pref("gfx.canvas.azure.backends", "skia"); +pref("gfx.content.azure.backends", "skia"); +#endif +#endif + +pref("gfx.canvas.skiagl.dynamic-cache", true); + +pref("gfx.text.disable-aa", false); + +pref("gfx.work-around-driver-bugs", true); +pref("gfx.prefer-mesa-llvmpipe", false); + +pref("gfx.draw-color-bars", false); + +pref("gfx.logging.painted-pixel-count.enabled", false); +pref("gfx.logging.texture-usage.enabled", false); +pref("gfx.logging.peak-texture-usage.enabled", false); + +pref("gfx.ycbcr.accurate-conversion", false); + +pref("accessibility.browsewithcaret", false); +pref("accessibility.warn_on_browsewithcaret", true); + +pref("accessibility.browsewithcaret_shortcut.enabled", true); + +#ifndef XP_MACOSX +// Tab focus model bit field: +// 1 focuses text controls, 2 focuses other form elements, 4 adds links. +// Most users will want 1, 3, or 7. +// On OS X, we use Full Keyboard Access system preference, +// unless accessibility.tabfocus is set by the user. +pref("accessibility.tabfocus", 7); +pref("accessibility.tabfocus_applies_to_xul", false); +#else +// Only on mac tabfocus is expected to handle UI widgets as well as web content +pref("accessibility.tabfocus_applies_to_xul", true); +#endif + +// We follow the "Click in the scrollbar to:" system preference on OS X and +// "gtk-primary-button-warps-slider" property with GTK (since 2.24 / 3.6), +// unless this preference is explicitly set. +#if !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GTK) +pref("ui.scrollToClick", 0); +#endif + +// provide ability to turn on support for canvas focus rings +pref("canvas.focusring.enabled", true); +pref("canvas.customfocusring.enabled", false); +pref("canvas.hitregions.enabled", false); +pref("canvas.filters.enabled", true); +// Add support for canvas path objects +pref("canvas.path.enabled", true); +pref("canvas.capturestream.enabled", true); + +// Disable the ImageBitmap-extensions for now. +pref("canvas.imagebitmap_extensions.enabled", false); + +// We want the ability to forcibly disable platform a11y, because +// some non-a11y-related components attempt to bring it up. See bug +// 538530 for details about Windows; we have a pref here that allows it +// to be disabled for performance and testing resons. +// See bug 761589 for the crossplatform aspect. +// +// This pref is checked only once, and the browser needs a restart to +// pick up any changes. +// +// Values are -1 always on. 1 always off, 0 is auto as some platform perform +// further checks. +pref("accessibility.force_disabled", 0); + +pref("accessibility.ipc_architecture.enabled", true); + +pref("accessibility.AOM.enabled", false); + +#ifdef XP_WIN +// Some accessibility tools poke at windows in the plugin process during setup +// which can cause hangs. To hack around this set accessibility.delay_plugins +// to true, you can also try increasing accessibility.delay_plugin_time if your +// machine is slow and you still experience hangs. +// See bug 781791. +pref("accessibility.delay_plugins", false); +pref("accessibility.delay_plugin_time", 10000); +#endif + +pref("focusmanager.testmode", false); + +pref("accessibility.usetexttospeech", ""); +pref("accessibility.usebrailledisplay", ""); +pref("accessibility.accesskeycausesactivation", true); +pref("accessibility.mouse_focuses_formcontrol", false); + +// Type Ahead Find +pref("accessibility.typeaheadfind", true); +pref("accessibility.typeaheadfind.autostart", true); +// casesensitive: controls the find bar's case-sensitivity +// 0 - "never" (case-insensitive) +// 1 - "always" (case-sensitive) +// other - "auto" (case-sensitive for mixed-case input, insensitive otherwise) +pref("accessibility.typeaheadfind.casesensitive", 0); +pref("accessibility.typeaheadfind.linksonly", true); +pref("accessibility.typeaheadfind.startlinksonly", false); +pref("accessibility.typeaheadfind.timeout", 4000); +pref("accessibility.typeaheadfind.enabletimeout", true); +pref("accessibility.typeaheadfind.soundURL", "beep"); +pref("accessibility.typeaheadfind.enablesound", true); +#ifdef XP_MACOSX +pref("accessibility.typeaheadfind.prefillwithselection", false); +#else +pref("accessibility.typeaheadfind.prefillwithselection", true); +#endif +pref("accessibility.typeaheadfind.matchesCountLimit", 1000); +pref("findbar.highlightAll", false); +pref("findbar.modalHighlight", false); +pref("findbar.entireword", false); +pref("findbar.iteratorTimeout", 100); + +// use Mac OS X Appearance panel text smoothing setting when rendering text, disabled by default +pref("gfx.use_text_smoothing_setting", false); + +// Number of characters to consider emphasizing for rich autocomplete results +pref("toolkit.autocomplete.richBoundaryCutoff", 200); + +// Variable controlling logging for osfile. +pref("toolkit.osfile.log", false); + +pref("toolkit.scrollbox.smoothScroll", true); +pref("toolkit.scrollbox.scrollIncrement", 20); +pref("toolkit.scrollbox.verticalScrollDistance", 3); +pref("toolkit.scrollbox.horizontalScrollDistance", 5); +pref("toolkit.scrollbox.clickToScroll.scrollDelay", 150); + +// Telemetry settings. +// Server to submit telemetry pings to. +pref("toolkit.telemetry.server", "https://incoming.telemetry.mozilla.org"); +// Telemetry server owner. Please change if you set toolkit.telemetry.server to a different server +pref("toolkit.telemetry.server_owner", "Mozilla"); +// Information page about telemetry (temporary ; will be about:telemetry in the end) +pref("toolkit.telemetry.infoURL", "https://www.mozilla.org/legal/privacy/firefox.html#telemetry"); +// Determines whether full SQL strings are returned when they might contain sensitive info +// i.e. dynamically constructed SQL strings or SQL executed by addons against addon DBs +pref("toolkit.telemetry.debugSlowSql", false); +// Whether to use the unified telemetry behavior, requires a restart. +pref("toolkit.telemetry.unified", true); + +// Identity module +pref("toolkit.identity.enabled", false); +pref("toolkit.identity.debug", false); + +// AsyncShutdown delay before crashing in case of shutdown freeze +pref("toolkit.asyncshutdown.crash_timeout", 60000); +// Extra logging for AsyncShutdown barriers and phases +pref("toolkit.asyncshutdown.log", false); + +// Enable deprecation warnings. +pref("devtools.errorconsole.deprecation_warnings", true); + +// Disable debugging chrome +pref("devtools.chrome.enabled", false); + +// Disable remote debugging protocol logging +pref("devtools.debugger.log", false); +pref("devtools.debugger.log.verbose", false); + +// Disable remote debugging connections +pref("devtools.debugger.remote-enabled", false); + +pref("devtools.debugger.remote-port", 6000); +pref("devtools.debugger.remote-websocket", false); +// Force debugger server binding on the loopback interface +pref("devtools.debugger.force-local", true); +// Display a prompt when a new connection starts to accept/reject it +pref("devtools.debugger.prompt-connection", true); +// Block tools from seeing / interacting with certified apps +pref("devtools.debugger.forbid-certified-apps", true); +// List of permissions that a sideloaded app can't ask for +pref("devtools.apps.forbidden-permissions", "embed-apps"); + +// DevTools default color unit +pref("devtools.defaultColorUnit", "authored"); + +// Used for devtools debugging +pref("devtools.dump.emit", false); + +// Disable device discovery logging +pref("devtools.discovery.log", false); +// Whether to scan for DevTools devices via WiFi +pref("devtools.remote.wifi.scan", true); +// Whether UI options for controlling device visibility over WiFi are shown +// N.B.: This does not set whether the device can be discovered via WiFi, only +// whether the UI control to make such a choice is shown to the user +pref("devtools.remote.wifi.visible", true); +// Client must complete TLS handshake within this window (ms) +pref("devtools.remote.tls-handshake-timeout", 10000); + +// URL of the remote JSON catalog used for device simulation +pref("devtools.devices.url", "https://code.cdn.mozilla.net/devices/devices.json"); + +// Display the introductory text +pref("devtools.gcli.hideIntro", false); + +// How eager are we to show help: never=1, sometimes=2, always=3 +pref("devtools.gcli.eagerHelper", 2); + +// Alias to the script URLs for inject command. +pref("devtools.gcli.jquerySrc", "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"); +pref("devtools.gcli.lodashSrc", "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.min.js"); +pref("devtools.gcli.underscoreSrc", "https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"); + +// Set imgur upload client ID +pref("devtools.gcli.imgurClientID", '0df414e888d7240'); +// Imgur's upload URL +pref("devtools.gcli.imgurUploadURL", "https://api.imgur.com/3/image"); + +// GCLI commands directory +pref("devtools.commands.dir", ""); + +// Allows setting the performance marks for which telemetry metrics will be recorded. +pref("devtools.telemetry.supported_performance_marks", "contentInteractive,navigationInteractive,navigationLoaded,visuallyLoaded,fullyLoaded,mediaEnumerated,scanEnd"); + +// Deprecation warnings after DevTools file migration. +pref("devtools.migration.warnings", true); + +// view source +pref("view_source.syntax_highlight", true); +pref("view_source.wrap_long_lines", false); +pref("view_source.editor.external", false); +pref("view_source.editor.path", ""); +// allows to add further arguments to the editor; use the %LINE% placeholder +// for jumping to a specific line (e.g. "/line:%LINE%" or "--goto %LINE%") +pref("view_source.editor.args", ""); + +// When true this will word-wrap plain text documents. +pref("plain_text.wrap_long_lines", false); + +// whether or not to draw images while dragging +pref("nglayout.enable_drag_images", true); + +// enable/disable paint flashing --- useful for debugging +// the first one applies to everything, the second one only to chrome +pref("nglayout.debug.paint_flashing", false); +pref("nglayout.debug.paint_flashing_chrome", false); + +// enable/disable widget update area flashing --- only supported with +// BasicLayers (other layer managers always update the entire widget area) +pref("nglayout.debug.widget_update_flashing", false); + +// Enable/disable display list invalidation logging --- useful for debugging. +pref("nglayout.debug.invalidation", false); + +// Whether frame visibility tracking is enabled globally. +pref("layout.framevisibility.enabled", true); + +pref("layout.framevisibility.numscrollportwidths", 0); +pref("layout.framevisibility.numscrollportheights", 1); + +// scrollbar snapping region +// 0 - off +// 1 and higher - slider thickness multiple +pref("slider.snapMultiplier", 0); + +// option to choose plug-in finder +pref("application.use_ns_plugin_finder", false); + +// URI fixup prefs +pref("browser.fixup.alternate.enabled", true); +pref("browser.fixup.alternate.prefix", "www."); +pref("browser.fixup.alternate.suffix", ".com"); +pref("browser.fixup.dns_first_for_single_words", false); +pref("browser.fixup.hide_user_pass", true); + +// Location Bar AutoComplete +pref("browser.urlbar.autocomplete.enabled", true); + +// Print header customization +// Use the following codes: +// &T - Title +// &U - Document URL +// &D - Date/Time +// &P - Page Number +// &PT - Page Number "of" Page total +// Set each header to a string containing zero or one of these codes +// and the code will be replaced in that string by the corresponding data +pref("print.print_headerleft", "&T"); +pref("print.print_headercenter", ""); +pref("print.print_headerright", "&U"); +pref("print.print_footerleft", "&PT"); +pref("print.print_footercenter", ""); +pref("print.print_footerright", "&D"); +pref("print.show_print_progress", true); + +// xxxbsmedberg: more toolkit prefs + +// When this is set to false each window has its own PrintSettings +// and a change in one window does not affect the others +pref("print.use_global_printsettings", true); + +// Save the Printings after each print job +pref("print.save_print_settings", true); + +// Cache old Presentation when going into Print Preview +pref("print.always_cache_old_pres", false); + +// Enables you to specify the amount of the paper that is to be treated +// as unwriteable. The print_edge_XXX and print_margin_XXX preferences +// are treated as offsets that are added to this pref. +// Default is "-1", which means "use the system default". (If there is +// no system default, then the -1 is treated as if it were 0.) +// This is used by both Printing and Print Preview. +// Units are in 1/100ths of an inch. +pref("print.print_unwriteable_margin_top", -1); +pref("print.print_unwriteable_margin_left", -1); +pref("print.print_unwriteable_margin_right", -1); +pref("print.print_unwriteable_margin_bottom", -1); + +// Enables you to specify the gap from the edge of the paper's +// unwriteable area to the margin. +// This is used by both Printing and Print Preview +// Units are in 1/100ths of an inch. +pref("print.print_edge_top", 0); +pref("print.print_edge_left", 0); +pref("print.print_edge_right", 0); +pref("print.print_edge_bottom", 0); + +// Print via the parent process. This is only used when e10s is enabled. +#if defined(XP_WIN) || defined(XP_MACOSX) +pref("print.print_via_parent", true); +#else +pref("print.print_via_parent", false); +#endif + +// Pref used by the spellchecker extension to control the +// maximum number of misspelled words that will be underlined +// in a document. +pref("extensions.spellcheck.inline.max-misspellings", 500); + +// Prefs used by libeditor. Prefs specific to seamonkey composer +// belong in comm-central/editor/ui/composer.js + +pref("editor.use_custom_colors", false); +pref("editor.singleLine.pasteNewlines", 2); +pref("editor.use_css", false); +pref("editor.css.default_length_unit", "px"); +pref("editor.resizing.preserve_ratio", true); +pref("editor.positioning.offset", 0); + +// Scripts & Windows prefs +pref("dom.disable_beforeunload", false); +pref("dom.disable_window_flip", false); +pref("dom.disable_window_move_resize", false); +pref("dom.disable_window_status_change", false); + +pref("dom.disable_window_open_feature.titlebar", false); +pref("dom.disable_window_open_feature.close", false); +pref("dom.disable_window_open_feature.toolbar", false); +pref("dom.disable_window_open_feature.location", false); +pref("dom.disable_window_open_feature.personalbar", false); +pref("dom.disable_window_open_feature.menubar", false); +pref("dom.disable_window_open_feature.resizable", true); +pref("dom.disable_window_open_feature.minimizable", false); +pref("dom.disable_window_open_feature.status", true); + +pref("dom.allow_scripts_to_close_windows", false); + +pref("dom.require_user_interaction_for_beforeunload", true); + +pref("dom.disable_open_during_load", false); +pref("dom.popup_maximum", 20); +pref("dom.popup_allowed_events", "change click dblclick mouseup notificationclick reset submit touchend"); +pref("dom.disable_open_click_delay", 1000); + +pref("dom.storage.enabled", true); +pref("dom.storage.default_quota", 5120); + +pref("dom.send_after_paint_to_content", false); + +// Timeout clamp in ms for timeouts we clamp +pref("dom.min_timeout_value", 4); +// And for background windows +pref("dom.min_background_timeout_value", 1000); + +// Don't use new input types +pref("dom.experimental_forms", false); + +// Enable : +pref("dom.forms.number", true); + +// Enable by default. It will be turned off for remaining +// platforms which don't have a color picker implemented yet. +pref("dom.forms.color", true); + +// Support for input type=date, time, month, week and datetime-local. By +// default, disabled. +pref("dom.forms.datetime", false); + +// Enable time picker UI. By default, disabled. +pref("dom.forms.datetime.timepicker", false); + +// Support for new @autocomplete values +pref("dom.forms.autocomplete.experimental", false); + +// Enables requestAutocomplete DOM API on forms. +pref("dom.forms.requestAutocomplete", false); + +// Enable Directory API. By default, disabled. +pref("dom.input.dirpicker", false); + +// Enables system messages and activities +pref("dom.sysmsg.enabled", false); + +// Enable pre-installed applications. +pref("dom.webapps.useCurrentProfile", false); + +pref("dom.cycle_collector.incremental", true); + +// Parsing perf prefs. For now just mimic what the old code did. +#ifndef XP_WIN +pref("content.sink.pending_event_mode", 0); +#endif + +// Disable popups from plugins by default +// 0 = openAllowed +// 1 = openControlled +// 2 = openAbused +pref("privacy.popups.disable_from_plugins", 2); + +// send "do not track" HTTP header, disabled by default +pref("privacy.donottrackheader.enabled", false); +// Enforce tracking protection in all modes +pref("privacy.trackingprotection.enabled", false); +// Enforce tracking protection in Private Browsing mode +pref("privacy.trackingprotection.pbmode.enabled", true); + +pref("dom.event.contextmenu.enabled", true); +pref("dom.event.clipboardevents.enabled", true); +#if defined(XP_WIN) && !defined(RELEASE_OR_BETA) || defined(MOZ_WIDGET_GTK) && !defined(RELEASE_OR_BETA) +pref("dom.event.highrestimestamp.enabled", true); +#else +pref("dom.event.highrestimestamp.enabled", false); +#endif + +pref("dom.webcomponents.enabled", false); +pref("dom.webcomponents.customelements.enabled", false); + +pref("javascript.enabled", true); +pref("javascript.options.strict", false); +#ifdef DEBUG +pref("javascript.options.strict.debug", false); +#endif +pref("javascript.options.baselinejit", true); +pref("javascript.options.ion", true); +pref("javascript.options.asmjs", true); +pref("javascript.options.wasm", false); +pref("javascript.options.wasm_baselinejit", false); +pref("javascript.options.native_regexp", true); +pref("javascript.options.parallel_parsing", true); +#if !defined(RELEASE_OR_BETA) && !defined(ANDROID) && !defined(MOZ_B2G) && !defined(XP_IOS) +pref("javascript.options.asyncstack", true); +#else +pref("javascript.options.asyncstack", false); +#endif +pref("javascript.options.throw_on_asmjs_validation_failure", false); +pref("javascript.options.ion.offthread_compilation", true); +// This preference instructs the JS engine to discard the +// source of any privileged JS after compilation. This saves +// memory, but makes things like Function.prototype.toSource() +// fail. +pref("javascript.options.discardSystemSource", false); +// This preference limits the memory usage of javascript. +// If you want to change these values for your device, +// please find Bug 417052 comment 17 and Bug 456721 +// Comment 32 and Bug 613551. +pref("javascript.options.mem.high_water_mark", 128); +pref("javascript.options.mem.max", -1); +pref("javascript.options.mem.gc_per_zone", true); +pref("javascript.options.mem.gc_incremental", true); +pref("javascript.options.mem.gc_incremental_slice_ms", 10); +pref("javascript.options.mem.gc_compacting", true); +pref("javascript.options.mem.log", false); +pref("javascript.options.mem.notify", false); +pref("javascript.options.gc_on_memory_pressure", true); +pref("javascript.options.compact_on_user_inactive", true); +#ifdef NIGHTLY_BUILD +pref("javascript.options.compact_on_user_inactive_delay", 15000); // ms +#else +pref("javascript.options.compact_on_user_inactive_delay", 300000); // ms +#endif + +pref("javascript.options.mem.gc_high_frequency_time_limit_ms", 1000); +pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 100); +pref("javascript.options.mem.gc_high_frequency_high_limit_mb", 500); +pref("javascript.options.mem.gc_high_frequency_heap_growth_max", 300); +pref("javascript.options.mem.gc_high_frequency_heap_growth_min", 150); +pref("javascript.options.mem.gc_low_frequency_heap_growth", 150); +pref("javascript.options.mem.gc_dynamic_heap_growth", true); +pref("javascript.options.mem.gc_dynamic_mark_slice", true); +pref("javascript.options.mem.gc_refresh_frame_slices_enabled", true); +pref("javascript.options.mem.gc_allocation_threshold_mb", 30); +pref("javascript.options.mem.gc_min_empty_chunk_count", 1); +pref("javascript.options.mem.gc_max_empty_chunk_count", 30); + +pref("javascript.options.showInConsole", false); + +#ifdef RELEASE_OR_BETA +// Disabled in Beta and Release for now, see bug 1225406 +pref("javascript.options.shared_memory", false); +#else +pref("javascript.options.shared_memory", true); +#endif + +pref("javascript.options.throw_on_debuggee_would_run", false); +pref("javascript.options.dump_stack_on_debuggee_would_run", false); + +// advanced prefs +pref("advanced.mailftp", false); +pref("image.animation_mode", "normal"); + +// Same-origin policy for file URIs, "false" is traditional +pref("security.fileuri.strict_origin_policy", true); + +// If this pref is true, prefs in the logging.config branch will be cleared on +// startup. This is done so that setting a log-file and log-modules at runtime +// doesn't persist across restarts leading to huge logfile and low disk space. +pref("logging.config.clear_on_startup", true); + +// If there is ever a security firedrill that requires +// us to block certian ports global, this is the pref +// to use. Is is a comma delimited list of port numbers +// for example: +// pref("network.security.ports.banned", "1,2,3,4,5"); +// prevents necko connecting to ports 1-5 unless the protocol +// overrides. + +// Allow necko to do A/B testing. Will generally only happen if +// telemetry is also enabled as otherwise there is no way to report +// the results +pref("network.allow-experiments", true); + +// Allow the network changed event to get sent when a network topology or +// setup change is noticed while running. +pref("network.notify.changed", true); + +// Allow network detection of IPv6 related changes (bug 1245059) +#if defined(XP_WIN) +pref("network.notify.IPv6", false); +#else +pref("network.notify.IPv6", true); +#endif + +// Transmit UDP busy-work to the LAN when anticipating low latency +// network reads and on wifi to mitigate 802.11 Power Save Polling delays +pref("network.tickle-wifi.enabled", false); +pref("network.tickle-wifi.duration", 400); +pref("network.tickle-wifi.delay", 16); + +// Turn off interprocess security checks. Needed to run xpcshell tests. +pref("network.disable.ipc.security", false); + +// Default action for unlisted external protocol handlers +pref("network.protocol-handler.external-default", true); // OK to load +pref("network.protocol-handler.warn-external-default", true); // warn before load + +// Prevent using external protocol handlers for these schemes +pref("network.protocol-handler.external.hcp", false); +pref("network.protocol-handler.external.vbscript", false); +pref("network.protocol-handler.external.javascript", false); +pref("network.protocol-handler.external.data", false); +pref("network.protocol-handler.external.ms-help", false); +pref("network.protocol-handler.external.shell", false); +pref("network.protocol-handler.external.vnd.ms.radio", false); +#ifdef XP_MACOSX +pref("network.protocol-handler.external.help", false); +#endif +pref("network.protocol-handler.external.disk", false); +pref("network.protocol-handler.external.disks", false); +pref("network.protocol-handler.external.afp", false); +pref("network.protocol-handler.external.moz-icon", false); + +// Don't allow external protocol handlers for common typos +pref("network.protocol-handler.external.ttp", false); // http +pref("network.protocol-handler.external.ttps", false); // https +pref("network.protocol-handler.external.tps", false); // https +pref("network.protocol-handler.external.ps", false); // https +pref("network.protocol-handler.external.ile", false); // file +pref("network.protocol-handler.external.le", false); // file + +// An exposed protocol handler is one that can be used in all contexts. A +// non-exposed protocol handler is one that can only be used internally by the +// application. For example, a non-exposed protocol would not be loaded by the +// application in response to a link click or a X-remote openURL command. +// Instead, it would be deferred to the system's external protocol handler. +// Only internal/built-in protocol handlers can be marked as exposed. + +// This pref controls the default settings. Per protocol settings can be used +// to override this value. +pref("network.protocol-handler.expose-all", true); + +// Warning for about:networking page +pref("network.warnOnAboutNetworking", true); + +// Example: make IMAP an exposed protocol +// pref("network.protocol-handler.expose.imap", true); + +// Whether IOService.connectivity and NS_IsOffline depends on connectivity status +pref("network.manage-offline-status", true); +// If set to true, IOService.offline depends on IOService.connectivity +pref("network.offline-mirrors-connectivity", false); + +// +pref("network.http.version", "1.1"); // default +// pref("network.http.version", "1.0"); // uncomment this out in case of problems +// pref("network.http.version", "0.9"); // it'll work too if you're crazy +// keep-alive option is effectively obsolete. Nevertheless it'll work with +// some older 1.0 servers: + +pref("network.http.proxy.version", "1.1"); // default +// pref("network.http.proxy.version", "1.0"); // uncomment this out in case of problems + // (required if using junkbuster proxy) + +// this preference can be set to override the socket type used for normal +// HTTP traffic. an empty value indicates the normal TCP/IP socket type. +pref("network.http.default-socket-type", ""); + +// There is a problem with some IIS7 servers that don't close the connection +// properly after it times out (bug #491541). Default timeout on IIS7 is +// 120 seconds. We need to reuse or drop the connection within this time. +// We set the timeout a little shorter to keep a reserve for cases when +// the packet is lost or delayed on the route. +pref("network.http.keep-alive.timeout", 115); + +// Timeout connections if an initial response is not received after 5 mins. +pref("network.http.response.timeout", 300); + +// Limit the absolute number of http connections. +// Note: the socket transport service will clamp the number below this if the OS +// cannot allocate that many FDs +#ifdef ANDROID +pref("network.http.max-connections", 256); +#else +pref("network.http.max-connections", 900); +#endif + +// If NOT connecting via a proxy, then +// a new connection will only be attempted if the number of active persistent +// connections to the server is less then max-persistent-connections-per-server. +pref("network.http.max-persistent-connections-per-server", 6); + +// If connecting via a proxy, then a +// new connection will only be attempted if the number of active persistent +// connections to the proxy is less then max-persistent-connections-per-proxy. +pref("network.http.max-persistent-connections-per-proxy", 32); + +// amount of time (in seconds) to suspend pending requests, before spawning a +// new connection, once the limit on the number of persistent connections per +// host has been reached. however, a new connection will not be created if +// max-connections or max-connections-per-server has also been reached. +pref("network.http.request.max-start-delay", 10); + +// If a connection is reset, we will retry it max-attempts times. +pref("network.http.request.max-attempts", 10); + +// Headers +pref("network.http.accept.default", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); + +// Prefs allowing granular control of referers +// 0=don't send any, 1=send only on clicks, 2=send on image requests as well +pref("network.http.sendRefererHeader", 2); +// false=real referer, true=spoof referer (use target URI as referer) +pref("network.http.referer.spoofSource", false); +// 0=full URI, 1=scheme+host+port+path, 2=scheme+host+port +pref("network.http.referer.trimmingPolicy", 0); +// 0=full URI, 1=scheme+host+port+path, 2=scheme+host+port +pref("network.http.referer.XOriginTrimmingPolicy", 0); +// 0=always send, 1=send iff base domains match, 2=send iff hosts match +pref("network.http.referer.XOriginPolicy", 0); + +// Controls whether referrer attributes in , , ,