I'm experiencing an issue with pending Mojo connections from new renderer processes being disconnected during cross-origin navigation and I'm trying to understand if this is a bug or intended behavior. My test setup is a Chromium-based application on Windows at M132 with prerendering disabled.
I have a test case where I create browsers and then navigate those browsers cross-origin. I'm initiating a Mojo channel from the renderer process (in the ContentRenderClient::RenderFrameCreated callback) like so:
// In the frame-specific .h file:
mojo::Remote<mojom::MyInterface> remote_;
// In the frame-specific .cc file:
render_frame->GetBrowserInterfaceBroker().GetInterface(
remote_.BindNewPipeAndPassReceiver());
remote_.set_disconnect_with_reason_handler(
base::BindOnce(&MyObject::OnDisconnect, this));
When I create only one 1 browser then the Mojo Channel connection from the new renderer process (new origin after the cross-origin navigation) is established successfully, meaning that my registered browser interface binder is executed in the browser process as expected. This occurs with a 100% success rate in my testing.
However, when I create 2+ browsers simultaneously I often see the Mojo Channel connection for the 2nd+ new renderer process fail (disconnect handler executed) due to MOJO_RESULT_FAILED_PRECONDITION on the renderer side. When this occurs my registered browser interface binder is not executed in the browser process. I can work around this issue currently by "retrying" the connection (calling GetInterface again) after the disconnect, and that workaround has a 100% success rate in my testing.
From debugging the disconnect issue this appears to be a race in the browser process between the binder execution and the main RFH change for the cross-origin navigation (WebContentsObserver::RenderFrameHostChanged called). The disconnect happens in cases where the main RFH change occurs before the binder is executed. If the binder is executed first then no disconnect occurs and the Mojo channel works as expected (e.g. messages on the new channel are eventually delivered).
Is this disconnect behavior expected for "normal" (non-prerender) frames? If so, can anyone point me to where in the code we're disconnecting the pending remotes on RFH change?
Thanks,
Marshall