// Copyright 2015 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 "core/inspector/DevToolsEmulator.h"

#include "core/events/WebInputEventConversion.h"
#include "core/exported/WebViewImpl.h"
#include "core/frame/LocalFrameView.h"
#include "core/frame/Settings.h"
#include "core/frame/VisualViewport.h"
#include "core/frame/WebLocalFrameImpl.h"
#include "core/input/EventHandler.h"
#include "core/page/Page.h"
#include "core/style/ComputedStyle.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/FloatSize.h"
#include "platform/geometry/IntRect.h"
#include "platform/geometry/IntSize.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/loader/fetch/MemoryCache.h"
#include "platform/runtime_enabled_features.h"
#include "platform/wtf/PtrUtil.h"
#include "public/platform/WebLayerTreeView.h"
#include "public/web/WebSettings.h"

namespace {

static float calculateDeviceScaleAdjustment(int width,
                                            int height,
                                            float deviceScaleFactor) {
  // Chromium on Android uses a device scale adjustment for fonts used in text
  // autosizing for improved legibility. This function computes this adjusted
  // value for text autosizing.
  // For a description of the Android device scale adjustment algorithm, see:
  // chrome/browser/chrome_content_browser_client.cc,
  // GetDeviceScaleAdjustment(...)
  if (!width || !height || !deviceScaleFactor)
    return 1;

  static const float kMinFSM = 1.05f;
  static const int kWidthForMinFSM = 320;
  static const float kMaxFSM = 1.3f;
  static const int kWidthForMaxFSM = 800;

  float minWidth = std::min(width, height) / deviceScaleFactor;
  if (minWidth <= kWidthForMinFSM)
    return kMinFSM;
  if (minWidth >= kWidthForMaxFSM)
    return kMaxFSM;

  // The font scale multiplier varies linearly between kMinFSM and kMaxFSM.
  float ratio = static_cast<float>(minWidth - kWidthForMinFSM) /
                (kWidthForMaxFSM - kWidthForMinFSM);
  return ratio * (kMaxFSM - kMinFSM) + kMinFSM;
}

}  // namespace

namespace blink {

DevToolsEmulator::DevToolsEmulator(WebViewImpl* web_view)
    : web_view_(web_view),
      device_metrics_enabled_(false),
      emulate_mobile_enabled_(false),
      is_overlay_scrollbars_enabled_(false),
      is_orientation_event_enabled_(false),
      is_mobile_layout_theme_enabled_(false),
      original_default_minimum_page_scale_factor_(0),
      original_default_maximum_page_scale_factor_(0),
      use_solid_color_scrollbar_(false),
      embedder_text_autosizing_enabled_(
          web_view->GetPage()->GetSettings().TextAutosizingEnabled()),
      embedder_device_scale_adjustment_(
          web_view->GetPage()->GetSettings().GetDeviceScaleAdjustment()),
      embedder_prefer_compositing_to_lcd_text_enabled_(
          web_view->GetPage()
              ->GetSettings()
              .GetPreferCompositingToLCDTextEnabled()),
      embedder_viewport_style_(
          web_view->GetPage()->GetSettings().GetViewportStyle()),
      embedder_plugins_enabled_(
          web_view->GetPage()->GetSettings().GetPluginsEnabled()),
      embedder_available_pointer_types_(
          web_view->GetPage()->GetSettings().GetAvailablePointerTypes()),
      embedder_primary_pointer_type_(
          web_view->GetPage()->GetSettings().GetPrimaryPointerType()),
      embedder_available_hover_types_(
          web_view->GetPage()->GetSettings().GetAvailableHoverTypes()),
      embedder_primary_hover_type_(
          web_view->GetPage()->GetSettings().GetPrimaryHoverType()),
      embedder_main_frame_resizes_are_orientation_changes_(
          web_view->GetPage()
              ->GetSettings()
              .GetMainFrameResizesAreOrientationChanges()),
      touch_event_emulation_enabled_(false),
      double_tap_to_zoom_enabled_(false),
      original_device_supports_touch_(false),
      original_max_touch_points_(0),
      embedder_script_enabled_(
          web_view->GetPage()->GetSettings().GetScriptEnabled()),
      script_execution_disabled_(false) {}

DevToolsEmulator::~DevToolsEmulator() = default;

DevToolsEmulator* DevToolsEmulator::Create(WebViewImpl* web_view_base) {
  return new DevToolsEmulator(web_view_base);
}

void DevToolsEmulator::Trace(blink::Visitor* visitor) {}

void DevToolsEmulator::SetTextAutosizingEnabled(bool enabled) {
  embedder_text_autosizing_enabled_ = enabled;
  bool emulate_mobile_enabled =
      device_metrics_enabled_ && emulate_mobile_enabled_;
  if (!emulate_mobile_enabled)
    web_view_->GetPage()->GetSettings().SetTextAutosizingEnabled(enabled);
}

void DevToolsEmulator::SetDeviceScaleAdjustment(float device_scale_adjustment) {
  embedder_device_scale_adjustment_ = device_scale_adjustment;
  bool emulate_mobile_enabled =
      device_metrics_enabled_ && emulate_mobile_enabled_;
  if (!emulate_mobile_enabled) {
    web_view_->GetPage()->GetSettings().SetDeviceScaleAdjustment(
        device_scale_adjustment);
  }
}

void DevToolsEmulator::SetPreferCompositingToLCDTextEnabled(bool enabled) {
  embedder_prefer_compositing_to_lcd_text_enabled_ = enabled;
  bool emulate_mobile_enabled =
      device_metrics_enabled_ && emulate_mobile_enabled_;
  if (!emulate_mobile_enabled) {
    web_view_->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
        enabled);
  }
}

void DevToolsEmulator::SetViewportStyle(WebViewportStyle style) {
  embedder_viewport_style_ = style;
  bool emulate_mobile_enabled =
      device_metrics_enabled_ && emulate_mobile_enabled_;
  if (!emulate_mobile_enabled)
    web_view_->GetPage()->GetSettings().SetViewportStyle(style);
}

void DevToolsEmulator::SetPluginsEnabled(bool enabled) {
  embedder_plugins_enabled_ = enabled;
  bool emulate_mobile_enabled =
      device_metrics_enabled_ && emulate_mobile_enabled_;
  if (!emulate_mobile_enabled)
    web_view_->GetPage()->GetSettings().SetPluginsEnabled(enabled);
}

void DevToolsEmulator::SetScriptEnabled(bool enabled) {
  embedder_script_enabled_ = enabled;
  if (!script_execution_disabled_)
    web_view_->GetPage()->GetSettings().SetScriptEnabled(enabled);
}

void DevToolsEmulator::SetDoubleTapToZoomEnabled(bool enabled) {
  double_tap_to_zoom_enabled_ = enabled;
}

bool DevToolsEmulator::DoubleTapToZoomEnabled() const {
  return touch_event_emulation_enabled_ ? true : double_tap_to_zoom_enabled_;
}

void DevToolsEmulator::SetMainFrameResizesAreOrientationChanges(bool value) {
  embedder_main_frame_resizes_are_orientation_changes_ = value;
  bool emulate_mobile_enabled =
      device_metrics_enabled_ && emulate_mobile_enabled_;
  if (!emulate_mobile_enabled) {
    web_view_->GetPage()
        ->GetSettings()
        .SetMainFrameResizesAreOrientationChanges(value);
  }
}

void DevToolsEmulator::SetAvailablePointerTypes(int types) {
  embedder_available_pointer_types_ = types;
  if (!touch_event_emulation_enabled_)
    web_view_->GetPage()->GetSettings().SetAvailablePointerTypes(types);
}

void DevToolsEmulator::SetPrimaryPointerType(PointerType pointer_type) {
  embedder_primary_pointer_type_ = pointer_type;
  if (!touch_event_emulation_enabled_)
    web_view_->GetPage()->GetSettings().SetPrimaryPointerType(pointer_type);
}

void DevToolsEmulator::SetAvailableHoverTypes(int types) {
  embedder_available_hover_types_ = types;
  if (!touch_event_emulation_enabled_)
    web_view_->GetPage()->GetSettings().SetAvailableHoverTypes(types);
}

void DevToolsEmulator::SetPrimaryHoverType(HoverType hover_type) {
  embedder_primary_hover_type_ = hover_type;
  if (!touch_event_emulation_enabled_)
    web_view_->GetPage()->GetSettings().SetPrimaryHoverType(hover_type);
}

void DevToolsEmulator::EnableDeviceEmulation(
    const WebDeviceEmulationParams& params) {
  if (device_metrics_enabled_ &&
      emulation_params_.view_size == params.view_size &&
      emulation_params_.screen_position == params.screen_position &&
      emulation_params_.device_scale_factor == params.device_scale_factor &&
      emulation_params_.scale == params.scale &&
      emulation_params_.viewport_offset == params.viewport_offset &&
      emulation_params_.viewport_scale == params.viewport_scale) {
    return;
  }
  if (emulation_params_.device_scale_factor != params.device_scale_factor ||
      !device_metrics_enabled_)
    GetMemoryCache()->EvictResources();

  emulation_params_ = params;
  device_metrics_enabled_ = true;

  web_view_->GetPage()->GetSettings().SetDeviceScaleAdjustment(
      calculateDeviceScaleAdjustment(params.view_size.width,
                                     params.view_size.height,
                                     params.device_scale_factor));

  if (params.screen_position == WebDeviceEmulationParams::kMobile)
    EnableMobileEmulation();
  else
    DisableMobileEmulation();

  web_view_->SetCompositorDeviceScaleFactorOverride(params.device_scale_factor);
  if (params.viewport_offset.x >= 0)
    ForceViewport(params.viewport_offset, params.viewport_scale);
  else
    ResetViewport();

  // TODO(dgozman): mainFrameImpl() is null when it's remote. Figure out how
  // we end up with enabling emulation in this case.
  if (web_view_->MainFrameImpl()) {
    if (Document* document =
            web_view_->MainFrameImpl()->GetFrame()->GetDocument())
      document->MediaQueryAffectingValueChanged();
  }
}

void DevToolsEmulator::DisableDeviceEmulation() {
  if (!device_metrics_enabled_)
    return;

  GetMemoryCache()->EvictResources();
  device_metrics_enabled_ = false;
  web_view_->GetPage()->GetSettings().SetDeviceScaleAdjustment(
      embedder_device_scale_adjustment_);
  DisableMobileEmulation();
  web_view_->SetCompositorDeviceScaleFactorOverride(0.f);
  web_view_->SetPageScaleFactor(1.f);
  ResetViewport();
  // mainFrameImpl() could be null during cleanup or remote <-> local swap.
  if (web_view_->MainFrameImpl()) {
    if (Document* document =
            web_view_->MainFrameImpl()->GetFrame()->GetDocument())
      document->MediaQueryAffectingValueChanged();
  }
}

void DevToolsEmulator::EnableMobileEmulation() {
  if (emulate_mobile_enabled_)
    return;
  emulate_mobile_enabled_ = true;
  is_overlay_scrollbars_enabled_ =
      RuntimeEnabledFeatures::OverlayScrollbarsEnabled();
  RuntimeEnabledFeatures::SetOverlayScrollbarsEnabled(true);
  is_orientation_event_enabled_ =
      RuntimeEnabledFeatures::OrientationEventEnabled();
  RuntimeEnabledFeatures::SetOrientationEventEnabled(true);
  is_mobile_layout_theme_enabled_ =
      RuntimeEnabledFeatures::MobileLayoutThemeEnabled();
  RuntimeEnabledFeatures::SetMobileLayoutThemeEnabled(true);
  ComputedStyle::InvalidateInitialStyle();
  web_view_->GetPage()->GetSettings().SetForceAndroidOverlayScrollbar(true);
  use_solid_color_scrollbar_ =
      web_view_->GetPage()->GetSettings().GetUseSolidColorScrollbars();
  web_view_->GetPage()->GetSettings().SetUseSolidColorScrollbars(true);
  web_view_->GetPage()->GetSettings().SetViewportStyle(
      WebViewportStyle::kMobile);
  web_view_->GetPage()->GetSettings().SetViewportEnabled(true);
  web_view_->GetPage()->GetSettings().SetViewportMetaEnabled(true);
  web_view_->GetPage()->GetVisualViewport().InitializeScrollbars();
  web_view_->GetSettings()->SetShrinksViewportContentToFit(true);
  web_view_->GetPage()->GetSettings().SetTextAutosizingEnabled(true);
  web_view_->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
      true);
  web_view_->GetPage()->GetSettings().SetPluginsEnabled(false);
  web_view_->GetPage()->GetSettings().SetMainFrameResizesAreOrientationChanges(
      true);
  web_view_->SetZoomFactorOverride(1);

  original_default_minimum_page_scale_factor_ =
      web_view_->DefaultMinimumPageScaleFactor();
  original_default_maximum_page_scale_factor_ =
      web_view_->DefaultMaximumPageScaleFactor();
  web_view_->SetDefaultPageScaleLimits(0.25f, 5);
  // TODO(dgozman): mainFrameImpl() is null when it's remote. Figure out how
  // we end up with enabling emulation in this case.
  if (web_view_->MainFrameImpl())
    web_view_->MainFrameImpl()->GetFrameView()->UpdateLayout();
}

void DevToolsEmulator::DisableMobileEmulation() {
  if (!emulate_mobile_enabled_)
    return;
  RuntimeEnabledFeatures::SetOverlayScrollbarsEnabled(
      is_overlay_scrollbars_enabled_);
  RuntimeEnabledFeatures::SetOrientationEventEnabled(
      is_orientation_event_enabled_);
  RuntimeEnabledFeatures::SetMobileLayoutThemeEnabled(
      is_mobile_layout_theme_enabled_);
  ComputedStyle::InvalidateInitialStyle();
  web_view_->GetPage()->GetSettings().SetUseSolidColorScrollbars(
      use_solid_color_scrollbar_);
  web_view_->GetPage()->GetSettings().SetForceAndroidOverlayScrollbar(false);
  web_view_->GetPage()->GetSettings().SetViewportEnabled(false);
  web_view_->GetPage()->GetSettings().SetViewportMetaEnabled(false);
  web_view_->GetPage()->GetVisualViewport().InitializeScrollbars();
  web_view_->GetSettings()->SetShrinksViewportContentToFit(false);
  web_view_->GetPage()->GetSettings().SetTextAutosizingEnabled(
      embedder_text_autosizing_enabled_);
  web_view_->GetPage()->GetSettings().SetPreferCompositingToLCDTextEnabled(
      embedder_prefer_compositing_to_lcd_text_enabled_);
  web_view_->GetPage()->GetSettings().SetViewportStyle(
      embedder_viewport_style_);
  web_view_->GetPage()->GetSettings().SetPluginsEnabled(
      embedder_plugins_enabled_);
  web_view_->GetPage()->GetSettings().SetMainFrameResizesAreOrientationChanges(
      embedder_main_frame_resizes_are_orientation_changes_);
  web_view_->SetZoomFactorOverride(0);
  emulate_mobile_enabled_ = false;
  web_view_->SetDefaultPageScaleLimits(
      original_default_minimum_page_scale_factor_,
      original_default_maximum_page_scale_factor_);
  // mainFrameImpl() could be null during cleanup or remote <-> local swap.
  if (web_view_->MainFrameImpl())
    web_view_->MainFrameImpl()->GetFrameView()->UpdateLayout();
}

float DevToolsEmulator::CompositorDeviceScaleFactor() const {
  if (device_metrics_enabled_)
    return emulation_params_.device_scale_factor;
  return web_view_->GetPage()->DeviceScaleFactorDeprecated();
}

void DevToolsEmulator::ForceViewport(const WebFloatPoint& position,
                                     float scale) {
  GraphicsLayer* container_layer =
      web_view_->GetPage()->GetVisualViewport().ContainerLayer();
  if (!viewport_override_) {
    viewport_override_ = ViewportOverride();

    // Disable clipping on the visual viewport layer, to ensure the whole area
    // is painted.
    if (container_layer) {
      viewport_override_->original_visual_viewport_masking =
          container_layer->MasksToBounds();
      container_layer->SetMasksToBounds(false);
    }
  }

  viewport_override_->position = position;
  viewport_override_->scale = scale;

  // Move the correct (scaled) content area to show in the top left of the
  // CompositorFrame via the root transform.
  UpdateRootLayerTransform();
}

void DevToolsEmulator::ResetViewport() {
  if (!viewport_override_) {
    UpdateRootLayerTransform();
    return;
  }

  bool original_masking = viewport_override_->original_visual_viewport_masking;
  viewport_override_ = WTF::nullopt;

  GraphicsLayer* container_layer =
      web_view_->GetPage()->GetVisualViewport().ContainerLayer();
  if (container_layer)
    container_layer->SetMasksToBounds(original_masking);

  UpdateRootLayerTransform();
}

void DevToolsEmulator::MainFrameScrollOrScaleChanged() {
  // Viewport override has to take current page scale and scroll offset into
  // account. Update the transform if override is active.
  if (viewport_override_)
    UpdateRootLayerTransform();
}

void DevToolsEmulator::ApplyDeviceEmulationTransform(
    TransformationMatrix* transform) {
  if (device_metrics_enabled_) {
    transform->Scale(emulation_params_.scale);
    if (web_view_->MainFrameImpl()) {
      web_view_->MainFrameImpl()->SetInputEventsScaleForEmulation(
          emulation_params_.scale);
    }
  } else {
    if (web_view_->MainFrameImpl()) {
      web_view_->MainFrameImpl()->SetInputEventsScaleForEmulation(1.0);
    }
  }
}

void DevToolsEmulator::ApplyViewportOverride(TransformationMatrix* transform) {
  if (!viewport_override_)
    return;

  // Transform operations follow in reverse application.
  // Last, scale positioned area according to override.
  transform->Scale(viewport_override_->scale);

  // Translate while taking into account current scroll offset.
  // TODO(lukasza): https://crbug.com/734201: Add OOPIF support.
  WebSize scroll_offset =
      web_view_->MainFrame()->IsWebLocalFrame()
          ? web_view_->MainFrame()->ToWebLocalFrame()->GetScrollOffset()
          : WebSize();
  WebFloatPoint visual_offset = web_view_->VisualViewportOffset();
  float scroll_x = scroll_offset.width + visual_offset.x;
  float scroll_y = scroll_offset.height + visual_offset.y;
  transform->Translate(-viewport_override_->position.x + scroll_x,
                       -viewport_override_->position.y + scroll_y);

  // First, reverse page scale, so we don't have to take it into account for
  // calculation of the translation.
  transform->Scale(1. / web_view_->PageScaleFactor());
}

void DevToolsEmulator::UpdateRootLayerTransform() {
  TransformationMatrix transform;

  // Apply device emulation transform first, so that it is affected by the
  // viewport override.
  ApplyViewportOverride(&transform);
  ApplyDeviceEmulationTransform(&transform);
  web_view_->SetDeviceEmulationTransform(transform);
}

WTF::Optional<IntRect> DevToolsEmulator::VisibleContentRectForPainting() const {
  if (!viewport_override_)
    return WTF::nullopt;
  FloatSize viewport_size(web_view_->LayerTreeView()->GetViewportSize());
  viewport_size.Scale(1. / CompositorDeviceScaleFactor());
  viewport_size.Scale(1. / viewport_override_->scale);
  return EnclosingIntRect(
      FloatRect(viewport_override_->position.x, viewport_override_->position.y,
                viewport_size.Width(), viewport_size.Height()));
}

void DevToolsEmulator::SetTouchEventEmulationEnabled(bool enabled,
                                                     int max_touch_points) {
  if (!touch_event_emulation_enabled_) {
    original_device_supports_touch_ =
        web_view_->GetPage()->GetSettings().GetDeviceSupportsTouch();
    original_max_touch_points_ =
        web_view_->GetPage()->GetSettings().GetMaxTouchPoints();
  }
  touch_event_emulation_enabled_ = enabled;
  web_view_->GetPage()
      ->GetSettings()
      .SetForceTouchEventFeatureDetectionForInspector(enabled);
  web_view_->GetPage()->GetSettings().SetDeviceSupportsTouch(
      enabled ? true : original_device_supports_touch_);
  web_view_->GetPage()->GetSettings().SetMaxTouchPoints(
      enabled ? max_touch_points : original_max_touch_points_);
  web_view_->GetPage()->GetSettings().SetAvailablePointerTypes(
      enabled ? kPointerTypeCoarse : embedder_available_pointer_types_);
  web_view_->GetPage()->GetSettings().SetPrimaryPointerType(
      enabled ? kPointerTypeCoarse : embedder_primary_pointer_type_);
  web_view_->GetPage()->GetSettings().SetAvailableHoverTypes(
      enabled ? kHoverTypeNone : embedder_available_hover_types_);
  web_view_->GetPage()->GetSettings().SetPrimaryHoverType(
      enabled ? kHoverTypeNone : embedder_primary_hover_type_);
  WebLocalFrameImpl* frame = web_view_->MainFrameImpl();
  if (!original_device_supports_touch_ && enabled && frame)
    frame->GetFrame()->GetEventHandler().ClearMouseEventManager();
}

void DevToolsEmulator::SetScriptExecutionDisabled(
    bool script_execution_disabled) {
  script_execution_disabled_ = script_execution_disabled;
  web_view_->GetPage()->GetSettings().SetScriptEnabled(
      script_execution_disabled_ ? false : embedder_script_enabled_);
}

bool DevToolsEmulator::HandleInputEvent(const WebInputEvent& input_event) {
  Page* page = web_view_->GetPage();
  if (!page)
    return false;

  if (!touch_event_emulation_enabled_ ||
      !WebInputEvent::IsPinchGestureEventType(input_event.GetType())) {
    return false;
  }

  // FIXME: This workaround is required for touch emulation on Mac, where
  // compositor-side pinch handling is not enabled. See http://crbug.com/138003.
  // TODO(lukasza): https://crbug.com/734201: Add OOPIF support.
  LocalFrameView* frame_view = page->DeprecatedLocalMainFrame()->View();
  WebGestureEvent scaled_event = TransformWebGestureEvent(
      frame_view, static_cast<const WebGestureEvent&>(input_event));
  float page_scale_factor = page->PageScaleFactor();
  if (scaled_event.GetType() == WebInputEvent::kGesturePinchBegin) {
    WebFloatPoint gesture_position = scaled_event.PositionInRootFrame();
    last_pinch_anchor_css_ = WTF::WrapUnique(new IntPoint(
        RoundedIntPoint(gesture_position + frame_view->GetScrollOffset())));
    last_pinch_anchor_dip_ =
        WTF::WrapUnique(new IntPoint(FlooredIntPoint(gesture_position)));
    last_pinch_anchor_dip_->Scale(page_scale_factor, page_scale_factor);
  }
  if (scaled_event.GetType() == WebInputEvent::kGesturePinchUpdate &&
      last_pinch_anchor_css_) {
    float new_page_scale_factor = page_scale_factor * scaled_event.PinchScale();
    IntPoint anchor_css(*last_pinch_anchor_dip_.get());
    anchor_css.Scale(1.f / new_page_scale_factor, 1.f / new_page_scale_factor);
    web_view_->SetPageScaleFactor(new_page_scale_factor);
    // TODO(lukasza): https://crbug.com/734201: Add OOPIF support.
    if (web_view_->MainFrame()->IsWebLocalFrame()) {
      web_view_->MainFrame()->ToWebLocalFrame()->SetScrollOffset(
          ToIntSize(*last_pinch_anchor_css_.get() - ToIntSize(anchor_css)));
    }
  }
  if (scaled_event.GetType() == WebInputEvent::kGesturePinchEnd) {
    last_pinch_anchor_css_.reset();
    last_pinch_anchor_dip_.reset();
  }
  return true;
}

}  // namespace blink
