// Copyright 2016 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 "ash/display/touch_calibrator_controller.h"

#include <algorithm>
#include <memory>

#include "ash/display/touch_calibrator_view.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/host/ash_window_tree_host.h"
#include "ash/shell.h"
#include "ash/touch/ash_touch_transform_controller.h"
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "ui/aura/window_tree_host.h"
#include "ui/display/manager/touch_device_manager.h"
#include "ui/display/screen.h"
#include "ui/events/devices/input_device_manager.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/geometry/size_conversions.h"

namespace ash {
namespace {

void InitInternalTouchDeviceIds(std::set<int>& internal_touch_device_ids) {
  internal_touch_device_ids.clear();
  const std::vector<ui::TouchscreenDevice>& device_list =
      ui::InputDeviceManager::GetInstance()->GetTouchscreenDevices();
  for (const auto& touchscreen_device : device_list) {
    if (touchscreen_device.type == ui::InputDeviceType::INPUT_DEVICE_INTERNAL)
      internal_touch_device_ids.insert(touchscreen_device.id);
  }
}

// Returns a transform to undo any transformations that are applied to events
// originating from the touch device identified with |touch_device_id|. This
// transform converts the event's location to the raw touch location.
gfx::Transform CalculateEventTransformer(int touch_device_id) {
  const display::DisplayManager* display_manager =
      Shell::Get()->display_manager();
  const std::vector<ui::TouchscreenDevice>& device_list =
      ui::InputDeviceManager::GetInstance()->GetTouchscreenDevices();

  auto device_it = std::find_if(
      device_list.begin(), device_list.end(),
      [&](const auto& device) { return device.id == touch_device_id; });
  DCHECK(device_it != device_list.end())
      << "Device id " << touch_device_id
      << " is invalid. No such device connected to system";

  int64_t previous_display_id =
      display_manager->touch_device_manager()->GetAssociatedDisplay(
          display::TouchDeviceIdentifier::FromDevice(*device_it));

  // If the touch device is not associated with any display. This may happen in
  // tests when the test does not setup the |ui::TouchDeviceTransform| before
  // generating a touch event.
  if (previous_display_id == display::kInvalidDisplayId)
    return gfx::Transform();

  // Undo the event transformations that the previous display applied on the
  // event location. We want to store the raw event location information.
  gfx::Transform tm =
      Shell::Get()
          ->window_tree_host_manager()
          ->GetAshWindowTreeHostForDisplayId(previous_display_id)
          ->AsWindowTreeHost()
          ->GetRootTransform();
  return tm;
}

}  // namespace

// Time interval after a touch event during which all other touch events are
// ignored during calibration.
const base::TimeDelta TouchCalibratorController::kTouchIntervalThreshold =
    base::TimeDelta::FromMilliseconds(200);

TouchCalibratorController::TouchCalibratorController()
    : last_touch_timestamp_(base::Time::Now()) {}

TouchCalibratorController::~TouchCalibratorController() {
  touch_calibrator_views_.clear();
  StopCalibrationAndResetParams();
}

void TouchCalibratorController::OnDisplayConfigurationChanged() {
  touch_calibrator_views_.clear();
  StopCalibrationAndResetParams();
}

void TouchCalibratorController::StartCalibration(
    const display::Display& target_display,
    bool is_custom_calibration,
    TouchCalibrationCallback opt_callback) {
  state_ = is_custom_calibration ? CalibrationState::kCustomCalibration
                                 : CalibrationState::kNativeCalibration;

  if (opt_callback)
    opt_callback_ = std::move(opt_callback);

  target_display_ = target_display;

  // Clear all touch calibrator views used in any previous calibration.
  touch_calibrator_views_.clear();

  // Set the touch device id as invalid so it can be set during calibration.
  touch_device_id_ = ui::InputDevice::kInvalidId;

  // Populate |internal_touch_device_ids_| with the ids of touch devices that
  // are currently associated with the internal display and are of type
  // |ui::InputDeviceType::INPUT_DEVICE_INTERNAL|.
  InitInternalTouchDeviceIds(internal_touch_device_ids_);

  // If this is a native touch calibration, then initialize the UX for it.
  if (state_ == CalibrationState::kNativeCalibration) {
    Shell::Get()->window_tree_host_manager()->AddObserver(this);

    // Reset the calibration data.
    touch_point_quad_.fill(std::make_pair(gfx::Point(0, 0), gfx::Point(0, 0)));

    std::vector<display::Display> displays =
        display::Screen::GetScreen()->GetAllDisplays();

    for (const display::Display& display : displays) {
      bool is_primary_view = display.id() == target_display_.id();
      touch_calibrator_views_[display.id()] =
          std::make_unique<TouchCalibratorView>(display, is_primary_view);
    }
  }

  Shell::Get()->touch_transformer_controller()->SetForCalibration(true);

  // Add self as an event handler target.
  Shell::Get()->AddPreTargetHandler(this);
}

void TouchCalibratorController::StopCalibrationAndResetParams() {
  if (!IsCalibrating())
    return;
  Shell::Get()->window_tree_host_manager()->RemoveObserver(this);

  Shell::Get()->touch_transformer_controller()->SetForCalibration(false);

  // Remove self as the event handler.
  Shell::Get()->RemovePreTargetHandler(this);

  // Transition all touch calibrator views to their final state for a graceful
  // exit if this is touch calibration with native UX.
  if (state_ == CalibrationState::kNativeCalibration) {
    for (const auto& it : touch_calibrator_views_)
      it.second->SkipToFinalState();
  }

  state_ = CalibrationState::kInactive;

  if (opt_callback_) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(opt_callback_), false /* failure */));
    opt_callback_.Reset();
  }
}

void TouchCalibratorController::CompleteCalibration(
    const CalibrationPointPairQuad& pairs,
    const gfx::Size& display_size) {
  bool did_find_touch_device = false;
  display::TouchDeviceIdentifier touch_device_identifier =
      display::TouchDeviceIdentifier::GetFallbackTouchDeviceIdentifier();

  const std::vector<ui::TouchscreenDevice>& device_list =
      ui::InputDeviceManager::GetInstance()->GetTouchscreenDevices();
  for (const auto& device : device_list) {
    if (device.id == touch_device_id_) {
      touch_device_identifier =
          display::TouchDeviceIdentifier::FromDevice(device);
      did_find_touch_device = true;
      break;
    }
  }

  if (!did_find_touch_device) {
    VLOG(1) << "No touch device with id: " << touch_device_id_ << " found to "
            << "complete touch calibration for display with id: "
            << target_display_.id() << ". Storing it as a fallback";
  } else if (touch_device_identifier ==
             display::TouchDeviceIdentifier::
                 GetFallbackTouchDeviceIdentifier()) {
    LOG(ERROR)
        << "Hash collision in generating touch device identifier for "
        << " device. Hash Generated: " << touch_device_identifier
        << " || Fallback touch device identifier: "
        << display::TouchDeviceIdentifier::GetFallbackTouchDeviceIdentifier();
  }

  if (opt_callback_) {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(opt_callback_), true /* success */));
    opt_callback_.Reset();
  }
  StopCalibrationAndResetParams();
  Shell::Get()->display_manager()->SetTouchCalibrationData(
      target_display_.id(), pairs, display_size, touch_device_identifier);
}

bool TouchCalibratorController::IsCalibrating() const {
  return state_ != CalibrationState::kInactive;
}

// ui::EventHandler:
void TouchCalibratorController::OnKeyEvent(ui::KeyEvent* key) {
  if (state_ != CalibrationState::kNativeCalibration)
    return;
  // Detect ESC key press.
  if (key->type() == ui::ET_KEY_PRESSED && key->key_code() == ui::VKEY_ESCAPE)
    StopCalibrationAndResetParams();

  key->StopPropagation();
}

void TouchCalibratorController::OnTouchEvent(ui::TouchEvent* touch) {
  if (!IsCalibrating())
    return;
  if (touch->type() != ui::ET_TOUCH_RELEASED)
    return;
  if (base::Time::Now() - last_touch_timestamp_ < kTouchIntervalThreshold)
    return;
  last_touch_timestamp_ = base::Time::Now();

  // If the touch event originated from a touch device that is associated with
  // the internal display, then ignore it.
  if (internal_touch_device_ids_.count(touch->source_device_id()))
    return;

  if (touch_device_id_ == ui::InputDevice::kInvalidId) {
    touch_device_id_ = touch->source_device_id();
    event_transformer_ = CalculateEventTransformer(touch_device_id_);
  }

  // If this is a custom touch calibration, then everything else is managed
  // by the application responsible for the custom calibration UX.
  if (state_ == CalibrationState::kCustomCalibration)
    return;
  touch->StopPropagation();

  TouchCalibratorView* target_screen_calibration_view =
      touch_calibrator_views_[target_display_.id()].get();

  // If this is the final state, then store all calibration data and stop
  // calibration.
  if (target_screen_calibration_view->state() ==
      TouchCalibratorView::CALIBRATION_COMPLETE) {
    gfx::RectF calibration_bounds(
        target_screen_calibration_view->GetLocalBounds());
    Shell::Get()
        ->window_tree_host_manager()
        ->GetAshWindowTreeHostForDisplayId(target_display_.id())
        ->AsWindowTreeHost()
        ->GetRootTransform()
        .TransformRect(&calibration_bounds);
    CompleteCalibration(touch_point_quad_,
                        gfx::ToRoundedSize(calibration_bounds.size()));
    return;
  }

  int state_index;
  // Maps the state to an integer value. Assigns a non negative integral value
  // for a state in which the user can interact with the the interface.
  switch (target_screen_calibration_view->state()) {
    case TouchCalibratorView::DISPLAY_POINT_1:
      state_index = 0;
      break;
    case TouchCalibratorView::DISPLAY_POINT_2:
      state_index = 1;
      break;
    case TouchCalibratorView::DISPLAY_POINT_3:
      state_index = 2;
      break;
    case TouchCalibratorView::DISPLAY_POINT_4:
      state_index = 3;
      break;
    default:
      // Return early if the interface is in a state that does not allow user
      // interaction.
      return;
  }

  // Store touch point corresponding to its display point.
  gfx::Point display_point;
  if (target_screen_calibration_view->GetDisplayPointLocation(&display_point)) {
    // If the screen has a root transform applied, the display point does not
    // correctly map to the touch point. This is specially evident if the
    // display is rotated or a device scale factor is applied. The display point
    // needs to have the root transform applied as well to correctly pair it
    // with the touch point.
    Shell::Get()
        ->window_tree_host_manager()
        ->GetAshWindowTreeHostForDisplayId(target_display_.id())
        ->AsWindowTreeHost()
        ->GetRootTransform()
        .TransformPoint(&display_point);

    // Why do we need this? To understand this we need to know the life of an
    // event location. The event location undergoes the following
    // transformations along its path from the device to the event handler that
    // is this class.
    //
    // Touch Device -> EventFactoryEvdev -> DrmWindowHost
    //     -> WindowEventDispatcher -> EventHandler(this)
    //
    //  - The touch device dispatches the raw device event location. Lets assume
    //    this is (x, y).
    //  - The EventFactoryEvdev applies a touch transform that includes the
    //    calibration information as well as an offset of the native bounds
    //    of the display. This effectively converts the coordinates of the event
    //    from the raw device event location to the native screen coordinates.
    //    It gets the offset information from DrmWindowHost via the
    //    ManagedDisplayInfo class. If the offset of the PlatformWindow is (A,B)
    //    then the event location after this stage would be (x + A, y + B).
    //  - The DrmWindowHost removes the offset from the event location so that
    //    the location becomes relative to the platform window's origin. In
    //    Chrome OS it so happens that each display is its own platform window.
    //    So an offset equal to the display's origin in screen space is
    //    subtracted from the event location. This effectively undoes the
    //    previous step's transformation. Thus the event location after this
    //    step is (x, y) again.
    //  - WindowEventDispatcher applies an inverse root transform on the event
    //    location. This means that if the display is rotated or has a device
    //    scale factor, then those transformation are also applied to the event
    //    location. It effectively converts the coordinates from platform window
    //    coordinates to the aura's root window coordinates. The display in
    //    context here is the display that is associated with the touch device
    //    from which the event originated from.
    //
    // Up until the output of DrmWindowHost, everything is as expected. But
    // WindowEventDispatcher applies an inverse root transform which modifies
    // the raw event location that we wanted. Moreover, it modifies the raw
    // event location using the root transform of the display that the touch
    // device was previously associated with. To solve this, we need to undo the
    // changes made to the event location by WindowEventDispatcher. This is what
    // is achieved by |event_transformer_|.
    gfx::PointF event_location_f(touch->location_f());
    event_transformer_.TransformPoint(&event_location_f);

    touch_point_quad_[state_index] =
        std::make_pair(display_point, gfx::ToRoundedPoint(event_location_f));
  } else {
    // TODO(malaykeshav): Display some kind of error for the user.
    NOTREACHED() << "Touch calibration failed. Could not retrieve location for"
                    " display point. Retry calibration.";
  }

  target_screen_calibration_view->AdvanceToNextState();
}

}  // namespace ash
