New issue
Advanced search Search tips

Issue 905448 link

Starred by 2 users

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 3
Type: Bug



Sign in to add a comment

Decide whether User Activation bits belong on FrameTreeNode or RenderFrameHost

Project Member Reported by creis@chromium.org, Nov 14

Issue description

User Activation state is currently stored on FrameTreeNode and replicated across processes involved in rendering a page.  Some background here:
https://mustaqahmed.github.io/user-activation-v2/

However, when reviewing https://chromium-review.googlesource.com/c/chromium/src/+/1320517/, it appears to me that we reset the User Activation state after every cross-document navigation in a frame.  In that sense, the state does not outlive the document loaded in the frame, and at a high level, it seems to be per-document rather than per-frame.  (Correct me if I'm wrong-- are there any cases where a new document is loaded in a frame and the user activation state for the frame is preserved for the new document?)

If this is the case, then it seems like state should perhaps live on RenderFrameHost rather than FrameTreeNode.  A FrameTreeNode may have different RenderFrameHosts over time (as we navigate across processes), and should mainly track things that exist for the lifetime of the frame rather than the document.  It doesn't seem worth having the possibility of forgetting to reset document-level state on the FrameTreeNode, as happened in  issue 901069 .

That approach seems like it would be an even better fit once we change RenderFrameHost to be RenderDocumentHost and swap on every cross-document navigation, rather than just cross-process navigations (as dcheng@ has been planning).

Let's use this bug to discuss whether this would be a better design, or if there are reasons the User Activation state belongs on FrameTreeNode instead.  (Maybe it makes replication easier?)
 
Status: Assigned (was: Untriaged)
Yes, UAv2 states should never be carried forward after a navigation.  So I agree they can be moved to RFH today.

However, your future plan to move them to RenderDocumentHost sounds wrong to me from the description above (I don't know anything else about RenderDocumentHost).  UAv2 bits represent a per-frame activation state, not a document-wide state (unlike current per-renderer state in UserGestureIndicator).

Let me explain a per-frame activation scenario, let me know if you still think RenderDocumentHost would be a better place:

Suppose we have root frame A containing two child frames B and C (each from a different origin).  If the user interacts with B, both B and its container (A) are considered activated in UAv2, allowing them to use activated-gated APIs (like window.open(), video autoplay, fullscreen etc.).  However, C is not activated as the user never interacted within this frame.

Ah, I see the point of confusion!  We use the term "document" to refer to the HTML document within a given frame, and "page" to refer to the whole tab's contents, including all frames in the tree.

In that sense, WebContents is a page-level abstraction (which contains many frames and documents), FrameTreeNode is a frame-level abstraction (which can contain different documents over time), and RenderDocumentHost will be a document-level abstraction (specific to a frame within a page).  Today's RenderFrameHost is kind of a confusing abstraction that spans multiple same-site documents within a frame but switches for cross-site documents, which explains why we want to move to RenderDocumentHost.

Would that match your expectations for UAv2 state?
Also, just to make sure: let's say we have a hierarchy A(B(C)), and C gets activated.  That also activates B and A, since activation applies to ancestors as well.  If B navigates to D (destroying C), is the end state that D is not activated (since a cross-document navigation should clear activation), but A is still activated?
creis@: Yes, UAv2 bits in RenderDocumentHost would make perfect sense.

alexmos@: Frame A should still be activated in your example, but there is one little detail I need to clarify: the sticky activation bit in A would remain set because the user has interacted within its bounding box, but the transient activation bit *may* get consumed by the navigation operation (because consumption calls clear the transient states across the whole tree).  I said "may" because I don't know if subframe navigations consume activation or not.  

Sign in to add a comment