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

#include "content/browser/renderer_host/render_widget_targeter.h"

#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
#include "components/viz/common/features.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/renderer_host/input/one_shot_timeout_monitor.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/public/browser/site_isolation_policy.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "ui/events/blink/blink_event_util.h"

namespace content {

namespace {

bool MergeEventIfPossible(const blink::WebInputEvent& event,
                          ui::WebScopedInputEvent* blink_event) {
  if (!blink::WebInputEvent::IsTouchEventType(event.GetType()) &&
      !blink::WebInputEvent::IsGestureEventType(event.GetType()) &&
      ui::CanCoalesce(event, **blink_event)) {
    ui::Coalesce(event, blink_event->get());
    return true;
  }
  return false;
}

gfx::PointF ComputeEventLocation(const blink::WebInputEvent& event) {
  if (blink::WebInputEvent::IsMouseEventType(event.GetType()) ||
      event.GetType() == blink::WebInputEvent::kMouseWheel) {
    return static_cast<const blink::WebMouseEvent&>(event).PositionInWidget();
  }
  if (blink::WebInputEvent::IsTouchEventType(event.GetType())) {
    return static_cast<const blink::WebTouchEvent&>(event)
        .touches[0]
        .PositionInWidget();
  }
  if (blink::WebInputEvent::IsGestureEventType(event.GetType()))
    return static_cast<const blink::WebGestureEvent&>(event).PositionInWidget();

  return gfx::PointF();
}

constexpr const char kTracingCategory[] = "input,latency";

}  // namespace

class TracingUmaTracker {
 public:
  explicit TracingUmaTracker(const char* metric_name)
      : id_(next_id_++),
        start_time_(base::TimeTicks::Now()),
        metric_name_(metric_name) {
    TRACE_EVENT_ASYNC_BEGIN0(
        kTracingCategory, metric_name_,
        TRACE_ID_WITH_SCOPE(metric_name_, TRACE_ID_LOCAL(id_)));
  }
  ~TracingUmaTracker() = default;
  TracingUmaTracker(TracingUmaTracker&& tracker) = default;

  void StopAndRecord() {
    Stop();
    UmaHistogramTimes(metric_name_, base::TimeTicks::Now() - start_time_);
  }

  void Stop() {
    TRACE_EVENT_ASYNC_END0(
        kTracingCategory, metric_name_,
        TRACE_ID_WITH_SCOPE(metric_name_, TRACE_ID_LOCAL(id_)));
  }

 private:
  const int id_;
  const base::TimeTicks start_time_;

  // These variables must be string literals and live for the duration
  // of the program since tracing stores pointers.
  const char* metric_name_;

  static int next_id_;

  DISALLOW_COPY_AND_ASSIGN(TracingUmaTracker);
};

int TracingUmaTracker::next_id_ = 1;

enum class HitTestResultsMatch {
  kDoNotMatch = 0,
  kMatch = 1,
  kHitTestResultChanged = 2,
  kMaxValue = kHitTestResultChanged,
};

RenderWidgetTargetResult::RenderWidgetTargetResult() = default;

RenderWidgetTargetResult::RenderWidgetTargetResult(
    const RenderWidgetTargetResult&) = default;

RenderWidgetTargetResult::RenderWidgetTargetResult(
    RenderWidgetHostViewBase* in_view,
    bool in_should_query_view,
    base::Optional<gfx::PointF> in_location,
    bool in_latched_target,
    bool in_should_verify_result)
    : view(in_view),
      should_query_view(in_should_query_view),
      target_location(in_location),
      latched_target(in_latched_target),
      should_verify_result(in_should_verify_result) {}

RenderWidgetTargetResult::~RenderWidgetTargetResult() = default;

RenderWidgetTargeter::TargetingRequest::TargetingRequest() = default;

RenderWidgetTargeter::TargetingRequest::TargetingRequest(
    TargetingRequest&& request) = default;

RenderWidgetTargeter::TargetingRequest& RenderWidgetTargeter::TargetingRequest::
operator=(TargetingRequest&&) = default;

RenderWidgetTargeter::TargetingRequest::~TargetingRequest() = default;

RenderWidgetTargeter::RenderWidgetTargeter(Delegate* delegate)
    : trace_id_(base::RandUint64()),
      is_viz_hit_testing_debug_enabled_(
          features::IsVizHitTestingDebugEnabled()),
      delegate_(delegate),
      weak_ptr_factory_(this) {
  DCHECK(delegate_);
}

RenderWidgetTargeter::~RenderWidgetTargeter() = default;

void RenderWidgetTargeter::FindTargetAndDispatch(
    RenderWidgetHostViewBase* root_view,
    const blink::WebInputEvent& event,
    const ui::LatencyInfo& latency) {
  DCHECK(blink::WebInputEvent::IsMouseEventType(event.GetType()) ||
         event.GetType() == blink::WebInputEvent::kMouseWheel ||
         blink::WebInputEvent::IsTouchEventType(event.GetType()) ||
         (blink::WebInputEvent::IsGestureEventType(event.GetType()) &&
          (static_cast<const blink::WebGestureEvent&>(event).SourceDevice() ==
               blink::WebGestureDevice::kWebGestureDeviceTouchscreen ||
           static_cast<const blink::WebGestureEvent&>(event).SourceDevice() ==
               blink::WebGestureDevice::kWebGestureDeviceTouchpad)));

  if (request_in_flight_) {
    if (!requests_.empty()) {
      auto& request = requests_.back();
      if (MergeEventIfPossible(event, &request.event))
        return;
    }
    TargetingRequest request;
    request.root_view = root_view->GetWeakPtr();
    request.event = ui::WebInputEventTraits::Clone(event);
    request.latency = latency;
    request.tracker =
        std::make_unique<TracingUmaTracker>("Event.AsyncTargeting.TimeInQueue");
    requests_.push(std::move(request));
    return;
  }

  RenderWidgetTargetResult result =
      delegate_->FindTargetSynchronously(root_view, event);

  const gfx::PointF event_location = ComputeEventLocation(event);

  RenderWidgetHostViewBase* target = result.view;
  auto* event_ptr = &event;
  async_depth_ = 0;
  if (result.should_query_view) {
    TRACE_EVENT_WITH_FLOW2(
        "viz,benchmark", "Event.Pipeline", TRACE_ID_GLOBAL(trace_id_),
        TRACE_EVENT_FLAG_FLOW_OUT, "step", "QueryClient(Start)",
        "event_location", event_location.ToString());

    // TODO(kenrb, sadrul): When all event types support asynchronous hit
    // testing, we should be able to have FindTargetSynchronously return the
    // view and location to use for the renderer hit test query.
    // Currently it has to return the surface hit test target, for event types
    // that ignore |result.should_query_view|, and therefore we have to use
    // root_view and the original event location for the initial query.
    // Do not compare hit test results if we are forced to do async hit testing
    // by HitTestQuery.
    QueryClient(root_view, root_view, *event_ptr, latency, event_location,
                nullptr, gfx::PointF());
  } else {
    FoundTarget(root_view, target, *event_ptr, latency, result.target_location,
                result.latched_target, viz::FrameSinkId());
    // Verify the event targeting results from surface layer viz hit testing if
    // --use-viz-hit-test-surface-layer is enabled.
    if (result.should_verify_result && !target->IsRenderWidgetHostViewGuest()) {
      QueryAndVerifyClient(root_view, root_view, *event_ptr, latency,
                           event_location, nullptr, gfx::PointF(),
                           target->GetFrameSinkId());
    }
  }
}

void RenderWidgetTargeter::ViewWillBeDestroyed(RenderWidgetHostViewBase* view) {
  unresponsive_views_.erase(view);
}

void RenderWidgetTargeter::QueryClientInternal(
    RenderWidgetHostViewBase* root_view,
    RenderWidgetHostViewBase* target,
    const blink::WebInputEvent& event,
    const ui::LatencyInfo& latency,
    const gfx::PointF& target_location,
    RenderWidgetHostViewBase* last_request_target,
    const gfx::PointF& last_target_location,
    const viz::FrameSinkId& expected_frame_sink_id) {
  // Async event targeting and verifying use two different queues, so they don't
  // block each other.
  bool is_verifying = expected_frame_sink_id.is_valid();
  DCHECK((!is_verifying && !request_in_flight_) ||
         (is_verifying && !verify_request_in_flight_));

  auto* target_client = target->host()->input_target_client();
  // |target_client| may not be set yet for this |target| on Mac, need to
  // understand why this happens. https://crbug.com/859492.
  // We do not verify hit testing result under this circumstance.
  if (!target_client) {
    FoundTarget(root_view, target, event, latency, target_location, false,
                viz::FrameSinkId());
    return;
  }

  if (is_verifying) {
    verify_request_in_flight_ = true;
  } else {
    request_in_flight_ = true;
    async_depth_++;
  }
  TracingUmaTracker tracker("Event.AsyncTargeting.ResponseTime");
  auto& hit_test_timeout =
      is_verifying ? async_verify_hit_test_timeout_ : async_hit_test_timeout_;
  hit_test_timeout.reset(new OneShotTimeoutMonitor(
      base::BindOnce(
          &RenderWidgetTargeter::AsyncHitTestTimedOut,
          weak_ptr_factory_.GetWeakPtr(), root_view->GetWeakPtr(),
          target->GetWeakPtr(), target_location,
          last_request_target ? last_request_target->GetWeakPtr() : nullptr,
          last_target_location, ui::WebInputEventTraits::Clone(event), latency,
          expected_frame_sink_id),
      async_hit_test_timeout_delay_));

  TRACE_EVENT_WITH_FLOW2(
      "viz,benchmark", "Event.Pipeline", TRACE_ID_GLOBAL(trace_id_),
      TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
      "QueryClient", "event", blink::WebInputEvent::GetName(event.GetType()));

  target_client->FrameSinkIdAt(
      target_location, trace_id_,
      base::BindOnce(
          &RenderWidgetTargeter::FoundFrameSinkId,
          weak_ptr_factory_.GetWeakPtr(), root_view->GetWeakPtr(),
          target->GetWeakPtr(), ui::WebInputEventTraits::Clone(event), latency,
          is_verifying ? ++last_verify_request_id_ : ++last_request_id_,
          target_location, std::move(tracker), expected_frame_sink_id));
}

void RenderWidgetTargeter::QueryClient(
    RenderWidgetHostViewBase* root_view,
    RenderWidgetHostViewBase* target,
    const blink::WebInputEvent& event,
    const ui::LatencyInfo& latency,
    const gfx::PointF& target_location,
    RenderWidgetHostViewBase* last_request_target,
    const gfx::PointF& last_target_location) {
  QueryClientInternal(root_view, target, event, latency, target_location,
                      last_request_target, last_target_location,
                      viz::FrameSinkId());
}

void RenderWidgetTargeter::QueryAndVerifyClient(
    RenderWidgetHostViewBase* root_view,
    RenderWidgetHostViewBase* target,
    const blink::WebInputEvent& event,
    const ui::LatencyInfo& latency,
    const gfx::PointF& target_location,
    RenderWidgetHostViewBase* last_request_target,
    const gfx::PointF& last_target_location,
    const viz::FrameSinkId& expected_frame_sink_id) {
  if (verify_request_in_flight_) {
    TargetingRequest request;
    request.root_view = root_view->GetWeakPtr();
    request.event = ui::WebInputEventTraits::Clone(event);
    request.latency = latency;
    request.expected_frame_sink_id = expected_frame_sink_id;
    verify_requests_.push(std::move(request));
    return;
  }
  QueryClientInternal(root_view, target, event, latency, target_location,
                      last_request_target, last_target_location,
                      expected_frame_sink_id);
}

void RenderWidgetTargeter::FlushEventQueue(bool is_verifying) {
  bool events_being_flushed = false;
  bool& request_in_flight =
      is_verifying ? verify_request_in_flight_ : request_in_flight_;
  auto* requests = is_verifying ? &verify_requests_ : &requests_;
  while (!request_in_flight && !requests->empty()) {
    auto request = std::move(requests->front());
    requests->pop();
    // The root-view has gone away. Ignore this event, and try to process the
    // next event.
    if (!request.root_view) {
      continue;
    }
    if (request.tracker)
      request.tracker->Stop();
    // Only notify the delegate once that the current event queue is being
    // flushed. Once all the events are flushed, notify the delegate again.
    if (!is_verifying && !events_being_flushed) {
      delegate_->SetEventsBeingFlushed(true);
      events_being_flushed = true;
    }
    if (is_verifying) {
      QueryAndVerifyClient(request.root_view.get(), request.root_view.get(),
                           *request.event, request.latency,
                           ComputeEventLocation(*request.event), nullptr,
                           gfx::PointF(), request.expected_frame_sink_id);
    } else {
      FindTargetAndDispatch(request.root_view.get(), *request.event,
                            request.latency);
    }
  }
  if (!is_verifying)
    delegate_->SetEventsBeingFlushed(false);
}

void RenderWidgetTargeter::FoundFrameSinkId(
    base::WeakPtr<RenderWidgetHostViewBase> root_view,
    base::WeakPtr<RenderWidgetHostViewBase> target,
    ui::WebScopedInputEvent event,
    const ui::LatencyInfo& latency,
    uint32_t request_id,
    const gfx::PointF& target_location,
    TracingUmaTracker tracker,
    const viz::FrameSinkId& expected_frame_sink_id,
    const viz::FrameSinkId& frame_sink_id,
    const gfx::PointF& transformed_location) {
  if (expected_frame_sink_id.is_valid()) {
    tracker.Stop();
  } else {
    tracker.StopAndRecord();
  }
  uint32_t last_id = expected_frame_sink_id.is_valid() ? last_verify_request_id_
                                                       : last_request_id_;
  bool in_flight = expected_frame_sink_id.is_valid() ? verify_request_in_flight_
                                                     : request_in_flight_;
  if (request_id != last_id || !in_flight) {
    // This is a response to a request that already timed out, so the event
    // should have already been dispatched. Mark the renderer as responsive
    // and otherwise ignore this response.
    unresponsive_views_.erase(target.get());
    return;
  }

  if (expected_frame_sink_id.is_valid()) {
    verify_request_in_flight_ = false;
    async_verify_hit_test_timeout_.reset(nullptr);
  } else {
    request_in_flight_ = false;
    async_hit_test_timeout_.reset(nullptr);

    if (is_viz_hit_testing_debug_enabled_ &&
        event->GetType() == blink::WebInputEvent::Type::kMouseDown) {
      hit_test_async_queried_debug_queue_.push_back(target->GetFrameSinkId());
    }
  }
  auto* view = delegate_->FindViewFromFrameSinkId(frame_sink_id);
  if (!view)
    view = target.get();

  // If a client returned an embedded target, then it might be necessary to
  // continue asking the clients until a client claims an event for itself.
  if (view == target.get() ||
      unresponsive_views_.find(view) != unresponsive_views_.end() ||
      !delegate_->ShouldContinueHitTesting(view)) {
    // Reduced scope is required since FoundTarget can trigger another query
    // which would end up linked to the current query.
    {
      TRACE_EVENT_WITH_FLOW1("viz,benchmark", "Event.Pipeline",
                             TRACE_ID_GLOBAL(trace_id_),
                             TRACE_EVENT_FLAG_FLOW_IN, "step", "FoundTarget");
    }

    FoundTarget(root_view.get(), view, *event, latency, transformed_location,
                false, expected_frame_sink_id);
  } else {
    QueryClientInternal(root_view.get(), view, *event, latency,
                        transformed_location, target.get(), target_location,
                        expected_frame_sink_id);
  }
}

void RenderWidgetTargeter::FoundTarget(
    RenderWidgetHostViewBase* root_view,
    RenderWidgetHostViewBase* target,
    const blink::WebInputEvent& event,
    const ui::LatencyInfo& latency,
    const base::Optional<gfx::PointF>& target_location,
    bool latched_target,
    const viz::FrameSinkId& expected_frame_sink_id) {
  if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites() &&
      !latched_target && !expected_frame_sink_id.is_valid()) {
    UMA_HISTOGRAM_COUNTS_100("Event.AsyncTargeting.AsyncClientDepth",
                             async_depth_);
  }

  // RenderWidgetHostViewMac can be deleted asynchronously, in which case the
  // View will be valid but there will no longer be a RenderWidgetHostImpl.
  if (!root_view || !root_view->GetRenderWidgetHost())
    return;

  if (is_viz_hit_testing_debug_enabled_ &&
      !hit_test_async_queried_debug_queue_.empty()) {
    GetHostFrameSinkManager()->SetHitTestAsyncQueriedDebugRegions(
        root_view->GetRootFrameSinkId(), hit_test_async_queried_debug_queue_);
    hit_test_async_queried_debug_queue_.clear();
  }

  if (features::IsVizHitTestingSurfaceLayerEnabled() &&
      expected_frame_sink_id.is_valid()) {
    static const char* kResultsMatchHistogramName =
        "Event.VizHitTestSurfaceLayer.ResultsMatch";
    bool results_match = target->GetFrameSinkId() == expected_frame_sink_id;
    HitTestResultsMatch match_result =
        HitTestResultsMatch::kHitTestResultChanged;
    if (results_match) {
      match_result = HitTestResultsMatch::kMatch;
    } else {
      // If the results do not match, it is possible that the hit test data
      // changed during verification. We do synchronous hit test again to make
      // sure the result is reliable.
      RenderWidgetTargetResult result =
          delegate_->FindTargetSynchronously(root_view, event);
      if (!result.should_query_view && result.view &&
          expected_frame_sink_id == result.view->GetFrameSinkId()) {
        // If the result did not change, it is likely that viz hit test finds
        // the wrong target.
        match_result = HitTestResultsMatch::kDoNotMatch;
      } else {
        // Hit test data changed, so the result is no longer reliable.
        match_result = HitTestResultsMatch::kHitTestResultChanged;
      }
    }
    UMA_HISTOGRAM_ENUMERATION(kResultsMatchHistogramName, match_result,
                              HitTestResultsMatch::kMaxValue);
    FlushEventQueue(true);
    return;
  }
  delegate_->DispatchEventToTarget(root_view, target, event, latency,
                                   target_location);
  FlushEventQueue(false);
}

void RenderWidgetTargeter::AsyncHitTestTimedOut(
    base::WeakPtr<RenderWidgetHostViewBase> current_request_root_view,
    base::WeakPtr<RenderWidgetHostViewBase> current_request_target,
    const gfx::PointF& current_target_location,
    base::WeakPtr<RenderWidgetHostViewBase> last_request_target,
    const gfx::PointF& last_target_location,
    ui::WebScopedInputEvent event,
    const ui::LatencyInfo& latency,
    const viz::FrameSinkId& expected_frame_sink_id) {
  DCHECK(request_in_flight_ || verify_request_in_flight_);
  // If we time out during a verification, we early out to avoid dispatching
  // event to root frame.
  if (expected_frame_sink_id.is_valid()) {
    verify_request_in_flight_ = false;
    return;
  } else {
    request_in_flight_ = false;
  }

  if (!current_request_root_view)
    return;

  // Mark view as unresponsive so further events will not be sent to it.
  if (current_request_target)
    unresponsive_views_.insert(current_request_target.get());

  if (current_request_root_view.get() == current_request_target.get()) {
    // When a request to the top-level frame times out then the event gets
    // sent there anyway. It will trigger the hung renderer dialog if the
    // renderer fails to process it.
    FoundTarget(current_request_root_view.get(),
                current_request_root_view.get(), *event, latency,
                current_target_location, false, viz::FrameSinkId());
  } else {
    FoundTarget(current_request_root_view.get(), last_request_target.get(),
                *event, latency, last_target_location, false,
                viz::FrameSinkId());
  }
}

}  // namespace content
