commit d8f8717930c264243730e242c72a89854654b65c parent db07192845a839032697001b9cafeeab86c27db8 Author: Alexandru Marc <amarc@mozilla.com> Date: Thu, 11 Dec 2025 20:32:31 +0200 Revert "Bug 1756056 - Actor messaging improvements r=geckoview-reviewers,nika" for causing lint failures @ GeckoViewPrompterParent.sys.mjs This reverts commit 3aa4f024fc89c7b3b0504433dac769029ef34db4. Diffstat:
20 files changed, 133 insertions(+), 187 deletions(-)
diff --git a/mobile/shared/actors/ContentDelegateChild.sys.mjs b/mobile/shared/actors/ContentDelegateChild.sys.mjs @@ -27,7 +27,10 @@ export class ContentDelegateChild extends GeckoViewActorChild { return; } this.lastViewportFit = viewportFit; - this.sendAsyncMessage("GeckoView:DOMMetaViewportFit", viewportFit); + this.eventDispatcher.sendRequest({ + type: "GeckoView:DOMMetaViewportFit", + viewportfit: viewportFit, + }); } ); } @@ -176,6 +179,7 @@ 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. @@ -196,13 +200,13 @@ export class ContentDelegateChild extends GeckoViewActorChild { null, }; - this.sendAsyncMessage("GeckoView:ContextMenu", msg); + this.eventDispatcher.sendRequest(msg); aEvent.preventDefault(); } break; } case "MozDOMFullscreen:Request": { - this.sendAsyncMessage("GeckoView:DOMFullscreenRequest"); + this.sendAsyncMessage("GeckoView:DOMFullscreenRequest", {}); break; } case "MozDOMFullscreen:Entered": @@ -215,7 +219,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) { @@ -237,17 +241,24 @@ export class ContentDelegateChild extends GeckoViewActorChild { this.contentWindow ); if (manifest) { - this.sendAsyncMessage("GeckoView:WebAppManifest", manifest); + this.eventDispatcher.sendRequest({ + type: "GeckoView:WebAppManifest", + manifest, + }); } }); break; } case "MozFirstContentfulPaint": { - this.sendAsyncMessage("GeckoView:FirstContentfulPaint"); + this.eventDispatcher.sendRequest({ + type: "GeckoView:FirstContentfulPaint", + }); break; } case "MozPaintStatusReset": { - this.sendAsyncMessage("GeckoView:PaintStatusReset"); + this.eventDispatcher.sendRequest({ + type: "GeckoView:PaintStatusReset", + }); break; } } diff --git a/mobile/shared/actors/ContentDelegateParent.sys.mjs b/mobile/shared/actors/ContentDelegateParent.sys.mjs @@ -29,39 +29,6 @@ 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,6 +32,8 @@ export class GeckoViewContentChild extends GeckoViewActorChild { } actorCreated() { + super.actorCreated(); + this.pageShow = new Promise(resolve => { this.receivedPageShow = resolve; }); @@ -333,7 +335,8 @@ export class GeckoViewContentChild extends GeckoViewActorChild { aEvent.reason === "presscaret" || aEvent.reason === "releasecaret" ) { - this.sendAsyncMessage("GeckoView:PinOnScreen", { + this.eventDispatcher.sendRequest({ + type: "GeckoView:PinOnScreen", pinned: aEvent.reason === "presscaret", }); } diff --git a/mobile/shared/actors/GeckoViewContentParent.sys.mjs b/mobile/shared/actors/GeckoViewContentParent.sys.mjs @@ -28,20 +28,6 @@ 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,7 +20,8 @@ const MAPPED_TO_EXTENSION_PERMISSIONS = [ export class GeckoViewPermissionChild extends GeckoViewActorChild { getMediaPermission(aPermission) { - return this.sendQuery("GeckoView:MediaPermission", { + return this.eventDispatcher.sendRequestForResult({ + type: "GeckoView:MediaPermission", ...aPermission, }); } @@ -34,7 +35,8 @@ export class GeckoViewPermissionChild extends GeckoViewActorChild { } mediaRecordingStatusChanged(aDevices) { - return this.sendAsyncMessage("GeckoView:MediaRecordingStatusChanged", { + return this.eventDispatcher.sendRequest({ + type: "GeckoView:MediaRecordingStatusChanged", devices: aDevices, }); } @@ -130,7 +132,8 @@ export class GeckoViewPermissionChild extends GeckoViewActorChild { let allowOrDeny; try { - allowOrDeny = await this.sendQuery("GeckoView:ContentPermission", { + allowOrDeny = await this.eventDispatcher.sendRequestForResult({ + type: "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,24 +56,6 @@ 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,14 +11,16 @@ export class GeckoViewPrompterChild extends GeckoViewActorChild { } dismissPrompt(prompt) { - this.sendAsyncMessage("GeckoView:Prompt:Dismiss", { + this.eventDispatcher.sendRequest({ + type: "GeckoView:Prompt:Dismiss", id: prompt.id, }); this.unregisterPrompt(prompt); } updatePrompt(message) { - this.sendAsyncMessage("GeckoView:Prompt:Update", { + this.eventDispatcher.sendRequest({ + type: "GeckoView:Prompt:Update", prompt: message, }); } @@ -39,7 +41,8 @@ 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.sendQuery("GeckoView:Prompt", { + const result = this.eventDispatcher.sendRequestForResult({ + type: "GeckoView:Prompt", prompt: message, }); this.sendAsyncMessage("NotifyPromptShow", { diff --git a/mobile/shared/actors/GeckoViewPrompterParent.sys.mjs b/mobile/shared/actors/GeckoViewPrompterParent.sys.mjs @@ -122,26 +122,6 @@ 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,26 +17,13 @@ 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, - errorPagePromise + this.eventDispatcher, + aUri, + aError, + aErrorModule ); } } diff --git a/mobile/shared/actors/LoadURIDelegateParent.sys.mjs b/mobile/shared/actors/LoadURIDelegateParent.sys.mjs @@ -4,18 +4,5 @@ import { GeckoViewActorParent } from "resource://gre/modules/GeckoViewActorParent.sys.mjs"; -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 }); - } - } - } -} +// For this.eventDispatcher in the child +export class LoadURIDelegateParent extends GeckoViewActorParent {} diff --git a/mobile/shared/actors/MediaControlDelegateChild.sys.mjs b/mobile/shared/actors/MediaControlDelegateChild.sys.mjs @@ -34,13 +34,11 @@ export class MediaControlDelegateChild extends GeckoViewActorChild { debug`No fullscreen media element found.`; } - const activated = await this.sendQuery( - "GeckoView:MediaSession:Fullscreen", - { - metadata: lazy.MediaUtils.getMetadata(mediaElement) ?? {}, - enabled: !!element, - } - ); + const activated = await this.eventDispatcher.sendRequestForResult({ + type: "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,18 +4,5 @@ import { GeckoViewActorParent } from "resource://gre/modules/GeckoViewActorParent.sys.mjs"; -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 }); - } - } - } -} +// For this.eventDispatcher in the child +export class MediaControlDelegateParent extends GeckoViewActorParent {} diff --git a/mobile/shared/actors/ScrollDelegateChild.sys.mjs b/mobile/shared/actors/ScrollDelegateChild.sys.mjs @@ -18,7 +18,8 @@ export class ScrollDelegateChild extends GeckoViewActorChild { const x = {}; const y = {}; this.contentWindow.windowUtils.getVisualViewportOffset(x, y); - this.sendAsyncMessage("GeckoView:ScrollChanged", { + this.eventDispatcher.sendRequest({ + type: "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,18 +4,5 @@ import { GeckoViewActorParent } from "resource://gre/modules/GeckoViewActorParent.sys.mjs"; -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 }); - } - } - } -} +// For this.eventDispatcher in the child +export class ScrollDelegateParent extends GeckoViewActorParent {} diff --git a/mobile/shared/actors/SelectionActionDelegateChild.sys.mjs b/mobile/shared/actors/SelectionActionDelegateChild.sys.mjs @@ -269,10 +269,15 @@ export class SelectionActionDelegateChild extends GeckoViewActorChild { if (["presscaret", "dragcaret"].includes(aEvent.reason)) { debug`_handleMagnifier: ${aEvent.reason}`; const screenPoint = this._getBetterMagnifierPoint(aEvent); - this.sendAsyncMessage("GeckoView:ShowMagnifier", { screenPoint }); + this.eventDispatcher.sendRequest({ + type: "GeckoView:ShowMagnifier", + screenPoint, + }); } else if (aEvent.reason == "releasecaret") { debug`_handleMagnifier: ${aEvent.reason}`; - this.sendAsyncMessage("GeckoView:HideMagnifier"); + this.eventDispatcher.sendRequest({ + type: "GeckoView:HideMagnifier", + }); } } @@ -426,7 +431,9 @@ export class SelectionActionDelegateChild extends GeckoViewActorChild { break; } // Reset magnifier - this.sendAsyncMessage("GeckoView:HideMagnifier"); + this.eventDispatcher.sendRequest({ + type: "GeckoView:HideMagnifier", + }); } } diff --git a/mobile/shared/actors/SelectionActionDelegateParent.sys.mjs b/mobile/shared/actors/SelectionActionDelegateParent.sys.mjs @@ -27,19 +27,6 @@ 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,12 +3,17 @@ * 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,6 +36,13 @@ 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,9 +44,25 @@ export const LoadURIDelegate = { } }, - handleLoadError(aWindow, aErrorPagePromise) { + 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, + }; + let errorPageURI = undefined; - aErrorPagePromise.then( + aEventDispatcher.sendRequestForResult(msg).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,6 +5,39 @@ 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; @@ -220,6 +253,15 @@ 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;