1 /* vim: set ts=2 sw=2 sts=2 et tw=80: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 _methodsCallableFromChild,
13 } from "resource://gre/modules/ContentPrefUtils.sys.mjs";
15 // We only need one bit of information out of the context.
16 function contextArg(context) {
17 return context && context.usePrivateBrowsing
18 ? { usePrivateBrowsing: true }
23 throw new Error("Do not add any new users of these functions");
26 function CallbackCaller(callback) {
27 this._callback = callback;
30 CallbackCaller.prototype = {
31 handleResult(contentPref) {
34 new ContentPref(contentPref.domain, contentPref.name, contentPref.value)
39 cbHandleError(this._callback, result);
42 handleCompletion(reason) {
43 cbHandleCompletion(this._callback, reason);
47 export class ContentPrefsChild extends JSProcessActorChild {
51 // Map from pref name -> set of observers
52 this._observers = new Map();
54 // Map from random ID string -> CallbackCaller, per request
55 this._requests = new Map();
59 return Services.uuid.generateUUID().toString();
66 case "ContentPrefs:HandleResult":
67 callback = this._requests.get(data.requestId);
68 callback.handleResult(data.contentPref);
71 case "ContentPrefs:HandleError":
72 callback = this._requests.get(data.requestId);
73 callback.handleError(data.error);
76 case "ContentPrefs:HandleCompletion":
77 callback = this._requests.get(data.requestId);
78 this._requests.delete(data.requestId);
79 callback.handleCompletion(data.reason);
82 case "ContentPrefs:NotifyObservers": {
83 let observerList = this._observers.get(data.name);
88 for (let observer of observerList) {
89 safeCallback(observer, data.callback, data.args);
97 callFunction(call, args, callback) {
98 let requestId = this._getRandomId();
99 let data = { call, args, requestId };
101 this._requests.set(requestId, new CallbackCaller(callback));
102 this.sendAsyncMessage("ContentPrefs:FunctionCall", data);
105 addObserverForName(name, observer) {
106 let set = this._observers.get(name);
110 // This is the first observer for this name. Start listening for changes
112 this.sendAsyncMessage("ContentPrefs:AddObserverForName", {
115 this._observers.set(name, set);
121 removeObserverForName(name, observer) {
122 let set = this._observers.get(name);
127 set.delete(observer);
128 if (set.size === 0) {
129 // This was the last observer for this name. Stop listening for changes.
130 this.sendAsyncMessage("ContentPrefs:RemoveObserverForName", {
134 this._observers.delete(name);
139 export var ContentPrefServiceChild = {
140 QueryInterface: ChromeUtils.generateQI(["nsIContentPrefService2"]),
142 addObserverForName: (name, observer) => {
143 ChromeUtils.domProcessChild
144 .getActor("ContentPrefs")
145 .addObserverForName(name, observer);
147 removeObserverForName: (name, observer) => {
148 ChromeUtils.domProcessChild
149 .getActor("ContentPrefs")
150 .removeObserverForName(name, observer);
153 getCachedByDomainAndName: NYI,
154 getCachedBySubdomainAndName: NYI,
155 getCachedGlobal: NYI,
159 function forwardMethodToParent(method, signature, ...args) {
160 // Ignore superfluous arguments
161 args = args.slice(0, signature.length);
163 // Process context argument for forwarding
164 let contextIndex = signature.indexOf("context");
165 if (contextIndex > -1) {
166 args[contextIndex] = contextArg(args[contextIndex]);
168 // Take out the callback argument, if present.
169 let callbackIndex = signature.indexOf("callback");
171 if (callbackIndex > -1 && args.length > callbackIndex) {
172 callback = args.splice(callbackIndex, 1)[0];
175 let actor = ChromeUtils.domProcessChild.getActor("ContentPrefs");
176 actor.callFunction(method, args, callback);
179 for (let [method, signature] of _methodsCallableFromChild) {
180 ContentPrefServiceChild[method] = forwardMethodToParent.bind(
181 ContentPrefServiceChild,