chromium/services/accessibility/features/devtools/os_devtools_agent.h

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

#ifndef SERVICES_ACCESSIBILITY_FEATURES_DEVTOOLS_OS_DEVTOOLS_AGENT_H_
#define SERVICES_ACCESSIBILITY_FEATURES_DEVTOOLS_OS_DEVTOOLS_AGENT_H_

#include "base/memory/raw_ptr.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/unique_associated_receiver_set.h"
#include "third_party/blink/public/mojom/devtools/devtools_agent.mojom.h"
#include "v8/include/v8-inspector.h"

namespace ax {

class V8Environment;
class OSDevToolsSession;
class DebugCommandQueue;

// This class acts as the receiver for a Devtools agent host. Specifically one
// that uses AccessibilityServiceDevToolsDelegate.
class OSDevToolsAgent : public blink::mojom::DevToolsAgent,
                        public v8_inspector::V8InspectorClient {
 public:
  OSDevToolsAgent(
      V8Environment& v8_env,
      scoped_refptr<base::SequencedTaskRunner> io_session_task_runner);
  OSDevToolsAgent(const OSDevToolsAgent&) = delete;
  OSDevToolsAgent& operator=(const OSDevToolsAgent&) = delete;
  ~OSDevToolsAgent() override;

  // Connects an incoming Mojo debugging connection to endpoint `agent`.
  void Connect(
      mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgent> agent);

  // If any session debugging `context_group_id` has an instrumentation
  // breakpoint named `name` set, asks for execution to be paused at next
  // statement.
  void MaybeTriggerInstrumentationBreakpoint(const std::string& name);

  // Creates the V8Session that OSDevToolsSession communicates with.
  std::unique_ptr<v8_inspector::V8InspectorSession> ConnectSession(
      OSDevToolsSession* session,
      bool session_waits_for_debugger);

 private:
  // DevToolsAgent implementation.
  void AttachDevToolsSession(
      mojo::PendingAssociatedRemote<blink::mojom::DevToolsSessionHost> host,
      mojo::PendingAssociatedReceiver<blink::mojom::DevToolsSession>
          session_receiver,
      mojo::PendingReceiver<blink::mojom::DevToolsSession> io_session_receiver,
      blink::mojom::DevToolsSessionStatePtr reattach_session_state,
      bool client_expects_binary_responses,
      bool client_is_trusted,
      const std::string& session_id,
      bool session_waits_for_debugger) override;
  void InspectElement(const ::gfx::Point& point) override;
  void ReportChildTargets(bool report,
                          bool wait_for_debugger,
                          ReportChildTargetsCallback callback) override;
  // V8InspectorClient implementation.

  // TODO(b/290815208): Implement after source files are able to be loaded.
  void runMessageLoopOnPause(int context_group_id) override;
  void quitMessageLoopOnPause() override;
  // TODO(b/290815208): Implement
  void runIfWaitingForDebugger(int context_group_id) override;

  // Called via ~OSDevToolsSession.
  void SessionDestroyed(OSDevToolsSession* session);

  const raw_ref<V8Environment> v8_env_;
  const scoped_refptr<DebugCommandQueue> debug_command_queue_;
  const scoped_refptr<base::SequencedTaskRunner> io_session_task_runner_;
  const std::unique_ptr<v8_inspector::V8Inspector> v8_inspector_;

  // Mojo pipes connected to `this`.
  mojo::AssociatedReceiver<blink::mojom::DevToolsAgent> receiver_{this};

  // All OSDevToolsSession objects have their lifetime limited by their mojo
  // pipes. Thus this class always outlives the sessions.
  mojo::UniqueAssociatedReceiverSet<blink::mojom::DevToolsSession>
      mojom_sessions_;
  // These pointers are kept around for access to the session for non-mojo
  // related tasks. The session destroyed callback ensures these are erased when
  // a session is disconnected.
  std::set<raw_ptr<OSDevToolsSession, SetExperimental>> sessions_;

  SEQUENCE_CHECKER(v8_sequence_checker_);
  base::WeakPtrFactory<OSDevToolsAgent> weak_ptr_factory_{this};
};

}  // namespace ax
#endif  // SERVICES_ACCESSIBILITY_FEATURES_DEVTOOLS_OS_DEVTOOLS_AGENT_H_