Bug 1056170 - Expose pref service 'dirty' flag and test it. r=bsmedberg

This commit is contained in:
Irving Reid 2014-09-04 09:52:28 -04:00
parent 5f59b02c90
commit bc89cfa2a7
6 changed files with 99 additions and 13 deletions

View File

@ -788,6 +788,11 @@ Preferences::GetDefaultBranch(const char *aPrefRoot, nsIPrefBranch **_retval)
return NS_OK;
}
NS_IMETHODIMP
Preferences::GetDirty(bool *_retval) {
*_retval = gDirty;
return NS_OK;
}
nsresult
Preferences::NotifyServiceObservers(const char *aTopic)

View File

@ -27,7 +27,7 @@ interface nsIFile;
* @see nsIPrefBranch
*/
[scriptable, uuid(decb9cc7-c08f-4ea5-be91-a8fc637ce2d2)]
[scriptable, uuid(1f84fd56-3956-40df-b86a-1ea01402ee96)]
interface nsIPrefService : nsISupports
{
/**
@ -120,6 +120,11 @@ interface nsIPrefService : nsISupports
*/
nsIPrefBranch getDefaultBranch(in string aPrefRoot);
/**
* The preference service is 'dirty' if there are changes to user preferences
* that have not been written to disk
*/
readonly attribute boolean dirty;
};
%{C++

View File

@ -312,7 +312,7 @@ pref_SetPref(const dom::PrefSetting& aPref)
if (userValue.type() == dom::MaybePrefValue::TPrefValue) {
rv = SetPrefValue(prefName, userValue.get_PrefValue(), USER_VALUE);
} else {
rv = PREF_ClearUserPref(prefName);
rv = PREF_ClearUserPref(prefName);
}
// NB: we should never try to clear a default value, that doesn't
@ -725,7 +725,6 @@ static void pref_SetValue(PrefValue* existingValue, uint16_t *existingFlags,
else {
*existingValue = newValue;
}
gDirty = true;
}
PrefHashEntry* pref_HashTableLookup(const void *key)
@ -785,6 +784,8 @@ nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t
if (!PREF_HAS_USER_VALUE(pref))
valueChanged = true;
}
// What if we change the default to be the same as the user value?
// Should we clear the user value?
}
}
else
@ -799,8 +800,10 @@ nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t
{
/* XXX should we free a user-set string value if there is one? */
pref->flags &= ~PREF_USERSET;
if (!PREF_IS_LOCKED(pref))
if (!PREF_IS_LOCKED(pref)) {
gDirty = true;
valueChanged = true;
}
}
}
else if (!PREF_HAS_USER_VALUE(pref) ||
@ -809,20 +812,17 @@ nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t
{
pref_SetValue(&pref->userPref, &pref->flags, value, type);
pref->flags |= PREF_USERSET;
if (!PREF_IS_LOCKED(pref))
if (!PREF_IS_LOCKED(pref)) {
gDirty = true;
valueChanged = true;
}
}
}
nsresult rv = NS_OK;
if (valueChanged) {
gDirty = true;
nsresult rv2 = pref_DoCallback(key);
if (NS_FAILED(rv2))
rv = rv2;
return pref_DoCallback(key);
}
return rv;
return NS_OK;
}
size_t

View File

@ -32,7 +32,7 @@ var provider = {
persistent.value = true;
if (prop == NS_APP_USER_PROFILE_50_DIR)
return dirSvc.get("CurProcD", Ci.nsIFile);
throw Cr.NS_ERROR_FAILURE;
throw Components.Exception("Tried to get test directory '" + prop + "'", Cr.NS_ERROR_FAILURE);
},
QueryInterface: function(iid) {
if (iid.equals(Ci.nsIDirectoryServiceProvider) ||

View File

@ -0,0 +1,75 @@
/* 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/. */
/* Tests for handling of the preferences 'dirty' flag (bug 985998) */
const PREF_INVALID = 0;
const PREF_BOOL = 128;
const PREF_INT = 64;
const PREF_STRING = 32;
function run_test() {
var ps = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService);
let defaultBranch = ps.getDefaultBranch("");
let userBranch = ps.getBranch("");
let prefFile = do_get_profile();
prefFile.append("prefs.js");
//**************************************************************************//
// prefs are not dirty after a write
ps.savePrefFile(prefFile);
do_check_false(ps.dirty);
// set a new a user value, we should become dirty
userBranch.setBoolPref("DirtyTest.new.bool", true);
do_check_true(ps.dirty);
ps.savePrefFile(prefFile);
// Overwrite a pref with the same value => not dirty
userBranch.setBoolPref("DirtyTest.new.bool", true);
do_check_false(ps.dirty);
// Repeat for the other two types
userBranch.setIntPref("DirtyTest.new.int", 1);
do_check_true(ps.dirty);
ps.savePrefFile(prefFile);
// Overwrite a pref with the same value => not dirty
userBranch.setIntPref("DirtyTest.new.int", 1);
do_check_false(ps.dirty);
userBranch.setCharPref("DirtyTest.new.char", "oop");
do_check_true(ps.dirty);
ps.savePrefFile(prefFile);
// Overwrite a pref with the same value => not dirty
userBranch.setCharPref("DirtyTest.new.char", "oop");
do_check_false(ps.dirty);
// change *type* of a user value -> dirty
userBranch.setBoolPref("DirtyTest.new.char", false);
do_check_true(ps.dirty);
ps.savePrefFile(prefFile);
// Set a default pref => not dirty (defaults don't go into prefs.js)
defaultBranch.setBoolPref("DirtyTest.existing.bool", true);
do_check_false(ps.dirty);
// Fail to change type of a pref with default value -> not dirty
do_check_throws(function() {
userBranch.setCharPref("DirtyTest.existing.bool", "boo"); }, Cr.NS_ERROR_UNEXPECTED);
do_check_false(ps.dirty);
// Set user value same as default, not dirty
userBranch.setBoolPref("DirtyTest.existing.bool", true);
do_check_false(ps.dirty);
// User value different from default, dirty
userBranch.setBoolPref("DirtyTest.existing.bool", false);
do_check_true(ps.dirty);
ps.savePrefFile(prefFile);
// Back to default value, dirty again
userBranch.setBoolPref("DirtyTest.existing.bool", true);
do_check_true(ps.dirty);
ps.savePrefFile(prefFile);
}

View File

@ -11,5 +11,6 @@ support-files =
[test_bug577950.js]
[test_bug790374.js]
[test_changeType.js]
[test_dirtyPrefs.js]
[test_extprefs.js]
[test_libPrefs.js]