Bug 1943650 - Command-line --help output misformatted after --dbus-service. r=emilio
[gecko.git] / toolkit / components / contentprefs / ContentPrefServiceChild.sys.mjs
blob38d0d3c16044cf935f6898d19bf6f500433a6078
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/. */
6 import {
7   ContentPref,
8   _methodsCallableFromChild,
9   cbHandleCompletion,
10   cbHandleError,
11   cbHandleResult,
12   safeCallback,
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 }
19     : null;
22 function NYI() {
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) {
32     cbHandleResult(
33       this._callback,
34       new ContentPref(contentPref.domain, contentPref.name, contentPref.value)
35     );
36   },
38   handleError(result) {
39     cbHandleError(this._callback, result);
40   },
42   handleCompletion(reason) {
43     cbHandleCompletion(this._callback, reason);
44   },
47 export class ContentPrefsChild extends JSProcessActorChild {
48   constructor() {
49     super();
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();
56   }
58   _getRandomId() {
59     return Services.uuid.generateUUID().toString();
60   }
62   receiveMessage(msg) {
63     let data = msg.data;
64     let callback;
65     switch (msg.name) {
66       case "ContentPrefs:HandleResult":
67         callback = this._requests.get(data.requestId);
68         callback.handleResult(data.contentPref);
69         break;
71       case "ContentPrefs:HandleError":
72         callback = this._requests.get(data.requestId);
73         callback.handleError(data.error);
74         break;
76       case "ContentPrefs:HandleCompletion":
77         callback = this._requests.get(data.requestId);
78         this._requests.delete(data.requestId);
79         callback.handleCompletion(data.reason);
80         break;
82       case "ContentPrefs:NotifyObservers": {
83         let observerList = this._observers.get(data.name);
84         if (!observerList) {
85           break;
86         }
88         for (let observer of observerList) {
89           safeCallback(observer, data.callback, data.args);
90         }
92         break;
93       }
94     }
95   }
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);
103   }
105   addObserverForName(name, observer) {
106     let set = this._observers.get(name);
107     if (!set) {
108       set = new Set();
110       // This is the first observer for this name. Start listening for changes
111       // to it.
112       this.sendAsyncMessage("ContentPrefs:AddObserverForName", {
113         name,
114       });
115       this._observers.set(name, set);
116     }
118     set.add(observer);
119   }
121   removeObserverForName(name, observer) {
122     let set = this._observers.get(name);
123     if (!set) {
124       return;
125     }
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", {
131         name,
132       });
134       this._observers.delete(name);
135     }
136   }
139 export var ContentPrefServiceChild = {
140   QueryInterface: ChromeUtils.generateQI(["nsIContentPrefService2"]),
142   addObserverForName: (name, observer) => {
143     ChromeUtils.domProcessChild
144       .getActor("ContentPrefs")
145       .addObserverForName(name, observer);
146   },
147   removeObserverForName: (name, observer) => {
148     ChromeUtils.domProcessChild
149       .getActor("ContentPrefs")
150       .removeObserverForName(name, observer);
151   },
153   getCachedByDomainAndName: NYI,
154   getCachedBySubdomainAndName: NYI,
155   getCachedGlobal: NYI,
156   extractDomain: 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]);
167   }
168   // Take out the callback argument, if present.
169   let callbackIndex = signature.indexOf("callback");
170   let callback = null;
171   if (callbackIndex > -1 && args.length > callbackIndex) {
172     callback = args.splice(callbackIndex, 1)[0];
173   }
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,
182     method,
183     signature
184   );