tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit fa01026f77710dc4980b0c5b93ef943466b321d6
parent c637943a81303282f79c9ba4f83651d8c7599440
Author: Alex Catarineu <acat@torproject.org>
Date:   Sun,  2 Aug 2020 19:12:25 +0200

BB 40069: Add helpers for message passing with extensions

Diffstat:
Mtoolkit/components/extensions/ExtensionParent.sys.mjs | 47+++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+), 0 deletions(-)

diff --git a/toolkit/components/extensions/ExtensionParent.sys.mjs b/toolkit/components/extensions/ExtensionParent.sys.mjs @@ -246,6 +246,8 @@ const ProxyMessenger = { /** @type {Map<number, Promise>} */ portPromises: new Map(), + _torRuntimeMessageListeners: [], + init() { this.conduit = new lazy.BroadcastConduit(ProxyMessenger, { id: "ProxyMessenger", @@ -346,6 +348,10 @@ const ProxyMessenger = { }, async recvRuntimeMessage(arg, { sender }) { + // We need to listen to some extension messages in Tor Browser + for (const listener of this._torRuntimeMessageListeners) { + listener(arg); + } arg.firstResponse = true; let kind = await this.normalizeArgs(arg, sender); arg.query = true; @@ -2411,6 +2417,45 @@ export var StartupCache = { Services.obs.addObserver(StartupCache, "startupcache-invalidate"); +async function torSendExtensionMessage(extensionId, message) { + // This should broadcast the message to all children "conduits" + // listening for a "RuntimeMessage". Those children conduits + // will either be extension background pages or other extension + // pages listening to browser.runtime.onMessage. + const result = await ProxyMessenger.conduit.castRuntimeMessage("messenger", { + extensionId, + holder: new StructuredCloneHolder("torSendExtensionMessage", null, message), + query: true, + firstResponse: true, + sender: { + id: extensionId, + envType: "addon_child", + }, + }); + return result + ? result.value + : Promise.reject({ message: ERROR_NO_RECEIVERS }); +} + +async function torWaitForExtensionMessage(extensionId, checker) { + return new Promise(resolve => { + const msgListener = msg => { + try { + if (msg && msg.extensionId === extensionId) { + const deserialized = msg.holder.deserialize({}); + if (checker(deserialized)) { + const idx = + ProxyMessenger._torRuntimeMessageListeners.indexOf(msgListener); + ProxyMessenger._torRuntimeMessageListeners.splice(idx, 1); + resolve(deserialized); + } + } + } catch (e) {} + }; + ProxyMessenger._torRuntimeMessageListeners.push(msgListener); + }); +} + export var ExtensionParent = { GlobalManager, HiddenExtensionPage, @@ -2423,6 +2468,8 @@ export var ExtensionParent = { watchExtensionProxyContextLoad, watchExtensionWorkerContextLoaded, DebugUtils, + torSendExtensionMessage, + torWaitForExtensionMessage, }; // browserPaintedPromise and browserStartupPromise are promises that