summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/ExtensionParent.sys.mjs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:50 +0000
commitdef92d1b8e9d373e2f6f27c366d578d97d8960c6 (patch)
tree2ef34b9ad8bb9a9220e05d60352558b15f513894 /toolkit/components/extensions/ExtensionParent.sys.mjs
parentAdding debian version 125.0.3-1. (diff)
downloadfirefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.tar.xz
firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/extensions/ExtensionParent.sys.mjs')
-rw-r--r--toolkit/components/extensions/ExtensionParent.sys.mjs125
1 files changed, 71 insertions, 54 deletions
diff --git a/toolkit/components/extensions/ExtensionParent.sys.mjs b/toolkit/components/extensions/ExtensionParent.sys.mjs
index b4812a702a..f951433713 100644
--- a/toolkit/components/extensions/ExtensionParent.sys.mjs
+++ b/toolkit/components/extensions/ExtensionParent.sys.mjs
@@ -14,6 +14,7 @@ import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
+/** @type {Lazy} */
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
@@ -245,8 +246,10 @@ let apiManager = new (class extends SchemaAPIManager {
// to relevant child messengers. Also handles Native messaging and GeckoView.
/** @typedef {typeof ProxyMessenger} NativeMessenger */
const ProxyMessenger = {
- /** @type {Map<number, Partial<ParentPort>&Promise<ParentPort>>} */
+ /** @type {Map<number, ParentPort>} */
ports: new Map(),
+ /** @type {Map<number, Promise>} */
+ portPromises: new Map(),
init() {
this.conduit = new lazy.BroadcastConduit(ProxyMessenger, {
@@ -300,7 +303,8 @@ const ProxyMessenger = {
};
if (JSWindowActorParent.isInstance(source.actor)) {
- let browser = source.actor.browsingContext.top.embedderElement;
+ let { currentWindowContext, top } = source.actor.browsingContext;
+ let browser = top.embedderElement;
let data =
browser && apiManager.global.tabTracker.getBrowserData(browser);
if (data?.tabId > 0) {
@@ -308,6 +312,13 @@ const ProxyMessenger = {
// frameId is documented to only be set if sender.tab is set.
sender.frameId = source.frameId;
}
+
+ let principal = currentWindowContext.documentPrincipal;
+ // We intend the serialization of null principals *and* file scheme to be
+ // "null".
+ sender.origin = new URL(principal.originNoSuffix).origin;
+ } else if (source.verified) {
+ sender.origin = `moz-extension://${extension.uuid}`;
}
return sender;
@@ -363,17 +374,24 @@ const ProxyMessenger = {
}
// PortMessages that follow will need to wait for the port to be opened.
- /** @type {callback} */
- let resolvePort;
- this.ports.set(arg.portId, new Promise(res => (resolvePort = res)));
+ let { promise, resolve, reject } = Promise.withResolvers();
+ this.portPromises.set(arg.portId, promise);
- let kind = await this.normalizeArgs(arg, sender);
- let all = await this.conduit.castPortConnect(kind, arg);
- resolvePort();
+ try {
+ let kind = await this.normalizeArgs(arg, sender);
+ let all = await this.conduit.castPortConnect(kind, arg);
+ resolve();
- // If there are no active onConnect listeners.
- if (!all.some(x => x.value)) {
- throw new ExtensionError(ERROR_NO_RECEIVERS);
+ // If there are no active onConnect listeners.
+ if (!all.some(x => x.value)) {
+ throw new ExtensionError(ERROR_NO_RECEIVERS);
+ }
+ } catch (err) {
+ // Throw _and_ reject with error, so everything awaiting this port fails.
+ reject(err);
+ throw err;
+ } finally {
+ this.portPromises.delete(arg.portId);
}
},
@@ -387,7 +405,7 @@ const ProxyMessenger = {
// NOTE: the following await make sure we await for promised ports
// (ports that were not yet open when added to the Map,
// see recvPortConnect).
- await this.ports.get(sender.portId);
+ await this.portPromises.get(sender.portId);
this.sendPortMessage(sender.portId, holder, !sender.source);
},
@@ -448,7 +466,7 @@ GlobalManager = {
extensionMap: new Map(),
initialized: false,
- /** @type {WeakMap<Browser, object>} Extension Context init data. */
+ /** @type {WeakMap<XULBrowserElement, object>} Extension Context init data. */
frameData: new WeakMap(),
init(extension) {
@@ -961,7 +979,6 @@ ParentAPIManager = {
throw new Error(`Bad sender context envType: ${sender.envType}`);
}
- let isBackgroundWorker = false;
if (JSWindowActorParent.isInstance(actor)) {
const target = actor.browsingContext.top.embedderElement;
let processMessageManager =
@@ -979,6 +996,22 @@ ParentAPIManager = {
"Attempt to create privileged extension parent from incorrect child process"
);
}
+
+ if (envType == "addon_parent") {
+ context = new ExtensionPageContextParent(
+ envType,
+ extension,
+ data,
+ actor.browsingContext
+ );
+ } else if (envType == "devtools_parent") {
+ context = new DevToolsExtensionPageContextParent(
+ envType,
+ extension,
+ data,
+ actor.browsingContext
+ );
+ }
} else if (JSProcessActorParent.isInstance(actor)) {
if (actor.manager.remoteType !== extension.remoteType) {
throw new Error(
@@ -996,7 +1029,7 @@ ParentAPIManager = {
`Unexpected viewType ${data.viewType} on an extension process actor`
);
}
- isBackgroundWorker = true;
+ context = new BackgroundWorkerContextParent(envType, extension, data);
} else {
// Unreacheable: JSWindowActorParent and JSProcessActorParent are the
// only actors.
@@ -1004,24 +1037,6 @@ ParentAPIManager = {
"Attempt to create privileged extension parent via incorrect actor"
);
}
-
- if (isBackgroundWorker) {
- context = new BackgroundWorkerContextParent(envType, extension, data);
- } else if (envType == "addon_parent") {
- context = new ExtensionPageContextParent(
- envType,
- extension,
- data,
- actor.browsingContext
- );
- } else if (envType == "devtools_parent") {
- context = new DevToolsExtensionPageContextParent(
- envType,
- extension,
- data,
- actor.browsingContext
- );
- }
} else if (envType == "content_parent") {
// Note: actor is always a JSWindowActorParent, with a browsingContext.
context = new ContentScriptContextParent(
@@ -1340,11 +1355,9 @@ class HiddenXULWindow {
// The windowless browser is a thin wrapper around a docShell that keeps
// its related resources alive. It implements nsIWebNavigation and
- // forwards its methods to the underlying docShell. That .docShell
- // needs `QueryInterface(nsIWebNavigation)` to give us access to the
- // webNav methods that are already available on the windowless browser.
+ // forwards its methods to the underlying docShell.
let chromeShell = windowlessBrowser.docShell;
- chromeShell.QueryInterface(Ci.nsIWebNavigation);
+ let webNav = chromeShell.QueryInterface(Ci.nsIWebNavigation);
if (lazy.PrivateBrowsingUtils.permanentPrivateBrowsing) {
let attrs = chromeShell.getOriginAttributes();
@@ -1353,13 +1366,13 @@ class HiddenXULWindow {
}
windowlessBrowser.browsingContext.useGlobalHistory = false;
- chromeShell.loadURI(DUMMY_PAGE_URI, {
+ webNav.loadURI(DUMMY_PAGE_URI, {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
await promiseObserved(
"chrome-document-global-created",
- win => win.document == chromeShell.document
+ win => win.document == webNav.document
);
await promiseDocumentLoaded(windowlessBrowser.document);
if (this.unloaded) {
@@ -1376,7 +1389,7 @@ class HiddenXULWindow {
* An object that contains the xul attributes to set of the newly
* created browser XUL element.
*
- * @returns {Promise<XULElement>}
+ * @returns {Promise<XULBrowserElement>}
* A Promise which resolves to the newly created browser XUL element.
*/
async createBrowserElement(xulAttributes) {
@@ -1458,16 +1471,17 @@ const SharedWindow = {
* to inherits the shared boilerplate code needed to create a parent document for the hidden
* extension pages (e.g. the background page, the devtools page) in the BackgroundPage and
* DevToolsPage classes.
- *
- * @param {Extension} extension
- * The Extension which owns the hidden extension page created (used to decide
- * if the hidden extension page parent doc is going to be a windowlessBrowser or
- * a visible XUL window).
- * @param {string} viewType
- * The viewType of the WebExtension page that is going to be loaded
- * in the created browser element (e.g. "background" or "devtools_page").
*/
class HiddenExtensionPage {
+ /**
+ * @param {Extension} extension
+ * The Extension which owns the hidden extension page created (used to decide
+ * if the hidden extension page parent doc is going to be a windowlessBrowser or
+ * a visible XUL window).
+ * @param {string} viewType
+ * The viewType of the WebExtension page that is going to be loaded
+ * in the created browser element (e.g. "background" or "devtools_page").
+ */
constructor(extension, viewType) {
if (!extension || !viewType) {
throw new Error("extension and viewType parameters are mandatory");
@@ -1535,6 +1549,9 @@ class HiddenExtensionPage {
}
}
+/** @typedef {import("resource://devtools/server/actors/descriptors/webextension.js")
+ .WebExtensionDescriptorActor} WebExtensionDescriptorActor */
+
/**
* This object provides utility functions needed by the devtools actors to
* be able to connect and debug an extension (which can run in the main or in
@@ -1545,9 +1562,9 @@ const DebugUtils = {
// which are used to connect the webextension patent actor to the extension process.
hiddenXULWindow: null,
- // Map<extensionId, Promise<XULElement>>
+ /** @type {Map<string, Promise<XULBrowserElement> & { browser: XULBrowserElement }>} */
debugBrowserPromises: new Map(),
- // DefaultWeakMap<Promise<browser XULElement>, Set<WebExtensionParentActor>>
+ /** @type {WeakMap<Promise<XULBrowserElement>, Set<WebExtensionDescriptorActor>>} */
debugActors: new DefaultWeakMap(() => new Set()),
_extensionUpdatedWatcher: null,
@@ -1696,10 +1713,10 @@ const DebugUtils = {
* Retrieve a XUL browser element which has been configured to be able to connect
* the devtools actor with the process where the extension is running.
*
- * @param {WebExtensionParentActor} webExtensionParentActor
+ * @param {WebExtensionDescriptorActor} webExtensionParentActor
* The devtools actor that is retrieving the browser element.
*
- * @returns {Promise<XULElement>}
+ * @returns {Promise<XULBrowserElement>}
* A promise which resolves to the configured browser XUL element.
*/
async getExtensionProcessBrowser(webExtensionParentActor) {
@@ -1753,7 +1770,7 @@ const DebugUtils = {
* it destroys the XUL browser element, and it also destroy the hidden XUL window
* if it is not currently needed.
*
- * @param {WebExtensionParentActor} webExtensionParentActor
+ * @param {WebExtensionDescriptorActor} webExtensionParentActor
* The devtools actor that has retrieved an addon debug browser element.
*/
async releaseExtensionProcessBrowser(webExtensionParentActor) {
@@ -1783,7 +1800,7 @@ const DebugUtils = {
* was received by the message manager. The promise is rejected if the message
* manager was closed before a message was received.
*
- * @param {nsIMessageListenerManager} messageManager
+ * @param {MessageListenerManager} messageManager
* The message manager on which to listen for messages.
* @param {string} messageName
* The message to listen for.