// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module blink.mojom;

import "cc/mojom/browser_controls_state.mojom";
import "cc/mojom/render_frame_metadata.mojom";
import "cc/mojom/touch_action.mojom";
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "mojo/public/mojom/base/text_direction.mojom";
import "mojo/public/mojom/base/time.mojom";
import "services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom";
import "services/network/public/mojom/content_security_policy.mojom";
import "services/network/public/mojom/cross_origin_opener_policy.mojom";
import "services/network/public/mojom/fetch_api.mojom";
import "services/network/public/mojom/source_location.mojom";
import "services/network/public/mojom/web_sandbox_flags.mojom";
import "services/viz/public/mojom/compositing/frame_sink_id.mojom";
import "skia/public/mojom/skcolor.mojom";
import "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom";
import "third_party/blink/public/mojom/blob/blob.mojom";
import "third_party/blink/public/mojom/blob/blob_url_store.mojom";
import "third_party/blink/public/mojom/messaging/transferable_message.mojom";
import "third_party/blink/public/mojom/choosers/popup_menu.mojom";
import "third_party/blink/public/mojom/context_menu/context_menu.mojom";
import "third_party/blink/public/mojom/devtools/console_message.mojom";
import "third_party/blink/public/mojom/devtools/inspector_issue.mojom";
import "third_party/blink/public/mojom/feature_policy/feature_policy.mojom";
import "third_party/blink/public/mojom/favicon/favicon_url.mojom";
import "third_party/blink/public/mojom/fetch/fetch_api_request.mojom";
import "third_party/blink/public/mojom/frame/blocked_navigation_types.mojom";
import "third_party/blink/public/mojom/frame/frame_owner_properties.mojom";
import "third_party/blink/public/mojom/frame/frame_policy.mojom";
import "third_party/blink/public/mojom/frame/frame_visual_properties.mojom";
import "third_party/blink/public/mojom/frame/fullscreen.mojom";
import "third_party/blink/public/mojom/frame/intrinsic_sizing_info.mojom";
import "third_party/blink/public/mojom/frame/lifecycle.mojom";
import "third_party/blink/public/mojom/frame/media_player_action.mojom";
import "third_party/blink/public/mojom/frame/policy_container.mojom";
import "third_party/blink/public/mojom/frame/reporting_observer.mojom";
import "third_party/blink/public/mojom/frame/sudden_termination_disabler_type.mojom";
import "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom";
import "third_party/blink/public/mojom/frame/user_activation_update_types.mojom";
import "third_party/blink/public/mojom/frame/viewport_intersection_state.mojom";
import "third_party/blink/public/mojom/input/focus_type.mojom";
import "third_party/blink/public/mojom/input/scroll_direction.mojom";
import "third_party/blink/public/mojom/modal_close_watcher/modal_close_listener.mojom";
import "third_party/blink/public/mojom/loader/referrer.mojom";
import "third_party/blink/public/mojom/portal/portal.mojom";
import "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom";
import "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom";
import "third_party/blink/public/mojom/timing/resource_timing.mojom";
import "third_party/blink/public/mojom/tokens/tokens.mojom";
import "third_party/blink/public/mojom/web_feature/web_feature.mojom";
import "ui/base/mojom/window_open_disposition.mojom";
import "ui/events/mojom/scroll_granularity.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/gfx/range/mojom/range.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";

[EnableIf=is_mac]
import "ui/gfx/range/mojom/range.mojom";

[EnableIf=is_mac]
import "ui/base/mojom/attributed_string.mojom";

// Information about a subframe being saved as "complete html".
struct SavableSubframe {
  // Original url of the subframe (i.e. based the parent's html sources).
  url.mojom.Url original_url;

  // The unique identifier of the RenderFrameHost or RenderFrameProxy for the
  // subframe.
  blink.mojom.FrameToken subframe_token;
};

struct GetSavableResourceLinksReply {
  array<url.mojom.Url> resources_list;
  blink.mojom.Referrer referrer;
  array<SavableSubframe> subframes;
};

struct FindInPageResultAXParams {
  // The find in page request id.
  int32 request_id;

  // The index of the result match.
  int32 match_index;

  // The id of the accessibility object for the start of the match range.
  int32 start_id;

  // The character offset into the text of the start object.
  int32 start_offset;

  // The id of the accessibility object for the end of the match range.
  int32 end_id;

  // The character offset into the text of the end object.
  int32 end_offset;
};

// This struct holds parameters sent by the renderer to the browser, that are
// needed to download an URL.
struct DownloadURLParams {
  url.mojom.Url url;
  blink.mojom.Referrer? referrer;
  url.mojom.Origin? initiator_origin;
  mojo_base.mojom.String16? suggested_name;
  network.mojom.RedirectMode cross_origin_redirects;

  // Non-null when |url| is for "blob:".
  pending_remote<BlobURLToken>? blob_url_token;

  // Non-null when |url| is for "data:", eg. when saving an image.
  pending_remote<Blob>? data_url_blob;

  // Whether the download is from context menu.
  bool is_context_menu_save = false;
};

// Actions browser can ask renderer to perform on a Plugin.
enum PluginActionType {
  kRotate90Clockwise,
  kRotate90Counterclockwise,
};

enum TriggeringEventInfo {
  kUnknown,

  // The navigation was not triggered via a JS Event.
  kNotFromEvent,

  // The navigation was triggered via a JS event with isTrusted() == true.
  kFromTrustedEvent,

  // The navigation was triggered via a JS event with isTrusted() == false.
  kFromUntrustedEvent,
};

// The maximum number of characters of the document's title that we're willing
// to accept in the browser process.
const uint16 kMaxTitleChars = 4096; // 4 * 1024;

struct TextAutosizerPageInfo {
  // Frame width in density-independent pixels.
  int32 main_frame_width;

  // Layout width in CSS pixels.
  int32 main_frame_layout_width;

  float device_scale_adjustment;
};

// An opaque handle that keeps alive the associated render process even after
// the frame is detached. Used by resource requests with "keepalive" specified.
interface KeepAliveHandle {};

// A factory interface for KeepAliveHandle. This is separate from LocalFrameHost
// because LocalFrameHost may not be usable when the frame is about to be gone.
interface KeepAliveHandleFactory {
  // Creates and returns a KeepAliveHandle.
  IssueKeepAliveHandle(
      pending_receiver<blink.mojom.KeepAliveHandle> keep_alive_handle);
};

// Implemented in Browser, this interface defines frame-specific methods that
// will be invoked from the render process (e.g. content::RenderFrameHostImpl).
//
// Note that this is different than content/common/frame.mojom in that the
// methods defined here are called directly in Blink without passing through
// content. In the future this interface will likely host more methods as the
// Onion Soup project advances, which can potentially lead to the removal of
// content/common/frame.mojom if enough code is moved to Blink.
interface LocalFrameHost {
  // Request to the browser that the frame wishes to enter fullscreen mode.
  // Returns either true if fullscreen is allowed to be entered, or false if the
  // request to enter fullscreen was denied. Note that the actual transition to
  // fullscreen will occur on the next visual update, when the next
  // Widget::UpdateVisualProperties is sent.
  EnterFullscreen(FullscreenOptions options) => (bool granted);

  // Request to the browser to exit fullscreen mode.
  ExitFullscreen();

  // Notifies the browser that the current frame has either become or is no
  // longer fullscreen. |options| is only provided if |is_fullscreen == true|.
  FullscreenStateChanged(bool is_fullscreen, FullscreenOptions? options);

  // Register a new handler for URL requests with the given scheme. |scheme|
  // and |url| are provided directly from javascript. See
  // https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers
  // |user_gesture| indicates if the javascript API was called in context of
  // having an active transient user gesture.
  RegisterProtocolHandler(string scheme, url.mojom.Url url, bool user_gesture);

  // Unregister the registered handler for URL requests with the given scheme.
  // |scheme|, and |url| are provided directly from javascript. See
  // https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers
  // |user_gesture| indicates if the javascript API was called in context of
  // having an active transient user gesture.
  UnregisterProtocolHandler(string scheme, url.mojom.Url url, bool user_gesture);

  // Indication that the associated frame has displayed inactive content
  // (such as an image) from an insecure source. Inactive content cannot spread
  // to other frames.
  DidDisplayInsecureContent();

  // Indication that the associated frame contains a form that submits to an
  // insecure target url.
  DidContainInsecureFormAction();

  // Indicates that the document element is available for the top-level frame.
  // This happens after the page starts loading, but before all resources are
  // finished.
  DocumentAvailableInMainFrame(bool uses_temporary_zoom_level);

  // Indicates that a child frame requires its parent frame to send it
  // information about whether it is occluded or has visual effects applied,
  // in order to service IntersectionObserver's that track visibility.
  SetNeedsOcclusionTracking(bool needs_tracking);

  // Indication that the associated frame would like to change the policy on
  // whether or not the virtual keyboard should overlay content (vs. default
  // behavior of 'shifting' the content via insets and a scrollIntoView).
  SetVirtualKeyboardOverlayPolicy(bool vk_overlays_content);

  // Notifies the browser that the associated frame has changed its visibility
  // status. Visibility status changes occur when the frame moves in/out
  // of the viewport, or the need for a layout object changes, e.g. if the
  // frame owner assigns a display: none style.
  VisibilityChanged(blink.mojom.FrameVisibility visibility);

  // Notifies the browser that the associated frame has changed theme color.
  // This will only be called on main-frames only. |theme_color| is optional
  // and indicates if a theme color has been specified or not, e.g. removal
  // of a theme color meta tag will generate a null value.
  DidChangeThemeColor(skia.mojom.SkColor? theme_color);

  // Notifies the browser that the associated frame has changed its computed CSS
  // background color. This will be called on main-frames only.
  // |color_adjust| is true if the background is forced by color adjustments.
  DidChangeBackgroundColor(skia.mojom.SkColor background_color, bool color_adjust);

  // Sent when the renderer fails to load with |error_code| which means a net
  // error code.
  DidFailLoadWithError(url.mojom.Url url, int32 error_code);

  // Sent by the renderer when the associated frame becomes focused.
  DidFocusFrame();

  // Called to notify the browser process counterpart of this local frame that
  // |window.focus()| on a page has been invoked in the renderer process.
  DidCallFocus();

  // Notifies the browser process about a new Content Security Policy that needs
  // to be applies to the frame. This message is sent when a frame commits
  // navigation to a new location (reporting accumulated policies from HTTP
  // headers and/or policies that might have been inherited from the parent
  // frame) or when a new policy has been discovered afterwards (i.e. found in a
  // dynamically added or a static <meta> element).
  DidAddContentSecurityPolicies(
      array<network.mojom.ContentSecurityPolicy> policies);

  // Sent when the frame starts enforcing an insecure request policy. Sending
  // this information in DidCommitProvisionalLoad isn't sufficient; this
  // message is needed because, for example, a document can dynamically insert
  // a <meta> tag that causes strict mixed content checking to be enforced.
  // |policy_bitmap| is a bitfield for InsecureRequestPolicy.
  EnforceInsecureRequestPolicy(blink.mojom.InsecureRequestPolicy policy_bitmap);

  // Elements of |set| are hashes of hosts to upgrade.
  EnforceInsecureNavigationsSet(array<uint32> set);

  // Sent by the blink's FrameScheduler when a list of active features
  // the scheduler tracks changes.
  // See blink::scheduler::SchedulingPolicy::Feature for the meaning
  // of the individual bits.
  // TODO(altimin): Move into a separate scheduling interface.
  DidChangeActiveSchedulerTrackedFeatures(uint64 features_mask);

  // Sent when a new sudden termination disabler condition is either introduced
  // or removed.
  SuddenTerminationDisablerChanged(bool present,
                                   SuddenTerminationDisablerType disabler_type);

  // Notifies the browser that the associated frame received a user gesture on
  // a previous navigation on the same eTLD+1. This ensures the state is
  // propagated to any remote frames.
  HadStickyUserActivationBeforeNavigationChanged(bool has_gesture);

  // Sent by a local root to request scrolling in its parent process.
  ScrollRectToVisibleInParentFrame(gfx.mojom.Rect rect_to_scroll,
                                   ScrollIntoViewParams params);

  // Sent by a local root to continue bubbling a logical scroll in its parent
  // process.
  BubbleLogicalScrollInParentFrame(ScrollDirection direction,
                                   ui.mojom.ScrollGranularity granularity);

  // Indicates that another page has accessed the DOM of the initial empty
  // document of a main frame. After this, it is no longer safe to show a
  // pending navigation's URL, because a URL spoof is possible.
  DidAccessInitialDocument();

  // Indicates an attempt by the associated frame to navigate from the
  // |initiator_url| to the |blocked_url|, but the navigation was
  // blocked because of |reason|.
  DidBlockNavigation(url.mojom.Url blocked_url, url.mojom.Url initiator_url,
                       blink.mojom.NavigationBlockedReason reason);

  // Sent when the renderer changed the progress of a load.
  DidChangeLoadProgress(double load_progress);

  // Notifies the browser that a frame finished loading.
  DidFinishLoad(url.mojom.Url validated_url);

  // Dispatch a load event for this frame in the iframe element of an
  // out-of-process parent frame. Once handled, the browser process should
  // call RemoteFrame::DispatchLoadEventForFrameOwner() in the renderer.
  DispatchLoad();

  // Tells the browser to navigate back or forward in session history by
  // the given offset (relative to the current position in session
  // history). |has_user_gesture| tells whether or not this is the consequence
  // of a user action.
  GoToEntryAtOffset(int32 offset, bool has_user_gesture);

  // Asks the frame host to notify the owner element in parent process that it
  // should render fallback content.
  RenderFallbackContentInParentProcess();

  // Changes the title for the page in the UI when the page is navigated or the
  // title changes. Sent for top-level frames. This can be null when loading an
  // initial empty document (and in some tests).
  UpdateTitle(mojo_base.mojom.String16? title,
              mojo_base.mojom.TextDirection title_direction);

  // Indicates that the user activation state in the current frame has been
  // updated, so the replicated states need to be synced (in the browser process
  // as well as in all other renderer processes).
  //
  // The |notification_type| parameter is used for histograms, only for the case
  // |update_state == kNotifyActivation|.
  UpdateUserActivationState(UserActivationUpdateType update_type,
                            UserActivationNotificationType notification_type);

  // Provides accessibility information about a find in page result.
  HandleAccessibilityFindInPageResult(FindInPageResultAXParams params);

  // Provides accessibility information about the termination of a find
  // in page operation.
  HandleAccessibilityFindInPageTermination();

  // Sent after the onload handler has been invoked for the document
  // in this frame. Sent for top-level frames.
  DocumentOnLoadCompleted();

  // Notifies the browser that resource timing information is available and
  // should be added to the performance entries of the parent frame.
  ForwardResourceTimingToParent(ResourceTimingInfo timing);

  // Notifies the browser that a document has been loaded.
  DidFinishDocumentLoad();

  // A request to run a JavaScript dialog displaying |alert_message|.
  [Sync]
  RunModalAlertDialog(mojo_base.mojom.String16 alert_message) => ();

  // A request to run a JavaScript dialog displaying |alert_message|.
  // |success| will be true if the user clicked 'OK', false if the
  // dialog was canceled.
  [Sync]
  RunModalConfirmDialog(mojo_base.mojom.String16 alert_message) =>
                        (bool success);

  // A request to run a confirm JavaScript dialog displaying
  // |alert_message| with an editable text area with |default_value|.
  // |success| will be true if the user clicked 'OK', false if the
  // dialog was canceled. |result| will contain the result of
  // the editable text area.
  [Sync]
  RunModalPromptDialog(mojo_base.mojom.String16 alert_message,
                       mojo_base.mojom.String16 default_value) =>
                       (bool success, mojo_base.mojom.String16 result);

  // A request to run a confirmation JavaScript dialog. |is_reload|
  // contains it the navigation causing the unload is a reload event.
  // |success| contains whether the page should be unloaded or not.
  [Sync]
  RunBeforeUnloadConfirm(bool is_reload) => (bool success);

  // Notifies that the urls for the favicon of a site has been determined.
  UpdateFaviconURL(array<FaviconURL> favicon_urls);

  // Initiates a download based on user actions like 'ALT+click'.
  DownloadURL(DownloadURLParams params);

  // Sent to the browser when focus changes inside the frame. The first
  // parameter says whether the newly focused element needs keyboard input
  // (true for textfields, text areas and content editable divs).
  // The second parameter is the newly focused element's bounds relative to
  // local root's view, and it will be an empty bounds if there is no focused
  // element.
  FocusedElementChanged(bool is_editable_element,
                        gfx.mojom.Rect bounds_in_frame_widget, blink.mojom.FocusType focus_type);

  // Notification that the text selection has changed.
  // Note: The second parameter is the character based offset of the
  // base::string16 text in the document.
  TextSelectionChanged(mojo_base.mojom.BigString16 text,
                       uint32 offset,
                       gfx.mojom.Range range);

  // Show a popup menu using native controls on Mac or Android.
  // The popup menu is hidden when the mojo channel is closed.
  ShowPopupMenu(pending_remote<PopupMenuClient> popup_client,
                gfx.mojom.Rect bounds,
                int32 item_height,
                double font_size,
                int32 selected_item,
                array<MenuItem> menu_items,
                bool right_aligned,
                bool allow_multiple_selection);

  // Used to tell the parent that the user right clicked on an area of the
  // content area, and a context menu should be shown for it. The params
  // object contains information about the node(s) that were selected when the
  // user right clicked.
  ShowContextMenu(pending_associated_remote<ContextMenuClient> client,
                  UntrustworthyContextMenuParams params);

  // Sent when the renderer loads a resource from its memory cache. This message
  // lets the browser know we loaded a resource from the memory cache and is
  // needed to display the correct SSL indicators.
  // TODO(kinuko): Need to check if this comment is still relevant.
  //
  // The recipients of this message have no use for data: URLs: they don't
  // affect the page's insecure content list and are not in the disk cache. To
  // prevent large (1M+) data: URLs from crashing in the Mojo system, we simply
  // filter them out before calling this message.
  //
  // Note: May only be sent once per URL per frame per committed load.
  DidLoadResourceFromMemoryCache(
      url.mojom.Url url, string http_method,
      string mime_type, network.mojom.RequestDestination request_destination);

  // Notifies the browser that frame owner properties have changed.
  //
  // Frame owner properties currently include: name, scrollbar_mode,
  // margin_width and margin_height, among others.
  DidChangeFrameOwnerProperties(
    blink.mojom.FrameToken child_frame_token,
    blink.mojom.FrameOwnerProperties frame_owner_properties);

  // Sent when a local renderer frame either updates its opener to another
  // frame identified by |opener_frame|, or, if |opener_frame| is "empty",
  // the frame disowns its opener for the lifetime of the window.
  DidChangeOpener(blink.mojom.LocalFrameToken? opener_frame);

  // Notifies the browser that sandbox flags or container policy have changed
  // for a subframe of this frame.
  DidChangeFramePolicy(
      blink.mojom.FrameToken child_frame_token,
      blink.mojom.FramePolicy frame_policy);

  // Notifies the browser that the frame changed the 'csp' attribute
  // of one of its child frames.
  DidChangeCSPAttribute(
      blink.mojom.FrameToken child_frame_token,
      network.mojom.ContentSecurityPolicy? parsed_csp_attribute);

  // Sent by the renderer to request a paint preview of a subframe. |clip_rect|
  // is the size of the frame in it's parent. |guid| is an an identifier for
  // all the capture work (regardless of the process captures are happening in)
  // that allows the results to be grouped together, even if there are multiple
  // requests in-flight.
  CapturePaintPreviewOfSubframe(
      gfx.mojom.Rect clip_rect, mojo_base.mojom.UnguessableToken guid);

  // Sent when a ModalCloseListener becomes active so the browser can notify if
  // a modal close signal occurs.
  SetModalCloseListener(
      pending_remote<blink.mojom.ModalCloseListener> listener);

  // Notifies the browser that a child frame is detached from the DOM.
  Detach();

  // Returns the associated KeepAliveHandleFactory.
  GetKeepAliveHandleFactory(
      pending_receiver<blink.mojom.KeepAliveHandleFactory> factory);

  // Blink and JavaScript error messages to log to the console, debugger UI, or
  // error reporting service. |source_id| is usually a URL.
  // |untrusted_stack_trace| should only be printed or sent to other services;
  // it's untrusted and should not be parsed to get a structured stack trace.
  // The stack trace is only present if
  // FrameNavigationControl.SetWantErrorMessageStackTrace has been called for
  // this frame and the log_level is kError.
  DidAddMessageToConsole(
      ConsoleMessageLevel log_level,
      mojo_base.mojom.BigString16 msg,
      int32 line_number,
      mojo_base.mojom.String16? source_id,
      mojo_base.mojom.BigString16? untrusted_stack_trace);

  // The frame's size is replicated in the browser so that the browser can
  // correctly set the initial size of the frame in case of a cross-process
  // navigation.
  FrameSizeChanged(gfx.mojom.Size size);
};

// Implemented in Blink, this interface defines frame-specific methods that will
// be invoked from the browser process (e.g. content::RenderFrameHostImpl).
//
// Note that this is different than content/common/frame.mojom in that the
// methods defined here are handled directly in Blink without passing through
// content. In the future this interface will likely host more methods as the
// Onion Soup project advances, which can potentially lead to the removal of
// content/common/frame.mojom if enough code is moved to Blink.
interface LocalFrame {
  // Retrieves the text surrounding the current selection for the frame up to
  // the length specified by |max_length|, along with its start and end offsets.
  GetTextSurroundingSelection(uint32 max_length)
      => (mojo_base.mojom.String16 content, uint32 start_offset,
          uint32 end_offset);

  // Creates an intervention report in the frame with contents |id| and
  // |message|, returns once the report has been queued. |id| identifies the
  // intervention that occurred. |message| is a human-readable string that
  // can provide additional context to the cause of the intervention.
  SendInterventionReport(string id, string message);

  // Updates this frame's FrameOwner properties, such as scrolling, margin,
  // or allowfullscreen.  This is used when this frame's parent is in
  // another process and it dynamically updates these properties.
  // TODO(dcheng): Currently, the update only takes effect on next frame
  // navigation.  This matches the in-process frame behavior.
  SetFrameOwnerProperties(FrameOwnerProperties properties);

  // Notifies the RenderFrame about a user activation detected in the browser
  // side (e.g. during Android voice search). The |notification_type| parameter
  // is used for histograms only.
  NotifyUserActivation(UserActivationNotificationType notification_type);

  // Notifies the |LocalFrame| about the Virtual keyboard rectangle that is occluding the web
  // content.
  NotifyVirtualKeyboardOverlayRect(gfx.mojom.Rect keyboard_rect);

  // Add message to the frame console.
  AddMessageToConsole(ConsoleMessageLevel level, string message,
                    bool discard_duplicates);

  // Add devtools issue to the frames issue storage.
  // Issues offer a more structured way to surface problems in DevTools than
  // doing so via console messages.
  AddInspectorIssue(InspectorIssueInfo info);

  // Requests that a provisional frame swap itself into the frame tree,
  // immediately replacing the RemoteFrame that it is associated with. Normally,
  // this swap happens when the navigation commits in the provisional frame.
  // However, if the RemoteFrame corresponds to a crashed (and non-live) frame,
  // the browser will immediately call this method to stop showing the sad
  // iframe without having to wait for the navigation to commit.
  SwapInImmediately();

  // Sent to a frame when one of its remote children finishes loading, so that
  // the frame can update its loading state.
  CheckCompleted();

  // Instructs the frame to stop the load in progress, if any.
  StopLoading();

  // Sent to the process that owns this frame's HTMLFrameOwnerElement to
  // control whether the element is collapsed or not. If the element is
  // collapsed, it will be removed from the layout tree of its parent
  // frame's document.
  Collapse(bool collapsed);

  // Used to instruct the frame to go into "view source" mode. This should
  // only be sent to the main frame.
  EnableViewSourceMode();

  // Notifies this frame that it is now focused.  This is used to
  // support cross-process focused frame changes.
  Focus();

  // Notifies this frame to clear the focused element (if any).
  ClearFocusedElement();

  // Gets the resource snapshot of the frame for creating Web Bundle.
  // The instance of ResourceSnapshotForWebBundle in the renderer process will
  // be kept alive as far as the Mojo endpoint is held and the renderer process
  // is alive.
  GetResourceSnapshotForWebBundle(
      pending_receiver<data_decoder.mojom.ResourceSnapshotForWebBundle> receiver);

  // Copies the image at |window_point| to the clipboard (if there indeed is an
  // image at that |window_point|).
  CopyImageAt(gfx.mojom.Point window_point);

  // Saves the image at |window_point| to the disk (if there indeed is an image
  // at that |window_point|).
  SaveImageAt(gfx.mojom.Point window_point);

  // Updates the frame with a list of unique WebFeature values representing
  // Blink features used, performed or encountered by the browser during the
  // current page load happening on the frame.
  ReportBlinkFeatureUsage(array<blink.mojom.WebFeature> features);

  // Sent to this frame in parent frame's process to ask for rendering fallback
  // contents. This only happens for frame owners which render their own
  // fallback contents (i.e., <object>).
  RenderFallbackContent();

  // Instructs the frame to invoke the beforeunload event handler.
  //
  // The closure callback is invoked to acknowledge the browser that
  // the beforeunload event is handled. |proceed| matches the return value
  // of the frame's beforeunload handler: true if the user decided to proceed
  // with leaving the page.
  BeforeUnload(bool is_reload)
      => (bool proceed, mojo_base.mojom.TimeTicks before_unload_start_time,
          mojo_base.mojom.TimeTicks before_unload_end_time);

  // Tells the renderer to perform the given action on the media player location
  // at the given point in the view coordinate space.
  MediaPlayerActionAt(gfx.mojom.Point location, blink.mojom.MediaPlayerAction action);

  // Request to continue running the sequential focus navigation algorithm in
  // this frame. |source_frame_token| identifies the frame that issued this
  // request. This message is sent when finding the next focusable element would
  // require moving onto a frame from a different process.
  AdvanceFocusInFrame(blink.mojom.FocusType focus_type,
                      blink.mojom.RemoteFrameToken? source_frame_token);

  // Notifies this Frame to advance the focus to next input node in the form by
  // moving in specified direction if the currently focused node is a Text node
  // (textfield, text area or content editable nodes).
  AdvanceFocusInForm(blink.mojom.FocusType focus_type);

  // Notifies the document navigation was blocked because a content security
  // policy was violated.
  ReportContentSecurityPolicyViolation(network.mojom.CSPViolation violation);

  // Notifies the frame that its parent has changed the frame's sandbox flags or
  // container policy.
  DidUpdateFramePolicy(blink.mojom.FramePolicy frame_policy);

  // Called when the device's screen information changes.
  // TODO(crbug.com/1068774): Include screen info with this event, perhaps
  // plumbing the multi-screen info via SynchronizeVisualProperties.
  OnScreensChange();

  // Posts a message from a frame in another process to the current renderer.
  // |source_frame_token| is the frame token of the RemoteFrame in the current
  // renderer representing the frame (from a different renderer) where this
  // message is coming from. |source_origin| is the origin of the source frame
  // when the message was sent, and |target_origin| specifies what the origin of
  // the target frame must be for the message to be dispatched. An empty string
  // allows the message to be dispatched to any origin. |message| is the encoded
  // data, and any extra properties such as transferred ports or blobs.
  PostMessageEvent(blink.mojom.RemoteFrameToken? source_frame_token,
                   mojo_base.mojom.String16 source_origin,
                   mojo_base.mojom.String16 target_origin,
                   blink.mojom.TransferableMessage message);

  // Requests the index of a character in the frame's text stream at the given
  // point. The point is in the viewport coordinate space. Replies using
  // TextInputHost.
  [EnableIf=is_mac]
  GetCharacterIndexAtPoint(gfx.mojom.Point location);

  // Requests the rectangle for a given character range. Replies using
  // TextInputHost.
  [EnableIf=is_mac]
  GetFirstRectForRange(gfx.mojom.Range range);

  // Requests the text fragment in a given range.
  [EnableIf=is_mac]
  GetStringForRange(gfx.mojom.Range range)
      => (ui.mojom.AttributedString? string, gfx.mojom.Point baseline_point);

  // Binds |receiver| to the document of this frame.
  BindReportingObserver(
      pending_receiver<blink.mojom.ReportingObserver> receiver);

  // Requests that the blink::LocalFrame updates its opener to the specified
  // frame. The frame token may be "empty" if the opener was disowned.
  UpdateOpener(blink.mojom.FrameToken? opener_frame_token);

  // Request to enumerate and return links to all savable resources in the frame
  // Note: this covers only the immediate frame / doesn't cover subframes.
  GetSavableResourceLinks() => (GetSavableResourceLinksReply? reply);

  // Sent to a frame to notify about mixed content found externally.
  MixedContentFound(url.mojom.Url main_resource_url,
                    url.mojom.Url mixed_content_url,
                    RequestContextType request_context,
                    bool was_allowed,
                    url.mojom.Url url_before_redirects,
                    bool had_redirect,
                    network.mojom.SourceLocation? source_location);
};

// Also implemented in Blink, this interface defines frame-specific methods
// that will be invoked from the browser process but processed at a higher
// priority than methods invoked on the LocalFrame interface.
//
// Note this interface does not use legacy IPC channels and as such there are
// no ordering guarantees for messages sent on this interface. This interface is
// for experimental purposes.
interface HighPriorityLocalFrame {

  // Instructs the frame to invoke the beforeunload event handler.
  //
  // The closure callback is invoked to acknowledge the browser that
  // the beforeunload event is handled. |proceed| matches the return value
  // of the frame's beforeunload handler: true if the user decided to proceed
  // with leaving the page.
  DispatchBeforeUnload(bool is_reload)
      => (bool proceed, mojo_base.mojom.TimeTicks before_unload_start_time,
          mojo_base.mojom.TimeTicks before_unload_end_time);
};

// Implemented in Browser, this interface defines frame-specific methods that
// will be invoked from the render process (e.g. blink::RemoteFrame).
//
// Note that this is different than content/common/frame.mojom in that the
// methods defined here are called directly in Blink without passing through
// content. In the future this interface will likely host more methods as the
// Onion Soup project advances, which can potentially lead to the removal of
// content/common/frame.mojom if enough code is moved to Blink.
interface RemoteFrameHost {
  // Notifies that an effective touch action has been calculated from an
  // ancestor of the associated RemoteFrame and should be propogated to
  // the associated LocalFrame in the other render process.
  SetInheritedEffectiveTouchAction(cc.mojom.TouchAction touch_action);

  // Toggles render throttling on a remote frame. |is_throttled| indicates
  // whether the current frame should be throttled based on its viewport
  // visibility; |subtree_throttled| indicates that an ancestor frame has
  // been throttled, so all descendant frames also should be throttled; and
  // |display_locked| indicates that an iframe is display locked by an ancestor
  // of its <iframe> element in the parent process.
  UpdateRenderThrottlingStatus(
      bool is_throttled, bool subtree_throttled, bool display_locked);

  // Notifies the browser that the associated frame has changed its visibility
  // status. Visibility status changes occur when the frame moves in/out
  // of the viewport, or the need for a layout object changes, e.g. if the
  // frame owner assigns a display: none style.
  VisibilityChanged(blink.mojom.FrameVisibility visibility);

  // Sent by the renderer when the frame becomes focused.
  DidFocusFrame();

  // Use to notify a parent remote frame that a local child frame has finished
  // loading. This will be forwarded to the renderer hosting the parent's local
  // frame to see if the parent can be marked as completed loading.
  CheckCompleted();

  // Sent by the renderer to request a paint preview of a subframe. |clip_rect|
  // is the size of the frame in it's parent. |guid| is an an identifier for
  // all the capture work (regardless of the process captures are happening in)
  // that allows the results to be grouped together, even if there are multiple
  // requests in-flight.
  CapturePaintPreviewOfCrossProcessSubframe(
    gfx.mojom.Rect clip_rect, mojo_base.mojom.UnguessableToken guid);

  // Sent by a parent frame to notify its child that the renderer has determined
  // the DOM subtree it represents is inert and should no longer process input
  // events.
  //
  // https://html.spec.whatwg.org/multipage/interaction.html#inert
  SetIsInert(bool inert);

  // Sent when a renderer remote frame either updates its opener to another
  // frame identified by |opener_frame|, or, if |opener_frame| is "empty",
  // the frame disowns its opener for the lifetime of the window.
  DidChangeOpener(blink.mojom.LocalFrameToken? opener_frame);

  // This message is sent from a RemoteFrame when sequential focus navigation
  // needs to advance into its actual frame. |source_frame_token| identifies the
  // frame that issued this request.  This is used when pressing <tab> or
  // <shift-tab> hits an out-of-process iframe when searching for the next
  // focusable element.
  AdvanceFocus(blink.mojom.FocusType focus_type,
               blink.mojom.LocalFrameToken source_frame_token);

  // Sent to the browser to post a message to the frame's active renderer, which
  // will receive the re-routed message from the browser process via the method
  // PostMessageEvent(), from the blink.mojom.LocalFrame interface.
  // |source_frame_token| is the frame token of the LocalFrame in the renderer
  // process originating the request, which will be translated by the browser
  // process to the frame token of the equivalent RemoteFrame in the target
  // renderer process.
  // |source_origin| is the origin of the source frame when the message was
  // sent, |target_origin| specifies what the origin of the target frame must be
  // for the message to be dispatched and |message| is the encoded data, plus
  // any extra properties such as transferred ports or blobs.
  RouteMessageEvent(blink.mojom.LocalFrameToken? source_frame_token,
                    mojo_base.mojom.String16 source_origin,
                    mojo_base.mojom.String16 target_origin,
                    blink.mojom.TransferableMessage message);

  // Ask the frame host to print a cross-process subframe.
  // The printed content of this subframe belongs to the document specified by
  // its document cookie. Document cookie is a unique id for a printed document
  // associated with a print job.
  // The content will be rendered in the specified rectangular area in its
  // parent frame.
  PrintCrossProcessSubframe(
      gfx.mojom.Rect frame_content_rect, int32 document_cookie);

  // Notifies the browser that a child frame is detached from the DOM.
  Detach();

  // Sent by a parent frame to notify its child about the state of the child's
  // intersection with the parent's viewport, primarily for use by the
  // IntersectionObserver API.
  UpdateViewportIntersection(
      ViewportIntersectionState intersection_state,
      FrameVisualProperties? visual_properties);

  // Tells the browser that a child's visual properties have changed.
  SynchronizeVisualProperties(
    FrameVisualProperties properties);
};

// Implemented in Blink, this interface defines frame-specific methods that will
// be invoked from the browser process (e.g. content::RenderFrameProxyHost).
//
// Note that this is different than content/common/frame.mojom in that the
// methods defined here are handled directly in Blink without passing through
// content. In the future this interface will likely host more methods as the
// Onion Soup project advances, which can potentially lead to the removal of
// content/common/frame.mojom if enough code is moved to Blink.
interface RemoteFrame {
  // Sent to a frame proxy when its real frame is preparing to enter fullscreen
  // in another process.  Actually entering fullscreen will be done separately
  // as part of ViewMsg_Resize, once the browser process has resized the tab for
  // fullscreen.
  WillEnterFullscreen(FullscreenOptions options);

  // Updates replicated ContentSecurityPolicy on the remote frame's
  // SecurityContent.
  AddReplicatedContentSecurityPolicies(
      array<network.mojom.ContentSecurityPolicy> csps);

  // Resets the replicated ContentSecurityPolicy on the remote frame's
  // SecurityContext. Used to reset CSP from the previous document on
  // a cross-document navigation.
  ResetReplicatedContentSecurityPolicy();

  // Update replicated set for enforcement of insecure navigations. |set|
  // is a hashed set of host/port pairs. See
  // SecurityContext::SetInsecureNavigationsSet.
  EnforceInsecureNavigationsSet(array<uint32> set);

  // Updates this frame's FrameOwner properties, such as scrolling, margin,
  // or allowfullscreen.  This is used when this frame's parent is in
  // another process and it dynamically updates these properties.
  // TODO(dcheng): Currently, the update only takes effect on next frame
  // navigation.  This matches the in-process frame behavior.
  SetFrameOwnerProperties(FrameOwnerProperties properties);

  // Updates the remote frame's replicated enforcement of insecure request
  // policy. Used when the frame's policy is changed in another renderer
  // process. Argument |policy| is a bitfield for InsecureRequestPolicy.
  EnforceInsecureRequestPolicy(blink.mojom.InsecureRequestPolicy policy);

  // Update the replicated origin. Used when the frame is navigated to a
  // new origin.
  SetReplicatedOrigin(url.mojom.Origin origin,
    bool is_potentially_trustworthy_unique_origin);

  // Update the replicated ad frame type. Used when the frame is determined to
  // be an ad frame.
  SetReplicatedAdFrameType(blink.mojom.AdFrameType ad_frame_type);

  // Sets the replicated name and unique name for the frame. Used when the
  // name of a frame changes.
  SetReplicatedName(string name, string unique_name);

  // Sent to dispatch a load event in the frame's owner element.
  // (eg. the iframe, portal, or object element).
  DispatchLoadEventForFrameOwner();

  // Sent to the remote frame placeholder in the parent process to indicate the
  // associated frame in the child process requires information about
  // whether it is occluded or has visual effects applied.
  SetNeedsOcclusionTracking(bool needs_tracking);

  // Sent to the process that owns this frame's HTMLFrameOwnerElement to
  // control whether the element is collapsed or not. If the element is
  // collapsed, it will be removed from the layout tree of its parent
  // frame's document.
  Collapse(bool collapsed);

  // Notifies this remote frame that it is now focused.  This is used to
  // support cross-process focused frame changes.
  Focus();

  // Notifies this remote frame to mark that the previous document on that
  // frame had received a user gesture on the same eTLD+1.
  SetHadStickyUserActivationBeforeNavigation(bool has_gesture);

  // Sent to the remote frame placeholder in the parent process to continue
  // bubbling a logical scroll from a cross-process frame.
  BubbleLogicalScroll(ScrollDirection direction,
                      ui.mojom.ScrollGranularity granularity);

  // Sent to the remote frame placeholder in the parent process to update the
  // user activation state in appropriate part of the frame tree (ancestors for
  // activation notification and all nodes for consumption).
  //
  // The |notification_type| parameter is used for histograms, only for the case
  // |update_state == kNotifyActivation|.
  UpdateUserActivationState(blink.mojom.UserActivationUpdateType state_update_type,
                            UserActivationNotificationType notification_type);

  // Sent to the process that owns this frame's HTMLFrameOwnerElement to
  // set the embedding token. This token uniquely specifies the relationship
  // between a frame and its parent.
  SetEmbeddingToken(mojo_base.mojom.UnguessableToken embedding_token);

  // Sets page-level focus and notifies FocusController.
  SetPageFocus(bool is_focused);

  // Sent to the remote frame in parent frame's process to ask for rendering fallback
  // contents. This only happens for frame owners which render their own
  // fallback contents (i.e., <object>).
  RenderFallbackContent();

  // Sent to the remote frame placeholder in the parent process so that
  // resource timing information can be added to the parent frame.
  AddResourceTimingFromChild(ResourceTimingInfo timing);

  // Sent to the remote frame placeholder in the parent process to request
  // scrolling.
  ScrollRectToVisible(gfx.mojom.Rect rect, ScrollIntoViewParams params);

  // Notifies this remote frame that its corresponding document has started
  // loading.
  DidStartLoading();

  // Notifies this remote frame that its corresponding document has completed
  // loading.
  DidStopLoading();

  // Sent to the remote frame placeholder in the parent process indicating the
  // intrinsic sizing parameters of the content frame have changed. Generated
  // when the browser receives a IntrinsicSizingInfoChanged message of
  // FrameWidgetHost interface.
  IntrinsicSizingInfoOfChildChanged(IntrinsicSizingInfo sizing_info);

  // Used to replicate the updated sandbox flags and feature policy headers to
  // all corresponding remote frames of a local frame when a navigation commits.
  DidSetFramePolicyHeaders(network.mojom.WebSandboxFlags sandbox_flags,
      array<blink.mojom.ParsedFeaturePolicyDeclaration> parsed_feature_policy);

  // Notifies the frame that its parent has changed the frame's sandbox flags or
  // container policy.
  DidUpdateFramePolicy(blink.mojom.FramePolicy frame_policy);

  // Requests that the blink::RemoteFrame updates its opener to the specified
  // frame. The frame token may be "empty" if the opener was disowned.
  UpdateOpener(blink.mojom.FrameToken? opener_frame_token);

  // Requests the corresponding RemoteFrame to be deleted and removed from
  // the frame tree. This should not be called on the main frame as that frame
  // is owned by the associated WebView.
  DetachAndDispose();

  // Enables autoresize mode as requested by the parent frame's renderer
  // process.
  EnableAutoResize(gfx.mojom.Size min_size, gfx.mojom.Size max_size);

  // Disables autoresize mode as requested by the parent frame's renderer
  // process.
  DisableAutoResize();

  // Informs the completion of an autoresize transaction from the parent
  // renderer and updates with the provided viz::LocalSurfaceId.
  DidUpdateVisualProperties(cc.mojom.RenderFrameMetadata metadata);

  // Notifies this remote frame that its associated compositing
  // destination (RenderWidgetHostView) has changed.
  SetFrameSinkId(viz.mojom.FrameSinkId frame_sink_id);
};

// Implemented in Blink, this interface defines main-frame-specific methods that
// will be invoked from the browser process (e.g. content::WebContentsImpl).
//
// There is only ever one local main frame for a given tab in all renderer
// processes.
//
// This interface will only be provided when the LocalFrame is a main frame.
interface LocalMainFrame {
  // Requests performing a page scale animation based on the point/rect provided.
  AnimateDoubleTapZoom(gfx.mojom.Point point, gfx.mojom.Rect rect);

  // Scales the view without affecting layout by using the visual viewport.
  SetScaleFactor(float scale);

  // Instructs the renderer to close the current page, including running the
  // onunload event handler.
  ClosePage() => ();

  // Instructs the renderer to perform the given action on the plugin located at
  // the given point.
  PluginActionAt(gfx.mojom.Point location,
                 blink.mojom.PluginActionType action);

  // Tells the renderer to focus the first (last if reverse is true) focusable
  // node.
  SetInitialFocus(bool reverse);

  // Instructs the renderer to send back updates to the preferred size.
  EnablePreferredSizeChangedMode();

  // Sent to the main-frame to request performing a zoom-to-find-in-page
  // based on the rect provided.
  ZoomToFindInPageRect(gfx.mojom.Rect rect_in_root_frame);

  // Cross-Origin-Opener-Policy(COOP):
  // Check accesses made from this window to |accessed_window|. If this happens,
  // 1) A network report will be sent to |reporter|.
  // 2) A ReportingObserver event will be dispatched.
  // 3) Devtool will be notified.
  //
  // |endpoint_defined|: The COOP header defines at least one endpoint.
  // |reported_window_url|: The reported window's sanitized URL. This
  // corresponds to openerURL, openeeURL or otherDocumentURL depending on the
  // |report_type|.
  InstallCoopAccessMonitor(
      network.mojom.CoopAccessReportType report_type,
      blink.mojom.FrameToken accessed_window,
      pending_remote<network.mojom.CrossOriginOpenerPolicyReporter> reporter,
      bool endpoint_defined,
      string reported_window_url);

  // Called on the main frame of a page embedded in a Portal when it is
  // activated. The frame has the option to adopt the previous page as a portal
  // identified by |portal_token| with the interface |portal|. The activation
  // can optionally include a message |data| dispatched with the
  // PortalActivateEvent. The return value |was_adopted| indicates if the portal
  // for the predecessor (identified by |portal_token|) was adopted by the
  // current frame. The |trace_id| is used to generate activation flow events.
  OnPortalActivated(
      blink.mojom.PortalToken portal_token,
      pending_associated_remote<blink.mojom.Portal> portal,
      pending_associated_receiver<blink.mojom.PortalClient> portal_client,
      blink.mojom.TransferableMessage data,
      uint64 trace_id)
      => (blink.mojom.PortalActivateResult result);

  // Forwards a message from a portal's host to the main frame in the portal's
  // guest contents.
  ForwardMessageFromHost(blink.mojom.TransferableMessage message,
                         url.mojom.Origin source_origin);

  // Notifies the renderer whether hiding/showing the browser controls is
  // enabled, what the current state should be, and whether or not to
  // animate to the proper state.
  UpdateBrowserControlsState(cc.mojom.BrowserControlsState constraints,
                             cc.mojom.BrowserControlsState current,
                             bool animate);

  // Notify renderer that the window controls overlay has changed size or
  // visibility.
  UpdateWindowControlsOverlay(gfx.mojom.Rect window_controls_overlay_rect,
                              gfx.mojom.Insets insets);
};

// Implemented in Blink, this interface defines remote main-frame-specific
// methods that will be invoked from the browser process (e.g.
// content::RenderFrameProxyHost).
//
// There is only ever one remote main frame for a given tab in all renderer
// processes.
//
// This interface will only be provided when the RemoteFrame is a main frame.
interface RemoteMainFrame {
  // Makes the TextAutosizerPageInfo received from a local main frame available
  // to remote main frame renderers.
  UpdateTextAutosizerPageInfo(blink.mojom.TextAutosizerPageInfo page_info);
};

// Implemented in Browser, this interface defines local-main-frame-specific
// methods that will be invoked from the renderer process (e.g. WebViewImpl).
interface LocalMainFrameHost {
  // Indicates the scale of the view has changed.
  ScaleFactorChanged(float scale);

  // Notifies that the preferred size of the view has changed.
  ContentsPreferredSizeChanged(gfx.mojom.Size pref_size);

  // Informs the browser that page metrics relevant to Blink's TextAutosizer
  // have changed, so that they can be shared with other renderers. The
  // browser will share this information with other renderers that have frames
  // in the page.
  TextAutosizerPageInfoChanged(TextAutosizerPageInfo page_info);

  // Asks the browser process to activate the page associated to the main frame.
  FocusPage();

  // Asks the browser to transfer focus cross-process on behalf of the renderer
  // in the focus hierarchy. This may focus an element in the browser ui or a
  // cross-process frame, as appropriate.
  TakeFocus(bool reverse);

  // Notifies the browser that we want to show a destination url for a potential
  // action (e.g. when the user is hovering over a link). Implementation of this
  // method will reply back to the renderer once the target URL gets received,
  // in order to prevent target URLs spamming the browser.
  UpdateTargetURL(url.mojom.Url url) => ();

  // Request close of the window. This corresponds to a window.close() javascript API call.
  // Frame unload handlers should have already been called before this method is called.
  RequestClose();

  // Causes a window previously opened via RenderMessageFilter::CreateNewWindow
  // to be shown on the screen. This message contains the opener_frame_token
  // which is always set. This is called on the main frame of the window to be shown.
  ShowCreatedWindow(blink.mojom.LocalFrameToken opener_frame_token,
                    ui.mojom.WindowOpenDisposition disposition,
                    gfx.mojom.Rect rect, bool opened_by_user_gesture) => ();

  // Request that the browser change the bounds of the window.
  // This corresponds to the window.resizeTo() and window.moveTo() APIs, and the browser
  // may ignore this message.
  SetWindowRect(gfx.mojom.Rect bounds) => ();
};

// Implemented in Browser, this interface defines remote-main-frame-specific
// methods that will be invoked from the renderer process (e.g. WebViewImpl).
interface RemoteMainFrameHost {
  // Asks the browser process to activate the page associated to the main frame.
  FocusPage();

  // Asks the browser to transfer focus cross-process on behalf of the renderer
  // in the focus hierarchy. This may focus an element in the browser ui or a
  // cross-process frame, as appropriate.
  TakeFocus(bool reverse);

  // Notifies the browser that we want to show a destination url for a potential
  // action (e.g. when the user is hovering over a link). Implementation of this
  // method will reply back to the renderer once the target URL gets received,
  // in order to prevent target URLs spamming the browser.
  UpdateTargetURL(url.mojom.Url url) => ();

  // Sent from an inactive renderer for the browser to route to the active
  // renderer, instructing it to close.
  RouteCloseEvent();
};
