diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index d245a0e693f2..dc4ceaca08c3 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -986,7 +986,7 @@ class MOZ_STACK_CLASS PrefWrapper : public PrefWrapperBase { return PrefValueKind::User; } - nsresult GetBoolValue(PrefValueKind aKind, bool* aResult) const { + nsresult GetValue(PrefValueKind aKind, bool* aResult) const { PrefValueKind kind; MOZ_TRY_VAR(kind, WantValueKind(PrefType::Bool, aKind)); @@ -994,7 +994,7 @@ class MOZ_STACK_CLASS PrefWrapper : public PrefWrapperBase { return NS_OK; } - nsresult GetIntValue(PrefValueKind aKind, int32_t* aResult) const { + nsresult GetValue(PrefValueKind aKind, int32_t* aResult) const { PrefValueKind kind; MOZ_TRY_VAR(kind, WantValueKind(PrefType::Int, aKind)); @@ -1002,7 +1002,21 @@ class MOZ_STACK_CLASS PrefWrapper : public PrefWrapperBase { return NS_OK; } - nsresult GetCStringValue(PrefValueKind aKind, nsACString& aResult) const { + nsresult GetValue(PrefValueKind aKind, uint32_t* aResult) const { + return GetValue(aKind, reinterpret_cast(aResult)); + } + + nsresult GetValue(PrefValueKind aKind, float* aResult) const { + nsAutoCString result; + nsresult rv = GetValue(aKind, result); + if (NS_SUCCEEDED(rv)) { + // ToFloat() does a locale-independent conversion. + *aResult = result.ToFloat(&rv); + } + return rv; + } + + nsresult GetValue(PrefValueKind aKind, nsACString& aResult) const { PrefValueKind kind; MOZ_TRY_VAR(kind, WantValueKind(PrefType::String, aKind)); @@ -4380,73 +4394,6 @@ static nsresult pref_ReadPrefFromJar(nsZipArchive* aJarReader, return NS_OK; } -// These preference getter wrappers allow us to look up the value for static -// preferences based on their native types, rather than manually mapping them to -// the appropriate Preferences::Get* functions. -template -static T GetPref(const char* aName, T aDefaultValue); - -template <> -bool MOZ_MAYBE_UNUSED GetPref(const char* aName, bool aDefaultValue) { - return Preferences::GetBool(aName, aDefaultValue); -} - -template <> -int32_t MOZ_MAYBE_UNUSED GetPref(const char* aName, int32_t aDefaultValue) { - return Preferences::GetInt(aName, aDefaultValue); -} - -template <> -uint32_t MOZ_MAYBE_UNUSED GetPref(const char* aName, uint32_t aDefaultValue) { - return Preferences::GetUint(aName, aDefaultValue); -} - -template <> -float MOZ_MAYBE_UNUSED GetPref(const char* aName, float aDefaultValue) { - return Preferences::GetFloat(aName, aDefaultValue); -} - -template -static nsresult GetSharedPref(const char* aName, T* aResult); - -template <> -nsresult MOZ_MAYBE_UNUSED GetSharedPref(const char* aName, bool* aResult) { - MOZ_ASSERT(aResult); - - Maybe pref = pref_SharedLookup(aName); - return pref ? pref->GetBoolValue(PrefValueKind::User, aResult) - : NS_ERROR_UNEXPECTED; -} - -template <> -nsresult MOZ_MAYBE_UNUSED GetSharedPref(const char* aName, int32_t* aResult) { - MOZ_ASSERT(aResult); - - Maybe pref = pref_SharedLookup(aName); - return pref ? pref->GetIntValue(PrefValueKind::User, aResult) - : NS_ERROR_UNEXPECTED; -} - -template <> -nsresult MOZ_MAYBE_UNUSED GetSharedPref(const char* aName, uint32_t* aResult) { - return GetSharedPref(aName, reinterpret_cast(aResult)); -} - -template <> -nsresult MOZ_MAYBE_UNUSED GetSharedPref(const char* aName, float* aResult) { - MOZ_ASSERT(aResult); - - Maybe pref = pref_SharedLookup(aName); - if (!pref) { - return NS_ERROR_UNEXPECTED; - } - nsAutoCString result; - nsresult rv = pref->GetCStringValue(PrefValueKind::User, result); - // ToFloat() does a locale-independent conversion. - *aResult = result.ToFloat(&rv); - return rv; -} - static nsresult pref_ReadDefaultPrefs(const RefPtr jarReader, const char* path) { nsZipFind* findPtr; @@ -4474,6 +4421,55 @@ static nsresult pref_ReadDefaultPrefs(const RefPtr jarReader, return NS_OK; } +// These preference getter wrappers allow us to look up the value for static +// preferences based on their native types, rather than manually mapping them to +// the appropriate Preferences::Get* functions. +// We define these methods in a struct which is made friend of Preferences in +// order to access private members. +struct PreferencesInternalMethods { + template + static nsresult GetPrefValue(const char* aPrefName, T&& aResult, + PrefValueKind aKind) { + NS_ENSURE_TRUE(Preferences::InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); + + if (Maybe pref = pref_Lookup(aPrefName)) { + return pref->GetValue(aKind, std::forward(aResult)); + } + return NS_ERROR_UNEXPECTED; + } + + template + static nsresult GetSharedPrefValue(const char* aName, T* aResult) { + if (Maybe pref = pref_SharedLookup(aName)) { + return pref->GetValue(PrefValueKind::User, aResult); + } + return NS_ERROR_UNEXPECTED; + } + + template + static T GetPref(const char* aPrefName, T aFallback, + PrefValueKind aKind = PrefValueKind::User) { + T result = aFallback; + GetPrefValue(aPrefName, &result, aKind); + return result; + } + + template + static void VarChanged(const char* aPref, void* aClosure) { + CacheData* cache = static_cast(aClosure); + *static_cast(cache->mCacheLocation) = + GetPref(aPref, cache->GetDefault>()); + } + + template + static nsresult RegisterCallback(CacheData* aCacheData, + const nsACString& aPref) { + return Preferences::RegisterCallback(VarChanged, aPref, aCacheData, + Preferences::ExactMatch, + /* isPriority */ true); + } +}; + // Initialize default preference JavaScript buffers from appropriate TEXT // resources. /* static */ Result Preferences::InitInitialObjects( @@ -4510,12 +4506,12 @@ static nsresult pref_ReadDefaultPrefs(const RefPtr jarReader, // and shouldn't be checked. # define PREF(name, cpp_type, value) -# define VARCACHE_PREF(policy, name, id, cpp_type, value) \ - MOZ_ASSERT( \ - StaticPrefs::UpdatePolicy::policy == \ - StaticPrefs::UpdatePolicy::Skip || \ - GetPref>(name, value) == StaticPrefs::id(), \ - "Incorrect cached value for " name); +# define VARCACHE_PREF(policy, name, id, cpp_type, value) \ + MOZ_ASSERT(StaticPrefs::UpdatePolicy::policy == \ + StaticPrefs::UpdatePolicy::Skip || \ + PreferencesInternalMethods::GetPref>( \ + name, value) == StaticPrefs::id(), \ + "Incorrect cached value for " name); # include "mozilla/StaticPrefList.h" # undef PREF # undef VARCACHE_PREF @@ -4718,48 +4714,28 @@ static nsresult pref_ReadDefaultPrefs(const RefPtr jarReader, nsresult Preferences::GetBool(const char* aPrefName, bool* aResult, PrefValueKind aKind) { MOZ_ASSERT(aResult); - NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - - Maybe pref = pref_Lookup(aPrefName); - return pref.isSome() ? pref->GetBoolValue(aKind, aResult) - : NS_ERROR_UNEXPECTED; + return PreferencesInternalMethods::GetPrefValue(aPrefName, aResult, aKind); } /* static */ nsresult Preferences::GetInt(const char* aPrefName, int32_t* aResult, PrefValueKind aKind) { MOZ_ASSERT(aResult); - NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - - Maybe pref = pref_Lookup(aPrefName); - return pref.isSome() ? pref->GetIntValue(aKind, aResult) - : NS_ERROR_UNEXPECTED; + return PreferencesInternalMethods::GetPrefValue(aPrefName, aResult, aKind); } /* static */ nsresult Preferences::GetFloat(const char* aPrefName, float* aResult, PrefValueKind aKind) { MOZ_ASSERT(aResult); - - nsAutoCString result; - nsresult rv = Preferences::GetCString(aPrefName, result, aKind); - if (NS_SUCCEEDED(rv)) { - // ToFloat() does a locale-independent conversion. - *aResult = result.ToFloat(&rv); - } - return rv; + return PreferencesInternalMethods::GetPrefValue(aPrefName, aResult, aKind); } /* static */ nsresult Preferences::GetCString(const char* aPrefName, nsACString& aResult, PrefValueKind aKind) { - NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - aResult.SetIsVoid(true); - - Maybe pref = pref_Lookup(aPrefName); - return pref.isSome() ? pref->GetCStringValue(aKind, aResult) - : NS_ERROR_UNEXPECTED; + return PreferencesInternalMethods::GetPrefValue(aPrefName, aResult, aKind); } /* static */ @@ -4808,6 +4784,30 @@ nsresult Preferences::GetComplex(const char* aPrefName, const nsIID& aType, return GetRootBranch(aKind)->GetComplexValue(aPrefName, aType, aResult); } +/* static */ +bool Preferences::GetBool(const char* aPrefName, bool aFallback, + PrefValueKind aKind) { + return PreferencesInternalMethods::GetPref(aPrefName, aFallback, aKind); +} + +/* static */ +int32_t Preferences::GetInt(const char* aPrefName, int32_t aFallback, + PrefValueKind aKind) { + return PreferencesInternalMethods::GetPref(aPrefName, aFallback, aKind); +} + +/* static */ +uint32_t Preferences::GetUint(const char* aPrefName, uint32_t aFallback, + PrefValueKind aKind) { + return PreferencesInternalMethods::GetPref(aPrefName, aFallback, aKind); +} + +/* static */ +float Preferences::GetFloat(const char* aPrefName, float aFallback, + PrefValueKind aKind) { + return PreferencesInternalMethods::GetPref(aPrefName, aFallback, aKind); +} + /* static */ nsresult Preferences::SetCString(const char* aPrefName, const nsACString& aValue, @@ -5199,34 +5199,16 @@ static void CacheDataAppendElement(CacheData* aData) { gCacheData->AppendElement(aData); } -template -static void VarChanged(const char* aPref, void* aClosure) { - CacheData* cache = static_cast(aClosure); - *static_cast(cache->mCacheLocation) = - GetPref(aPref, cache->GetDefault>()); -} - -// We define this method in a struct which is made friend of Preferences in -// order to access private members. -struct RegisterCallbacksInternal { - template - static nsresult RegisterCallback(CacheData* aCacheData, - const nsACString& aPref) { - return Preferences::RegisterCallback(VarChanged, aPref, aCacheData, - Preferences::ExactMatch, - /* isPriority */ true); - } -}; - template static nsresult AddVarCache(T* aCache, const nsACString& aPref, StripAtomic aDefault, bool aSkipAssignment) { if (!aSkipAssignment) { - *aCache = GetPref(PromiseFlatCString(aPref).get(), aDefault); + *aCache = PreferencesInternalMethods::GetPref( + PromiseFlatCString(aPref).get(), aDefault); } CacheData* data = new CacheData(aCache, aDefault); CacheDataAppendElement(data); - RegisterCallbacksInternal::RegisterCallback(data, aPref); + PreferencesInternalMethods::RegisterCallback(data, aPref); return NS_OK; } @@ -5440,8 +5422,8 @@ static StaticMutex sOncePrefMutex; // void StaticPrefs::Setmy_varcache(int32_t aValue) { // SetPref(Getmy_varcachePrefName(), aValue); // if (UpdatePolicy::policy == UpdatePolicy::Once) { -// sVarCache_my_varcache = -// GetPref(Getmy_varcachePrefName(), sVarCache_my_varcache); +// sVarCache_my_varcache = PreferencesInternalMethods::GetPref( +// Getmy_varcachePrefName(), sVarCache_my_varcache); // } // return; // } @@ -5468,8 +5450,8 @@ static StaticMutex sOncePrefMutex; !sOncePrefRead); \ SetPref(Get##id##PrefName(), aValue); \ if (UpdatePolicy::policy == UpdatePolicy::Once) { \ - sVarCache_##id = \ - GetPref(Get##id##PrefName(), StripAtomic(sVarCache_##id)); \ + sVarCache_##id = PreferencesInternalMethods::GetPref( \ + Get##id##PrefName(), StripAtomic(sVarCache_##id)); \ } \ /* The StaticPrefs storage will be updated by the registered callback */ \ return; \ @@ -5522,7 +5504,8 @@ void StaticPrefs::InitOncePrefs() { // // if (UpdatePolicy::Skip == UpdatePolicy::Once) { // StaticPrefs::sVarCache_my_varcache = - // GetPref("my.varcache", StripAtomic(99)); + // PreferencesInternalMethods::GetPref("my.varcache", + // StripAtomic(99)); // } // // This is done to get the potentially updated Preference value as we didn't @@ -5534,31 +5517,32 @@ void StaticPrefs::InitOncePrefs() { // and that maybe instead they should have been made `Live`. #define PREF(name, cpp_type, value) #ifdef DEBUG -# define VARCACHE_PREF(policy, name, id, cpp_type, value) \ - if (UpdatePolicy::policy == UpdatePolicy::Once) { \ - StaticPrefs::sVarCache_##id = \ - GetPref(name, StripAtomic(value)); \ - auto checkPref = [&]() { \ - if (!sOncePrefRead) { \ - return; \ - } \ - StripAtomic staticPrefValue = StaticPrefs::id(); \ - StripAtomic preferenceValue = \ - GetPref(Get##id##PrefName(), StripAtomic(value)); \ - MOZ_ASSERT( \ - staticPrefValue == preferenceValue, \ - "Preference '" name "' got modified since StaticPrefs::" #id \ - " got initialized. Consider using a `Live` StaticPrefs instead"); \ - }; \ - gOnceStaticPrefsAntiFootgun->insert( \ - std::pair(Get##id##PrefName(), \ - std::move(checkPref))); \ +# define VARCACHE_PREF(policy, name, id, cpp_type, value) \ + if (UpdatePolicy::policy == UpdatePolicy::Once) { \ + StaticPrefs::sVarCache_##id = PreferencesInternalMethods::GetPref( \ + name, StripAtomic(value)); \ + auto checkPref = [&]() { \ + if (!sOncePrefRead) { \ + return; \ + } \ + StripAtomic staticPrefValue = StaticPrefs::id(); \ + StripAtomic preferenceValue = \ + PreferencesInternalMethods::GetPref(Get##id##PrefName(), \ + StripAtomic(value)); \ + MOZ_ASSERT( \ + staticPrefValue == preferenceValue, \ + "Preference '" name "' got modified since StaticPrefs::" #id \ + " got initialized. Consider using a `Live` StaticPrefs instead"); \ + }; \ + gOnceStaticPrefsAntiFootgun->insert( \ + std::pair(Get##id##PrefName(), \ + std::move(checkPref))); \ } #else -# define VARCACHE_PREF(policy, name, id, cpp_type, value) \ - if (UpdatePolicy::policy == UpdatePolicy::Once) { \ - StaticPrefs::sVarCache_##id = \ - GetPref(name, StripAtomic(value)); \ +# define VARCACHE_PREF(policy, name, id, cpp_type, value) \ + if (UpdatePolicy::policy == UpdatePolicy::Once) { \ + StaticPrefs::sVarCache_##id = PreferencesInternalMethods::GetPref( \ + name, StripAtomic(value)); \ } #endif @@ -5668,17 +5652,19 @@ void StaticPrefs::InitOncePrefsFromShared() { // if (UpdatePolicy::Once == UpdatePolicy::Once) { // int32_t val; // MOZ_DIAGNOSTIC_ALWAYS_TRUE( - // NS_SUCCEEDED(GetSharedPref(ONCE_PREF_NAME(name), &val))); + // NS_SUCCEEDED(PreferencesInternalMethods::GetSharedPrefValue( + // ONCE_PREF_NAME(name), &val))); // StaticPrefs::sVarCache_my_varcache = val; // } #define PREF(name, cpp_type, value) -#define VARCACHE_PREF(policy, name, id, cpp_type, value) \ - if (UpdatePolicy::policy == UpdatePolicy::Once) { \ - StripAtomic val; \ - MOZ_DIAGNOSTIC_ALWAYS_TRUE( \ - NS_SUCCEEDED(GetSharedPref(ONCE_PREF_NAME(name), &val))); \ - StaticPrefs::sVarCache_##id = val; \ +#define VARCACHE_PREF(policy, name, id, cpp_type, value) \ + if (UpdatePolicy::policy == UpdatePolicy::Once) { \ + StripAtomic val; \ + MOZ_DIAGNOSTIC_ALWAYS_TRUE( \ + NS_SUCCEEDED(PreferencesInternalMethods::GetSharedPrefValue( \ + ONCE_PREF_NAME(name), &val))); \ + StaticPrefs::sVarCache_##id = val; \ } #include "mozilla/StaticPrefList.h" #undef PREF diff --git a/modules/libpref/Preferences.h b/modules/libpref/Preferences.h index 6b89b74fc1d7..d6a189d5a6bd 100644 --- a/modules/libpref/Preferences.h +++ b/modules/libpref/Preferences.h @@ -229,29 +229,13 @@ class Preferences final : public nsIPrefService, // failure. When `aKind` is `User` they will get the user value if possible, // and fall back to the default value otherwise. static bool GetBool(const char* aPrefName, bool aFallback = false, - PrefValueKind aKind = PrefValueKind::User) { - bool result = aFallback; - GetBool(aPrefName, &result, aKind); - return result; - } + PrefValueKind aKind = PrefValueKind::User); static int32_t GetInt(const char* aPrefName, int32_t aFallback = 0, - PrefValueKind aKind = PrefValueKind::User) { - int32_t result = aFallback; - GetInt(aPrefName, &result, aKind); - return result; - } + PrefValueKind aKind = PrefValueKind::User); static uint32_t GetUint(const char* aPrefName, uint32_t aFallback = 0, - PrefValueKind aKind = PrefValueKind::User) { - uint32_t result = aFallback; - GetUint(aPrefName, &result, aKind); - return result; - } + PrefValueKind aKind = PrefValueKind::User); static float GetFloat(const char* aPrefName, float aFallback = 0.0f, - PrefValueKind aKind = PrefValueKind::User) { - float result = aFallback; - GetFloat(aPrefName, &result, aKind); - return result; - } + PrefValueKind aKind = PrefValueKind::User); // Value setters. These fail if run outside the parent process. @@ -642,7 +626,8 @@ class Preferences final : public nsIPrefService, static mozilla::Result InitInitialObjects( bool aIsStartup); - friend struct RegisterCallbacksInternal; + friend struct PreferencesInternalMethods; + static nsresult RegisterCallback(PrefChangedFunc aCallback, const nsACString& aPref, void* aClosure, MatchKind aMatchKind,