chromium/third_party/blink/public/mojom/devtools/devtools_agent.mojom

// Copyright 2017 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/big_buffer.mojom";
import "mojo/public/mojom/base/read_only_buffer.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "url/mojom/url.mojom";

struct DevToolsMessage {
  mojo_base.mojom.BigBuffer data;
};

enum DevToolsExecutionContextType {
  kDedicatedWorker,
  // kWorklet includes all types of worklets (animation, paint and audio).
  kWorklet,
};

// Debugging interactions are defined in Remote Debugging Protocol.
// See https://chromedevtools.github.io/devtools-protocol/ for more
// information on the protocol itself.
//
// All interfaces defined here serve as a transport level for the
// remote debugging protocol, passing messages opaquely between debugging
// client (like DevTools frontend) and debugging agent (like core/inspector).

// Implemented by debugging targets which expose remote debugging protocol.
// Examples are local frame roots and service workers.
//
// Note that frame instances of this interface must be associated with
// navigation-related interface, since we should reattach sessions before
// the navigation commits in the frame.
//
// This interface is implemented in renderer hosting entity under debug,
// and is used by the browser-side DevToolsSession and agent hosts.
// Note that this interface just provides a mean to start a debugging session,
// so the presence of it does not mean the entity is under debug just yet.
interface DevToolsAgent {
  // Attaches a new debugging session. This session speaks remote debugging
  // protocol and restores all the changes to original state once destroyed.
  //
  // Associated |session| receives messages on UI thread and guarantees
  // relative ordering with e.g. navigations.
  //
  // Non-associated |io_session| receives messages on IO thread and may
  // interrupt long running JavaScript on the main thread. It should be used
  // for debugging messages which are intended to interrupt execution,
  // e.g. requesting a pause. There is no ordering guarantee relative to
  // regular |session|.
  //
  // If |reattach_session_state| is present, restores the state of the session
  // to previously saved one (see DevToolsSessionHost). This is useful when
  // transferring a session from one agent to another while preserving the
  // state. For example, cross-process navigation in a frame creates a new
  // DevToolsAgent (in a different process), but we can preserve the state of
  // debugging session by copying it from one agent to another.
  //
  // ------ Why separate sessions? ------
  //
  // To guarantee ordering with legacy IPC channel, we must bind session
  // synchronously on the UI thread. Otherwise there is a time window
  // when the request is not yet bound, but the messages may already come.
  // In this case, messages will be sent to UI hoping that interface
  // is bound there, and get incorrectly dispatched.
  //
  // On the other hand, we need to handle some of the messages on IO without
  // going to UI first (as described above). This means an interface bound
  // on IO thread. Thus a session per thread.
  //
  // Note that |io_session| is not associated with DevToolsAgent, and so
  // there is no ordering guarantee for commands send to |io_session|
  // relative to anything coming over regular |session|.
  // For example, |session| may be already detached (interface unbound),
  // while commands are still coming to |io_session|, and vice versa.
  //
  // |client_expects_binary_response| indicates that responses (and
  // notifications) sent from this session should use binary (CBOR)
  // encoding as opposed to JSON encoding.
  //
  // |client_is_trusted| indicates that the client is considered to be
  // in the same trust domain from security perspective. For example browser
  // automation tool using remote debugging interface is trusted but Chrome
  // Extension using chrome.debugger API is not. Therefore the former will have
  // access to the Database CDP domain and the latter won't.
  //
  // |session_id| is a string which, if provided, uniquely identifies the
  // session. The renderer must send this back with each response. The current
  // implementation uses the string serialization of an UnguessableToken, but
  // that is subject to change.
  //
  // |session_waits_for_debugger| indicates that the session has been created
  // in the paused state and the agent should only resume execution when all
  // such sessions have been resumed by the client.
  AttachDevToolsSession(pending_associated_remote<DevToolsSessionHost> host,
                        pending_associated_receiver<DevToolsSession> session,
                        pending_receiver<DevToolsSession> io_session,
                        DevToolsSessionState? reattach_session_state,
                        bool client_expects_binary_responses,
                        bool client_is_trusted,
                        string session_id,
                        bool session_waits_for_debugger);

  // Requests an element at specific position to be inspected in every
  // attached session (or the next attached one if none yet).
  //
  // Note that inspecting element does not start/stop any debugging sessions
  // by itself, and has no effect unless a debugging session is
  // or will be attached.
  InspectElement(gfx.mojom.Point point);

  // Instructs agent to start/stop reporting child workers to the host.
  // |wait_for_debugger| controls whether the worker should be paused
  // on start waiting for debugger to connect.
  // See ChildTargetCreated in DevToolsAgentHost for details.
  ReportChildTargets(bool report, bool wait_for_debugger) => ();
};

// This interface is implemented in the browser and is notified by
// DevToolsAgent when a new child dedicated worker or a worklet is available for
// future debugging.
interface DevToolsAgentHost {
  // Informs the host about the new child worker and gives its DevToolsAgent
  // for debugging.
  // |devtools_worker_token| is a unique token identifying this worker.
  // |waiting_for_debugger| is true if worker was paused on startup and
  // should be resumed by debugger to actually start.
  ChildTargetCreated(
      pending_remote<DevToolsAgent> worker_devtools_agent,
      pending_receiver<DevToolsAgentHost> worker_devtools_agent_host,
      url.mojom.Url url,
      string name,
      mojo_base.mojom.UnguessableToken devtools_worker_token,
      bool waiting_for_debugger,
      DevToolsExecutionContextType context_type);

  // Informs the host that the main thread debugger is paused. Must be used only
  // for recording histograms.
  // TODO(https://crbug.com/1449114): Remove this method once we collect enough
  // data.
  MainThreadDebuggerPaused();

  // Informs the host that the main thread debugger is resumed. Must be used
  // only for recording histograms.
  // TODO(https://crbug.com/1449114): Remove this method once we collect enough
  // data.
  MainThreadDebuggerResumed();

  // Bring the associated frame to the foreground if possible.
  BringToForeground();
};

// Represents an attached session which exposes remote debugging protocol.
// This interface is implemented in renderer hosting entity under debug.
//
// Lifetime of the session exactly matches the debugging time span. In other
// words, the entity is under debug if and only if there is at least one
// session.
interface DevToolsSession {
  // Dispatches protocol command from a client to a debugging target.
  // |method| is a method name as defined in protocol (e.g. "Runtime.evaluate").
  // |call_id| is a command id as defined in protocol, and is going to be
  // reported back to host in a response message (see DevToolsSessionHost).
  DispatchProtocolCommand(int32 call_id,
                          string method,
                          mojo_base.mojom.ReadOnlyBuffer message);
};

// A peer of DevToolsSession representing a remote debugging client
// which receives notifications and responses from a session.
// This interface is implemented in browser.
interface DevToolsSessionHost {
  // Dispatches protocol command response to a remote debugging client.
  // |call_id| is a command id as defined in protocol.
  // |updates| are the session state deltas for future reattach (see
  // DevToolsAgent), may be missing if the state did not change since
  // last time.
  //
  // TODO(crbug.com/1142000): Investigate whether it's possible to remove
  // [UnlimitedSize] from these messages.
  [UnlimitedSize]
  DispatchProtocolResponse(DevToolsMessage message,
                           int32 call_id,
                           DevToolsSessionState? updates);

  // Dispatches protocol notification to a remote debugging client.
  [UnlimitedSize]
  DispatchProtocolNotification(DevToolsMessage message,
                               DevToolsSessionState? updates);
};

// The session state is a mapping from keys to either values or missing
// values. Missing values are only used when updates are sent; that's
// in DispatchProtocolResponse and DispatchProtocolNotification. The
// DevToolsSession will then interpret these missing values by deleting
// the respective key when its applying the updates in
// DevToolsSession::ApplySessionStateUpdates.
struct DevToolsSessionState {
  map<string, array<uint8>?> entries;
};