User activation same-origin visibility: add detailed comments.

Also consolidate all UAv2 comments in one place (UserActivationState).

Bug: 923160
Change-Id: I00ccde42887d38f0c40ac91f347e9cf71fe156f8
TBR: dcheng@chromium.org,alexmos@chromium.org
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1423158
Reviewed-by: Mustaq Ahmed <mustaq@chromium.org>
Commit-Queue: Mustaq Ahmed <mustaq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#642952}
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc
index 6036fde..7e443f7c 100644
--- a/content/browser/frame_host/frame_tree_node.cc
+++ b/content/browser/frame_host/frame_tree_node.cc
@@ -563,10 +563,8 @@
   }
   replication_state_.has_received_user_gesture = true;
 
-  // TODO(mustaq): The following block relaxes UAv2 a bit to make it slightly
-  // closer to the old (v1) model, to address a Hangout regression.  We will
-  // remove this after implementing a mechanism to delegate activation to
-  // subframes (https://crbug.com/728334)
+  // See the "Same-origin Visibility" section in |UserActivationState| class
+  // doc.
   if (base::FeatureList::IsEnabled(features::kUserActivationV2) &&
       base::FeatureList::IsEnabled(
           features::kUserActivationSameOriginVisibility)) {
diff --git a/content/browser/frame_host/frame_tree_node.h b/content/browser/frame_host/frame_tree_node.h
index ca60b43..c6700766 100644
--- a/content/browser/frame_host/frame_tree_node.h
+++ b/content/browser/frame_host/frame_tree_node.h
@@ -535,32 +535,8 @@
 
   bool was_discarded_;
 
-  // The user activation state of the current frame.
-  //
-  // Changes to this state update other FrameTreeNodes as follows: for
-  // notification updates (on user inputs) all ancestor nodes are updated; for
-  // activation consumption calls, the whole frame tree is updated (w/o such
-  // exhaustive consumption, a rouge iframe can cause multiple consumptions per
-  // user activation).
-  //
-  // The user activation state is replicated in the browser process (in
-  // FrameTreeNode) and in the renderer processes (in LocalFrame and
-  // RemoteFrames).  The replicated states across the browser and renderer
-  // processes are kept in sync as follows:
-  //
-  // [A] Consumption of activation state for popups starts in the frame tree of
-  // the browser process and propagate to the renderer trees through direct IPCs
-  // (one IPC sent to each renderer).
-  //
-  // [B] Consumption calls from JS/blink side (e.g. video picture-in-picture)
-  // update the originating renderer's local frame tree and send an IPC to the
-  // browser; the browser updates its frame tree and sends IPCs to all other
-  // renderers each of which then updates its local frame tree.
-  //
-  // [B'] Notification updates on user inputs still follow [B] but they should
-  // really follow [A].  TODO(mustaq): fix through https://crbug.com/848778.
-  //
-  // [C] Expiration of an active state is tracked independently in each process.
+  // The user activation state of the current frame.  See |UserActivationState|
+  // for details on how this state is maintained.
   blink::UserActivationState user_activation_state_;
 
   // A helper for tracing the snapshots of this FrameTreeNode and attributing
diff --git a/third_party/blink/public/common/frame/user_activation_state.h b/third_party/blink/public/common/frame/user_activation_state.h
index 1568a01..a73a235 100644
--- a/third_party/blink/public/common/frame/user_activation_state.h
+++ b/third_party/blink/public/common/frame/user_activation_state.h
@@ -12,11 +12,78 @@
 
 // This class represents the user activation state of a frame.  It maintains two
 // bits of information: whether this frame has ever seen an activation in its
-// lifetime, and whether this frame has a current activation that was neither
-// expired nor consumed.
+// lifetime (the sticky bit), and whether this frame has a current activation
+// that is neither expired nor consumed (the transient bit).  See User
+// Activation v2 (UAv2) links below for more info.
 //
-// This provides a simple alternative to current user gesture tracking code
-// based on UserGestureIndicator and UserGestureToken.
+//
+// Tracking User Activation across the Frame Tree
+// ==============================================
+//
+// This state changes in three ways: activation (of both bits) through user
+// input notifications, and deactivation (of transient bit only) through expiry
+// and consumption.
+//
+// - A notification update at a frame activates all ancestor frames (sets both
+// bits to true).  Also see "Same-origin Visibility" below.
+//
+// - A consumption call deactivates the transient bits in the whole frame tree.
+// This exhaustive consumption guarantees that a malicious subframe can't embed
+// sub-subframes in a way that could allow multiple consumptions per user
+// activation.
+//
+// - After a certain time limit (few seconds), the transient bit is deactivated.
+// Internally this is updated lazily on state polling.
+//
+//
+// Same-origin Visibility of User Activation
+// =========================================
+//
+// We launched UAv2 with a relaxed visibility model that a user activation is
+// visible to all same-origin frames (w.r.t. the originally-activated frame), in
+// addition to the ancestor frames as per UAv2.  We will remove this relaxation
+// after implementing a mechanism for activation transfer
+// (https://crbug.com/928838).
+//
+// Details: Before UAv2, user activation was visible to all same-process frames
+// and no cross-process frames (undocumented).  The ancestor-only restriction
+// with UAv2 caused a few breakages because of reliance on the old assumption,
+// see the Type=Bug-Regression bugs blocking the above bug.  Once we have a
+// workaround for those broken cases (most likely through a postMessage
+// transfer), we will go back to the ancestor-only visibility model.
+//
+//
+// State Replication in Browser and Renderers
+// ==========================================
+//
+// The user activation state is replicated in the browser process (in
+// |FrameTreeNode|) and in the renderer processes (in |LocalFrame| and
+// |RemoteFrame|).  The replicated states across the browser and renderer
+// processes are kept in sync as follows:
+//
+// [A] Consumption of activation state for popups starts in the frame tree of
+// the browser process and propagate to the renderer trees through direct IPCs
+// (one IPC sent to each renderer).
+//
+// [B] Consumption calls from JS/blink side (e.g. video picture-in-picture)
+// update the originating renderer's local frame tree and send an IPC to the
+// browser; the browser updates its frame tree and sends IPCs to all other
+// renderers each of which then updates its local frame tree.
+//
+// [B'] Notification updates on user inputs is like [B] (renderer first).  These
+// should really be like [A] (browser first), see https://crbug.com/848778.
+//
+// [C] Expiration of an active state is tracked independently in each process.
+//
+//
+// More Info
+// =========
+//
+// - UAv2 explainer: https://mustaqahmed.github.io/user-activation-v2
+// - Main design:
+//   https://docs.google.com/a/chromium.org/document/d/1erpl1yqJlc1pH0QvVVmi1s3WzqQLsEXTLLh6VuYp228
+// - Browser-side replication for OOPIFs:
+//   https://docs.google.com/document/d/1XL3vCedkqL65ueaGVD-kfB5RnnrnTaxLc7kmU91oerg
 class BLINK_COMMON_EXPORT UserActivationState {
  public:
   void Activate();
diff --git a/third_party/blink/renderer/core/dom/user_gesture_indicator.h b/third_party/blink/renderer/core/dom/user_gesture_indicator.h
index e32295f..12736ad6 100644
--- a/third_party/blink/renderer/core/dom/user_gesture_indicator.h
+++ b/third_party/blink/renderer/core/dom/user_gesture_indicator.h
@@ -17,6 +17,8 @@
 // which propagates user gestures to the timer fire in certain situations).
 // Passing it to a UserGestureIndicator later on will cause it to be considered
 // as currently being processed.
+//
+// DEPRECATED: Use |UserActivationState| accessors in |Frame|.
 class CORE_EXPORT UserGestureToken : public RefCounted<UserGestureToken> {
   friend class UserGestureIndicator;
 
@@ -48,6 +50,7 @@
   DISALLOW_COPY_AND_ASSIGN(UserGestureToken);
 };
 
+// DEPRECATED: Use |UserActivationState| accessors in |Frame|.
 class CORE_EXPORT UserGestureIndicator final {
   USING_FAST_MALLOC(UserGestureIndicator);
 
diff --git a/third_party/blink/renderer/core/frame/frame.cc b/third_party/blink/renderer/core/frame/frame.cc
index 17a8160..b97e74d 100644
--- a/third_party/blink/renderer/core/frame/frame.cc
+++ b/third_party/blink/renderer/core/frame/frame.cc
@@ -190,7 +190,8 @@
   for (Frame* node = this; node; node = node->Tree().Parent())
     node->user_activation_state_.Activate();
 
-  // See FrameTreeNode::NotifyUserActivation() for details about this block.
+  // See the "Same-origin Visibility" section in |UserActivationState| class
+  // doc.
   auto* local_frame = DynamicTo<LocalFrame>(this);
   if (local_frame && RuntimeEnabledFeatures::UserActivationV2Enabled() &&
       RuntimeEnabledFeatures::UserActivationSameOriginVisibilityEnabled()) {
@@ -212,9 +213,6 @@
 bool Frame::ConsumeTransientUserActivationInLocalTree() {
   bool was_active = user_activation_state_.IsActive();
 
-  // Note that consumption "touches" the whole frame tree, to guarantee that a
-  // malicious subframe can't embed sub-subframes in a way that could allow
-  // multiple consumptions per user activation.
   Frame& root = Tree().Top();
   for (Frame* node = &root; node; node = node->Tree().TraverseNext(&root))
     node->user_activation_state_.ConsumeIfActive();
diff --git a/third_party/blink/renderer/core/frame/frame.h b/third_party/blink/renderer/core/frame/frame.h
index a777236..2b477a2 100644
--- a/third_party/blink/renderer/core/frame/frame.h
+++ b/third_party/blink/renderer/core/frame/frame.h
@@ -267,8 +267,8 @@
   Member<FrameOwner> owner_;
   Member<DOMWindow> dom_window_;
 
-  // The user activation state of the current frame.  See
-  // FrameTreeNode::user_activation_state_ for details.
+  // The user activation state of the current frame.  See |UserActivationState|
+  // for details on how this state is maintained.
   UserActivationState user_activation_state_;
 
   bool has_received_user_gesture_before_nav_ = false;
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index e77b504..52c1777e 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -483,8 +483,8 @@
   // Returns the transient user activation state of this frame
   bool HasTransientUserActivation();
 
-  // Consumes and returns the transient user activation state of this frame,
-  // after updating all ancestor/descendant frames.
+  // Consumes and returns the transient user activation state this frame, after
+  // updating all other frames in the frame tree.
   bool ConsumeTransientUserActivation(UserActivationUpdateSource update_source);
 
   void SetFrameColorOverlay(SkColor color);