Bug 1943650 - Command-line --help output misformatted after --dbus-service. r=emilio
[gecko.git] / toolkit / components / contentprefs / ContentPrefServiceParent.sys.mjs
blob13ef8e871c6ec4b51be31e7c0d1e3a4a1de346da
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 { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
8 const lazy = {};
10 ChromeUtils.defineESModuleGetters(lazy, {
11   _methodsCallableFromChild: "resource://gre/modules/ContentPrefUtils.sys.mjs",
12 });
14 let loadContext = Cu.createLoadContext();
15 let privateLoadContext = Cu.createPrivateLoadContext();
17 function contextArg(context) {
18   return context && context.usePrivateBrowsing
19     ? privateLoadContext
20     : loadContext;
23 export class ContentPrefsParent extends JSProcessActorParent {
24   constructor() {
25     super();
27     // The names we're using this observer object for, used to keep track
28     // of the number of names we care about as well as for removing this
29     // observer if its associated process goes away.
30     this._prefsToObserve = new Set();
31     this._observer = null;
32   }
34   didDestroy() {
35     if (this._observer) {
36       for (let i of this._prefsToObserve) {
37         lazy.cps2.removeObserverForName(i, this._observer);
38       }
39       this._observer = null;
40     }
41   }
43   receiveMessage(msg) {
44     switch (msg.name) {
45       case "ContentPrefs:AddObserverForName": {
46         // The child process is responsible for not adding multiple parent
47         // observers for the same name.
48         let actor = this;
49         if (!this._observer) {
50           this._observer = {
51             onContentPrefSet(group, name, value, isPrivate) {
52               actor.onContentPrefSet(group, name, value, isPrivate);
53             },
54             onContentPrefRemoved(group, name, isPrivate) {
55               actor.onContentPrefRemoved(group, name, isPrivate);
56             },
57           };
58         }
60         let prefName = msg.data.name;
61         this._prefsToObserve.add(prefName);
62         lazy.cps2.addObserverForName(prefName, this._observer);
63         break;
64       }
66       case "ContentPrefs:RemoveObserverForName": {
67         let prefName = msg.data.name;
68         this._prefsToObserve.delete(prefName);
69         if (this._prefsToObserve.size == 0) {
70           lazy.cps2.removeObserverForName(prefName, this._observer);
71           this._observer = null;
72         }
73         break;
74       }
76       case "ContentPrefs:FunctionCall":
77         let data = msg.data;
78         let signature;
80         if (
81           !lazy._methodsCallableFromChild.some(([method, args]) => {
82             if (method == data.call) {
83               signature = args;
84               return true;
85             }
86             return false;
87           })
88         ) {
89           throw new Error(`Can't call ${data.call} from child!`);
90         }
92         let actor = this;
93         let args = data.args;
95         return new Promise(() => {
96           let listener = {
97             handleResult(pref) {
98               actor.sendAsyncMessage("ContentPrefs:HandleResult", {
99                 requestId: data.requestId,
100                 contentPref: {
101                   domain: pref.domain,
102                   name: pref.name,
103                   value: pref.value,
104                 },
105               });
106             },
108             handleError(error) {
109               actor.sendAsyncMessage("ContentPrefs:HandleError", {
110                 requestId: data.requestId,
111                 error,
112               });
113             },
114             handleCompletion(reason) {
115               actor.sendAsyncMessage("ContentPrefs:HandleCompletion", {
116                 requestId: data.requestId,
117                 reason,
118               });
119             },
120           };
121           // Push our special listener.
122           args.push(listener);
124           // Process context argument for forwarding
125           let contextIndex = signature.indexOf("context");
126           if (contextIndex > -1) {
127             args[contextIndex] = contextArg(args[contextIndex]);
128           }
130           // And call the function.
131           lazy.cps2[data.call](...args);
132         });
133     }
135     return undefined;
136   }
138   onContentPrefSet(group, name, value, isPrivate) {
139     this.sendAsyncMessage("ContentPrefs:NotifyObservers", {
140       name,
141       callback: "onContentPrefSet",
142       args: [group, name, value, isPrivate],
143     });
144   }
146   onContentPrefRemoved(group, name, isPrivate) {
147     this.sendAsyncMessage("ContentPrefs:NotifyObservers", {
148       name,
149       callback: "onContentPrefRemoved",
150       args: [group, name, isPrivate],
151     });
152   }
155 XPCOMUtils.defineLazyServiceGetter(
156   lazy,
157   "cps2",
158   "@mozilla.org/content-pref/service;1",
159   "nsIContentPrefService2"