Closed Bug 1775463 Opened 2 years ago Closed 2 years ago

Allow windowglobal-in-root modules to intercept events from their corresponding windowglobal module

Categories

(Remote Protocol :: Agent, task, P1)

task
Points:
3

Tracking

(firefox104 fixed)

RESOLVED FIXED
104 Branch
Tracking Status
firefox104 --- fixed

People

(Reporter: jdescottes, Assigned: Sasha)

References

(Blocks 1 open bug)

Details

(Whiteboard: [webdriver:m4])

Attachments

(1 file)

It would be useful to allow the parent process to "intercept" events emitted originally in content process.

Typical use case from Bug 1767260, we want to emit a content process event with a browsing context, however our browsing context map of unique ids is for now in a singleton only available in the parent process. So while most of the payload comes from the content process, we need something in the parent process to add the correct unique id.

windowglobal-in-root modules are a good candidate to fill this role. They are supposed to "intercept" commands targeting windowglobal modules, so it makes sense to extend their role to also intercept events coming from windowglobal modules.

We probably need to come up with a method name which can be defined on those modules to handle the interception. Then when the RootMessageHandler receives a protocol event, it should always try to see if the "windowglobal-in-root" module implements that method, and if it does it should allow the module to process / modify the event before emitting it.

We will need to discuss the features and semantics for interception:

  • able to modify the event's payload (I guess this is mandatory, that's the whole point :) )
  • able to cancel the event?
  • should probably return the modified payload?
  • can be async?

I'm happy with a very basic implemenation for the beginning which as filed can intercept and modify the event payload. Additional features like canceling an event could follow later. Yes, and I think we should consider this method to be async given that some extra data is needed which needs to be retrieved from some async APIs first. Otherwise the description looks great, and should indeed be easy to implement.

Agreed, let's keep this as simple as possible.

The main task will be to know when an event is candidate for interception.
Let's look at the flow for an event coming from a windowglobal module:

-> Module:emitProtocolEvent calls MessageHandler:emitEvent (here a WindowGlobalMessageHandler)
-> MessageHandler emits "message-handler-event"
-> MessageHandlerFrameChild captures "message-handler-event"
-> MessageHandlerFrameChild sends the event to the parent process (sendAsyncMessage)
-> MessageHandlerFrameParent receives the event in the parent process
-> MessageHandlerFrameParent calls MessageHandler:emitEvent (here a RootMessageHandler)

Based on that I guess we have two spots where we can attempt to intercept the event.

First option is to do it in MessageHandler:emitEvent. This method is only implemented in the base MessageHandler.jsm class. Perhaps we should override it in RootMessageHandler to handle the interception. One thing to be careful with here is that we should only attempt to intercept events which come from a windowglobal module. A root Module could call emitEvent on the root message handler and we should not try to perform any interception here. Maybe we need some additional metadata in the event to indicate it comes from "windowglobal".

Second option is to do it in MessageHandlerFrameParent, right before we call MessageHandler:emitEvent. We could still implement the logic in a method exposed by the RootMessageHandler but it would be driven by MessageHandlerFrameParent. Might seem a bit odd, but the good thing with this approach is that by design all events which go through the MessageHandlerFrameParent are known to come from the windowglobal layer. So there's no need to check where the event comes from, we already know it's an event which is candidate for interception.

Getting the correct module from the RootMessageHandler should be easy, we have to call this._moduleCache.getModuleInstance(moduleName, { type: "WINDOW_GLOBAL" }) (which is a bit weird because those APIs were designed to be called in the scope of a command, so they all take a "destination" parameter, even though they only care about the destination type).

As I'm thinking about this, I'm reminded of an alternative solution we probably discussed at some point: protocol events could be restricted to the parent process. Modules would have to explicitly setup some logic to listen to events from their windowglobal counterparts and create proper protocol events. More verbose, but interception would not be necessary since the bubbling would no longer happen automatically. But I still think interception is the most reasonable change with the least impact on the current codebase.

Points: --- → 3
Priority: -- → P1
Whiteboard: [webdriver:m4]
Assignee: nobody → aborovova
Status: NEW → ASSIGNED
Blocks: 1767260
See Also: 1767260
Attachment #9282550 - Attachment description: WIP: Bug 1775463 - Allow windowglobal-in-root modules to intercept events from their corresponding windowglobal module. → Bug 1775463 - Allow windowglobal-in-root modules to intercept events from their corresponding windowglobal module. r=jdescottes
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 104 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: