// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module blink.mojom;
import "mojo/public/mojom/base/time.mojom";
import "url/mojom/url.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "third_party/blink/public/mojom/preloading/anchor_element_interaction_host.mojom";
// This mojom file is for user navigation prediction experiment, using anchor
// element metrics gathered from the renderer process. See crbug.com/850624.
// Struct holding metrics of an anchor element extracted in the renderer
// process.
struct AnchorElementMetrics {
// An ID assigned to this Anchor. This is the hash of the anchor's pointer
// value. This means module hash collisions, anchor IDs should be unique for
// a given page load and given renderer, but are not stable across page loads
// (loading the same page twice will give two different IDs for the same
// anchor element). If anchor IDs from different renderers are combined on the
// browser site (for the same page load), then the browser has to be careful
// about collisions. Since we currently do not report anchor elements from
// OOPIFs, this is not a concern at this point.
uint32 anchor_id;
// The ratio between the absolute clickable region area of an anchor
// element, and the viewport area. The value is capped at 1.
float ratio_area;
// The distance between the top of the clickable region of an anchor
// element and the top edge of the visible region, divided by the viewport
// height.
float ratio_distance_top_to_visible_top;
// The distance between the top of the clickable region of an anchor element
// and the top edge of the root frame, divided by the viewport height.
float ratio_distance_root_top;
// Whether the anchor element is within an iframe.
bool is_in_iframe;
// Whether the anchor element contains an image element.
bool contains_image;
// Whether the link target has the same host as the root document.
bool is_same_host;
// Whether the target URL and the host URL only differ by one number,
// and the number in target URL equals the one in host URL plus one.
bool is_url_incremented_by_one;
// Whether the anchor element has an immediate sibling that is a text node.
bool has_text_sibling;
// The font size in pixels of the anchor element according to its computed
// style.
uint32 font_size_px;
// The font weight of the anchor element according to its computed style.
uint32 font_weight;
// The target URL (href) specified by the anchor element. URLs sent from a
// renderer process are not trusted, however it is intended here since it
// is only used for metrics calculation.
url.mojom.Url target_url;
// The size of the viewport at the time the anchor element was created.
gfx.mojom.Size viewport_size;
};
struct AnchorElementClick {
// The ID of the anchor that was clicked.
uint32 anchor_id;
// The URL of the anchor when it was clicked.
url.mojom.Url target_url;
// The time between navigation start of the anchor element's root document and
// the time the user clicked on the link.
mojo_base.mojom.TimeDelta navigation_start_to_click;
};
struct AnchorElementPointerDataOnHoverTimerFired {
// The ID of the anchor that was clicked.
uint32 anchor_id;
// The pointer data including mouse velocity and acceleration.
blink.mojom.AnchorElementPointerData pointer_data;
};
struct AnchorElementEnteredViewport {
// The ID of the anchor that entered the viewport.
uint32 anchor_id;
// The time between navigation start of the anchor element's root document and
// the time the anchor element entered the viewport.
mojo_base.mojom.TimeDelta navigation_start_to_entered_viewport;
};
struct AnchorElementLeftViewport {
// The ID of the anchor that exited the viewport.
uint32 anchor_id;
// The time between the moment the anchor element entered the viewport and the
// moment it left the viewport.
mojo_base.mojom.TimeDelta time_in_viewport;
};
struct AnchorElementPointerOver {
// The ID of the anchor that pointer started hovering over it.
uint32 anchor_id;
// The time between navigation start of the anchor element's root document and
// the time the pointer started hovering over the anchor element event.
mojo_base.mojom.TimeDelta navigation_start_to_pointer_over;
};
struct AnchorElementPointerOut {
// The ID of the anchor that pointer hovered over it.
uint32 anchor_id;
// The time interval pointer was hovering over the anchor element.
mojo_base.mojom.TimeDelta hover_dwell_time;
};
// Represents different user interaction types used for computing preloading ML
// model inputs..
enum AnchorElementUserInteractionEventForMLModelType {
kPointerOver,
kPointerOut,
kEnteredViewport,
kLeftViewport,
kUnknown,
};
struct AnchorElementPointerEventForMLModel {
// The ID of the anchor that pointer hovered over it.
uint32 anchor_id;
// Whether the point event triggered by mouse or not.
bool is_mouse;
// User interaction event type.
AnchorElementUserInteractionEventForMLModelType user_interaction_event_type;
};
struct AnchorElementPointerDown {
// The ID of the anchor that pointer down event happened over it.
uint32 anchor_id;
// The time between navigation start of the anchor element's root document and
// the time the pointer down event happened over the anchor element event.
mojo_base.mojom.TimeDelta navigation_start_to_pointer_down;
};
struct AnchorElementPositionUpdate {
// The ID of the anchor.
uint32 anchor_id;
// The vertical position of the anchor's center in the viewport (expressed as
// a ratio of the viewport height).
float vertical_position_ratio;
// The vertical distance between the anchor's center and the last recorded
// pointer down (expressed as a ratio of the screen height).
float? distance_from_pointer_down_ratio;
};
// TODO(isaboori): It's better to move the methods that are called for all
// anchor elements and not just the down-sampled ones to a new
// `AnchorElementInteractionHost` interface.
// An interface to pass descriptive information about anchor elements from
// the renderer process to the implementation of this interface living in the
// browser process.
interface AnchorElementMetricsHost {
// This is called when an anchor element is clicked. The renderer extracts and
// sends |metrics| of the clicked anchor element.
// This is called for all anchor elements.
ReportAnchorElementClick(AnchorElementClick clicked);
// At each layout, HTMLAnchorElements that have been newly created (since the
// last layout) may be reported. Only elements with an HTTPS href attribute
// that are 'visible' (they have non-empty bounding box, though they may not
// be in the viewport) are reported. This reports various metrics about each
// element. New HTMLAnchorElements that are not visible after the first layout
// since their creation will never be reported. This is not ideal, but allows
// us to avoid keeping references to elements that may never become visible.
// `removed_elements` contains the anchor ids of anchor elements that have
// been removed from the document since the last call to this method.
// This is called for all anchor elements.
ReportNewAnchorElements(array<AnchorElementMetrics> metrics,
array<uint32> removed_elements);
// This is called regularly to report anchors that entered the viewport. This
// just reports the ID of each element entering the viewport. These records
// can be joined with the metrics reported by ReportNewAnchorElements.
// However, it is possible that some elements reported by this RPC have not
// previously been reported by ReportNewAnchorElements (e.g. because they were
// not visible following the first layout after the HTMLAnchorElement was
// created).
// This is called only for randomly selected anchor elements that we track.
ReportAnchorElementsEnteredViewport(
array<AnchorElementEnteredViewport> elements);
// This is called regularly to report anchors that left the viewport. This
// just reports the ID of each element leaving the viewport. These records
// can be joined with the metrics reported by
// |ReportAnchorElementsEnteredViewport|.
// This is called only for randomly selected anchor elements that we track.
ReportAnchorElementsLeftViewport(array<AnchorElementLeftViewport> elements);
// This is called after the end of a scroll to report metrics related to the
// position of anchors in the viewport. The update will only include metrics
// for anchors that have already been reported to be inside the viewport.
// This is called only for randomly selected anchor elements that we track.
ReportAnchorElementsPositionUpdate(
array<AnchorElementPositionUpdate> elements);
// This is called whenever the pointer starts hovering over anchor element.
// This is called only for randomly selected anchor elements that we track.
ReportAnchorElementPointerOver(AnchorElementPointerOver pointer_over_event);
// This is called whenever pointer stops hovering over the anchor element.
// This is called only for randomly selected anchor elements that we track.
ReportAnchorElementPointerOut(AnchorElementPointerOut hover_event);
// This is called whenever pointer down event happens over the anchor element.
// This is called only for randomly selected anchor elements that we track.
ReportAnchorElementPointerDown(AnchorElementPointerDown pointer_down_event);
// This is called whenever the on-hover timer for the anchor element is fired.
// This is called for all anchor elements.
ReportAnchorElementPointerDataOnHoverTimerFired(
AnchorElementPointerDataOnHoverTimerFired pointer_data);
// This is called whenever a pointer event is triggered and intended to be
// used by the preloading heuristics ML model.
// This is called for all anchor elements.
ProcessPointerEventUsingMLModel(
AnchorElementPointerEventForMLModel pointer_event);
// Asks the browser whether to send subsequent updates immediately
// instead of rate limiting.
// Skipping the delays is only expected to be done for testing.
ShouldSkipUpdateDelays() => (bool should_skip_for_testing);
};