// 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, anchor elements 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 anchor elements 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 metrics, array 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 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 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 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); };