Bug 1267868 - Make AddXXXVarCache only match exact prefs, not prefixes. r=froydnj

This commit is contained in:
Matt Woodrow 2016-05-04 12:26:04 +12:00
Родитель d669b36504
Коммит 6451cce121
2 изменённых файлов: 43 добавлений и 21 удалений

Просмотреть файл

@ -103,19 +103,24 @@ public:
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) :
mPrefName(aPref), mCallback(aCallback) { }
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)
mPrefName(aOther->mPrefName),
mCallback(aOther->mCallback),
mMatchKind(aOther->mMatchKind)
{ }
bool KeyEquals(const ValueObserverHashKey *aOther) const
{
return mCallback == aOther->mCallback && mPrefName == aOther->mPrefName;
return mCallback == aOther->mCallback &&
mPrefName == aOther->mPrefName &&
mMatchKind == aOther->mMatchKind;
}
ValueObserverHashKey *GetKey() const
@ -127,6 +132,7 @@ public:
nsCString mPrefName;
PrefChangedFunc mCallback;
Preferences::MatchKind mMatchKind;
};
class ValueObserver final : public nsIObserver,
@ -140,8 +146,8 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
ValueObserver(const char *aPref, PrefChangedFunc aCallback)
: ValueObserverHashKey(aPref, aCallback) { }
ValueObserver(const char *aPref, PrefChangedFunc aCallback, Preferences::MatchKind aMatchKind)
: ValueObserverHashKey(aPref, aCallback, aMatchKind) { }
void AppendClosure(void *aClosure) {
mClosures.AppendElement(aClosure);
@ -168,6 +174,9 @@ ValueObserver::Observe(nsISupports *aSubject,
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));
}
@ -1662,11 +1671,12 @@ Preferences::RemoveObservers(nsIObserver* aObserver,
nsresult
Preferences::RegisterCallback(PrefChangedFunc aCallback,
const char* aPref,
void* aClosure)
void* aClosure,
MatchKind aMatchKind)
{
NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE);
ValueObserverHashKey hashKey(aPref, aCallback);
ValueObserverHashKey hashKey(aPref, aCallback, aMatchKind);
RefPtr<ValueObserver> observer;
gObserverTable->Get(&hashKey, getter_AddRefs(observer));
if (observer) {
@ -1674,7 +1684,7 @@ Preferences::RegisterCallback(PrefChangedFunc aCallback,
return NS_OK;
}
observer = new ValueObserver(aPref, aCallback);
observer = new ValueObserver(aPref, aCallback, aMatchKind);
observer->AppendClosure(aClosure);
nsresult rv = AddStrongObserver(observer, aPref);
NS_ENSURE_SUCCESS(rv, rv);
@ -1686,9 +1696,10 @@ Preferences::RegisterCallback(PrefChangedFunc aCallback,
nsresult
Preferences::RegisterCallbackAndCall(PrefChangedFunc aCallback,
const char* aPref,
void* aClosure)
void* aClosure,
MatchKind aMatchKind)
{
nsresult rv = RegisterCallback(aCallback, aPref, aClosure);
nsresult rv = RegisterCallback(aCallback, aPref, aClosure, aMatchKind);
if (NS_SUCCEEDED(rv)) {
(*aCallback)(aPref, aClosure);
}
@ -1699,14 +1710,15 @@ Preferences::RegisterCallbackAndCall(PrefChangedFunc aCallback,
nsresult
Preferences::UnregisterCallback(PrefChangedFunc aCallback,
const char* aPref,
void* aClosure)
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);
ValueObserverHashKey hashKey(aPref, aCallback, aMatchKind);
RefPtr<ValueObserver> observer;
gObserverTable->Get(&hashKey, getter_AddRefs(observer));
if (!observer) {
@ -1743,7 +1755,7 @@ Preferences::AddBoolVarCache(bool* aCache,
data->cacheLocation = aCache;
data->defaultValueBool = aDefault;
gCacheData->AppendElement(data);
return RegisterCallback(BoolVarChanged, aPref, data);
return RegisterCallback(BoolVarChanged, aPref, data, ExactMatch);
}
static void IntVarChanged(const char* aPref, void* aClosure)
@ -1768,7 +1780,7 @@ Preferences::AddIntVarCache(int32_t* aCache,
data->cacheLocation = aCache;
data->defaultValueInt = aDefault;
gCacheData->AppendElement(data);
return RegisterCallback(IntVarChanged, aPref, data);
return RegisterCallback(IntVarChanged, aPref, data, ExactMatch);
}
static void UintVarChanged(const char* aPref, void* aClosure)
@ -1793,7 +1805,7 @@ Preferences::AddUintVarCache(uint32_t* aCache,
data->cacheLocation = aCache;
data->defaultValueUint = aDefault;
gCacheData->AppendElement(data);
return RegisterCallback(UintVarChanged, aPref, data);
return RegisterCallback(UintVarChanged, aPref, data, ExactMatch);
}
template <MemoryOrdering Order>
@ -1820,7 +1832,7 @@ Preferences::AddAtomicUintVarCache(Atomic<uint32_t, Order>* aCache,
data->cacheLocation = aCache;
data->defaultValueUint = aDefault;
gCacheData->AppendElement(data);
return RegisterCallback(AtomicUintVarChanged<Order>, aPref, data);
return RegisterCallback(AtomicUintVarChanged<Order>, aPref, data, ExactMatch);
}
// Since the definition of this template function is not in a header file,
@ -1852,7 +1864,7 @@ Preferences::AddFloatVarCache(float* aCache,
data->cacheLocation = aCache;
data->defaultValueFloat = aDefault;
gCacheData->AppendElement(data);
return RegisterCallback(FloatVarChanged, aPref, data);
return RegisterCallback(FloatVarChanged, aPref, data, ExactMatch);
}
// static

Просмотреть файл

@ -246,18 +246,28 @@ public:
/**
* 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);
void* aClosure = nullptr,
MatchKind aMatchKind = PrefixMatch);
static nsresult UnregisterCallback(PrefChangedFunc aCallback,
const char* aPref,
void* aClosure = nullptr);
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);
void* aClosure = nullptr,
MatchKind aMatchKind = PrefixMatch);
/**
* Adds the aVariable to cache table. aVariable must be a pointer for a