From 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:47:29 +0200 Subject: Adding upstream version 115.8.0esr. Signed-off-by: Daniel Baumann --- .../contentprefs/ContentPrefServiceChild.sys.mjs | 185 +++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 toolkit/components/contentprefs/ContentPrefServiceChild.sys.mjs (limited to 'toolkit/components/contentprefs/ContentPrefServiceChild.sys.mjs') diff --git a/toolkit/components/contentprefs/ContentPrefServiceChild.sys.mjs b/toolkit/components/contentprefs/ContentPrefServiceChild.sys.mjs new file mode 100644 index 0000000000..38d0d3c160 --- /dev/null +++ b/toolkit/components/contentprefs/ContentPrefServiceChild.sys.mjs @@ -0,0 +1,185 @@ +/* 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 { + ContentPref, + _methodsCallableFromChild, + cbHandleCompletion, + cbHandleError, + cbHandleResult, + safeCallback, +} from "resource://gre/modules/ContentPrefUtils.sys.mjs"; + +// 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(contentPref) { + cbHandleResult( + this._callback, + new ContentPref(contentPref.domain, contentPref.name, contentPref.value) + ); + }, + + handleError(result) { + cbHandleError(this._callback, result); + }, + + handleCompletion(reason) { + cbHandleCompletion(this._callback, reason); + }, +}; + +export class ContentPrefsChild extends JSProcessActorChild { + constructor() { + super(); + + // Map from pref name -> set of observers + this._observers = new Map(); + + // Map from random ID string -> CallbackCaller, per request + this._requests = new Map(); + } + + _getRandomId() { + return Services.uuid.generateUUID().toString(); + } + + receiveMessage(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(call, args, callback) { + let requestId = this._getRandomId(); + let data = { call, args, requestId }; + + this._requests.set(requestId, new CallbackCaller(callback)); + this.sendAsyncMessage("ContentPrefs:FunctionCall", data); + } + + addObserverForName(name, observer) { + let set = this._observers.get(name); + if (!set) { + set = new Set(); + + // This is the first observer for this name. Start listening for changes + // to it. + this.sendAsyncMessage("ContentPrefs:AddObserverForName", { + name, + }); + this._observers.set(name, set); + } + + set.add(observer); + } + + removeObserverForName(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.sendAsyncMessage("ContentPrefs:RemoveObserverForName", { + name, + }); + + this._observers.delete(name); + } + } +} + +export var ContentPrefServiceChild = { + QueryInterface: ChromeUtils.generateQI(["nsIContentPrefService2"]), + + addObserverForName: (name, observer) => { + ChromeUtils.domProcessChild + .getActor("ContentPrefs") + .addObserverForName(name, observer); + }, + removeObserverForName: (name, observer) => { + ChromeUtils.domProcessChild + .getActor("ContentPrefs") + .removeObserverForName(name, observer); + }, + + getCachedByDomainAndName: NYI, + getCachedBySubdomainAndName: NYI, + getCachedGlobal: NYI, + extractDomain: NYI, +}; + +function forwardMethodToParent(method, signature, ...args) { + // Ignore superfluous arguments + args = args.slice(0, signature.length); + + // Process context argument for forwarding + let contextIndex = signature.indexOf("context"); + if (contextIndex > -1) { + args[contextIndex] = contextArg(args[contextIndex]); + } + // Take out the callback argument, if present. + let callbackIndex = signature.indexOf("callback"); + let callback = null; + if (callbackIndex > -1 && args.length > callbackIndex) { + callback = args.splice(callbackIndex, 1)[0]; + } + + let actor = ChromeUtils.domProcessChild.getActor("ContentPrefs"); + actor.callFunction(method, args, callback); +} + +for (let [method, signature] of _methodsCallableFromChild) { + ContentPrefServiceChild[method] = forwardMethodToParent.bind( + ContentPrefServiceChild, + method, + signature + ); +} -- cgit v1.2.3