Bug 1394578 - Pass pref locked status to content processes. r=glandium
This makes the IPC messages a little bigger, but that's unavoidable.
MozReview-Commit-ID: 1oPz2Yjjd9y
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2792,17 +2792,17 @@ ContentParent::Observe(nsISupports* aSub
if (NS_strncmp(entry.mPrefBranch, aData, entry.mLen) == 0) {
return NS_OK;
}
}
// We know prefs are ASCII here.
NS_LossyConvertUTF16toASCII strData(aData);
- Pref pref(strData, null_t(), null_t());
+ Pref pref(strData, false, null_t(), null_t());
Preferences::GetPreference(&pref);
if (!SendPreferenceUpdate(pref)) {
return NS_ERROR_NOT_AVAILABLE;
}
}
else if (!strcmp(aTopic, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC)) {
NS_ConvertUTF16toUTF8 dataStr(aData);
const char *offline = dataStr.get();
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -151,48 +151,51 @@ ContentProcess::Init(int aArgc, char* aA
char* str = aArgv[idx + 1];
while (*str) {
int32_t index = strtol(str, &str, 10);
MOZ_ASSERT(str[0] == ':');
str++;
MaybePrefValue value(PrefValue(static_cast<int32_t>(strtol(str, &str, 10))));
MOZ_ASSERT(str[0] == '|');
str++;
- Pref pref(nsCString(ContentPrefs::GetContentPref(index)), value, MaybePrefValue());
+ // XXX: we assume these values as default values, which may not be
+ // true. We also assume they are unlocked. Fortunately, these prefs
+ // get reset properly by the first IPC message.
+ Pref pref(nsCString(ContentPrefs::GetContentPref(index)), false, value, MaybePrefValue());
prefsArray.AppendElement(pref);
}
SET_PREF_PHASE(END_INIT_PREFS);
foundIntPrefs = true;
} else if (!strcmp(aArgv[idx], "-boolPrefs")) {
SET_PREF_PHASE(BEGIN_INIT_PREFS);
char* str = aArgv[idx + 1];
while (*str) {
int32_t index = strtol(str, &str, 10);
MOZ_ASSERT(str[0] == ':');
str++;
MaybePrefValue value(PrefValue(!!strtol(str, &str, 10)));
MOZ_ASSERT(str[0] == '|');
str++;
- Pref pref(nsCString(ContentPrefs::GetContentPref(index)), value, MaybePrefValue());
+ Pref pref(nsCString(ContentPrefs::GetContentPref(index)), false, value, MaybePrefValue());
prefsArray.AppendElement(pref);
}
SET_PREF_PHASE(END_INIT_PREFS);
foundBoolPrefs = true;
} else if (!strcmp(aArgv[idx], "-stringPrefs")) {
SET_PREF_PHASE(BEGIN_INIT_PREFS);
char* str = aArgv[idx + 1];
while (*str) {
int32_t index = strtol(str, &str, 10);
MOZ_ASSERT(str[0] == ':');
str++;
int32_t length = strtol(str, &str, 10);
MOZ_ASSERT(str[0] == ';');
str++;
MaybePrefValue value(PrefValue(nsCString(str, length)));
- Pref pref(nsCString(ContentPrefs::GetContentPref(index)), value, MaybePrefValue());
+ Pref pref(nsCString(ContentPrefs::GetContentPref(index)), false, value, MaybePrefValue());
prefsArray.AppendElement(pref);
str += length + 1;
MOZ_ASSERT(*(str - 1) == '|');
}
SET_PREF_PHASE(END_INIT_PREFS);
foundStringPrefs = true;
} else if (!strcmp(aArgv[idx], "-schedulerPrefs")) {
schedulerPrefs = aArgv[idx + 1];
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -153,16 +153,17 @@ union PrefValue {
union MaybePrefValue {
PrefValue;
null_t;
};
struct Pref {
nsCString name;
+ bool isLocked;
MaybePrefValue defaultValue;
MaybePrefValue userValue;
};
struct DataStorageItem {
nsCString key;
nsCString value;
DataStorageType type;
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -419,16 +419,18 @@ public:
aResult = stringVal;
return NS_OK;
}
void ToDomPref(dom::Pref* aDomPref)
{
aDomPref->name() = mName;
+ aDomPref->isLocked() = mIsLocked;
+
if (mHasDefaultValue) {
aDomPref->defaultValue() = dom::PrefValue();
mDefaultValue.ToDomPrefValue(Type(),
&aDomPref->defaultValue().get_PrefValue());
} else {
aDomPref->defaultValue() = null_t();
}
@@ -445,16 +447,18 @@ public:
(aDomPref->defaultValue().get_PrefValue().type() ==
aDomPref->userValue().get_PrefValue().type()));
}
void FromDomPref(const dom::Pref& aDomPref, bool* aValueChanged)
{
MOZ_ASSERT(strcmp(mName, aDomPref.name().get()) == 0);
+ mIsLocked = aDomPref.isLocked();
+
const dom::MaybePrefValue& defaultValue = aDomPref.defaultValue();
bool defaultValueChanged = false;
if (defaultValue.type() == dom::MaybePrefValue::TPrefValue) {
PrefValue value;
PrefType type = value.FromDomPrefValue(defaultValue.get_PrefValue());
if (!ValueMatches(PrefValueKind::Default, type, value)) {
// Type() is PrefType::None if it's a newly added pref. This is ok.
mDefaultValue.Replace(Type(), type, value);
--- a/modules/libpref/test/unit_ipc/test_initial_prefs.js
+++ b/modules/libpref/test/unit_ipc/test_initial_prefs.js
@@ -8,11 +8,11 @@ function isParentProcess() {
function run_test() {
if (isParentProcess() == false) {
var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
pb.setBoolPref("Test.IPC.bool", true);
pb.setIntPref("Test.IPC.int", 23);
pb.setCharPref("Test.IPC.char", "hey");
- run_test_in_child("test_existing_prefs.JS");
+ run_test_in_child("test_existing_prefs.js");
}
-}
\ No newline at end of file
+}
new file mode 100644
--- /dev/null
+++ b/modules/libpref/test/unit_ipc/test_locked_prefs.js
@@ -0,0 +1,40 @@
+/* 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/. */
+
+// Locked status should be communicated to children.
+
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+
+function isParentProcess() {
+ let appInfo = Cc["@mozilla.org/xre/app-info;1"];
+ return (!appInfo || appInfo.getService(Ci.nsIXULRuntime).processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT);
+}
+
+function run_test() {
+ let pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+
+ let bprefname = "Test.IPC.locked.bool";
+ let iprefname = "Test.IPC.locked.int";
+ let sprefname = "Test.IPC.locked.string";
+
+ let isParent = isParentProcess();
+ if (isParent) {
+ pb.setBoolPref(bprefname, true);
+ pb.lockPref(bprefname);
+
+ pb.setIntPref(iprefname, true);
+ pb.lockPref(iprefname);
+
+ pb.setStringPref(sprefname, true);
+ pb.lockPref(sprefname);
+ pb.unlockPref(sprefname);
+
+ run_test_in_child("test_locked_prefs.js");
+ }
+
+ ok(pb.prefIsLocked(bprefname), bprefname + " should be locked in the child");
+ ok(pb.prefIsLocked(iprefname), iprefname + " should be locked in the child");
+ ok(!pb.prefIsLocked(sprefname), sprefname + " should be unlocked in the child");
+}
--- a/modules/libpref/test/unit_ipc/test_observed_prefs.js
+++ b/modules/libpref/test/unit_ipc/test_observed_prefs.js
@@ -8,9 +8,9 @@ function isParentProcess() {
function run_test() {
if (isParentProcess() == false) {
var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
do_check_eq(pb.getBoolPref("Test.IPC.bool.new"), true);
do_check_eq(pb.getIntPref("Test.IPC.int.new"), 23);
do_check_eq(pb.getCharPref("Test.IPC.char.new"), "hey");
}
-}
\ No newline at end of file
+}
--- a/modules/libpref/test/unit_ipc/test_update_prefs.js
+++ b/modules/libpref/test/unit_ipc/test_update_prefs.js
@@ -30,9 +30,9 @@ function testPrefClear() {
'var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);\n'+
'pb.prefHasUserValue("Test.IPC.bool.new");\n',
checkWasCleared);
}
function checkWasCleared(existsStr) {
do_check_eq(existsStr, "false");
do_test_finished();
-}
\ No newline at end of file
+}
--- a/modules/libpref/test/unit_ipc/xpcshell.ini
+++ b/modules/libpref/test/unit_ipc/xpcshell.ini
@@ -1,10 +1,11 @@
[DEFAULT]
head =
skip-if = toolkit == 'android'
[test_existing_prefs.js]
[test_initial_prefs.js]
[test_large_pref.js]
+[test_locked_prefs.js]
[test_observed_prefs.js]
[test_update_prefs.js]
[test_user_default_prefs.js]