// Copyright 2014 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/android/overscroll_controller_android.h"

#include "base/command_line.h"
#include "base/metrics/field_trial_params.h"
#include "cc/layers/layer.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
#include "third_party/blink/public/common/input/web_gesture_device.h"
#include "third_party/blink/public/common/input/web_gesture_event.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "ui/android/edge_effect.h"
#include "ui/android/resources/resource_manager.h"
#include "ui/android/window_android.h"
#include "ui/android/window_android_compositor.h"
#include "ui/base/l10n/l10n_util_android.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/events/android/motion_event_android.h"
#include "ui/events/blink/did_overscroll_params.h"
#include "ui/gfx/geometry/vector2d_f.h"

using ui::DidOverscrollParams;
using ui::EdgeEffect;
using ui::OverscrollGlow;
using ui::OverscrollGlowClient;
using ui::OverscrollRefresh;

namespace content {
namespace {

// If the glow effect alpha is greater than this value, the refresh effect will
// be suppressed. This value was experimentally determined to provide a
// reasonable balance between avoiding accidental refresh activation and
// minimizing the wait required to refresh after the glow has been triggered.
const float kMinGlowAlphaToDisableRefresh = 0.085f;

std::unique_ptr<EdgeEffect> CreateGlowEdgeEffect(
    ui::ResourceManager* resource_manager,
    float dpi_scale) {
  DCHECK(resource_manager);
  return std::make_unique<EdgeEffect>(resource_manager);
}

std::unique_ptr<OverscrollGlow> CreateGlowEffect(OverscrollGlowClient* client) {
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableOverscrollEdgeEffect)) {
    return nullptr;
  }

  // The elastic overscroll feature indicates when the user is scrolling beyond
  // the range of the scrollable area. Showing a glow in addition would be
  // redundant.
  if (switches::IsElasticOverscrollEnabled())
    return nullptr;

  return std::make_unique<OverscrollGlow>(client);
}

std::unique_ptr<OverscrollRefresh> CreateRefreshEffect(
    ui::OverscrollRefreshHandler* overscroll_refresh_handler,
    float dpi_scale) {
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisablePullToRefreshEffect)) {
    return nullptr;
  }

  float edge_width = OverscrollRefresh::kDefaultNavigationEdgeWidth * dpi_scale;
  return std::make_unique<OverscrollRefresh>(overscroll_refresh_handler,
                                             edge_width);
}

}  // namespace

// static
std::unique_ptr<OverscrollControllerAndroid>
OverscrollControllerAndroid::CreateForTests(
    ui::WindowAndroidCompositor* compositor,
    float dpi_scale,
    std::unique_ptr<ui::OverscrollGlow> glow_effect,
    std::unique_ptr<ui::OverscrollRefresh> refresh_effect) {
  return std::unique_ptr<OverscrollControllerAndroid>(
      new OverscrollControllerAndroid(compositor, dpi_scale,
                                      std::move(glow_effect),
                                      std::move(refresh_effect)));
}

OverscrollControllerAndroid::OverscrollControllerAndroid(
    ui::WindowAndroidCompositor* compositor,
    float dpi_scale,
    std::unique_ptr<ui::OverscrollGlow> glow_effect,
    std::unique_ptr<ui::OverscrollRefresh> refresh_effect)
    : compositor_(compositor),
      dpi_scale_(dpi_scale),
      enabled_(true),
      glow_effect_(std::move(glow_effect)),
      refresh_effect_(std::move(refresh_effect)) {}

OverscrollControllerAndroid::OverscrollControllerAndroid(
    ui::OverscrollRefreshHandler* overscroll_refresh_handler,
    ui::WindowAndroidCompositor* compositor,
    float dpi_scale,
    RenderWidgetHost* host)
    : compositor_(compositor),
      dpi_scale_(dpi_scale),
      enabled_(true),
      glow_effect_(CreateGlowEffect(this)),
      refresh_effect_(
          CreateRefreshEffect(overscroll_refresh_handler, dpi_scale_)) {
  DCHECK(compositor_);
  if (host) {
    obs_.Observe(host);
  }
}

OverscrollControllerAndroid::~OverscrollControllerAndroid() {
}

void OverscrollControllerAndroid::OnGestureEvent(
    const blink::WebGestureEvent& event) {
  if (!ShouldHandleInputEvents()) {
    return;
  }

  switch (event.GetType()) {
    case blink::WebInputEvent::Type::kGestureScrollBegin:
      refresh_effect_->OnScrollBegin(
          gfx::ScalePoint(event.PositionInWidget(), dpi_scale_));
      break;
    case blink::WebInputEvent::Type::kGestureScrollUpdate: {
      if (event.SourceDevice() == blink::WebGestureDevice::kTouchpad) {
        gfx::Vector2dF scroll_delta(event.data.scroll_update.delta_x,
                                    event.data.scroll_update.delta_y);
        refresh_effect_->WillHandleScrollUpdate(scroll_delta);
      }
    } break;
    case blink::WebInputEvent::Type::kGestureScrollEnd: {
      if (event.SourceDevice() == blink::WebGestureDevice::kTouchpad) {
        refresh_effect_->OnScrollEnd(gfx::Vector2dF());
      }
      break;
    }

    case blink::WebInputEvent::Type::kGestureFlingStart: {
      if (refresh_effect_->IsActive()) {
        gfx::Vector2dF scroll_velocity(event.data.fling_start.velocity_x,
                                       event.data.fling_start.velocity_y);
        scroll_velocity.Scale(dpi_scale_);
        refresh_effect_->OnScrollEnd(scroll_velocity);
        // TODO(jdduke): Figure out a cleaner way of suppressing a fling.
        // It's important that the any downstream code sees a scroll-ending
        // event (in this case GestureFlingStart) if it has seen a scroll begin.
        // Thus, we cannot simply consume the fling. Changing the event type to
        // a GestureScrollEnd might work in practice, but could lead to
        // unexpected results. For now, simply truncate the fling velocity, but
        // not to zero as downstream code may not expect a zero-velocity fling.
        blink::WebGestureEvent& modified_event =
            const_cast<blink::WebGestureEvent&>(event);
        modified_event.data.fling_start.velocity_x = .01f;
        modified_event.data.fling_start.velocity_y = .01f;
      }
    } break;

    default:
      break;
  }
}

void OverscrollControllerAndroid::OnGestureEventAck(
    const blink::WebGestureEvent& event,
    blink::mojom::InputEventResultState ack_result) {
  if (!enabled_)
    return;

  // The overscroll effect requires an explicit release signal that may not be
  // sent from the renderer compositor.
  if (event.GetType() == blink::WebInputEvent::Type::kGestureScrollEnd ||
      event.GetType() == blink::WebInputEvent::Type::kGestureFlingStart) {
    OnOverscrolled(DidOverscrollParams());
  }

  if (event.GetType() == blink::WebInputEvent::Type::kGestureScrollBegin &&
      refresh_effect_) {
    // The effect should only be allowed if the scroll events go unconsumed.
    if (refresh_effect_->IsAwaitingScrollUpdateAck() &&
        ack_result == blink::mojom::InputEventResultState::kConsumed) {
      refresh_effect_->Reset();
    }
  }
}

void OverscrollControllerAndroid::OnOverscrolled(
    const DidOverscrollParams& params) {
  if (!enabled_)
    return;

  if (refresh_effect_) {
    refresh_effect_->OnOverscrolled(params.overscroll_behavior,
                                    params.accumulated_overscroll,
                                    params.source_device);
    bool refresh_effect_active = refresh_effect_->IsActive();
    is_handling_sequence_ |= refresh_effect_active;

    if (refresh_effect_active || refresh_effect_->IsAwaitingScrollUpdateAck()) {
      // An active (or potentially active) refresh effect should always pre-empt
      // the passive glow effect.
      return;
    }
  }

  // When use-zoom-for-dsf is enabled, each value of params was already scaled
  // by the device scale factor.
  gfx::Vector2dF accumulated_overscroll = params.accumulated_overscroll;
  gfx::Vector2dF latest_overscroll_delta = params.latest_overscroll_delta;
  gfx::Vector2dF current_fling_velocity = params.current_fling_velocity;
  gfx::Vector2dF overscroll_location =
      params.causal_event_viewport_point.OffsetFromOrigin();

  if (params.overscroll_behavior.x == cc::OverscrollBehavior::Type::kNone) {
    accumulated_overscroll.set_x(0);
    latest_overscroll_delta.set_x(0);
    current_fling_velocity.set_x(0);
  }

  if (params.overscroll_behavior.y == cc::OverscrollBehavior::Type::kNone) {
    accumulated_overscroll.set_y(0);
    latest_overscroll_delta.set_y(0);
    current_fling_velocity.set_y(0);
  }

  if (glow_effect_ && glow_effect_->OnOverscrolled(
                          base::TimeTicks::Now(), accumulated_overscroll,
                          latest_overscroll_delta, current_fling_velocity,
                          overscroll_location)) {
    SetNeedsAnimate();
  }
}

bool OverscrollControllerAndroid::Animate(base::TimeTicks current_time,
                                          cc::slim::Layer* parent_layer) {
  DCHECK(parent_layer);
  if (!enabled_ || !glow_effect_)
    return false;

  return glow_effect_->Animate(current_time, parent_layer);
}

void OverscrollControllerAndroid::OnFrameMetadataUpdated(
    float page_scale_factor,
    float device_scale_factor,
    const gfx::SizeF& scrollable_viewport_size,
    const gfx::SizeF& root_layer_size,
    const gfx::PointF& root_scroll_offset,
    bool root_overflow_y_hidden) {
  if (!refresh_effect_ && !glow_effect_)
    return;

  // When use-zoom-for-dsf is enabled, frame_metadata.page_scale_factor was
  // already scaled by the device scale factor.
  float scale_factor = page_scale_factor;
  gfx::SizeF viewport_size =
      gfx::ScaleSize(scrollable_viewport_size, scale_factor);
  gfx::SizeF content_size = gfx::ScaleSize(root_layer_size, scale_factor);
  gfx::PointF content_scroll_offset =
      gfx::ScalePoint(root_scroll_offset, scale_factor);

  if (refresh_effect_) {
    refresh_effect_->OnFrameUpdated(viewport_size, content_scroll_offset,
                                    content_size, root_overflow_y_hidden);
  }

  if (glow_effect_) {
    glow_effect_->OnFrameUpdated(viewport_size, content_size,
                                 content_scroll_offset);
  }
}

void OverscrollControllerAndroid::Enable() {
  enabled_ = true;
}

void OverscrollControllerAndroid::Disable() {
  if (!enabled_)
    return;
  enabled_ = false;
  if (!enabled_) {
    if (refresh_effect_)
      refresh_effect_->Reset();
    if (glow_effect_)
      glow_effect_->Reset();
  }
}

void OverscrollControllerAndroid::SetTouchpadOverscrollHistoryNavigation(
    bool enabled) {
  if (refresh_effect_) {
    refresh_effect_->SetTouchpadOverscrollHistoryNavigation(enabled);
  }
}

bool OverscrollControllerAndroid::ShouldHandleInputEvents() {
  if (!enabled_) {
    return false;
  }

  if (!refresh_effect_) {
    return false;
  }

  // Suppress refresh detection if the glow effect is still prominent.
  if (glow_effect_ && glow_effect_->IsActive()) {
    if (glow_effect_->GetVisibleAlpha() > kMinGlowAlphaToDisableRefresh) {
      return false;
    }
  }
  return true;
}

bool OverscrollControllerAndroid::IsHandlingInputSequence() {
  return is_handling_sequence_;
}

bool OverscrollControllerAndroid::OnTouchEvent(
    const ui::MotionEventAndroid& event) {
  const auto action = event.GetAction();
  // This will consume touch events until the next Action::DOWN. Ideally we
  // should consume until the final Action::UP/Action::CANCEL. But, apparently,
  // we can't reliably determine the final Action::CANCEL in a multi-touch
  // scenario. See https://crbug.com/653212.
  if (action == ui::MotionEventAndroid::Action::DOWN) {
    is_handling_sequence_ = false;
  }

  const bool handles_current_event = IsHandlingInputSequence();

  // |refresh_effect_| might have been consuming input events earlier, return if
  // the OverscrollController is consuming the whole input sequence.
  if (!ShouldHandleInputEvents()) {
    return handles_current_event;
  }

  switch (action) {
    case ui::MotionEventAndroid::Action::DOWN:
      last_pos_ = gfx::Vector2dF(event.GetXPix(0), event.GetYPix(0));
      break;

    case ui::MotionEventAndroid::Action::MOVE: {
      gfx::Vector2dF curr_pointer(event.GetXPix(0), event.GetYPix(0));
      gfx::Vector2dF scroll_delta = curr_pointer - last_pos_;
      refresh_effect_->WillHandleScrollUpdate(scroll_delta);
      last_pos_ = curr_pointer;
    } break;

    case ui::MotionEventAndroid::Action::CANCEL:
    case ui::MotionEventAndroid::Action::UP: {
      refresh_effect_->OnScrollEnd(gfx::Vector2dF());
    } break;

    default:
      break;
  }

  return handles_current_event;
}

void OverscrollControllerAndroid::OnInputEvent(
    const RenderWidgetHost& widget,
    const blink::WebInputEvent& input_event) {
  if (!blink::WebInputEvent::IsGestureEventType(input_event.GetType())) {
    return;
  }

  blink::WebGestureEvent gesture_event =
      static_cast<const blink::WebGestureEvent&>(input_event);
  OnGestureEvent(gesture_event);
}

void OverscrollControllerAndroid::OnInputEventAck(
    const RenderWidgetHost& widget,
    blink::mojom::InputEventResultSource source,
    blink::mojom::InputEventResultState state,
    const blink::WebInputEvent& input_event) {
  if (!blink::WebInputEvent::IsGestureEventType(input_event.GetType())) {
    return;
  }

  blink::WebGestureEvent gesture_event =
      static_cast<const blink::WebGestureEvent&>(input_event);
  OnGestureEventAck(gesture_event, state);
}

std::unique_ptr<EdgeEffect> OverscrollControllerAndroid::CreateEdgeEffect() {
  return CreateGlowEdgeEffect(&compositor_->GetResourceManager(), dpi_scale_);
}

void OverscrollControllerAndroid::SetNeedsAnimate() {
  compositor_->SetNeedsAnimate();
}

}  // namespace content
