tor-browser

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

commit 3aa4f024fc89c7b3b0504433dac769029ef34db4
parent 90fcd296eb9254aa8092ab94543c0561426578ed
Author: owlishDeveloper <bugzeeeeee@gmail.com>
Date:   Thu, 11 Dec 2025 16:14:49 +0000

Bug 1756056 - Actor messaging improvements r=geckoview-reviewers,nika

Differential Revision: https://phabricator.services.mozilla.com/D260906

Diffstat:
Mmobile/shared/actors/ContentDelegateChild.sys.mjs | 25+++++++------------------
Mmobile/shared/actors/ContentDelegateParent.sys.mjs | 33+++++++++++++++++++++++++++++++++
Mmobile/shared/actors/GeckoViewContentChild.sys.mjs | 5+----
Mmobile/shared/actors/GeckoViewContentParent.sys.mjs | 14++++++++++++++
Mmobile/shared/actors/GeckoViewPermissionChild.sys.mjs | 9+++------
Mmobile/shared/actors/GeckoViewPermissionParent.sys.mjs | 18++++++++++++++++++
Mmobile/shared/actors/GeckoViewPrompterChild.sys.mjs | 9+++------
Mmobile/shared/actors/GeckoViewPrompterParent.sys.mjs | 20++++++++++++++++++++
Mmobile/shared/actors/LoadURIDelegateChild.sys.mjs | 21+++++++++++++++++----
Mmobile/shared/actors/LoadURIDelegateParent.sys.mjs | 17+++++++++++++++--
Mmobile/shared/actors/MediaControlDelegateChild.sys.mjs | 12+++++++-----
Mmobile/shared/actors/MediaControlDelegateParent.sys.mjs | 17+++++++++++++++--
Mmobile/shared/actors/ScrollDelegateChild.sys.mjs | 3+--
Mmobile/shared/actors/ScrollDelegateParent.sys.mjs | 17+++++++++++++++--
Mmobile/shared/actors/SelectionActionDelegateChild.sys.mjs | 13+++----------
Mmobile/shared/actors/SelectionActionDelegateParent.sys.mjs | 13+++++++++++++
Mmobile/shared/modules/geckoview/GeckoViewActorChild.sys.mjs | 5-----
Mmobile/shared/modules/geckoview/GeckoViewActorParent.sys.mjs | 7-------
Mmobile/shared/modules/geckoview/LoadURIDelegate.sys.mjs | 20++------------------
Mmobile/shared/modules/geckoview/Messaging.sys.mjs | 42------------------------------------------
20 files changed, 187 insertions(+), 133 deletions(-)

diff --git a/mobile/shared/actors/ContentDelegateChild.sys.mjs b/mobile/shared/actors/ContentDelegateChild.sys.mjs @@ -27,10 +27,7 @@ export class ContentDelegateChild extends GeckoViewActorChild { return; } this.lastViewportFit = viewportFit; - this.eventDispatcher.sendRequest({ - type: "GeckoView:DOMMetaViewportFit", - viewportfit: viewportFit, - }); + this.sendAsyncMessage("GeckoView:DOMMetaViewportFit", viewportFit); } ); } @@ -179,7 +176,6 @@ export class ContentDelegateChild extends GeckoViewActorChild { if (uri || isImage || isMedia) { const msg = { - type: "GeckoView:ContextMenu", // We don't have full zoom on Android, so using CSS coordinates // here is fine, since the CSS coordinate spaces match between the // child and parent processes. @@ -200,13 +196,13 @@ export class ContentDelegateChild extends GeckoViewActorChild { null, }; - this.eventDispatcher.sendRequest(msg); + this.sendAsyncMessage("GeckoView:ContextMenu", msg); aEvent.preventDefault(); } break; } case "MozDOMFullscreen:Request": { - this.sendAsyncMessage("GeckoView:DOMFullscreenRequest", {}); + this.sendAsyncMessage("GeckoView:DOMFullscreenRequest"); break; } case "MozDOMFullscreen:Entered": @@ -219,7 +215,7 @@ export class ContentDelegateChild extends GeckoViewActorChild { } // fall-through case "MozDOMFullscreen:Exit": - this.sendAsyncMessage("GeckoView:DOMFullscreenExit", {}); + this.sendAsyncMessage("GeckoView:DOMFullscreenExit"); break; case "DOMMetaViewportFitChanged": if (aEvent.originalTarget.ownerGlobal == this.contentWindow) { @@ -241,24 +237,17 @@ export class ContentDelegateChild extends GeckoViewActorChild { this.contentWindow ); if (manifest) { - this.eventDispatcher.sendRequest({ - type: "GeckoView:WebAppManifest", - manifest, - }); + this.sendAsyncMessage("GeckoView:WebAppManifest", manifest); } }); break; } case "MozFirstContentfulPaint": { - this.eventDispatcher.sendRequest({ - type: "GeckoView:FirstContentfulPaint", - }); + this.sendAsyncMessage("GeckoView:FirstContentfulPaint"); break; } case "MozPaintStatusReset": { - this.eventDispatcher.sendRequest({ - type: "GeckoView:PaintStatusReset", - }); + this.sendAsyncMessage("GeckoView:PaintStatusReset"); break; } } diff --git a/mobile/shared/actors/ContentDelegateParent.sys.mjs b/mobile/shared/actors/ContentDelegateParent.sys.mjs @@ -29,6 +29,39 @@ export class ContentDelegateParent extends GeckoViewActorParent { this.window.windowUtils.remoteFrameFullscreenChanged(this.browser); return null; } + + case "GeckoView:DOMMetaViewportFit": { + return this.eventDispatcher.sendRequest({ + viewportfit: aMsg.data, + type: "GeckoView:DOMMetaViewportFit", + }); + } + + case "GeckoView:ContextMenu": { + return this.eventDispatcher.sendRequest({ + ...aMsg.data, + type: "GeckoView:ContextMenu", + }); + } + + case "GeckoView:WebAppManifest": { + return this.eventDispatcher.sendRequest({ + manifest: aMsg.data, + type: "GeckoView:WebAppManifest", + }); + } + + case "GeckoView:FirstContentfulPaint": { + return this.eventDispatcher.sendRequest({ + type: "GeckoView:FirstContentfulPaint", + }); + } + + case "GeckoView:PaintStatusReset": { + return this.eventDispatcher.sendRequest({ + type: "GeckoView:PaintStatusReset", + }); + } } return super.receiveMessage(aMsg); diff --git a/mobile/shared/actors/GeckoViewContentChild.sys.mjs b/mobile/shared/actors/GeckoViewContentChild.sys.mjs @@ -32,8 +32,6 @@ export class GeckoViewContentChild extends GeckoViewActorChild { } actorCreated() { - super.actorCreated(); - this.pageShow = new Promise(resolve => { this.receivedPageShow = resolve; }); @@ -335,8 +333,7 @@ export class GeckoViewContentChild extends GeckoViewActorChild { aEvent.reason === "presscaret" || aEvent.reason === "releasecaret" ) { - this.eventDispatcher.sendRequest({ - type: "GeckoView:PinOnScreen", + this.sendAsyncMessage("GeckoView:PinOnScreen", { pinned: aEvent.reason === "presscaret", }); } diff --git a/mobile/shared/actors/GeckoViewContentParent.sys.mjs b/mobile/shared/actors/GeckoViewContentParent.sys.mjs @@ -28,6 +28,20 @@ export class GeckoViewContentParent extends GeckoViewActorParent { return this.sendQuery("ContainsFormData"); } + async receiveMessage(aMsg) { + switch (aMsg.name) { + case "GeckoView:PinOnScreen": { + return this.eventDispatcher.sendRequest({ + ...aMsg.data, + type: "GeckoView:PinOnScreen", + }); + } + default: { + return super.receiveMessage(aMsg); + } + } + } + restoreState({ history, switchId, formdata, scrolldata }) { if (Services.appinfo.sessionHistoryInParent) { const { browsingContext } = this.browser; diff --git a/mobile/shared/actors/GeckoViewPermissionChild.sys.mjs b/mobile/shared/actors/GeckoViewPermissionChild.sys.mjs @@ -20,8 +20,7 @@ const MAPPED_TO_EXTENSION_PERMISSIONS = [ export class GeckoViewPermissionChild extends GeckoViewActorChild { getMediaPermission(aPermission) { - return this.eventDispatcher.sendRequestForResult({ - type: "GeckoView:MediaPermission", + return this.sendQuery("GeckoView:MediaPermission", { ...aPermission, }); } @@ -35,8 +34,7 @@ export class GeckoViewPermissionChild extends GeckoViewActorChild { } mediaRecordingStatusChanged(aDevices) { - return this.eventDispatcher.sendRequest({ - type: "GeckoView:MediaRecordingStatusChanged", + return this.sendAsyncMessage("GeckoView:MediaRecordingStatusChanged", { devices: aDevices, }); } @@ -132,8 +130,7 @@ export class GeckoViewPermissionChild extends GeckoViewActorChild { let allowOrDeny; try { - allowOrDeny = await this.eventDispatcher.sendRequestForResult({ - type: "GeckoView:ContentPermission", + allowOrDeny = await this.sendQuery("GeckoView:ContentPermission", { uri: principal.URI.displaySpec, thirdPartyOrigin: aRequest.principal.origin, principal: lazy.E10SUtils.serializePrincipal(principal), diff --git a/mobile/shared/actors/GeckoViewPermissionParent.sys.mjs b/mobile/shared/actors/GeckoViewPermissionParent.sys.mjs @@ -56,6 +56,24 @@ export class GeckoViewPermissionParent extends GeckoViewActorParent { case "AddCameraPermission": { return this.addCameraPermission(); } + case "GeckoView:MediaPermission": { + return this.eventDispatcher.sendRequestForResult({ + ...aMessage.data, + type: "GeckoView:MediaPermission", + }); + } + case "GeckoView:MediaRecordingStatusChanged": { + return this.eventDispatcher.sendRequest({ + ...aMessage.data, + type: "GeckoView:MediaRecordingStatusChanged", + }); + } + case "GeckoView:ContentPermission": { + return this.eventDispatcher.sendRequestForResult({ + ...aMessage.data, + type: "GeckoView:ContentPermission", + }); + } } return super.receiveMessage(aMessage); diff --git a/mobile/shared/actors/GeckoViewPrompterChild.sys.mjs b/mobile/shared/actors/GeckoViewPrompterChild.sys.mjs @@ -11,16 +11,14 @@ export class GeckoViewPrompterChild extends GeckoViewActorChild { } dismissPrompt(prompt) { - this.eventDispatcher.sendRequest({ - type: "GeckoView:Prompt:Dismiss", + this.sendAsyncMessage("GeckoView:Prompt:Dismiss", { id: prompt.id, }); this.unregisterPrompt(prompt); } updatePrompt(message) { - this.eventDispatcher.sendRequest({ - type: "GeckoView:Prompt:Update", + this.sendAsyncMessage("GeckoView:Prompt:Update", { prompt: message, }); } @@ -41,8 +39,7 @@ export class GeckoViewPrompterChild extends GeckoViewActorChild { // We intentionally do not await here as we want to fire NotifyPromptShow // immediately rather than waiting until the user accepts/dismisses the // prompt. - const result = this.eventDispatcher.sendRequestForResult({ - type: "GeckoView:Prompt", + const result = this.sendQuery("GeckoView:Prompt", { prompt: message, }); this.sendAsyncMessage("NotifyPromptShow", { diff --git a/mobile/shared/actors/GeckoViewPrompterParent.sys.mjs b/mobile/shared/actors/GeckoViewPrompterParent.sys.mjs @@ -122,6 +122,26 @@ export class GeckoViewPrompterParent extends GeckoViewActorParent { this.rootActor.notifyPromptShow(data.id); break; } + case "GeckoView:Prompt:Dismiss": { + return this.eventDispatcher.sendRequest({ + ...data, + type: "GeckoView:Prompt:Dismiss", + }); + break; + } + case "GeckoView:Prompt:Update": { + this.eventDispatcher.sendRequest({ + ...data, + type: "GeckoView:Prompt:Update", + }); + break; + } + case "GeckoView:Prompt": { + return this.eventDispatcher.sendRequestForResult({ + ...data, + type: "GeckoView:Prompt", + }); + } default: { return super.receiveMessage({ name, data }); } diff --git a/mobile/shared/actors/LoadURIDelegateChild.sys.mjs b/mobile/shared/actors/LoadURIDelegateChild.sys.mjs @@ -17,13 +17,26 @@ export class LoadURIDelegateChild extends GeckoViewActorChild { debug`handleLoadError: uri=${aUri && aUri.spec} displaySpec=${aUri && aUri.displaySpec} error=${aError}`; + let errorClass = 0; + try { + const nssErrorsService = Cc[ + "@mozilla.org/nss_errors_service;1" + ].getService(Ci.nsINSSErrorsService); + errorClass = nssErrorsService.getErrorClass(aError); + } catch (e) {} + + const msg = { + uri: aUri && aUri.spec, + error: aError, + errorModule: aErrorModule, + errorClass, + }; + + let errorPagePromise = this.sendQuery("GeckoView:OnLoadError", msg); return lazy.LoadURIDelegate.handleLoadError( this.contentWindow, - this.eventDispatcher, - aUri, - aError, - aErrorModule + errorPagePromise ); } } diff --git a/mobile/shared/actors/LoadURIDelegateParent.sys.mjs b/mobile/shared/actors/LoadURIDelegateParent.sys.mjs @@ -4,5 +4,18 @@ import { GeckoViewActorParent } from "resource://gre/modules/GeckoViewActorParent.sys.mjs"; -// For this.eventDispatcher in the child -export class LoadURIDelegateParent extends GeckoViewActorParent {} +export class LoadURIDelegateParent extends GeckoViewActorParent { + async receiveMessage({ name, data }) { + switch (name) { + case "GeckoView:OnLoadError": { + return this.eventDispatcher.sendRequestForResult({ + ...data, + type: "GeckoView:OnLoadError", + }); + } + default: { + return super.receiveMessage({ name, data }); + } + } + } +} diff --git a/mobile/shared/actors/MediaControlDelegateChild.sys.mjs b/mobile/shared/actors/MediaControlDelegateChild.sys.mjs @@ -34,11 +34,13 @@ export class MediaControlDelegateChild extends GeckoViewActorChild { debug`No fullscreen media element found.`; } - const activated = await this.eventDispatcher.sendRequestForResult({ - type: "GeckoView:MediaSession:Fullscreen", - metadata: lazy.MediaUtils.getMetadata(mediaElement) ?? {}, - enabled: !!element, - }); + const activated = await this.sendQuery( + "GeckoView:MediaSession:Fullscreen", + { + metadata: lazy.MediaUtils.getMetadata(mediaElement) ?? {}, + enabled: !!element, + } + ); if (activated) { return; } diff --git a/mobile/shared/actors/MediaControlDelegateParent.sys.mjs b/mobile/shared/actors/MediaControlDelegateParent.sys.mjs @@ -4,5 +4,18 @@ import { GeckoViewActorParent } from "resource://gre/modules/GeckoViewActorParent.sys.mjs"; -// For this.eventDispatcher in the child -export class MediaControlDelegateParent extends GeckoViewActorParent {} +export class MediaControlDelegateParent extends GeckoViewActorParent { + async receiveMessage({ name, data }) { + switch (name) { + case "GeckoView:MediaSession:Fullscreen": { + return this.eventDispatcher.sendRequestForResult({ + ...data, + type: "GeckoView:MediaSession:Fullscreen", + }); + } + default: { + return super.receiveMessage({ name, data }); + } + } + } +} diff --git a/mobile/shared/actors/ScrollDelegateChild.sys.mjs b/mobile/shared/actors/ScrollDelegateChild.sys.mjs @@ -18,8 +18,7 @@ export class ScrollDelegateChild extends GeckoViewActorChild { const x = {}; const y = {}; this.contentWindow.windowUtils.getVisualViewportOffset(x, y); - this.eventDispatcher.sendRequest({ - type: "GeckoView:ScrollChanged", + this.sendAsyncMessage("GeckoView:ScrollChanged", { scrollX: x.value, scrollY: y.value, }); diff --git a/mobile/shared/actors/ScrollDelegateParent.sys.mjs b/mobile/shared/actors/ScrollDelegateParent.sys.mjs @@ -4,5 +4,18 @@ import { GeckoViewActorParent } from "resource://gre/modules/GeckoViewActorParent.sys.mjs"; -// For this.eventDispatcher in the child -export class ScrollDelegateParent extends GeckoViewActorParent {} +export class ScrollDelegateParent extends GeckoViewActorParent { + async receiveMessage({ name, data }) { + switch (name) { + case "GeckoView:ScrollChanged": { + return this.eventDispatcher.sendRequest({ + ...data, + type: "GeckoView:ScrollChanged", + }); + } + default: { + return super.receiveMessage({ name, data }); + } + } + } +} diff --git a/mobile/shared/actors/SelectionActionDelegateChild.sys.mjs b/mobile/shared/actors/SelectionActionDelegateChild.sys.mjs @@ -269,15 +269,10 @@ export class SelectionActionDelegateChild extends GeckoViewActorChild { if (["presscaret", "dragcaret"].includes(aEvent.reason)) { debug`_handleMagnifier: ${aEvent.reason}`; const screenPoint = this._getBetterMagnifierPoint(aEvent); - this.eventDispatcher.sendRequest({ - type: "GeckoView:ShowMagnifier", - screenPoint, - }); + this.sendAsyncMessage("GeckoView:ShowMagnifier", { screenPoint }); } else if (aEvent.reason == "releasecaret") { debug`_handleMagnifier: ${aEvent.reason}`; - this.eventDispatcher.sendRequest({ - type: "GeckoView:HideMagnifier", - }); + this.sendAsyncMessage("GeckoView:HideMagnifier"); } } @@ -431,9 +426,7 @@ export class SelectionActionDelegateChild extends GeckoViewActorChild { break; } // Reset magnifier - this.eventDispatcher.sendRequest({ - type: "GeckoView:HideMagnifier", - }); + this.sendAsyncMessage("GeckoView:HideMagnifier"); } } diff --git a/mobile/shared/actors/SelectionActionDelegateParent.sys.mjs b/mobile/shared/actors/SelectionActionDelegateParent.sys.mjs @@ -27,6 +27,19 @@ export class SelectionActionDelegateParent extends GeckoViewActorParent { break; } + case "GeckoView:ShowMagnifier": { + this.eventDispatcher.sendRequest({ + ...data, + type: "GeckoView:ShowMagnifier", + }); + break; + } + + case "GeckoView:HideMagnifier": { + this.eventDispatcher.sendRequest({ type: "GeckoView:HideMagnifier" }); + break; + } + default: { super.receiveMessage(aMessage); } diff --git a/mobile/shared/modules/geckoview/GeckoViewActorChild.sys.mjs b/mobile/shared/modules/geckoview/GeckoViewActorChild.sys.mjs @@ -3,17 +3,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { GeckoViewUtils } from "resource://gre/modules/GeckoViewUtils.sys.mjs"; -import { EventDispatcher } from "resource://gre/modules/Messaging.sys.mjs"; export class GeckoViewActorChild extends JSWindowActorChild { static initLogging(aModuleName) { const tag = aModuleName.replace("GeckoView", "") + "[C]"; return GeckoViewUtils.initLogging(tag); } - - actorCreated() { - this.eventDispatcher = EventDispatcher.forActor(this); - } } const { debug, warn } = GeckoViewUtils.initLogging("Actor[C]"); diff --git a/mobile/shared/modules/geckoview/GeckoViewActorParent.sys.mjs b/mobile/shared/modules/geckoview/GeckoViewActorParent.sys.mjs @@ -36,13 +36,6 @@ export class GeckoViewActorParent extends JSWindowActorParent { return null; } - switch (aMessage.name) { - case "DispatcherMessage": - return this.eventDispatcher.sendRequest(aMessage.data); - case "DispatcherQuery": - return this.eventDispatcher.sendRequestForResult(aMessage.data); - } - // By default messages are forwarded to the module. return this.window.moduleManager.onMessageFromActor(this.name, aMessage); } diff --git a/mobile/shared/modules/geckoview/LoadURIDelegate.sys.mjs b/mobile/shared/modules/geckoview/LoadURIDelegate.sys.mjs @@ -44,25 +44,9 @@ export const LoadURIDelegate = { } }, - handleLoadError(aWindow, aEventDispatcher, aUri, aError, aErrorModule) { - let errorClass = 0; - try { - const nssErrorsService = Cc[ - "@mozilla.org/nss_errors_service;1" - ].getService(Ci.nsINSSErrorsService); - errorClass = nssErrorsService.getErrorClass(aError); - } catch (e) {} - - const msg = { - type: "GeckoView:OnLoadError", - uri: aUri && aUri.spec, - error: aError, - errorModule: aErrorModule, - errorClass, - }; - + handleLoadError(aWindow, aErrorPagePromise) { let errorPageURI = undefined; - aEventDispatcher.sendRequestForResult(msg).then( + aErrorPagePromise.then( response => { try { errorPageURI = response ? Services.io.newURI(response) : null; diff --git a/mobile/shared/modules/geckoview/Messaging.sys.mjs b/mobile/shared/modules/geckoview/Messaging.sys.mjs @@ -5,39 +5,6 @@ const IS_PARENT_PROCESS = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT; -class ChildActorDispatcher { - constructor(actor) { - this._actor = actor; - } - - // TODO: Bug 1658980 - registerListener() { - throw new Error("Cannot registerListener in child actor"); - } - unregisterListener() { - throw new Error("Cannot registerListener in child actor"); - } - - /** - * Sends a request to Java. - * - * @param aMsg Message to send; must be an object with a "type" property - */ - sendRequest(aMsg) { - this._actor.sendAsyncMessage("DispatcherMessage", aMsg); - } - - /** - * Sends a request to Java, returning a Promise that resolves to the response. - * - * @param aMsg Message to send; must be an object with a "type" property - * @return A Promise resolving to the response - */ - sendRequestForResult(aMsg) { - return this._actor.sendQuery("DispatcherQuery", aMsg); - } -} - function DispatcherDelegate(aDispatcher, aMessageManager) { this._dispatcher = aDispatcher; this._messageManager = aMessageManager; @@ -253,15 +220,6 @@ export var EventDispatcher = { return new DispatcherDelegate(null, aMessageManager); }, - /** - * Return the EventDispatcher instance associated with an actor. - * - * @param aActor an actor - */ - forActor(aActor) { - return new ChildActorDispatcher(aActor); - }, - receiveMessage(aMsg) { // aMsg.data includes keys: global, event, data, uuid let callback;