910e62b5创建于 1月15日历史提交
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_RENDERER_ACTOR_CLICK_DISPATCHER_H_
#define CHROME_RENDERER_ACTOR_CLICK_DISPATCHER_H_

#include <optional>

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "chrome/common/actor.mojom-forward.h"
#include "chrome/renderer/actor/tool_base.h"
#include "third_party/blink/public/common/input/web_mouse_event.h"

namespace actor {

// Handles the sequence of mouse move to target, mouse down, mouse up, with
// delays in between each.
//
// If cancel is called and a click has started, this will synchronously inject
// the mouse up event to ensure the page is left in a consistent state.
//
// The `on_complete` caller may safely destroy this ClickDispatcher.
class ClickDispatcher {
 public:
  // Starts the sequence of mouse events upon creation.
  //
  // The passed in `tool` must own this instance.
  //
  // `on_complete` is always called asynchronously, but isn't invoked if
  // Cancel() is invoked first.
  ClickDispatcher(blink::WebMouseEvent::Button button,
                  int count,
                  const ResolvedTarget& target,
                  const ToolBase& tool,
                  base::OnceCallback<void(mojom::ActionResultPtr)> on_complete);
  ~ClickDispatcher();

  // Cancels future dispatching, with the exception that if a mouse button is in
  // a down state, mouse up will be synchronously dispatched.
  void Cancel();

 private:
  // Clicks the mouse down, and calls DoMouseUp() asynchronously after a delay.
  void DoMouseDown(blink::WebMouseEvent::Button button,
                   int count,
                   const ResolvedTarget& target);

  // Calls DoMouseUpImpl(), then calls Finish(). Used by Cancel() so it can
  // Finish() with a different result.
  void DoMouseUp();

  // Lifts the mouse without calling Finish().
  void DoMouseUpImpl();

  // Asynchronously calls `on_complete_` with `result`. Does nothing if already
  // called, or if Cancel() has been called.
  void Finish(mojom::ActionResultPtr result);

  // The target to click on.
  const ResolvedTarget target_;

  // The tool initiating the click, containing the target.
  const raw_ref<const ToolBase> tool_;

  // Callback to invoke asynchronously after the sequence of events has
  // completed, or upon Cancel().
  base::OnceCallback<void(mojom::ActionResultPtr)> on_complete_;

  // Once the mouse has been clicked down, `mouse_up_event_` will be set so that
  // the mouse can be lifted, either after a delay, or at Cancel().
  std::optional<blink::WebMouseEvent> mouse_up_event_;

  base::WeakPtrFactory<ClickDispatcher> weak_ptr_factory_{this};
};

}  // namespace actor

#endif  // CHROME_RENDERER_ACTOR_CLICK_DISPATCHER_H_