mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1027898 - Implement most of nsIContentPrefService2 for e10s. r=adw
This commit is contained in:
parent
8c277a965f
commit
23294fd2f8
@ -81,8 +81,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "OS",
|
||||
"resource://gre/modules/osfile.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RemotePrompt",
|
||||
"resource:///modules/RemotePrompt.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RemotePrompt",
|
||||
"resource:///modules/RemotePrompt.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ContentPrefServiceParent",
|
||||
"resource://gre/modules/ContentPrefServiceParent.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
|
||||
"resource:///modules/sessionstore/SessionStore.jsm");
|
||||
@ -507,10 +510,9 @@ BrowserGlue.prototype = {
|
||||
BrowserUITelemetry.init();
|
||||
ContentSearch.init();
|
||||
|
||||
if (Services.appinfo.browserTabsRemote) {
|
||||
ContentClick.init();
|
||||
RemotePrompt.init();
|
||||
}
|
||||
ContentClick.init();
|
||||
RemotePrompt.init();
|
||||
ContentPrefServiceParent.init();
|
||||
|
||||
LoginManagerParent.init();
|
||||
|
||||
|
@ -29,7 +29,7 @@ let EXPORTED_SYMBOLS = [
|
||||
const { interfaces: Ci, classes: Cc, results: Cr, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/ContentPrefUtils.jsm");
|
||||
Cu.import("resource://gre/modules/ContentPrefStore.jsm");
|
||||
|
||||
function ContentPrefService2(cps) {
|
||||
@ -823,39 +823,6 @@ ContentPrefService2.prototype = {
|
||||
},
|
||||
};
|
||||
|
||||
function ContentPref(domain, name, value) {
|
||||
this.domain = domain;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
ContentPref.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPref]),
|
||||
};
|
||||
|
||||
function cbHandleResult(callback, pref) {
|
||||
safeCallback(callback, "handleResult", [pref]);
|
||||
}
|
||||
|
||||
function cbHandleCompletion(callback, reason) {
|
||||
safeCallback(callback, "handleCompletion", [reason]);
|
||||
}
|
||||
|
||||
function cbHandleError(callback, nsresult) {
|
||||
safeCallback(callback, "handleError", [nsresult]);
|
||||
}
|
||||
|
||||
function safeCallback(callbackObj, methodName, args) {
|
||||
if (!callbackObj || typeof(callbackObj[methodName]) != "function")
|
||||
return;
|
||||
try {
|
||||
callbackObj[methodName].apply(callbackObj, args);
|
||||
}
|
||||
catch (err) {
|
||||
Cu.reportError(err);
|
||||
}
|
||||
}
|
||||
|
||||
function checkGroupArg(group) {
|
||||
if (!group || typeof(group) != "string")
|
||||
throw invalidArg("domain must be nonempty string.");
|
||||
|
236
toolkit/components/contentprefs/ContentPrefServiceChild.jsm
Normal file
236
toolkit/components/contentprefs/ContentPrefServiceChild.jsm
Normal file
@ -0,0 +1,236 @@
|
||||
/* vim: set ts=2 sw=2 sts=2 et 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "ContentPrefServiceChild" ];
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/ContentPrefUtils.jsm");
|
||||
Cu.import("resource://gre/modules/ContentPrefStore.jsm");
|
||||
|
||||
// We only need one bit of information out of the context.
|
||||
function contextArg(context) {
|
||||
return (context && context.usePrivateBrowsing) ?
|
||||
{ usePrivateBrowsing: true } :
|
||||
null;
|
||||
}
|
||||
|
||||
function NYI() {
|
||||
throw new Error("Do not add any new users of these functions");
|
||||
}
|
||||
|
||||
function CallbackCaller(callback) {
|
||||
this._callback = callback;
|
||||
}
|
||||
|
||||
CallbackCaller.prototype = {
|
||||
handleResult: function(contentPref) {
|
||||
cbHandleResult(this._callback,
|
||||
new ContentPref(contentPref.domain,
|
||||
contentPref.name,
|
||||
contentPref.value));
|
||||
},
|
||||
|
||||
handleError: function(result) {
|
||||
cbHandleError(this._callback, result);
|
||||
},
|
||||
|
||||
handleCompletion: function(reason) {
|
||||
cbHandleCompletion(this._callback, reason);
|
||||
},
|
||||
};
|
||||
|
||||
let ContentPrefServiceChild = {
|
||||
QueryInterface: XPCOMUtils.generateQI([ Ci.nsIContentPrefService2 ]),
|
||||
|
||||
// Map from pref name -> set of observers
|
||||
_observers: new Map(),
|
||||
|
||||
_mm: Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageSender),
|
||||
|
||||
_getRandomId: function() {
|
||||
return Cc["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Ci.nsIUUIDGenerator).generateUUID().toString();
|
||||
},
|
||||
|
||||
// Map from random ID string -> CallbackCaller, per request
|
||||
_requests: new Map(),
|
||||
|
||||
init: function() {
|
||||
this._mm.addMessageListener("ContentPrefs:HandleResult", this);
|
||||
this._mm.addMessageListener("ContentPrefs:HandleError", this);
|
||||
this._mm.addMessageListener("ContentPrefs:HandleCompletion", this);
|
||||
},
|
||||
|
||||
receiveMessage: function(msg) {
|
||||
let data = msg.data;
|
||||
let callback;
|
||||
switch (msg.name) {
|
||||
case "ContentPrefs:HandleResult":
|
||||
callback = this._requests.get(data.requestId);
|
||||
callback.handleResult(data.contentPref);
|
||||
break;
|
||||
|
||||
case "ContentPrefs:HandleError":
|
||||
callback = this._requests.get(data.requestId);
|
||||
callback.handleError(data.error);
|
||||
break;
|
||||
|
||||
case "ContentPrefs:HandleCompletion":
|
||||
callback = this._requests.get(data.requestId);
|
||||
this._requests.delete(data.requestId);
|
||||
callback.handleCompletion(data.reason);
|
||||
break;
|
||||
|
||||
case "ContentPrefs:NotifyObservers": {
|
||||
let observerList = this._observers.get(data.name);
|
||||
if (!observerList)
|
||||
break;
|
||||
|
||||
for (let observer of observerList) {
|
||||
safeCallback(observer, data.callback, data.args);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_callFunction: function(call, args, callback) {
|
||||
let requestId = this._getRandomId();
|
||||
let data = { call: call, args: args, requestId: requestId };
|
||||
|
||||
this._mm.sendAsyncMessage("ContentPrefs:FunctionCall", data);
|
||||
|
||||
this._requests.set(requestId, new CallbackCaller(callback));
|
||||
},
|
||||
|
||||
getByName: function(name, context, callback) {
|
||||
return this._callFunction("getByName",
|
||||
[ name, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
getByDomainAndName: function(domain, name, context, callback) {
|
||||
return this._callFunction("getByDomainAndName",
|
||||
[ domain, name, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
getBySubdomainAndName: function(domain, name, context, callback) {
|
||||
return this._callFunction("getBySubdomainAndName",
|
||||
[ domain, name, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
getGlobal: function(name, context, callback) {
|
||||
return this._callFunction("getGlobal",
|
||||
[ name, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
getCachedByDomainAndName: NYI,
|
||||
getCachedBySubdomainAndName: NYI,
|
||||
getCachedGlobal: NYI,
|
||||
|
||||
set: function(domain, name, value, context, callback) {
|
||||
this._callFunction("set",
|
||||
[ domain, name, value, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
setGlobal: function(name, value, context, callback) {
|
||||
this._callFunction("setGlobal",
|
||||
[ name, value, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
removeByDomainAndName: function(domain, name, context, callback) {
|
||||
this._callFunction("removeByDomainAndName",
|
||||
[ domain, name, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
removeBySubdomainAndName: function(domain, name, context, callback) {
|
||||
this._callFunction("removeBySubdomainAndName",
|
||||
[ domain, name, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
removeGlobal: function(name, context, callback) {
|
||||
this._callFunction("removeGlobal", [ name, contextArg(context) ], callback);
|
||||
},
|
||||
|
||||
removeByDomain: function(domain, context, callback) {
|
||||
this._callFunction("removeByDomain", [ domain, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
removeBySubdomain: function(domain, context, callback) {
|
||||
this._callFunction("removeBySubdomain", [ domain, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
removeByName: function(name, context, callback) {
|
||||
this._callFunction("removeByName", [ name, value, contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
removeAllDomains: function(context, callback) {
|
||||
this._callFunction("removeAllDomains", [ contextArg(context) ], callback);
|
||||
},
|
||||
|
||||
removeAllGlobals: function(context, callback) {
|
||||
this._callFunction("removeAllGlobals", [ contextArg(context) ],
|
||||
callback);
|
||||
},
|
||||
|
||||
addObserverForName: function(name, observer) {
|
||||
let set = this._observers.get(name);
|
||||
if (!set) {
|
||||
set = new Set();
|
||||
if (this._observers.size === 0) {
|
||||
// This is the first observer of any kind. Start listening for changes.
|
||||
this._mm.addMessageListener("ContentPrefs:NotifyObservers", this);
|
||||
}
|
||||
|
||||
// This is the first observer for this name. Start listening for changes
|
||||
// to it.
|
||||
this._mm.sendAsyncMessage("ContentPrefs:AddObserverForName", { name: name });
|
||||
this._observers.set(name, set);
|
||||
}
|
||||
|
||||
set.add(observer);
|
||||
},
|
||||
|
||||
removeObserverForName: function(name, observer) {
|
||||
let set = this._observers.get(name);
|
||||
if (!set)
|
||||
return;
|
||||
|
||||
set.delete(observer);
|
||||
if (set.size === 0) {
|
||||
// This was the last observer for this name. Stop listening for changes.
|
||||
this._mm.sendAsyncMessage("ContentPrefs:RemoveObserverForName", { name: name });
|
||||
|
||||
this._observers.delete(name);
|
||||
if (this._observers.size === 0) {
|
||||
// This was the last observer for this process. Stop listing for all
|
||||
// changes.
|
||||
this._mm.removeMessageListener("ContentPrefs:NotifyObservers", this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
extractDomain: NYI
|
||||
};
|
||||
|
||||
ContentPrefServiceChild.init();
|
127
toolkit/components/contentprefs/ContentPrefServiceParent.jsm
Normal file
127
toolkit/components/contentprefs/ContentPrefServiceParent.jsm
Normal file
@ -0,0 +1,127 @@
|
||||
/* vim: set ts=2 sw=2 sts=2 et 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "ContentPrefServiceParent" ];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
let ContentPrefServiceParent = {
|
||||
_cps2: null,
|
||||
|
||||
init: function() {
|
||||
let globalMM = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageListenerManager);
|
||||
|
||||
this._cps2 = Cc["@mozilla.org/content-pref/service;1"]
|
||||
.getService(Ci.nsIContentPrefService2);
|
||||
|
||||
globalMM.addMessageListener("ContentPrefs:FunctionCall", this);
|
||||
|
||||
let observerChangeHandler = this.handleObserverChange.bind(this);
|
||||
globalMM.addMessageListener("ContentPrefs:AddObserverForName", observerChangeHandler);
|
||||
globalMM.addMessageListener("ContentPrefs:RemoveObserverForName", observerChangeHandler);
|
||||
globalMM.addMessageListener("child-process-shutdown", observerChangeHandler);
|
||||
},
|
||||
|
||||
// Map from message manager -> content pref observer.
|
||||
_observers: new Map(),
|
||||
|
||||
handleObserverChange: function(msg) {
|
||||
let observer = this._observers.get(msg.target);
|
||||
if (msg.name === "child-process-shutdown") {
|
||||
// If we didn't have any observers for this child process, don't do
|
||||
// anything.
|
||||
if (!observer)
|
||||
return;
|
||||
|
||||
for (let i of observer._names) {
|
||||
this._cps2.removeObserverForName(i, observer);
|
||||
}
|
||||
|
||||
this._observers.delete(msg.target);
|
||||
return;
|
||||
}
|
||||
|
||||
let prefName = msg.data.name;
|
||||
if (msg.name === "ContentPrefs:AddObserverForName") {
|
||||
// The child process is responsible for not adding multiple parent
|
||||
// observers for the same name.
|
||||
if (!observer) {
|
||||
observer = {
|
||||
onContentPrefSet: function(group, name, value) {
|
||||
msg.target.sendAsyncMessage("ContentPrefs:NotifyObservers",
|
||||
{ name: name, callback: "onContentPrefSet",
|
||||
args: [ group, name, value ] });
|
||||
},
|
||||
|
||||
onContentPrefRemoved: function(group, name) {
|
||||
msg.target.sendAsyncMessage("ContentPrefs:NotifyObservers",
|
||||
{ name: name, callback: "onContentPrefRemoved",
|
||||
args: [ group, name ] });
|
||||
},
|
||||
|
||||
// The names we're using this observer object for, used to keep track
|
||||
// of the number of names we care about as well as for removing this
|
||||
// observer if its associated process goes away.
|
||||
_names: new Set()
|
||||
};
|
||||
|
||||
this._observers.set(msg.target, observer);
|
||||
}
|
||||
|
||||
observer._names.add(prefName);
|
||||
|
||||
this._cps2.addObserverForName(prefName, observer);
|
||||
} else {
|
||||
// RemoveObserverForName
|
||||
|
||||
// We must have an observer.
|
||||
this._cps2.removeObserverForName(prefName, observer);
|
||||
|
||||
observer._names.delete(prefName);
|
||||
if (observer._names.size === 0) {
|
||||
// This was the last use for this observer.
|
||||
this._observers.delete(msg.target);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function(msg) {
|
||||
let data = msg.data;
|
||||
|
||||
let args = data.args;
|
||||
let requestId = data.requestId;
|
||||
|
||||
let listener = {
|
||||
handleResult: function(pref) {
|
||||
msg.target.sendAsyncMessage("ContentPrefs:HandleResult",
|
||||
{ requestId: requestId,
|
||||
contentPref: pref });
|
||||
},
|
||||
|
||||
handleError: function(error) {
|
||||
msg.target.sendAsyncMessage("ContentPrefs:HandleError",
|
||||
{ requestId: requestId,
|
||||
error: error });
|
||||
},
|
||||
|
||||
handleCompletion: function(reason) {
|
||||
msg.target.sendAsyncMessage("ContentPrefs:HandleCompletion",
|
||||
{ requestId: requestId,
|
||||
reason: reason });
|
||||
}
|
||||
};
|
||||
|
||||
// Push our special listener.
|
||||
args.push(listener);
|
||||
|
||||
// And call the function.
|
||||
this._cps2[data.call](...args);
|
||||
}
|
||||
};
|
52
toolkit/components/contentprefs/ContentPrefUtils.jsm
Normal file
52
toolkit/components/contentprefs/ContentPrefUtils.jsm
Normal file
@ -0,0 +1,52 @@
|
||||
/* vim: set ts=2 sw=2 sts=2 et 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"ContentPref",
|
||||
"cbHandleResult",
|
||||
"cbHandleError",
|
||||
"cbHandleCompletion",
|
||||
"safeCallback",
|
||||
];
|
||||
|
||||
const { interfaces: Ci, classes: Cc, results: Cr, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function ContentPref(domain, name, value) {
|
||||
this.domain = domain;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
ContentPref.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPref]),
|
||||
};
|
||||
|
||||
function cbHandleResult(callback, pref) {
|
||||
safeCallback(callback, "handleResult", [pref]);
|
||||
}
|
||||
|
||||
function cbHandleCompletion(callback, reason) {
|
||||
safeCallback(callback, "handleCompletion", [reason]);
|
||||
}
|
||||
|
||||
function cbHandleError(callback, nsresult) {
|
||||
safeCallback(callback, "handleError", [nsresult]);
|
||||
}
|
||||
|
||||
function safeCallback(callbackObj, methodName, args) {
|
||||
if (!callbackObj || typeof(callbackObj[methodName]) != "function")
|
||||
return;
|
||||
try {
|
||||
callbackObj[methodName].apply(callbackObj, args);
|
||||
}
|
||||
catch (err) {
|
||||
Cu.reportError(err);
|
||||
}
|
||||
}
|
@ -9,6 +9,10 @@ XPCSHELL_TESTS_MANIFESTS += [
|
||||
'tests/unit_cps2/xpcshell.ini',
|
||||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += [
|
||||
'tests/mochitest/mochitest.ini'
|
||||
]
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'nsContentPrefService.js',
|
||||
'nsContentPrefService.manifest',
|
||||
@ -17,6 +21,9 @@ EXTRA_COMPONENTS += [
|
||||
EXTRA_JS_MODULES += [
|
||||
'ContentPrefInstance.jsm',
|
||||
'ContentPrefService2.jsm',
|
||||
'ContentPrefServiceChild.jsm',
|
||||
'ContentPrefServiceParent.jsm',
|
||||
'ContentPrefStore.jsm',
|
||||
'ContentPrefUtils.jsm',
|
||||
]
|
||||
|
||||
|
@ -10,8 +10,14 @@ const Cu = Components.utils;
|
||||
const CACHE_MAX_GROUP_ENTRIES = 100;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function ContentPrefService() {
|
||||
if (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) {
|
||||
return Cu.import("resource://gre/modules/ContentPrefServiceChild.jsm")
|
||||
.ContentPrefServiceChild;
|
||||
}
|
||||
|
||||
// If this throws an exception, it causes the getService call to fail,
|
||||
// but the next time a consumer tries to retrieve the service, we'll try
|
||||
// to initialize the database again, which might work if the failure
|
||||
|
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
|
||||
[test_remoteContentPrefs.html]
|
||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s #bug 783513 # b2g(nested ipc not working) b2g-debug(nested ipc not working) b2g-desktop(nested ipc not working)
|
@ -0,0 +1,296 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for nsIContentPrefService2 in child processes</title>
|
||||
<script type="application/javascript"
|
||||
src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="application/javascript;version=1.8">
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const childFrameURL =
|
||||
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
|
||||
|
||||
function childFrameScript() {
|
||||
"use strict";
|
||||
|
||||
function Tester(resultArray) {
|
||||
this.results = [];
|
||||
}
|
||||
|
||||
Tester.prototype.is =
|
||||
function(a, b, note) {
|
||||
this.results.push([a === b, note + " (" + a + ", " + b + ")"]);
|
||||
};
|
||||
Tester.prototype.ok =
|
||||
function(b, note) {
|
||||
this.results.push([b != false, note]);
|
||||
};
|
||||
|
||||
var cps = Components.classes["@mozilla.org/content-pref/service;1"]
|
||||
.getService(Components.interfaces.nsIContentPrefService2);
|
||||
|
||||
let test = null;
|
||||
function* test1(message) {
|
||||
let tester = new Tester();
|
||||
|
||||
tester.ok(cps !== null, "got the content pref service");
|
||||
|
||||
cps.setGlobal("testing", 42, null, {
|
||||
handleCompletion: function(reason) {
|
||||
tester.is(reason, 0, "set a pref?");
|
||||
test.next();
|
||||
}
|
||||
});
|
||||
|
||||
yield;
|
||||
|
||||
let numResults = 0;
|
||||
cps.getGlobal("testing", null, {
|
||||
handleResult: function(pref) {
|
||||
numResults++;
|
||||
tester.is(pref.name, "testing", "pref has the right name");
|
||||
tester.is(pref.value, 42, "pref has the right value");
|
||||
},
|
||||
|
||||
handleCompletion: function(reason) {
|
||||
tester.is(reason, 0, "get a pref?");
|
||||
tester.is(numResults, 1, "got the right number of prefs");
|
||||
tester.is(test.next().done, true, "done with test1");
|
||||
message.target.sendAsyncMessage("testRemoteContentPrefs:test1Finished",
|
||||
{ results: tester.results });
|
||||
}
|
||||
});
|
||||
|
||||
yield;
|
||||
}
|
||||
|
||||
function* test2(message) {
|
||||
let tester = new Tester();
|
||||
|
||||
let observer;
|
||||
let removed = false;
|
||||
cps.addObserverForName("testName", observer = {
|
||||
onContentPrefSet: function(group, name, value) {
|
||||
if (removed) {
|
||||
message.target.sendAsyncMessage("testRemoteContentPrefs:fail",
|
||||
{ reason: "unexpected notification" });
|
||||
}
|
||||
tester.is(group, null, "group should be null");
|
||||
tester.is(name, "testName", "should only see testName");
|
||||
tester.is(value, 42, "value should be correct");
|
||||
|
||||
message.target.sendAsyncMessage("testRemoteContentPrefs:test2poke2", {})
|
||||
},
|
||||
|
||||
onContentPrefRemoved: function(group, name) {
|
||||
tester.is(group, null, "group should be null");
|
||||
tester.is(name, "testName");
|
||||
tester.is(test.next().done, true, "should be done with test2");
|
||||
|
||||
cps.removeObserverForName("testName", observer);
|
||||
removed = true;
|
||||
|
||||
message.target.sendAsyncMessage("testRemoteContentPrefs:test2Finished",
|
||||
{ results: tester.results });
|
||||
}
|
||||
});
|
||||
|
||||
message.target.sendAsyncMessage("testRemoteContentPrefs:test2poke", {});
|
||||
yield;
|
||||
}
|
||||
|
||||
function* test3(message) {
|
||||
let tester = new Tester();
|
||||
|
||||
cps.setGlobal("testName", 42, null, {
|
||||
handleCompletion: function(reason) {
|
||||
tester.is(reason, 0, "set a pref");
|
||||
cps.set("http://mochi.test", "testpref", "str", null, {
|
||||
handleCompletion: function(reason) {
|
||||
tester.is(reason, 0, "set a pref");
|
||||
test.next();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
yield;
|
||||
|
||||
cps.removeByDomain("http://mochi.test", null, {
|
||||
handleCompletion: function(reason) {
|
||||
tester.is(reason, 0, "remove succeeded");
|
||||
cps.getByDomainAndName("http://mochi.test", "testpref", null, {
|
||||
handleResult: function() {
|
||||
message.target.sendAsyncMessage("testRemoteContentPrefs:fail",
|
||||
{ reason: "got removed pref in test3" });
|
||||
},
|
||||
handleCompletion: function() {
|
||||
test.next();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
yield;
|
||||
|
||||
message.target.sendAsyncMessage("testRemoteContentPrefs:test3Finished",
|
||||
{ results: tester.results });
|
||||
}
|
||||
|
||||
function* test4(message) {
|
||||
let tester = new Tester();
|
||||
|
||||
let prefObserver = {
|
||||
onContentPrefSet: function(group, name, value) {
|
||||
test.next({ group: group, name: name, value: value });
|
||||
},
|
||||
onContentPrefRemoved: function(group, name) {
|
||||
test.next({ group: group, name: name });
|
||||
}
|
||||
};
|
||||
|
||||
addMessageListener("testRemoteContentPrefs:prefResults", (msg) => {
|
||||
test.next(msg.data.results);
|
||||
});
|
||||
|
||||
cps.addObserverForName("test", prefObserver);
|
||||
|
||||
cps.set("http://mochi.test", "test", 42, { usePrivateBrowsing: true });
|
||||
let event = yield;
|
||||
tester.is(event.name, "test");
|
||||
|
||||
message.target.sendAsyncMessage("testRemoteContentPrefs:getPref",
|
||||
{ group: "http://mochi.test", name: "test" });
|
||||
|
||||
let results = yield;
|
||||
tester.is(results.length, 0, "should not have seen the pb pref");
|
||||
|
||||
message.target.sendAsyncMessage("testRemoteContentPrefs:test4Finished",
|
||||
{ results: tester.results });
|
||||
}
|
||||
|
||||
addMessageListener("testRemoteContentPrefs:test1", function(message) {
|
||||
test = test1(message);
|
||||
test.next();
|
||||
});
|
||||
addMessageListener("testRemoteContentPrefs:test2", function(message) {
|
||||
test = test2(message);
|
||||
test.next();
|
||||
});
|
||||
addMessageListener("testRemoteContentPrefs:test3", function(message) {
|
||||
test = test3(message);
|
||||
test.next();
|
||||
});
|
||||
addMessageListener("testRemoteContentPrefs:test4", function(message) {
|
||||
test = test4(message);
|
||||
test.next();
|
||||
});
|
||||
}
|
||||
|
||||
function processResults(results) {
|
||||
for (let i of results) {
|
||||
ok(...i);
|
||||
}
|
||||
}
|
||||
|
||||
let test;
|
||||
function* testStructure(mm) {
|
||||
let lastResult;
|
||||
|
||||
function testDone(msg) {
|
||||
test.next(msg.data);
|
||||
}
|
||||
|
||||
mm.addMessageListener("testRemoteContentPrefs:test1Finished", testDone);
|
||||
mm.addMessageListener("testRemoteContentPrefs:test2Finished", testDone);
|
||||
mm.addMessageListener("testRemoteContentPrefs:test3Finished", testDone);
|
||||
mm.addMessageListener("testRemoteContentPrefs:test4Finished", testDone);
|
||||
|
||||
mm.addMessageListener("testRemoteContentPrefs:fail", function(msg) {
|
||||
ok(false, msg.data.reason);
|
||||
});
|
||||
|
||||
mm.sendAsyncMessage("testRemoteContentPrefs:test1", {});
|
||||
lastResult = yield;
|
||||
processResults(lastResult.results);
|
||||
|
||||
var cps = SpecialPowers.Cc["@mozilla.org/content-pref/service;1"]
|
||||
.getService(SpecialPowers.Ci.nsIContentPrefService2);
|
||||
mm.sendAsyncMessage("testRemoteContentPrefs:test2", {});
|
||||
mm.addMessageListener("testRemoteContentPrefs:test2poke", function() {
|
||||
cps.setGlobal("testName", 42, null);
|
||||
});
|
||||
mm.addMessageListener("testRemoteContentPrefs:test2poke2", function() {
|
||||
cps.removeGlobal("testName", null);
|
||||
});
|
||||
|
||||
lastResult = yield;
|
||||
processResults(lastResult.results);
|
||||
|
||||
mm.sendAsyncMessage("testRemoteContentPrefs:test3", {});
|
||||
lastResult = yield;
|
||||
processResults(lastResult.results);
|
||||
|
||||
mm.addMessageListener("testRemoteContentPrefs:getPref", function(msg) {
|
||||
let results = [];
|
||||
cps.getByDomainAndName(msg.data.group, msg.data.name, null, {
|
||||
handleResult: function(pref) {
|
||||
results.push(pref);
|
||||
},
|
||||
handleCompletion: function(reason) {
|
||||
mm.sendAsyncMessage("testRemoteContentPrefs:prefResults",
|
||||
{ results: results });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
mm.sendAsyncMessage("testRemoteContentPrefs:test4", {});
|
||||
lastResult = yield;
|
||||
processResults(lastResult.results);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
info("Browser prefs set.");
|
||||
|
||||
let iframe = document.createElement("iframe");
|
||||
SpecialPowers.wrap(iframe).mozbrowser = true;
|
||||
iframe.id = "iframe";
|
||||
iframe.src = childFrameURL;
|
||||
|
||||
iframe.addEventListener("mozbrowserloadend", function() {
|
||||
info("Got iframe load event.");
|
||||
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
|
||||
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
|
||||
false);
|
||||
|
||||
test = testStructure(mm);
|
||||
test.next();
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
addEventListener("load", function() {
|
||||
info("Got load event.");
|
||||
|
||||
SpecialPowers.addPermission("browser", true, document);
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["dom.ipc.browser_frames.oop_by_default", true],
|
||||
["dom.mozBrowserFramesEnabled", true],
|
||||
["browser.pagethumbnails.capturing_disabled", true]
|
||||
]
|
||||
}, runTests);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user