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:
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