// 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.

#include "content/browser/media/captured_surface_controller.h"

#include <limits>
#include <list>
#include <memory>

#include "base/functional/bind.h"
#include "base/notreached.h"
#include "base/run_loop.h"
#include "content/browser/host_zoom_map_impl.h"
#include "content/browser/media/captured_surface_control_permission_manager.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/test/browser_task_environment.h"
#include "content/test/test_web_contents.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
#include "url/gurl.h"

namespace content {
namespace {

using ::blink::mojom::CapturedWheelAction;
using ::blink::mojom::CapturedWheelActionPtr;
using ::blink::mojom::ZoomLevelAction;
using CSCResult = ::blink::mojom::CapturedSurfaceControlResult;
using CSCPermissionResult = CapturedSurfaceControlPermissionManager::
    CapturedSurfaceControlPermissionStatus;

const char* const kUrlString = "http://www.example.com/";

enum class Boundary {
  kMin,
  kMax,
};

enum class CapturedSurfaceControlAPI {
  kSendWheel,
  kIncreaseZoomLevel,
  kDecreaseZoomLevel,
  kResetZoomLevel,
  kRequestPermission,
};

ZoomLevelAction ToZoomLevelAction(CapturedSurfaceControlAPI input) {
  switch (input) {
    case CapturedSurfaceControlAPI::kIncreaseZoomLevel:
      return ZoomLevelAction::kIncrease;
    case CapturedSurfaceControlAPI::kDecreaseZoomLevel:
      return ZoomLevelAction::kDecrease;
    case CapturedSurfaceControlAPI::kResetZoomLevel:
      return ZoomLevelAction::kReset;
    case CapturedSurfaceControlAPI::kSendWheel:
    case CapturedSurfaceControlAPI::kRequestPermission:
      break;
  }
  NOTREACHED() << "Not a ZoomLevelAction.";
}

// The concept of "zoom level" is overloaded. For clarity, when we mean the
// "factor times 100," we'll just name it "zoom level percentage," at least
// in tests.
double GetZoomLevelPercentageFor(WebContents* wc) {
  CHECK(wc);
  return 100 * blink::ZoomLevelToZoomFactor(HostZoomMap::GetZoomLevel(wc));
}

// Make an arbitrary valid CapturedWheelAction.
CapturedWheelActionPtr MakeCapturedWheelActionPtr() {
  return CapturedWheelAction::New(
      /*x=*/0,
      /*y=*/0,
      /*wheel_delta_x=*/0,
      /*wheel_delta_y=*/0);
}

class InputObserver : public RenderWidgetHost::InputEventObserver {
 public:
  struct ExpectedWheelEvent {
    double x = 0;
    double y = 0;
    double delta_x = 0;
    double delta_y = 0;
  };

  ~InputObserver() override { EXPECT_TRUE(expected_events_.empty()); }

  void OnInputEvent(const RenderWidgetHost& widget,
                    const blink::WebInputEvent& event) override {
    if (event.GetType() != blink::WebInputEvent::Type::kMouseWheel) {
      return;
    }

    const blink::WebMouseWheelEvent& wheel_event =
        static_cast<const blink::WebMouseWheelEvent&>(event);

    CHECK(!expected_events_.empty());
    ExpectedWheelEvent expected_event = expected_events_.front();
    expected_events_.pop_front();

    EXPECT_EQ(expected_event.x, wheel_event.PositionInWidget().x());
    EXPECT_EQ(expected_event.y, wheel_event.PositionInWidget().y());
    EXPECT_EQ(expected_event.delta_x, wheel_event.delta_x);
    EXPECT_EQ(expected_event.delta_y, wheel_event.delta_y);
  }

  void AddExpectation(ExpectedWheelEvent expected_event) {
    expected_events_.push_back(expected_event);

    // The wheel event chains are closed with a scroll of zero
    // magnitude in the same location.
    expected_events_.push_back(ExpectedWheelEvent{.x = expected_event.x,
                                                  .y = expected_event.y,
                                                  .delta_x = 0,
                                                  .delta_y = 0});
  }

 private:
  std::list<ExpectedWheelEvent> expected_events_;
};

class TestView : public TestRenderWidgetHostView {
 public:
  explicit TestView(RenderWidgetHostImpl* rwhi)
      : TestRenderWidgetHostView(rwhi) {}
  ~TestView() override = default;

  void SetSize(const gfx::Size& size) override { size_ = size; }

  gfx::Size GetVisibleViewportSize() override { return size_; }

 private:
  gfx::Size size_;
};

// Simulates a tab.
//
// Wraps a `WebContents`, which is the main object of interest, along with a
// `TestView`, which is essentially a `RenderWidgetHostView` that allows us to
// set a custom size, which is needed when testing SendWheel().
//
// This object records the original `RenderWidgetHostView` and injects it back
// from the destructor. This prevents LSAN/ASAN failures. This functionality is
// the main value proposition of this class.
class TestTab {
 public:
  static constexpr gfx::Size kDefaultViewportSize = gfx::Size(100, 400);

  explicit TestTab(BrowserContext* browser_context,
                   std::optional<GURL> gurl = std::nullopt)
      : web_contents_(MakeTestWebContents(browser_context)) {
    // Store the original RenderWidgetHost, allowing it to be injected back from
    // the destructor.
    original_rwhv_ = GetRenderWidgetHostImpl()->GetView();

    // Set a new RenderWidgetHost that allows us control over its size.
    rwhv_ = std::make_unique<TestView>(GetRenderWidgetHostImpl());
    SetView(rwhv_.get());
    SetSize(kDefaultViewportSize);

    if (gurl.has_value()) {
      web_contents_->NavigateAndCommit(gurl.value());
    }
  }

  virtual ~TestTab() {
    SetView(original_rwhv_);
    original_rwhv_ = nullptr;
  }

  TestWebContents* web_contents() const { return web_contents_.get(); }

  WebContentsMediaCaptureId GetWebContentsMediaCaptureId() const {
    RenderFrameHost* const rfh = web_contents_->GetPrimaryMainFrame();
    return WebContentsMediaCaptureId(rfh->GetProcess()->GetDeprecatedID(),
                                     rfh->GetRoutingID());
  }

  void SetSize(const gfx::Size& size) { rwhv_->SetSize(size); }

  RenderWidgetHostImpl* GetRenderWidgetHostImpl() const {
    return RenderWidgetHostImpl::From(
        web_contents_->GetPrimaryMainFrame()->GetRenderWidgetHost());
  }

  void Focus() {
    web_contents_->GetPrimaryMainFrame()->GetRenderWidgetHost()->Focus();
    FrameTree& frame_tree = web_contents_->GetPrimaryFrameTree();
    FrameTreeNode* const root = frame_tree.root();
    frame_tree.SetFocusedFrame(
        root, root->current_frame_host()->GetSiteInstance()->group());
  }

  double GetZoomLevelPercentage() {
    return GetZoomLevelPercentageFor(web_contents_.get());
  }

 protected:
  static std::unique_ptr<TestWebContents> MakeTestWebContents(
      BrowserContext* browser_context) {
    scoped_refptr<SiteInstance> instance =
        SiteInstance::Create(browser_context);
    instance->GetOrCreateProcessForTesting()->Init();
    return TestWebContents::Create(browser_context, std::move(instance));
  }

  void SetView(RenderWidgetHostViewBase* rwhv) {
    GetRenderWidgetHostImpl()->SetView(rwhv);
  }

 private:
  const std::unique_ptr<TestWebContents> web_contents_;
  std::unique_ptr<TestView> rwhv_;
  raw_ptr<RenderWidgetHostViewBase> original_rwhv_ = nullptr;
};

class MockCapturedSurfaceControlPermissionManager
    : public CapturedSurfaceControlPermissionManager {
 public:
  MockCapturedSurfaceControlPermissionManager(
      GlobalRenderFrameHostId capturer_rfh_id)
      : CapturedSurfaceControlPermissionManager(capturer_rfh_id) {}
  ~MockCapturedSurfaceControlPermissionManager() override = default;

  void SetPermissionResult(CSCPermissionResult result) {
    DCHECK_CURRENTLY_ON(BrowserThread::IO);
    result_ = result;
  }

  void CheckPermission(
      base::OnceCallback<void(CSCPermissionResult)> callback) override {
    DCHECK_CURRENTLY_ON(BrowserThread::IO);
    CHECK(result_.has_value());
    std::move(callback).Run(result_.value());
  }

 private:
  std::optional<CSCPermissionResult> result_;
};

using MockPermissionManager = MockCapturedSurfaceControlPermissionManager;

class MockObserver : public content::WebContentsObserver {
 public:
  explicit MockObserver(content::WebContents* web_contents)
      : content::WebContentsObserver(web_contents) {}
  ~MockObserver() override = default;

  // content::WebContentsObserver:
  MOCK_METHOD(void, OnCapturedSurfaceControl, (), (override));
};

// Make a callback that expects `result` and then unblock `run_loop`.
base::OnceCallback<void(CSCResult)> MakeCallbackExpectingResult(
    base::RunLoop* run_loop,
    CSCResult expected_result,
    MockWidgetInputHandler* mock_widget_input_handler) {
  return base::BindOnce(
      [](base::RunLoop* run_loop, CSCResult expected_result,
         MockWidgetInputHandler* mock_widget_input_handler, CSCResult result) {
        EXPECT_EQ(result, expected_result);

        // Run callbacks corresponding to `DispatchEvent` method in
        // `WidgetInputHandler` to allow processing of inputs in
        // `MouseWheelEventQueue`.
        if (mock_widget_input_handler) {
          MockWidgetInputHandler::MessageVector messages =
              mock_widget_input_handler->GetAndResetDispatchedMessages();
          if (!messages.empty()) {
            messages.clear();
            mock_widget_input_handler->FlushReceiverForTesting();
          }
        }

        run_loop->Quit();
      },
      run_loop, expected_result, mock_widget_input_handler);
}

class CapturedSurfaceControllerTestBase : public RenderViewHostTestHarness {
 public:
  ~CapturedSurfaceControllerTestBase() override = default;

  void SetUp() override {
    RenderViewHostTestHarness::SetUp();

    SetUpTestTabs();
    StartCaptureOf(*capturee_);
    AwaitWebContentsResolution();

    auto* test_host = static_cast<TestRenderWidgetHost*>(
        capturee_->GetRenderWidgetHostImpl());
    mojo::Remote<blink::mojom::WidgetInputHandler> remote;
    mock_widget_input_handler_ = std::make_unique<MockWidgetInputHandler>(
        remote.BindNewPipeAndPassReceiver(), mojo::NullRemote());
    test_host->GetRenderInputRouter()->SetWidgetInputHandlerForTesting(
        std::move(remote));
  }

  void SetUpTestTabs(bool focus_capturer = true) {
    capturer_ = std::make_unique<TestTab>(GetBrowserContext());
    capturee_ =
        std::make_unique<TestTab>(GetBrowserContext(), GURL(kUrlString));
    if (focus_capturer) {
      capturer_->Focus();
    }
  }

  void StartCaptureOf(const TestTab& tab) {
    auto permission_manager = std::make_unique<MockPermissionManager>(
        capturer_->web_contents()->GetPrimaryMainFrame()->GetGlobalId());
    permission_manager_ = permission_manager.get();

    // `base::Unretained(this)` is safe because `this` owns `controller_` and
    // therefore has a longer lifetime.
    controller_ = CapturedSurfaceController::CreateForTesting(
        capturer_->web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
        tab.GetWebContentsMediaCaptureId(), std::move(permission_manager),
        base::BindRepeating(
            &CapturedSurfaceControllerTestBase::OnZoomLevelChange,
            base::Unretained(this)),
        base::BindRepeating(
            &CapturedSurfaceControllerTestBase::OnWebContentsResolved,
            base::Unretained(this)));
  }

  void TearDown() override {
    mock_widget_input_handler_.reset();
    permission_manager_ = nullptr;
    controller_.reset();
    capturer_.reset();
    capturee_.reset();

    RenderViewHostTestHarness::TearDown();
  }

  void SetZoomFactor(std::unique_ptr<TestTab>& tab, double zoom_factor) {
    WebContents* const wc = tab->web_contents();

    content::HostZoomMap* const host_zoom_map =
        content::HostZoomMap::GetForWebContents(wc);
    CHECK(host_zoom_map);

    host_zoom_map->SetTemporaryZoomLevel(
        wc->GetPrimaryMainFrame()->GetGlobalId(),
        blink::ZoomFactorToZoomLevel(zoom_factor));

    if (!blink::ZoomValuesEqual(GetZoomLevelPercentageFor(wc),
                                100 * zoom_factor)) {
      FAIL();  // Abort test, not just the helper method.
    }
  }

  void AwaitWebContentsResolution() {
    CHECK(!wc_resolution_run_loop_);
    wc_resolution_run_loop_ = std::make_unique<base::RunLoop>();
    wc_resolution_run_loop_->Run();
    wc_resolution_run_loop_.reset();
  }

  void AwaitOnZoomLevelChange() {
    CHECK(!on_zoom_level_change_run_loop_);
    on_zoom_level_change_run_loop_ = std::make_unique<base::RunLoop>();
    on_zoom_level_change_run_loop_->Run();
    on_zoom_level_change_run_loop_.reset();
  }

  void OnZoomLevelChange(int zoom_level) {
    if (on_zoom_level_change_run_loop_) {
      on_zoom_level_change_run_loop_->Quit();
    }
    zoom_level_ = zoom_level;
  }

  void OnWebContentsResolved(base::WeakPtr<WebContents> wc) {
    if (wc_resolution_run_loop_) {
      wc_resolution_run_loop_->Quit();
    }
    last_resolved_web_contents_ = wc;
  }

 protected:
  std::unique_ptr<CapturedSurfaceController> controller_;
  raw_ptr<MockPermissionManager> permission_manager_ = nullptr;
  std::unique_ptr<TestTab> capturer_;
  std::unique_ptr<TestTab> capturee_;
  std::unique_ptr<base::RunLoop> wc_resolution_run_loop_;
  std::unique_ptr<base::RunLoop> on_zoom_level_change_run_loop_;
  std::optional<base::WeakPtr<WebContents>> last_resolved_web_contents_;
  std::optional<int> zoom_level_;
  std::unique_ptr<MockWidgetInputHandler> mock_widget_input_handler_ = nullptr;
};

class CapturedSurfaceControllerSendWheelTest
    : public CapturedSurfaceControllerTestBase {
 public:
  ~CapturedSurfaceControllerSendWheelTest() override = default;

  void SetUp() override {
    CapturedSurfaceControllerTestBase::SetUp();

    input_observer_ = std::make_unique<InputObserver>();
    capturee_->GetRenderWidgetHostImpl()->AddInputEventObserver(
        input_observer_.get());
  }

  void TearDown() override {
    capturee_->GetRenderWidgetHostImpl()->RemoveInputEventObserver(
        input_observer_.get());

    CapturedSurfaceControllerTestBase::TearDown();
  }

 protected:
  std::unique_ptr<InputObserver> input_observer_;
};

TEST_F(CapturedSurfaceControllerSendWheelTest, CorrectScaling) {
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  capturee_->SetSize(gfx::Size(256, 4096));
  base::RunLoop run_loop;
  input_observer_->AddExpectation(InputObserver::ExpectedWheelEvent{
      .x = 256 * 0.25, .y = 4096 * 0.5, .delta_x = 300, .delta_y = 400});
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0.25,
          /*y=*/0.5,
          /*wheel_delta_x=*/300,
          /*wheel_delta_y=*/400),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

TEST_F(CapturedSurfaceControllerSendWheelTest,
       GracefullyHandleZeroWidthCapturedSurface) {
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  capturee_->SetSize(gfx::Size(0, 4096));
  base::RunLoop run_loop;
  // Note absence of call to input_observer_->AddExpectation().
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0.25,
          /*y=*/0.5,
          /*wheel_delta_x=*/300,
          /*wheel_delta_y=*/400),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kUnknownError,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

TEST_F(CapturedSurfaceControllerSendWheelTest,
       GracefullyHandleZeroHeightCapturedSurface) {
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  capturee_->SetSize(gfx::Size(256, 0));
  base::RunLoop run_loop;
  // Note absence of call to input_observer_->AddExpectation().
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0.25,
          /*y=*/0.5,
          /*wheel_delta_x=*/300,
          /*wheel_delta_y=*/400),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kUnknownError,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

TEST_F(CapturedSurfaceControllerSendWheelTest,
       GracefullyHandleExtremelyNarrowCapturedSurface) {
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  capturee_->SetSize(gfx::Size(1, 4096));
  base::RunLoop run_loop;
  input_observer_->AddExpectation(InputObserver::ExpectedWheelEvent{
      .x = 0, .y = 4096 * 0.5, .delta_x = 300, .delta_y = 400});
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0.25,
          /*y=*/0.5,
          /*wheel_delta_x=*/300,
          /*wheel_delta_y=*/400),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

TEST_F(CapturedSurfaceControllerSendWheelTest,
       GracefullyHandleExtremelyShortCapturedSurface) {
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  capturee_->SetSize(gfx::Size(256, 1));
  base::RunLoop run_loop;
  input_observer_->AddExpectation(InputObserver::ExpectedWheelEvent{
      .x = 256 * 0.25, .y = 0, .delta_x = 300, .delta_y = 400});
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0.25,
          /*y=*/0.5,
          /*wheel_delta_x=*/300,
          /*wheel_delta_y=*/400),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

class CapturedSurfaceControllerZoomEventTest
    : public CapturedSurfaceControllerTestBase {
 public:
  ~CapturedSurfaceControllerZoomEventTest() override = default;

  void SetUp() override {
    CapturedSurfaceControllerTestBase::SetUp();
    new_capturee_ = std::make_unique<TestTab>(GetBrowserContext());
  }

  void TearDown() override {
    new_capturee_.reset();
    CapturedSurfaceControllerTestBase::TearDown();
  }

 protected:
  std::unique_ptr<TestTab> new_capturee_;
};

TEST_F(CapturedSurfaceControllerZoomEventTest, ZoomEventProducedByZoomChange) {
  HostZoomMap::SetZoomLevel(capturee_->web_contents(),
                            blink::ZoomFactorToZoomLevel(0.9));
  AwaitOnZoomLevelChange();
  ASSERT_TRUE(zoom_level_);
  EXPECT_EQ(zoom_level_, 90);
}

TEST_F(CapturedSurfaceControllerZoomEventTest,
       ZoomEventProducedByTemporaryZoomChange) {
  content::HostZoomMap* const host_zoom_map =
      content::HostZoomMap::GetForWebContents(capturee_->web_contents());
  CHECK(host_zoom_map);

  host_zoom_map->SetTemporaryZoomLevel(
      capturee_->web_contents()->GetPrimaryMainFrame()->GetGlobalId(),
      blink::ZoomFactorToZoomLevel(0.9));

  AwaitOnZoomLevelChange();
  ASSERT_TRUE(zoom_level_);
  EXPECT_EQ(zoom_level_, 90);
}

TEST_F(CapturedSurfaceControllerZoomEventTest, ZoomEventUpdateTarget) {
  const RenderFrameHost* const new_main_rfh =
      new_capturee_->web_contents()->GetPrimaryMainFrame();
  const WebContentsMediaCaptureId new_wc_id(
      new_main_rfh->GetProcess()->GetDeprecatedID(),
      new_main_rfh->GetRoutingID());
  controller_->UpdateCaptureTarget(new_wc_id);

  AwaitWebContentsResolution();

  // Set a temporary zoom level so only the second WebContents is affected.
  HostZoomMapImpl* mock_widget_input_handler_zoom_map =
      static_cast<HostZoomMapImpl*>(
          HostZoomMap::GetForWebContents(new_capturee_->web_contents()));
  mock_widget_input_handler_zoom_map->SetTemporaryZoomLevel(
      new_main_rfh->GetGlobalId(), blink::ZoomFactorToZoomLevel(1.1));

  AwaitOnZoomLevelChange();
  ASSERT_TRUE(zoom_level_);
  EXPECT_EQ(zoom_level_, 110);
}

class CapturedSurfaceControllerUpdateZoomLevelTest
    : public CapturedSurfaceControllerTestBase {
 public:
  CapturedSurfaceControllerUpdateZoomLevelTest()
      : min_zoom_factor_(blink::kPresetBrowserZoomFactors.front()),
        max_zoom_factor_(blink::kPresetBrowserZoomFactors.back()) {}

  ~CapturedSurfaceControllerUpdateZoomLevelTest() override = default;

  void SetUp() override {
    CapturedSurfaceControllerTestBase::SetUp();
    permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  }

 protected:
  const double min_zoom_factor_;
  const double max_zoom_factor_;
};

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       IncreaseZoomLevelSucceedsUntilMaxLevel) {
  SetZoomFactor(capturee_, min_zoom_factor_);

  for (int i = 1; i < blink::kPresetBrowserZoomFactors.size(); ++i) {
    base::RunLoop run_loop;
    controller_->UpdateZoomLevel(
        ZoomLevelAction::kIncrease,
        MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                    mock_widget_input_handler_.get()));
    run_loop.Run();

    EXPECT_TRUE(
        blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                               100 * blink::kPresetBrowserZoomFactors[i]));
  }
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       IncreaseZoomLevelSucceedsBetweenCanonicalValues) {
  for (int i = 0; i < blink::kPresetBrowserZoomFactors.size() - 1; ++i) {
    // Average the two factors and set the zoom level to that,
    // thereby getting a non-canonical zoom level.
    const double mid_zoom_factor = (blink::kPresetBrowserZoomFactors[i] +
                                    blink::kPresetBrowserZoomFactors[i + 1]) /
                                   2;
    SetZoomFactor(capturee_, mid_zoom_factor);

    base::RunLoop run_loop;
    controller_->UpdateZoomLevel(
        ZoomLevelAction::kIncrease,
        MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                    mock_widget_input_handler_.get()));
    run_loop.Run();

    EXPECT_TRUE(
        blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                               100 * blink::kPresetBrowserZoomFactors[i + 1]));
  }
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       DecreaseZoomLevelSucceedsUntilMinLevel) {
  SetZoomFactor(capturee_, max_zoom_factor_);

  for (int i = blink::kPresetBrowserZoomFactors.size() - 2; i >= 0; --i) {
    base::RunLoop run_loop;
    controller_->UpdateZoomLevel(
        ZoomLevelAction::kDecrease,
        MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                    mock_widget_input_handler_.get()));
    run_loop.Run();

    EXPECT_TRUE(
        blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                               100 * blink::kPresetBrowserZoomFactors[i]));
  }
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       DecreaseZoomLevelSucceedsBetweenCanonicalValues) {
  for (int i = 0; i < blink::kPresetBrowserZoomFactors.size() - 1; ++i) {
    // Average the two factors and set the zoom level to that,
    // thereby getting a non-canonical zoom level.
    const double mid_zoom_factor = (blink::kPresetBrowserZoomFactors[i] +
                                    blink::kPresetBrowserZoomFactors[i + 1]) /
                                   2;
    SetZoomFactor(capturee_, mid_zoom_factor);

    base::RunLoop run_loop;
    controller_->UpdateZoomLevel(
        ZoomLevelAction::kDecrease,
        MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                    mock_widget_input_handler_.get()));
    run_loop.Run();

    EXPECT_TRUE(
        blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                               100 * blink::kPresetBrowserZoomFactors[i]));
  }
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       IncreaseZoomLevelFailsWhenAtMaxLevel) {
  SetZoomFactor(capturee_, max_zoom_factor_);

  // Main expectation - the call to UpdateZoomLevel() fails.
  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ZoomLevelAction::kIncrease,
      MakeCallbackExpectingResult(&run_loop, CSCResult::kMaxZoomLevel,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();

  // Secondary expectation - zoom level remains unchanged.
  EXPECT_TRUE(blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                                     100 * max_zoom_factor_));
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       DecreaseZoomLevelFailsWhenAtMinLevel) {
  SetZoomFactor(capturee_, min_zoom_factor_);

  // Main expectation - the call to UpdateZoomLevel() fails.
  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ZoomLevelAction::kDecrease,
      MakeCallbackExpectingResult(&run_loop, CSCResult::kMinZoomLevel,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();

  // Secondary expectation - zoom level remains unchanged.
  EXPECT_TRUE(blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                                     100 * min_zoom_factor_));
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       IncreaseZoomLevelFailsWhenWithinEpsilonOfMaxLevel) {
  // Start out within epsilon of the maximum zoom level.
  // (Note that this has to be even smaller than the value within
  // blink::ZoomValuesEqual()).
  constexpr double kEpsilon = 0.000001;
  SetZoomFactor(capturee_, max_zoom_factor_ - kEpsilon);

  // Secondary expectation - zoom level remains unchanged.
  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ZoomLevelAction::kIncrease,
      MakeCallbackExpectingResult(&run_loop, CSCResult::kMaxZoomLevel,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();

  // Secondary expectation - zoom level updated to actual maximum.
  EXPECT_TRUE(blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                                     100 * max_zoom_factor_));
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       DecreaseZoomLevelFailsWhenWithinEpsilonOfMinLevel) {
  // Start out within epsilon of the minimum zoom level.
  // (Note that this has to be even smaller than the value within
  // blink::ZoomValuesEqual()).
  constexpr double kEpsilon = 0.000001;
  SetZoomFactor(capturee_, min_zoom_factor_ + kEpsilon);

  // Secondary expectation - zoom level remains unchanged.
  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ZoomLevelAction::kDecrease,
      MakeCallbackExpectingResult(&run_loop, CSCResult::kMinZoomLevel,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();

  // Secondary expectation - zoom level updated to actual maximum.
  EXPECT_TRUE(blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                                     100 * min_zoom_factor_));
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       IncreaseZoomLevelSucceedsWhenWithinEpsilonOfMaxLevel) {
  // Set the captured tab to a zoom level that would appear to the user as
  // roughly 1% less than the maximum.
  SetZoomFactor(capturee_, max_zoom_factor_ - 0.01);

  // Main expectation - the call to UpdateZoomLevel() succeeds.
  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ZoomLevelAction::kIncrease,
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();

  // Secondary expectation - zoom level updated to maximum.
  EXPECT_TRUE(blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                                     100 * max_zoom_factor_));
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       DecreaseZoomLevelSucceedsWhenWithinEpsilonOfMinLevel) {
  // Set the captured tab to a zoom level that would appear to the user as
  // roughly 1% more than the minimum.
  SetZoomFactor(capturee_, min_zoom_factor_ + 0.01);

  // Main expectation - the call to UpdateZoomLevel() succeeds.
  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ZoomLevelAction::kDecrease,
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();

  // Secondary expectation - zoom level updated to minimum.
  EXPECT_TRUE(blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(),
                                     100 * min_zoom_factor_));
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       ResetZoomLevelSucceedsAtAllCanonicalLevels) {
  for (double zoom_factor : blink::kPresetBrowserZoomFactors) {
    SetZoomFactor(capturee_, zoom_factor);

    base::RunLoop run_loop;
    controller_->UpdateZoomLevel(
        ZoomLevelAction::kReset,
        MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                    mock_widget_input_handler_.get()));
    run_loop.Run();

    EXPECT_TRUE(
        blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(), 100));
  }
}

TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       ResetZoomLevelSucceedsBetweenCanonicalLevels) {
  for (int i = 1; i < blink::kPresetBrowserZoomFactors.size() - 1; ++i) {
    // Average the two factors and set the zoom level to that,
    // thereby getting a non-canonical zoom level.
    const double mid_zoom_factor = (blink::kPresetBrowserZoomFactors[i] +
                                    blink::kPresetBrowserZoomFactors[i + 1]) /
                                   2;
    SetZoomFactor(capturee_, mid_zoom_factor);

    base::RunLoop run_loop;
    controller_->UpdateZoomLevel(
        ZoomLevelAction::kReset,
        MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                    mock_widget_input_handler_.get()));
    run_loop.Run();

    EXPECT_TRUE(
        blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(), 100));
  }
}

// This is vicariously tested by ResetZoomLevelSucceedsAtAllCanonicalLevels,
// but it is important enough a use case to merit its own explicit test.
TEST_F(CapturedSurfaceControllerUpdateZoomLevelTest,
       ResetZoomLevelSucceedsEvenWhenAlreadyAtDefaultZoom) {
  SetZoomFactor(capturee_, 1.0);
  ASSERT_TRUE(blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(), 100));

  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ZoomLevelAction::kReset,
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();

  EXPECT_TRUE(blink::ZoomValuesEqual(capturee_->GetZoomLevelPercentage(), 100));
}

class CapturedSurfaceControllerUpdateZoomLevelImpermanenceTest
    : public CapturedSurfaceControllerTestBase {
 public:
  ~CapturedSurfaceControllerUpdateZoomLevelImpermanenceTest() override =
      default;
};

// Ensure the effect does not extend to other tabs, even if they are dialed
// to the same origin.
TEST_F(CapturedSurfaceControllerUpdateZoomLevelImpermanenceTest,
       UpdateZoomLevelOnlyAffectsCapturedTab) {
  ASSERT_EQ(capturee_->GetZoomLevelPercentage(), 100);

  // Create another tab and navigate it to the same URL as the captured tab.
  auto duplicate_tab =
      std::make_unique<TestTab>(GetBrowserContext(), GURL(kUrlString));
  ASSERT_EQ(duplicate_tab->GetZoomLevelPercentage(), 100);

  // Change the zoom-level on the captured tab.
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ZoomLevelAction::kIncrease,
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
  ASSERT_GT(capturee_->GetZoomLevelPercentage(), 100);

  // Setting the zoom level only affected the captured tab, not the
  // Chrome-level settings for the origin.
  EXPECT_EQ(duplicate_tab->GetZoomLevelPercentage(), 100);
}

// Ensure the effect does not get persisted and does not affect newly
// opened tabs later, even if they are navigated to the same URL.
TEST_F(CapturedSurfaceControllerUpdateZoomLevelImpermanenceTest,
       UpdateZoomLevelEffectsDoNotPersistAfterClosed) {
  ASSERT_EQ(capturee_->GetZoomLevelPercentage(), 100);

  // Change the zoom-level on the captured tab.
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ZoomLevelAction::kIncrease,
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
  ASSERT_GT(capturee_->GetZoomLevelPercentage(), 100);

  // Close the tab.
  capturee_.reset();

  // Create another tab and navigate it to the same URL as the captured tab.
  auto new_tab =
      std::make_unique<TestTab>(GetBrowserContext(), GURL(kUrlString));

  // Setting the zoom level only affected the captured tab, not the
  // Chrome-level settings for the origin.
  EXPECT_EQ(new_tab->GetZoomLevelPercentage(), 100);
}

class CapturedSurfaceControllerInterfaceTestBase
    : public CapturedSurfaceControllerTestBase {
 public:
  explicit CapturedSurfaceControllerInterfaceTestBase(
      CapturedSurfaceControlAPI tested_interface)
      : tested_interface_(tested_interface) {}
  ~CapturedSurfaceControllerInterfaceTestBase() override = default;

  void RunTestedActionAndExpect(base::RunLoop* run_loop,
                                CSCResult expected_result) {
    switch (tested_interface_) {
      case CapturedSurfaceControlAPI::kSendWheel:
        controller_->SendWheel(
            MakeCapturedWheelActionPtr(),
            MakeCallbackExpectingResult(run_loop, expected_result,
                                        mock_widget_input_handler_.get()));
        return;
      case CapturedSurfaceControlAPI::kIncreaseZoomLevel:
      case CapturedSurfaceControlAPI::kDecreaseZoomLevel:
      case CapturedSurfaceControlAPI::kResetZoomLevel:
        controller_->UpdateZoomLevel(
            ToZoomLevelAction(tested_interface_),
            MakeCallbackExpectingResult(run_loop, expected_result,
                                        /*mock_widget_input_handler=*/nullptr));
        return;
      case CapturedSurfaceControlAPI::kRequestPermission:
        controller_->RequestPermission(MakeCallbackExpectingResult(
            run_loop, expected_result, /*mock_widget_input_handler=*/nullptr));
        return;
    }
    NOTREACHED();
  }

 protected:
  const CapturedSurfaceControlAPI tested_interface_;
};

class CapturedSurfaceControllerInterfaceTest
    : public CapturedSurfaceControllerInterfaceTestBase,
      public ::testing::WithParamInterface<CapturedSurfaceControlAPI> {
 public:
  CapturedSurfaceControllerInterfaceTest()
      : CapturedSurfaceControllerInterfaceTestBase(GetParam()) {}

  ~CapturedSurfaceControllerInterfaceTest() override = default;
};

INSTANTIATE_TEST_SUITE_P(
    ,
    CapturedSurfaceControllerInterfaceTest,
    ::testing::Values(CapturedSurfaceControlAPI::kSendWheel,
                      CapturedSurfaceControlAPI::kIncreaseZoomLevel,
                      CapturedSurfaceControlAPI::kDecreaseZoomLevel,
                      CapturedSurfaceControlAPI::kResetZoomLevel,
                      CapturedSurfaceControlAPI::kRequestPermission));

TEST_P(CapturedSurfaceControllerInterfaceTest, SuccessReportedIfPermitted) {
  base::RunLoop run_loop;
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  RunTestedActionAndExpect(&run_loop, CSCResult::kSuccess);
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerInterfaceTest, NoPermissionReportedIfDenied) {
  base::RunLoop run_loop;
  permission_manager_->SetPermissionResult(CSCPermissionResult::kDenied);
  RunTestedActionAndExpect(&run_loop, CSCResult::kNoPermissionError);
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerInterfaceTest,
       UnknownErrorReportedIfPermissionError) {
  base::RunLoop run_loop;
  permission_manager_->SetPermissionResult(CSCPermissionResult::kError);
  RunTestedActionAndExpect(&run_loop, CSCResult::kUnknownError);
  run_loop.Run();
}

// Simulate the captured tab being closed after permission is granted but before
// the controller has time to process the response from the permission manager.
TEST_P(CapturedSurfaceControllerInterfaceTest,
       SurfaceNotFoundReportedIfTabClosedBeforePromptResponseHandled) {
  base::RunLoop run_loop;
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  capturee_.reset();
  RunTestedActionAndExpect(&run_loop, CSCResult::kCapturedSurfaceNotFoundError);
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerInterfaceTest,
       SurfaceNotFoundReportedIfCaptureTargetUpdatedToNonTabSurface) {
  base::RunLoop run_loop;
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  controller_->UpdateCaptureTarget(WebContentsMediaCaptureId());
  RunTestedActionAndExpect(&run_loop, CSCResult::kCapturedSurfaceNotFoundError);
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerInterfaceTest,
       CapturerNotFoundErrorReportedIfCapturerClosed) {
  base::RunLoop run_loop;
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  capturer_.reset();
  RunTestedActionAndExpect(&run_loop, CSCResult::kCapturerNotFoundError);
  run_loop.Run();
}

// Test suite ensuring that API calls before/after the WebContents ID is
// resolved to a base::WeakPtr<WebContents> behave as expected.
class CapturedSurfaceControllerWebContentsResolutionTest
    : public CapturedSurfaceControllerInterfaceTestBase,
      public ::testing::WithParamInterface<CapturedSurfaceControlAPI> {
 public:
  CapturedSurfaceControllerWebContentsResolutionTest()
      : CapturedSurfaceControllerInterfaceTestBase(GetParam()) {}

  ~CapturedSurfaceControllerWebContentsResolutionTest() override = default;

  void SetUp() override {
    // Intentionally skip CapturedSurfaceControllerInterfaceTestBase's SetUp(),
    // and therefore also CapturedSurfaceControllerTestBase's SetUp().
    RenderViewHostTestHarness::SetUp();

    // Prepare a new tab to capture instead of the original one.
    new_capturee_ = std::make_unique<TestTab>(GetBrowserContext());
  }

  void TearDown() override {
    new_capturee_.reset();

    CapturedSurfaceControllerInterfaceTestBase::TearDown();
  }

 protected:
  std::unique_ptr<TestTab> new_capturee_;
};

INSTANTIATE_TEST_SUITE_P(
    ,
    CapturedSurfaceControllerWebContentsResolutionTest,
    ::testing::Values(CapturedSurfaceControlAPI::kSendWheel,
                      CapturedSurfaceControlAPI::kIncreaseZoomLevel,
                      CapturedSurfaceControlAPI::kDecreaseZoomLevel,
                      CapturedSurfaceControlAPI::kResetZoomLevel));

TEST_P(CapturedSurfaceControllerWebContentsResolutionTest,
       ApiInvocationAfterWebContentsResolutionSucceeds) {
  SetUpTestTabs();  // Triggers resolution but does not await it.
  StartCaptureOf(*capturee_);
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);

  AwaitWebContentsResolution();

  base::RunLoop run_loop;
  RunTestedActionAndExpect(&run_loop, CSCResult::kSuccess);
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerWebContentsResolutionTest,
       ApiInvocationPriorToWebContentsResolutionFails) {
  SetUpTestTabs();  // Triggers resolution but does not await it.
  StartCaptureOf(*capturee_);
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);

  base::RunLoop run_loop;
  RunTestedActionAndExpect(&run_loop, CSCResult::kCapturedSurfaceNotFoundError);
  run_loop.Run();

  AwaitWebContentsResolution();
}

TEST_P(
    CapturedSurfaceControllerWebContentsResolutionTest,
    ApiInvocationPriorToWebContentsResolutionFailsButSubsequentCallsAreNotBlocked) {
  // Setup - repeat ApiInvocationPriorToWebContentsResolutionFails.
  {
    SetUpTestTabs();  // Triggers resolution but does not await it.
    StartCaptureOf(*capturee_);
    permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);

    base::RunLoop run_loop;
    RunTestedActionAndExpect(&run_loop,
                             CSCResult::kCapturedSurfaceNotFoundError);
    run_loop.Run();

    AwaitWebContentsResolution();
  }

  // After AwaitWebContentsResolution() is called, subsequent API calls succeed.
  base::RunLoop run_loop;
  RunTestedActionAndExpect(&run_loop, CSCResult::kSuccess);
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerWebContentsResolutionTest,
       MultiplePendingResolutions) {
  SetUpTestTabs();  // Triggers resolution but does not await it.
  StartCaptureOf(*capturee_);
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);

  // The original resolution has not yet resolved.
  ASSERT_FALSE(last_resolved_web_contents_.has_value());

  // Updating to capture another tab schedules a new task to resolve.
  controller_->UpdateCaptureTarget(
      new_capturee_->GetWebContentsMediaCaptureId());

  // Neither resolutions has completed at this point.
  ASSERT_FALSE(last_resolved_web_contents_.has_value());

  // We await the resolution to be considered complete.
  // This should only happen after the last pending task resolves.
  // In our cases, that is for the new tab. The first response
  // should be ignored.
  AwaitWebContentsResolution();
  ASSERT_TRUE(last_resolved_web_contents_.has_value());
  EXPECT_EQ(last_resolved_web_contents_.value().get(),
            new_capturee_->web_contents());
}

// Similar to CapturedSurfaceControllerWebContentsResolutionTest,
// but focuses on calls to UpdateCaptureTarget(), which also trigger resolution.
class CapturedSurfaceControllerWebContentsResolutionOfUpdatesTest
    : public CapturedSurfaceControllerInterfaceTestBase,
      public ::testing::WithParamInterface<CapturedSurfaceControlAPI> {
 public:
  CapturedSurfaceControllerWebContentsResolutionOfUpdatesTest()
      : CapturedSurfaceControllerInterfaceTestBase(GetParam()) {}

  ~CapturedSurfaceControllerWebContentsResolutionOfUpdatesTest() override =
      default;

  void SetUp() override {
    // Unlike CapturedSurfaceControllerWebContentsResolutionTest, the current
    // test works well with the parent's SetUp(), which awaits the resolution
    // of the *first* ID. This is due to the current test's focus on what
    // happens before/after the call to UpdateCaptureTarget().
    CapturedSurfaceControllerInterfaceTestBase::SetUp();

    permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);

    // Prepare a new tab to capture instead of the original one.
    new_capturee_ = std::make_unique<TestTab>(GetBrowserContext());
  }

  void TearDown() override {
    new_capturee_.reset();

    CapturedSurfaceControllerInterfaceTestBase::TearDown();
  }

 protected:
  std::unique_ptr<TestTab> new_capturee_;
};

INSTANTIATE_TEST_SUITE_P(
    ,
    CapturedSurfaceControllerWebContentsResolutionOfUpdatesTest,
    ::testing::Values(CapturedSurfaceControlAPI::kSendWheel,
                      CapturedSurfaceControlAPI::kIncreaseZoomLevel,
                      CapturedSurfaceControlAPI::kDecreaseZoomLevel,
                      CapturedSurfaceControlAPI::kResetZoomLevel));

TEST_P(
    CapturedSurfaceControllerWebContentsResolutionOfUpdatesTest,
    AfterUpdateCaptureTargetApiInvocationAfterToWebContentsResolutionSucceeds) {
  // Call UpdateCaptureTarget() - capturing a new tab.
  controller_->UpdateCaptureTarget(
      new_capturee_->GetWebContentsMediaCaptureId());
  AwaitWebContentsResolution();

  base::RunLoop run_loop;
  RunTestedActionAndExpect(&run_loop, CSCResult::kSuccess);
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerWebContentsResolutionOfUpdatesTest,
       AfterUpdateCaptureTargetApiInvocationPriorToWebContentsResolutionFails) {
  // Call UpdateCaptureTarget() - capturing a new tab.
  controller_->UpdateCaptureTarget(
      new_capturee_->GetWebContentsMediaCaptureId());
  // Note absence of call to AwaitWebContentsResolution().

  base::RunLoop run_loop;
  RunTestedActionAndExpect(&run_loop, CSCResult::kCapturedSurfaceNotFoundError);
  run_loop.Run();

  AwaitWebContentsResolution();
}

// Test suite ensuring that API calls before/after the WebContents ID is
// resolved to a base::WeakPtr<WebContents> behave as expected.
class CapturedSurfaceControllerSelfCaptureTest
    : public CapturedSurfaceControllerInterfaceTestBase,
      public ::testing::WithParamInterface<CapturedSurfaceControlAPI> {
 public:
  CapturedSurfaceControllerSelfCaptureTest()
      : CapturedSurfaceControllerInterfaceTestBase(GetParam()) {}

  ~CapturedSurfaceControllerSelfCaptureTest() override = default;

  void SetUp() override {
    // Intentionally skip CapturedSurfaceControllerInterfaceTestBase's SetUp(),
    // and therefore also CapturedSurfaceControllerTestBase's SetUp().
    RenderViewHostTestHarness::SetUp();
    SetUpTestTabs();
  }
};

INSTANTIATE_TEST_SUITE_P(
    ,
    CapturedSurfaceControllerSelfCaptureTest,
    ::testing::Values(CapturedSurfaceControlAPI::kSendWheel,
                      CapturedSurfaceControlAPI::kIncreaseZoomLevel,
                      CapturedSurfaceControlAPI::kDecreaseZoomLevel,
                      CapturedSurfaceControlAPI::kResetZoomLevel));

TEST_P(CapturedSurfaceControllerSelfCaptureTest, SelfCaptureDisallowed) {
  StartCaptureOf(*capturer_);
  AwaitWebContentsResolution();
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);

  base::RunLoop run_loop;
  RunTestedActionAndExpect(&run_loop,
                           CSCResult::kDisallowedForSelfCaptureError);
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerSelfCaptureTest,
       UpdateCaptureTargetToOtherTabEnablesCapturedSurfaceControl) {
  StartCaptureOf(*capturer_);
  AwaitWebContentsResolution();
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);

  controller_->UpdateCaptureTarget(capturee_->GetWebContentsMediaCaptureId());
  AwaitWebContentsResolution();

  base::RunLoop run_loop;
  RunTestedActionAndExpect(&run_loop, CSCResult::kSuccess);
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerSelfCaptureTest,
       UpdateCaptureTargetToCapturingTabDisablesCapturedSurfaceControl) {
  StartCaptureOf(*capturee_);
  AwaitWebContentsResolution();
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);

  {
    base::RunLoop run_loop;
    RunTestedActionAndExpect(&run_loop, CSCResult::kSuccess);
    run_loop.Run();
  }

  controller_->UpdateCaptureTarget(capturer_->GetWebContentsMediaCaptureId());
  AwaitWebContentsResolution();

  base::RunLoop run_loop;
  RunTestedActionAndExpect(&run_loop,
                           CSCResult::kDisallowedForSelfCaptureError);
  run_loop.Run();
}

// This test suite checks correct clamping of x/y wheel-deltas to min/max.
//
// The suite is parameterized on the *zoom* level because that affects
// the values that will ultimately be fed into the UI system, and checking
// at both the min/max zoom levels increases coverage somewhat.
//
// The suite is *not* parameterized on the wheel deltas themselves, as that
// would increase test complexity and reduce confidence in test correctness.
class CapturedSurfaceControllerSendWheelClampTest
    : public CapturedSurfaceControllerSendWheelTest,
      public ::testing::WithParamInterface<Boundary> {
 public:
  CapturedSurfaceControllerSendWheelClampTest()
      : zoom_level_boundary_(GetParam()) {}
  ~CapturedSurfaceControllerSendWheelClampTest() override = default;

 protected:
  int zoom_level() const {
    static const double kMin = 100 * blink::kMaximumBrowserZoomFactor;
    static const double kMax = 100 * blink::kMinimumBrowserZoomFactor;
    switch (zoom_level_boundary_) {
      case Boundary::kMin:
        return static_cast<int>(std::ceil(kMin));
      case Boundary::kMax:
        return static_cast<int>(std::floor(kMax));
    }
    NOTREACHED();
  }

 private:
  const Boundary zoom_level_boundary_;
};

INSTANTIATE_TEST_SUITE_P(,
                         CapturedSurfaceControllerSendWheelClampTest,
                         ::testing::Values(Boundary::kMin, Boundary::kMax));

TEST_P(CapturedSurfaceControllerSendWheelClampTest, ClampMinWheelDeltaX) {
  using WheelDeltaType = decltype(CapturedWheelAction::wheel_delta_x);
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  base::RunLoop run_loop;
  input_observer_->AddExpectation(InputObserver::ExpectedWheelEvent{
      .x = 0,
      .y = 0,
      .delta_x = -CapturedSurfaceController::kMaxWheelDeltaMagnitude,
      .delta_y = 0});
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0,
          /*y=*/0,
          /*wheel_delta_x=*/std::numeric_limits<WheelDeltaType>::min(),
          /*wheel_delta_y=*/0),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerSendWheelClampTest, ClampMaxWheelDeltaX) {
  using WheelDeltaType = decltype(CapturedWheelAction::wheel_delta_x);
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  base::RunLoop run_loop;
  input_observer_->AddExpectation(InputObserver::ExpectedWheelEvent{
      .x = 0,
      .y = 0,
      .delta_x = CapturedSurfaceController::kMaxWheelDeltaMagnitude,
      .delta_y = 0});
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0,
          /*y=*/0,
          /*wheel_delta_x=*/std::numeric_limits<WheelDeltaType>::max(),
          /*wheel_delta_y=*/0),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerSendWheelClampTest, ClampMinWheelDeltaY) {
  using WheelDeltaType = decltype(CapturedWheelAction::wheel_delta_y);
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  base::RunLoop run_loop;
  input_observer_->AddExpectation(InputObserver::ExpectedWheelEvent{
      .x = 0,
      .y = 0,
      .delta_x = 0,
      .delta_y = -CapturedSurfaceController::kMaxWheelDeltaMagnitude});
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0,
          /*y=*/0,
          /*wheel_delta_x=*/0,
          /*wheel_delta_y=*/std::numeric_limits<WheelDeltaType>::min()),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

TEST_P(CapturedSurfaceControllerSendWheelClampTest, ClampMaxWheelDeltaY) {
  using WheelDeltaType = decltype(CapturedWheelAction::wheel_delta_y);
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  base::RunLoop run_loop;
  input_observer_->AddExpectation(InputObserver::ExpectedWheelEvent{
      .x = 0,
      .y = 0,
      .delta_x = 0,
      .delta_y = CapturedSurfaceController::kMaxWheelDeltaMagnitude});
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0,
          /*y=*/0,
          /*wheel_delta_x=*/0,
          /*wheel_delta_y=*/std::numeric_limits<WheelDeltaType>::max()),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

class WebContentsObserverCscNotifiedBySendWheelTest
    : public CapturedSurfaceControllerTestBase {
 public:
  ~WebContentsObserverCscNotifiedBySendWheelTest() override = default;
};

TEST_F(WebContentsObserverCscNotifiedBySendWheelTest,
       NotifiedBySendWheelIfSuccessful) {
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);
  testing::StrictMock<MockObserver> observer(capturer_->web_contents());
  EXPECT_CALL(observer, OnCapturedSurfaceControl()).Times(1);

  base::RunLoop run_loop;
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0.25,
          /*y=*/0.5,
          /*wheel_delta_x=*/300,
          /*wheel_delta_y=*/400),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

TEST_F(WebContentsObserverCscNotifiedBySendWheelTest,
       NotNotifiedBySendWheelIfUnsuccessful) {
  permission_manager_->SetPermissionResult(CSCPermissionResult::kDenied);

  testing::StrictMock<MockObserver> observer(capturer_->web_contents());
  EXPECT_CALL(observer, OnCapturedSurfaceControl()).Times(0);

  base::RunLoop run_loop;
  controller_->SendWheel(
      CapturedWheelAction::New(
          /*x=*/0.25,
          /*y=*/0.5,
          /*wheel_delta_x=*/300,
          /*wheel_delta_y=*/400),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kNoPermissionError,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

class WebContentsObserverCscNotifiedByUpdateZoomLevelTest
    : public CapturedSurfaceControllerTestBase,
      public ::testing::WithParamInterface<CapturedSurfaceControlAPI> {
 public:
  WebContentsObserverCscNotifiedByUpdateZoomLevelTest()
      : tested_interface_(GetParam()) {}
  ~WebContentsObserverCscNotifiedByUpdateZoomLevelTest() override = default;

 protected:
  const CapturedSurfaceControlAPI tested_interface_;
};

INSTANTIATE_TEST_SUITE_P(
    ,
    WebContentsObserverCscNotifiedByUpdateZoomLevelTest,
    ::testing::Values(CapturedSurfaceControlAPI::kIncreaseZoomLevel,
                      CapturedSurfaceControlAPI::kDecreaseZoomLevel,
                      CapturedSurfaceControlAPI::kResetZoomLevel));

TEST_P(WebContentsObserverCscNotifiedByUpdateZoomLevelTest,
       NotifiedByUpdateZoomLevelIfSuccessful) {
  permission_manager_->SetPermissionResult(CSCPermissionResult::kGranted);

  testing::StrictMock<MockObserver> observer(capturer_->web_contents());
  EXPECT_CALL(observer, OnCapturedSurfaceControl()).Times(1);

  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ToZoomLevelAction(tested_interface_),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kSuccess,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

TEST_P(WebContentsObserverCscNotifiedByUpdateZoomLevelTest,
       NotNotifiedByUpdateZoomLevelIfUnsuccessful) {
  permission_manager_->SetPermissionResult(CSCPermissionResult::kDenied);

  testing::StrictMock<MockObserver> observer(capturer_->web_contents());
  EXPECT_CALL(observer, OnCapturedSurfaceControl()).Times(0);

  base::RunLoop run_loop;
  controller_->UpdateZoomLevel(
      ToZoomLevelAction(tested_interface_),
      MakeCallbackExpectingResult(&run_loop, CSCResult::kNoPermissionError,
                                  mock_widget_input_handler_.get()));
  run_loop.Run();
}

}  // namespace
}  // namespace content
