--
You received this message because you are subscribed to the Google Groups "navigation-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to navigation-de...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/navigation-dev/CAJ_xCimj-eXHcNrYrcTQacvoL55FPafzxEduz8SBDNaLDynQug%40mail.gmail.com.
Thanks Matt for looking into this — it indeed looks like a problem which we should fix.A few thoughts from my side:BrowserInterfaceBroker is per-document (IIUC, this includes provisional / speculative documents and initial empty documents).There are two ways to create a new document:
- (1) create a new RenderFrame(Host) (and some document will be created together with it)
- (2) commit a cross-document navigation in the RenderFrameHost.
(1): There are two ways to create a RenderFrameHost as well:
- (1a) create a speculative RenderFrameHost for cross-RFH navigation in a frame. This RFH will be created in a live state (with a RenderFrame) with a provisional document (if I got the Blink terminology correctly).
- (1b) When a new FrameTreeNode is created, a starting RenderFrameHost is created with it (see rakina@'s initial empty document for more details).
- For (most of) the main frames, we just make their RFH live when we start to navigate. This, as well as the case in (1a) are done through the browser sending an IPC to the renderer.
- However, there is a different story for subframes (and main frames created via window.open) — there the renderer needs to have a functioning RenderFrame synchronously, so it creates it itself and sends the necessary parameters (including BIB) to the browser and then the browser creates the RenderFrameHost.
(Loading a cross-origin subframe is a two-step procedure: create a frame with about:blank RFH (case 1b) and then perform a cross-RFH navigation in the new frame (case 2)).(2): This case is more straightforward — the only thing to keep in mind is that the navigation commit can both replace an old document in the active RFH (cross-document same-RFH navigation) and replace a provisional document in a speculative / commit pending RFH.With that said, usually the case (2) is more interesting for most features (as they don't interact with provisional documents and most of the properties are set when the "real" document is created), but here I think we have a different situation: for the purpose of `is_prerendering` tracker, the case (2) actually doesn't change much.(RFH can't transition from `is_prerendered=false` to `is_prerendered=true` state, and the `is_prerendered=true` to `is_prerendered=false` transition is not triggered by the navigation itself).So the first step of my proposal here would be "let's move setting is_prerendering=true" to the place where RenderFrame is created rather than setting it via the commit params.It's fairly straightforward to do for cases where the browser creates RenderFrame, but in the subframe case, whether this process is initiated by the renderer is trickier.As you mentioned, inheriting the `is_prerendered` value from the parent RenderFrame seems possible, but it seems fragile and I think we might have a better solution here:Let's store `is_prerenderer` in RenderView, not RenderFrame :).The main benefit is that for the subframe case the renderer creates a new RenderFrame, but uses the same RenderView, so we'll get "inherit from parent" behaviour by default.
(there is a case when the renderer creates a RenderView for a window.open, but this is disallowed in prerendering, so we won't have to worry about that).The added bonus is that it will be aligned with how bfcache state is tracked in the renderer :).On Tue, 6 Jul 2021 at 12:16, Lingqi Chi <lin...@chromium.org> wrote:From MCC's point of view:
- Regarding the first case of "For example, an about:blank iframe appears to get the broker by sending the receiver in a CreateChildFrame message:
- That's why we start applying MojoBinderPolicies at the moment when a RFH instance is created.
- For the prerendering state, their parent can teach them. (as FramePolicy does?
- Regarding the second case of binding BIB in CreateRenderView
- Under the old architecture, i.e., prerender pages have their own WebContents, we noticed that for the main frame of prerendering page, BindBrowserInterfaceBrokerReceiver() is called twice. (I'm not sure whether it is turn under the MPArch, but it would be easy to confirm.
- one is called when RenderView is created, the other is called in DidCommitNavigation()
- I feel it would still be safe and would not break our design, because:
- a newly created main document without a navigation committed is nearly empty, which means the Mojo messages it sends are not decided by sites owners, but by us, so it would be easy to collect the data we want.
- (In Feb. or Jan.) So, I collected pending receivers that RFH's BIB received before RFH committed the main frame navigation(on my gLinux device), and found RFH's BIB doesn't receive anything before the navigation is committed .
- ( we may want to collect this kind of data again on other devices and on the current branch, but feel it would be 0.)
--
You received this message because you are subscribed to the Google Groups "navigation-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to navigation-de...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/navigation-dev/CALHg4nnTh41vGi1vKYRZD8OHzyNq1kL8Y4HpWD5a_CCvHEbL%3Dg%40mail.gmail.com.
Thanks all. I started formulating an approach just before Alexander's last email came in, so I'll write what I had been thinking. I think there is some subtlety here due to MCC....
I also found it unsatisfying to completely rely on the renderer getting the prerendering state from the parent. It seems possible to hit races where the frame in the renderer looks at the parent just as activation is happening, and the parent may or may not have received the Activate IPC yet. It also feels error-prone that RFHI does not know with certainty whether the corresponding frame in the renderer thinks it's prerendering, since RFHI decides when to apply/release MCC.
I feel MCC is really related to the prerendering state. The RFHI needs to know whether to apply the policies, and whether to expect a DidActivate IPC to release them.
With that in mind I'm starting to feel we need to do something like this:
1. Whenever the renderer sends a BIB receiver to the browser, it needs to pass an "is_prerendering" along with it. The "is_prerendering" is computed either from the CommitNavigation param or from the parent. This way in BindBrowserInterfaceBrokerReceiver(), the RFHI can know whether it needs to apply MCC, and if it does, it knows it needs to send the Activate IPC on activation and wait for DidActivate before releasing. In cases where the browser can compute what it expects "is_prerendering" to be, it can validate what the renderer is saying (e.g., if it previously sent a CommitNavigation with is_prerendering).
Cases: DidCommitNavigation, CreateChildFrame,
2. Whenever the browser pushes a BIB remote to the renderer, it needs to pass an "is_prerendering" along with it.
Cases: AgentSchedulingGroup.CreateFrame, AgentSchedulingGroup.CreateView
Just a few questions from my side:On Tue, 6 Jul 2021 at 07:01, Matt Falkenhagen <fal...@chromium.org> wrote:Thanks all. I started formulating an approach just before Alexander's last email came in, so I'll write what I had been thinking. I think there is some subtlety here due to MCC....
I also found it unsatisfying to completely rely on the renderer getting the prerendering state from the parent. It seems possible to hit races where the frame in the renderer looks at the parent just as activation is happening, and the parent may or may not have received the Activate IPC yet. It also feels error-prone that RFHI does not know with certainty whether the corresponding frame in the renderer thinks it's prerendering, since RFHI decides when to apply/release MCC.
I feel MCC is really related to the prerendering state. The RFHI needs to know whether to apply the policies, and whether to expect a DidActivate IPC to release them.
With that in mind I'm starting to feel we need to do something like this:
1. Whenever the renderer sends a BIB receiver to the browser, it needs to pass an "is_prerendering" along with it. The "is_prerendering" is computed either from the CommitNavigation param or from the parent. This way in BindBrowserInterfaceBrokerReceiver(), the RFHI can know whether it needs to apply MCC, and if it does, it knows it needs to send the Activate IPC on activation and wait for DidActivate before releasing. In cases where the browser can compute what it expects "is_prerendering" to be, it can validate what the renderer is saying (e.g., if it previously sent a CommitNavigation with is_prerendering).
Cases: DidCommitNavigation, CreateChildFrame,
2. Whenever the browser pushes a BIB remote to the renderer, it needs to pass an "is_prerendering" along with it.
Cases: AgentSchedulingGroup.CreateFrame, AgentSchedulingGroup.CreateViewFor AgentSchedulingGroup.CreateView:Just to confirm, when we create the renderer for a prerendered page, we still create the RenderView via CreateRenderViewForRenderManager() right? The main frame in this case seems like it probably wouldn't /need/ to know about prerendering, as it shouldn't be doing anything--but maybe there's stuff injected by content embedders that would trigger interface requests, et cetera?
For AgentSchedulingGroup.CreateFrame:I expect we wouldn't hit this currently at all for prerendered pages. I believe it's used for recreating RenderFrames after a crash, and also for creating provisional RenderFrames. Per the chat, my understanding is that prerendering is limited to same-origin subframes currently, so we would never hit either of these cases--though we would hit the latter with RenderDocument.That being said, it makes sense to me to plumb it for consistency. Will RenderFrameObservers and such also need to know about prerendering?
Thanks Daniel.2021年7月7日(水) 16:49 Daniel Cheng <dch...@chromium.org>:Just a few questions from my side:On Tue, 6 Jul 2021 at 07:01, Matt Falkenhagen <fal...@chromium.org> wrote:Thanks all. I started formulating an approach just before Alexander's last email came in, so I'll write what I had been thinking. I think there is some subtlety here due to MCC....
I also found it unsatisfying to completely rely on the renderer getting the prerendering state from the parent. It seems possible to hit races where the frame in the renderer looks at the parent just as activation is happening, and the parent may or may not have received the Activate IPC yet. It also feels error-prone that RFHI does not know with certainty whether the corresponding frame in the renderer thinks it's prerendering, since RFHI decides when to apply/release MCC.
I feel MCC is really related to the prerendering state. The RFHI needs to know whether to apply the policies, and whether to expect a DidActivate IPC to release them.
With that in mind I'm starting to feel we need to do something like this:
1. Whenever the renderer sends a BIB receiver to the browser, it needs to pass an "is_prerendering" along with it. The "is_prerendering" is computed either from the CommitNavigation param or from the parent. This way in BindBrowserInterfaceBrokerReceiver(), the RFHI can know whether it needs to apply MCC, and if it does, it knows it needs to send the Activate IPC on activation and wait for DidActivate before releasing. In cases where the browser can compute what it expects "is_prerendering" to be, it can validate what the renderer is saying (e.g., if it previously sent a CommitNavigation with is_prerendering).
Cases: DidCommitNavigation, CreateChildFrame,
2. Whenever the browser pushes a BIB remote to the renderer, it needs to pass an "is_prerendering" along with it.
Cases: AgentSchedulingGroup.CreateFrame, AgentSchedulingGroup.CreateViewFor AgentSchedulingGroup.CreateView:Just to confirm, when we create the renderer for a prerendered page, we still create the RenderView via CreateRenderViewForRenderManager() right? The main frame in this case seems like it probably wouldn't /need/ to know about prerendering, as it shouldn't be doing anything--but maybe there's stuff injected by content embedders that would trigger interface requests, et cetera?That's right. As Kinuko pointed out, I was completely incorrect when I said "this probably never happens for prerendering"ーit always happens when we make the Prerendered main frame via NavigationControllerImpl::LoadURLWithParams. I'm not sure how I missed that.I agree with that analysis about embedders, etc,... it feels error-prone to give the BIB to the renderer and expect it to be OK by expecting the renderer to not use it.For AgentSchedulingGroup.CreateFrame:I expect we wouldn't hit this currently at all for prerendered pages. I believe it's used for recreating RenderFrames after a crash, and also for creating provisional RenderFrames. Per the chat, my understanding is that prerendering is limited to same-origin subframes currently, so we would never hit either of these cases--though we would hit the latter with RenderDocument.That being said, it makes sense to me to plumb it for consistency. Will RenderFrameObservers and such also need to know about prerendering?Yep, plumbing for consistency/safety is also the conclusion I'm arriving at. I think the RenderView idea Alexander had can augment but not entirely replace this, because of the way each Document needs its own prerendering state which gets reset after the Document finishes dispatching the prerenderingchange event, per the specification steps.
On Wed, 7 Jul 2021 at 09:18, Matt Falkenhagen <fal...@chromium.org> wrote:Thanks Daniel.2021年7月7日(水) 16:49 Daniel Cheng <dch...@chromium.org>:Just a few questions from my side:On Tue, 6 Jul 2021 at 07:01, Matt Falkenhagen <fal...@chromium.org> wrote:Thanks all. I started formulating an approach just before Alexander's last email came in, so I'll write what I had been thinking. I think there is some subtlety here due to MCC....
I also found it unsatisfying to completely rely on the renderer getting the prerendering state from the parent. It seems possible to hit races where the frame in the renderer looks at the parent just as activation is happening, and the parent may or may not have received the Activate IPC yet. It also feels error-prone that RFHI does not know with certainty whether the corresponding frame in the renderer thinks it's prerendering, since RFHI decides when to apply/release MCC.
I feel MCC is really related to the prerendering state. The RFHI needs to know whether to apply the policies, and whether to expect a DidActivate IPC to release them.
With that in mind I'm starting to feel we need to do something like this:
1. Whenever the renderer sends a BIB receiver to the browser, it needs to pass an "is_prerendering" along with it. The "is_prerendering" is computed either from the CommitNavigation param or from the parent. This way in BindBrowserInterfaceBrokerReceiver(), the RFHI can know whether it needs to apply MCC, and if it does, it knows it needs to send the Activate IPC on activation and wait for DidActivate before releasing. In cases where the browser can compute what it expects "is_prerendering" to be, it can validate what the renderer is saying (e.g., if it previously sent a CommitNavigation with is_prerendering).
Cases: DidCommitNavigation, CreateChildFrame,
2. Whenever the browser pushes a BIB remote to the renderer, it needs to pass an "is_prerendering" along with it.
Cases: AgentSchedulingGroup.CreateFrame, AgentSchedulingGroup.CreateViewFor AgentSchedulingGroup.CreateView:Just to confirm, when we create the renderer for a prerendered page, we still create the RenderView via CreateRenderViewForRenderManager() right? The main frame in this case seems like it probably wouldn't /need/ to know about prerendering, as it shouldn't be doing anything--but maybe there's stuff injected by content embedders that would trigger interface requests, et cetera?That's right. As Kinuko pointed out, I was completely incorrect when I said "this probably never happens for prerendering"ーit always happens when we make the Prerendered main frame via NavigationControllerImpl::LoadURLWithParams. I'm not sure how I missed that.I agree with that analysis about embedders, etc,... it feels error-prone to give the BIB to the renderer and expect it to be OK by expecting the renderer to not use it.For AgentSchedulingGroup.CreateFrame:I expect we wouldn't hit this currently at all for prerendered pages. I believe it's used for recreating RenderFrames after a crash, and also for creating provisional RenderFrames. Per the chat, my understanding is that prerendering is limited to same-origin subframes currently, so we would never hit either of these cases--though we would hit the latter with RenderDocument.That being said, it makes sense to me to plumb it for consistency. Will RenderFrameObservers and such also need to know about prerendering?Yep, plumbing for consistency/safety is also the conclusion I'm arriving at. I think the RenderView idea Alexander had can augment but not entirely replace this, because of the way each Document needs its own prerendering state which gets reset after the Document finishes dispatching the prerenderingchange event, per the specification steps.I'd like to understand the problem a bit more here — in particular, I wonder if we could iterate all LocalFrames belonging to a given blink::WebView on the blink side and dispatch the necessary `prerenderingchange` events to each Document there?
Note that we used to use a single Activation IPC but it was reversed, I think the reasons listed there are tractable though.
If we could defer instead of run kCancel/kUnexpected in loose mode, that could be more viable, but there are other challenges there.