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

#include "base/task/bind_post_task.h"
#include "content/browser/media/captured_surface_control_permission_manager.h"
#include "content/browser/media/media_stream_web_contents_observer.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/host_zoom_map.h"
#include "content/public/browser/permission_result.h"
#include "content/public/browser/web_contents_media_capture_id.h"
#include "third_party/blink/public/common/input/synthetic_web_input_event_builders.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
#include "ui/events/types/scroll_types.h"
#include "ui/gfx/geometry/size.h"

namespace content {

namespace {

using ::blink::kPresetBrowserZoomFactors;
using ::blink::ZoomFactorToZoomLevel;
using ::blink::ZoomLevelToZoomFactor;
using ::blink::ZoomValuesEqual;
using ::blink::mojom::CapturedSurfaceControlResult;
using ::blink::mojom::ZoomLevelAction;
using PermissionManager = CapturedSurfaceControlPermissionManager;
using CapturedSurfaceControlPermissionStatus =
    PermissionManager::CapturedSurfaceControlPermissionStatus;
using CapturedSurfaceInfo = CapturedSurfaceController::CapturedSurfaceInfo;

void OnZoomLevelChangeOnUI(
    base::RepeatingCallback<void(int)> on_zoom_level_change_callback,
    base::WeakPtr<WebContents> captured_wc,
    const HostZoomMap::ZoomLevelChange& change) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (!captured_wc) {
    return;
  }

  int zoom_level =
      std::round(100 * ZoomLevelToZoomFactor(
                           HostZoomMap::GetZoomLevel(captured_wc.get())));
  on_zoom_level_change_callback.Run(zoom_level);
}

std::optional<CapturedSurfaceInfo> ResolveCapturedSurfaceOnUI(
    WebContentsMediaCaptureId wc_id,
    int subscription_version,
    base::RepeatingCallback<void(int)> on_zoom_level_change_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (wc_id.is_null()) {
    return std::nullopt;
  }

  WebContents* const wc =
      WebContents::FromRenderFrameHost(RenderFrameHost::FromID(
          wc_id.render_process_id, wc_id.main_render_frame_id));

  if (!wc) {
    return std::nullopt;
  }

  HostZoomMap* host_zoom_map = HostZoomMap::GetForWebContents(wc);
  if (!host_zoom_map) {
    return std::nullopt;
  }

  int initial_zoom_level =
      std::round(100 * ZoomLevelToZoomFactor(HostZoomMap::GetZoomLevel(wc)));

  std::unique_ptr<base::CallbackListSubscription,
                  BrowserThread::DeleteOnUIThread>
      subscription_ptr(new base::CallbackListSubscription());
  base::WeakPtr<WebContents> wc_weak_ptr = wc->GetWeakPtr();
  *subscription_ptr =
      host_zoom_map->AddZoomLevelChangedCallback(base::BindRepeating(
          &OnZoomLevelChangeOnUI, on_zoom_level_change_callback, wc_weak_ptr));

  return CapturedSurfaceInfo(wc_weak_ptr, std::move(subscription_ptr),
                             subscription_version, initial_zoom_level);
}

// Deliver a synthetic MouseWheel action on `captured_wc` with the parameters
// described by the values in `action`.
//
// Return `CapturedSurfaceControlResult` to be reported back to the renderer,
// indicating success or failure (with reason).
CapturedSurfaceControlResult DoSendWheel(
    GlobalRenderFrameHostId capturer_rfh_id,
    base::WeakPtr<WebContents> captured_wc,
    blink::mojom::CapturedWheelActionPtr action) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  WebContentsImpl* const capturer_wci =
      WebContentsImpl::FromRenderFrameHostImpl(
          RenderFrameHostImpl::FromID(capturer_rfh_id));
  if (!capturer_wci) {
    // The capturing frame or tab appears to have closed asynchronously.
    return CapturedSurfaceControlResult::kCapturerNotFoundError;
  }

  RenderFrameHost* const captured_rfh =
      captured_wc ? captured_wc->GetPrimaryMainFrame() : nullptr;
  if (!captured_rfh) {
    return CapturedSurfaceControlResult::kCapturedSurfaceNotFoundError;
  }

  RenderFrameHostImpl* const captured_rfhi =
      RenderFrameHostImpl::FromID(captured_rfh->GetGlobalId());
  RenderWidgetHostImpl* const captured_rwhi =
      captured_rfhi ? captured_rfhi->GetRenderWidgetHost() : nullptr;
  if (!captured_rwhi) {
    return CapturedSurfaceControlResult::kCapturedSurfaceNotFoundError;
  }

  if (capturer_wci == captured_wc.get()) {
    return CapturedSurfaceControlResult::kDisallowedForSelfCaptureError;
  }

  // Scale (x, y).
  const gfx::Size captured_viewport_size =
      captured_rwhi->GetRenderInputRouter()->GetRootWidgetViewportSize();
  if (captured_viewport_size.width() < 1 ||
      captured_viewport_size.height() < 1) {
    return CapturedSurfaceControlResult::kUnknownError;
  }
  const double x =
      std::floor(action->relative_x * captured_viewport_size.width());
  const double y =
      std::floor(action->relative_y * captured_viewport_size.height());

  // Clamp deltas.
  // Note that `action->wheel_delta_x` and `action->wheel_delta_y` are
  // `int32_t`s, but `blink::SyntheticWebMouseWheelEventBuilder::Build()`
  // receives `float`s.
  const float wheel_delta_x =
      std::min(CapturedSurfaceController::kMaxWheelDeltaMagnitude,
               std::max(action->wheel_delta_x,
                        -CapturedSurfaceController::kMaxWheelDeltaMagnitude));
  const float wheel_delta_y =
      std::min(CapturedSurfaceController::kMaxWheelDeltaMagnitude,
               std::max(action->wheel_delta_y,
                        -CapturedSurfaceController::kMaxWheelDeltaMagnitude));

  // Produce the wheel event on the captured surface.
  {
    blink::WebMouseWheelEvent event =
        blink::SyntheticWebMouseWheelEventBuilder::Build(
            x, y, wheel_delta_x, wheel_delta_y,
            blink::WebInputEvent::kNoModifiers,
            ui::ScrollGranularity::kScrollByPixel);
    event.phase = blink::WebMouseWheelEvent::Phase::kPhaseBegan;
    captured_rwhi->ForwardWheelEvent(event);
  }

  // Close the loop by producing an event at the same location with zero deltas
  // and with the phase set to kPhaseEnded.
  {
    blink::WebMouseWheelEvent event =
        blink::SyntheticWebMouseWheelEventBuilder::Build(
            x, y, /*dx=*/0, /*dy=*/0, blink::WebInputEvent::kNoModifiers,
            ui::ScrollGranularity::kScrollByPixel);
    event.phase = blink::WebMouseWheelEvent::Phase::kPhaseEnded;
    captured_rwhi->ForwardWheelEvent(event);
  }

  capturer_wci->DidCapturedSurfaceControl();

  return CapturedSurfaceControlResult::kSuccess;
}

// We use this helper to check if a given zoom factor is within [closed, open),
// or within (open, closed], depending on which of the two is greater.
// We allow for some small epsilon in either direction using ZoomValuesEqual().
bool IsFactorWithinHalfOpenInterval(double val, double closed, double open) {
  CHECK_NE(closed, open);

  if (ZoomValuesEqual(val, closed)) {
    return true;
  }

  const double min = std::min(closed, open);
  const double max = std::max(closed, open);

  return val > min && val < max && !ZoomValuesEqual(val, open);
}

base::expected<double, CapturedSurfaceControlResult> GetNewZoomLevel(
    WebContents* wc,
    ZoomLevelAction action) {
  if (action == ZoomLevelAction::kReset) {
    return ZoomFactorToZoomLevel(1);
  }

  CHECK(action == ZoomLevelAction::kIncrease ||
        action == ZoomLevelAction::kDecrease);
  const bool is_increase = (action == ZoomLevelAction::kIncrease);

  const double factor = ZoomLevelToZoomFactor(HostZoomMap::GetZoomLevel(wc));

  CHECK_GE(kPresetBrowserZoomFactors.size(), 2u);
  for (size_t i = 1; i < kPresetBrowserZoomFactors.size(); ++i) {
    const double prev = kPresetBrowserZoomFactors[i - 1];
    const double next = kPresetBrowserZoomFactors[i];

    if (is_increase) {
      if (IsFactorWithinHalfOpenInterval(factor, prev, next)) {
        return ZoomFactorToZoomLevel(next);
      }
    } else {  // !is_increase
      if (IsFactorWithinHalfOpenInterval(factor, next, prev)) {
        return ZoomFactorToZoomLevel(prev);
      }
    }
  }

  return base::unexpected(action == ZoomLevelAction::kIncrease
                              ? CapturedSurfaceControlResult::kMaxZoomLevel
                              : CapturedSurfaceControlResult::kMinZoomLevel);
}

// Update the zoom level of the tab indicated by `captured_wc`,
// either increasing, decreasing or resetting the zoom level,
// according to the desired change indicated by `action`.
//
// Return `CapturedSurfaceControlResult` to be reported back to the renderer,
// indicating success or failure (with reason).
CapturedSurfaceControlResult DoUpdateZoomLevel(
    GlobalRenderFrameHostId capturer_rfh_id,
    base::WeakPtr<WebContents> captured_wc,
    ZoomLevelAction action) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  WebContentsImpl* const capturer_wci =
      WebContentsImpl::FromRenderFrameHostImpl(
          RenderFrameHostImpl::FromID(capturer_rfh_id));
  if (!capturer_wci) {
    // The capturing frame or tab appears to have closed asynchronously.
    return CapturedSurfaceControlResult::kCapturerNotFoundError;
  }

  if (!captured_wc) {
    return CapturedSurfaceControlResult::kCapturedSurfaceNotFoundError;
  }

  if (capturer_wci == captured_wc.get()) {
    return CapturedSurfaceControlResult::kDisallowedForSelfCaptureError;
  }

  HostZoomMap* const host_zoom_map =
      HostZoomMap::GetForWebContents(captured_wc.get());
  if (!host_zoom_map) {
    return CapturedSurfaceControlResult::kUnknownError;
  }

  const base::expected<double, CapturedSurfaceControlResult> new_zoom_level =
      GetNewZoomLevel(captured_wc.get(), action);
  if (!new_zoom_level.has_value()) {
    return new_zoom_level.error();
  }

  host_zoom_map->SetTemporaryZoomLevel(
      captured_wc->GetPrimaryMainFrame()->GetGlobalId(),
      new_zoom_level.value());

  capturer_wci->DidCapturedSurfaceControl();

  return CapturedSurfaceControlResult::kSuccess;
}

// Return success if all conditions for CSC apply, otherwise fail with the
// appropriate error code.
CapturedSurfaceControlResult FinalizeRequestPermission(
    GlobalRenderFrameHostId capturer_rfh_id,
    base::WeakPtr<WebContents> captured_wc) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  WebContentsImpl* const capturer_wci =
      WebContentsImpl::FromRenderFrameHostImpl(
          RenderFrameHostImpl::FromID(capturer_rfh_id));
  if (!capturer_wci) {
    // The capturing frame or tab appears to have closed asynchronously.
    return CapturedSurfaceControlResult::kCapturerNotFoundError;
  }

  RenderFrameHost* const captured_rfh =
      captured_wc ? captured_wc->GetPrimaryMainFrame() : nullptr;
  if (!captured_rfh) {
    return CapturedSurfaceControlResult::kCapturedSurfaceNotFoundError;
  }

  RenderFrameHostImpl* const captured_rfhi =
      RenderFrameHostImpl::FromID(captured_rfh->GetGlobalId());
  RenderWidgetHostImpl* const captured_rwhi =
      captured_rfhi ? captured_rfhi->GetRenderWidgetHost() : nullptr;
  if (!captured_rwhi) {
    return CapturedSurfaceControlResult::kCapturedSurfaceNotFoundError;
  }

  if (capturer_wci == captured_wc.get()) {
    return CapturedSurfaceControlResult::kDisallowedForSelfCaptureError;
  }

  capturer_wci->DidCapturedSurfaceControl();

  return CapturedSurfaceControlResult::kSuccess;
}

void OnPermissionCheckResult(
    base::OnceCallback<CapturedSurfaceControlResult()> action_callback,
    base::OnceCallback<void(CapturedSurfaceControlResult)> reply_callback,
    CapturedSurfaceControlPermissionStatus permission_check_result) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  if (permission_check_result ==
      CapturedSurfaceControlPermissionStatus::kDenied) {
    std::move(reply_callback)
        .Run(CapturedSurfaceControlResult::kNoPermissionError);
    return;
  }

  if (permission_check_result ==
      CapturedSurfaceControlPermissionStatus::kError) {
    std::move(reply_callback).Run(CapturedSurfaceControlResult::kUnknownError);
    return;
  }

  const CapturedSurfaceControlResult result = std::move(action_callback).Run();
  std::move(reply_callback).Run(result);
}

// Given:
// 1. A callback that will attempt to perform an action if permitted.
// 2. A callback that will report to the renderer process whether the
//    action succeeded, failed or was not permitted.
//
// Return:
// A callback that composes these two into a single callback that,
// after the permission manager has checked for permission, runs the
// action callback if it is permitted, and reports the result to the renderer.
//
// It is assumed that `action_callback` runs on the UI thread.
base::OnceCallback<
    void(PermissionManager::CapturedSurfaceControlPermissionStatus)>
ComposeCallbacks(
    base::OnceCallback<CapturedSurfaceControlResult(void)> action_callback,
    base::OnceCallback<void(CapturedSurfaceControlResult)> reply_callback) {
  // Callback for reporting result of both permission-prompt as well as action
  // (if permitted) to the renderer.
  base::OnceCallback<void(CapturedSurfaceControlResult)> reply_callback_io =
      base::BindPostTask(GetIOThreadTaskRunner({}), std::move(reply_callback));

  return base::BindPostTask(
      GetUIThreadTaskRunner({}),
      base::BindOnce(&OnPermissionCheckResult, std::move(action_callback),
                     std::move(reply_callback_io)));
}

}  // namespace

CapturedSurfaceInfo::CapturedSurfaceInfo(
    base::WeakPtr<WebContents> captured_wc,
    std::unique_ptr<base::CallbackListSubscription,
                    BrowserThread::DeleteOnUIThread> subscription,
    int subscription_version,
    int initial_zoom_level)
    : captured_wc(captured_wc),
      subscription(std::move(subscription)),
      subscription_version(subscription_version),
      initial_zoom_level(initial_zoom_level) {}

CapturedSurfaceInfo::CapturedSurfaceInfo(CapturedSurfaceInfo&& other) = default;
CapturedSurfaceInfo& CapturedSurfaceInfo::operator=(
    CapturedSurfaceInfo&& other) = default;

CapturedSurfaceInfo::~CapturedSurfaceInfo() = default;

std::unique_ptr<CapturedSurfaceController>
CapturedSurfaceController::CreateForTesting(
    GlobalRenderFrameHostId capturer_rfh_id,
    WebContentsMediaCaptureId captured_wc_id,
    std::unique_ptr<PermissionManager> permission_manager,
    base::RepeatingCallback<void(int)> on_zoom_level_change_callback,
    base::RepeatingCallback<void(base::WeakPtr<WebContents>)>
        wc_resolution_callback) {
  return base::WrapUnique(new CapturedSurfaceController(
      capturer_rfh_id, captured_wc_id, std::move(permission_manager),
      on_zoom_level_change_callback, std::move(wc_resolution_callback)));
}

CapturedSurfaceController::CapturedSurfaceController(
    GlobalRenderFrameHostId capturer_rfh_id,
    WebContentsMediaCaptureId captured_wc_id,
    base::RepeatingCallback<void(int)> on_zoom_level_change_callback)
    : CapturedSurfaceController(
          capturer_rfh_id,
          captured_wc_id,
          std::make_unique<PermissionManager>(capturer_rfh_id),
          std::move(on_zoom_level_change_callback),
          /*wc_resolution_callback=*/base::DoNothing()) {}

CapturedSurfaceController::CapturedSurfaceController(
    GlobalRenderFrameHostId capturer_rfh_id,
    WebContentsMediaCaptureId captured_wc_id,
    std::unique_ptr<PermissionManager> permission_manager,
    base::RepeatingCallback<void(int)> on_zoom_level_change_callback,
    base::RepeatingCallback<void(base::WeakPtr<WebContents>)>
        wc_resolution_callback)
    : capturer_rfh_id_(capturer_rfh_id),
      permission_manager_(std::move(permission_manager)),
      wc_resolution_callback_(std::move(wc_resolution_callback)),
      on_zoom_level_change_callback_(std::move(on_zoom_level_change_callback)) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  ResolveCapturedSurface(captured_wc_id);
}

CapturedSurfaceController::~CapturedSurfaceController() = default;

void CapturedSurfaceController::UpdateCaptureTarget(
    WebContentsMediaCaptureId captured_wc_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  ResolveCapturedSurface(captured_wc_id);
}

void CapturedSurfaceController::SendWheel(
    blink::mojom::CapturedWheelActionPtr action,
    base::OnceCallback<void(CapturedSurfaceControlResult)> reply_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  if (!captured_wc_.has_value()) {
    std::move(reply_callback)
        .Run(CapturedSurfaceControlResult::kCapturedSurfaceNotFoundError);
    return;
  }

  // Action to be performed on the UI thread if permitted.
  base::OnceCallback<CapturedSurfaceControlResult(void)> action_callback =
      base::BindOnce(&DoSendWheel, capturer_rfh_id_, captured_wc_.value(),
                     std::move(action));

  permission_manager_->CheckPermission(
      ComposeCallbacks(std::move(action_callback), std::move(reply_callback)));
}

void CapturedSurfaceController::UpdateZoomLevel(
    ZoomLevelAction action,
    base::OnceCallback<void(CapturedSurfaceControlResult)> reply_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  if (!captured_wc_.has_value()) {
    std::move(reply_callback)
        .Run(CapturedSurfaceControlResult::kCapturedSurfaceNotFoundError);
    return;
  }

  // Action to be performed on the UI thread if permitted.
  base::OnceCallback<CapturedSurfaceControlResult(void)> action_callback =
      base::BindOnce(&DoUpdateZoomLevel, capturer_rfh_id_, captured_wc_.value(),
                     action);

  permission_manager_->CheckPermission(
      ComposeCallbacks(std::move(action_callback), std::move(reply_callback)));
}

void CapturedSurfaceController::RequestPermission(
    base::OnceCallback<void(CapturedSurfaceControlResult)> reply_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  if (!captured_wc_.has_value()) {
    std::move(reply_callback)
        .Run(CapturedSurfaceControlResult::kCapturedSurfaceNotFoundError);
    return;
  }

  // If the permission check is successful, just return success.
  base::OnceCallback<CapturedSurfaceControlResult(void)> action_callback =
      base::BindOnce(&FinalizeRequestPermission, capturer_rfh_id_,
                     captured_wc_.value());
  permission_manager_->CheckPermission(
      ComposeCallbacks(std::move(action_callback), std::move(reply_callback)));
}

void CapturedSurfaceController::ResolveCapturedSurface(
    WebContentsMediaCaptureId captured_wc_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  // Avoid posting new tasks (DoSendWheel/DoUpdateZoomLevel) with the old target
  // while pending resolution.
  captured_wc_ = std::nullopt;
  zoom_level_subscription_.reset();

  // Ensure that, in the unlikely case that multiple resolutions are pending at
  // the same time, only the resolution of the last one will set `captured_wc_`
  // back to a concrete value.
  ++pending_wc_resolutions_;

  base::RepeatingCallback on_zoom_level_change_callback =
      base::BindRepeating(&CapturedSurfaceController::OnZoomLevelChange,
                          weak_factory_.GetWeakPtr(), ++subscription_version_);

  GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
      FROM_HERE,
      base::BindOnce(
          &ResolveCapturedSurfaceOnUI, captured_wc_id, subscription_version_,
          base::BindPostTask(GetIOThreadTaskRunner({}),
                             std::move(on_zoom_level_change_callback))),
      base::BindOnce(&CapturedSurfaceController::OnCapturedSurfaceResolved,
                     weak_factory_.GetWeakPtr()));
}

void CapturedSurfaceController::OnCapturedSurfaceResolved(
    std::optional<CapturedSurfaceInfo> captured_surface_info) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  DCHECK_GE(pending_wc_resolutions_, 1);
  if (--pending_wc_resolutions_ > 0) {
    return;
  }
  if (!captured_surface_info) {
    return;
  }

  captured_wc_ = captured_surface_info->captured_wc;
  zoom_level_subscription_ = std::move(captured_surface_info->subscription);
  OnZoomLevelChange(captured_surface_info->subscription_version,
                    captured_surface_info->initial_zoom_level);
  wc_resolution_callback_.Run(captured_surface_info->captured_wc);
}

void CapturedSurfaceController::OnZoomLevelChange(
    int zoom_level_subscription_version,
    int zoom_level) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  // Only propagate zoom-level updates if they are sent with the current
  // zoom-level subscription version.
  if (zoom_level_subscription_version != subscription_version_) {
    return;
  }

  on_zoom_level_change_callback_.Run(zoom_level);
}

}  // namespace content
