summaryrefslogtreecommitdiffstats
path: root/toolkit/components/contentprefs/ContentPrefServiceParent.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/contentprefs/ContentPrefServiceParent.sys.mjs')
-rw-r--r--toolkit/components/contentprefs/ContentPrefServiceParent.sys.mjs160
1 files changed, 160 insertions, 0 deletions
diff --git a/toolkit/components/contentprefs/ContentPrefServiceParent.sys.mjs b/toolkit/components/contentprefs/ContentPrefServiceParent.sys.mjs
new file mode 100644
index 0000000000..66b4a02741
--- /dev/null
+++ b/toolkit/components/contentprefs/ContentPrefServiceParent.sys.mjs
@@ -0,0 +1,160 @@
+/* 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/. */
+
+import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
+
+const lazy = {};
+
+ChromeUtils.defineESModuleGetters(lazy, {
+ _methodsCallableFromChild: "resource://gre/modules/ContentPrefUtils.sys.mjs",
+});
+
+let loadContext = Cu.createLoadContext();
+let privateLoadContext = Cu.createPrivateLoadContext();
+
+function contextArg(context) {
+ return context && context.usePrivateBrowsing
+ ? privateLoadContext
+ : loadContext;
+}
+
+export class ContentPrefsParent extends JSProcessActorParent {
+ constructor() {
+ super();
+
+ // 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.
+ this._prefsToObserve = new Set();
+ this._observer = null;
+ }
+
+ didDestroy() {
+ if (this._observer) {
+ for (let i of this._prefsToObserve) {
+ lazy.cps2.removeObserverForName(i, this._observer);
+ }
+ this._observer = null;
+ }
+ }
+
+ receiveMessage(msg) {
+ switch (msg.name) {
+ case "ContentPrefs:AddObserverForName": {
+ // The child process is responsible for not adding multiple parent
+ // observers for the same name.
+ let actor = this;
+ if (!this._observer) {
+ this._observer = {
+ onContentPrefSet(group, name, value, isPrivate) {
+ actor.onContentPrefSet(group, name, value, isPrivate);
+ },
+ onContentPrefRemoved(group, name, isPrivate) {
+ actor.onContentPrefRemoved(group, name, isPrivate);
+ },
+ };
+ }
+
+ let prefName = msg.data.name;
+ this._prefsToObserve.add(prefName);
+ lazy.cps2.addObserverForName(prefName, this._observer);
+ break;
+ }
+
+ case "ContentPrefs:RemoveObserverForName": {
+ let prefName = msg.data.name;
+ this._prefsToObserve.delete(prefName);
+ if (this._prefsToObserve.size == 0) {
+ lazy.cps2.removeObserverForName(prefName, this._observer);
+ this._observer = null;
+ }
+ break;
+ }
+
+ case "ContentPrefs:FunctionCall":
+ let data = msg.data;
+ let signature;
+
+ if (
+ !lazy._methodsCallableFromChild.some(([method, args]) => {
+ if (method == data.call) {
+ signature = args;
+ return true;
+ }
+ return false;
+ })
+ ) {
+ throw new Error(`Can't call ${data.call} from child!`);
+ }
+
+ let actor = this;
+ let args = data.args;
+
+ return new Promise(resolve => {
+ let listener = {
+ handleResult(pref) {
+ actor.sendAsyncMessage("ContentPrefs:HandleResult", {
+ requestId: data.requestId,
+ contentPref: {
+ domain: pref.domain,
+ name: pref.name,
+ value: pref.value,
+ },
+ });
+ },
+
+ handleError(error) {
+ actor.sendAsyncMessage("ContentPrefs:HandleError", {
+ requestId: data.requestId,
+ error,
+ });
+ },
+ handleCompletion(reason) {
+ actor.sendAsyncMessage("ContentPrefs:HandleCompletion", {
+ requestId: data.requestId,
+ reason,
+ });
+ },
+ };
+ // Push our special listener.
+ args.push(listener);
+
+ // Process context argument for forwarding
+ let contextIndex = signature.indexOf("context");
+ if (contextIndex > -1) {
+ args[contextIndex] = contextArg(args[contextIndex]);
+ }
+
+ // And call the function.
+ lazy.cps2[data.call](...args);
+ });
+ }
+
+ return undefined;
+ }
+
+ onContentPrefSet(group, name, value, isPrivate) {
+ this.sendAsyncMessage("ContentPrefs:NotifyObservers", {
+ name,
+ callback: "onContentPrefSet",
+ args: [group, name, value, isPrivate],
+ });
+ }
+
+ onContentPrefRemoved(group, name, isPrivate) {
+ this.sendAsyncMessage("ContentPrefs:NotifyObservers", {
+ name,
+ callback: "onContentPrefRemoved",
+ args: [group, name, isPrivate],
+ });
+ }
+}
+
+XPCOMUtils.defineLazyServiceGetter(
+ lazy,
+ "cps2",
+ "@mozilla.org/content-pref/service;1",
+ "nsIContentPrefService2"
+);