// 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 "remoting/host/touch_injector_win.h"

#include <stddef.h>
#include <stdint.h>

#include <map>
#include <utility>

#include "base/stl_util.h"
#include "remoting/proto/event.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::InSequence;
using ::testing::ExpectationSet;
using ::testing::Return;

namespace remoting {

using protocol::TouchEvent;
using protocol::TouchEventPoint;

namespace {

// Maps touch pointer ID to expected flags [start, move, end, cancel] listed
// below.
typedef std::map<uint32_t, uint32_t> IdFlagMap;

const uint32_t kStartFlag =
    POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT | POINTER_FLAG_DOWN;

const uint32_t kMoveFlag =
    POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT | POINTER_FLAG_UPDATE;

const uint32_t kEndFlag = POINTER_FLAG_UP;

const uint32_t kCancelFlag = POINTER_FLAG_UP | POINTER_FLAG_CANCELED;

MATCHER_P(EqualsSinglePointerTouchInfo, expected, "") {
  return arg->touchMask == expected.touchMask &&
         arg->rcContact.left == expected.rcContact.left &&
         arg->rcContact.top == expected.rcContact.top &&
         arg->rcContact.right == expected.rcContact.right &&
         arg->rcContact.bottom == expected.rcContact.bottom &&
         arg->orientation == expected.orientation &&
         arg->pressure == expected.pressure &&
         arg->pointerInfo.pointerType == expected.pointerInfo.pointerType &&
         arg->pointerInfo.pointerId == expected.pointerInfo.pointerId &&
         arg->pointerInfo.ptPixelLocation.x ==
             expected.pointerInfo.ptPixelLocation.x &&
         arg->pointerInfo.ptPixelLocation.y ==
             expected.pointerInfo.ptPixelLocation.y;
}

// Make sure that every touch point has the right flag (pointerFlags).
MATCHER_P(EqualsPointerTouchInfoFlag, id_to_flag_map, "") {
  for (size_t i = 0; i < id_to_flag_map.size(); ++i) {
    const POINTER_TOUCH_INFO* touch_info = arg + i;
    const uint32_t id = touch_info->pointerInfo.pointerId;
    if (!base::ContainsKey(id_to_flag_map, id))
      return false;

    if (id_to_flag_map.find(id)->second != touch_info->pointerInfo.pointerFlags)
      return false;
  }
  return true;
}

class TouchInjectorWinDelegateMock : public TouchInjectorWinDelegate {
 public:
  TouchInjectorWinDelegateMock()
      : TouchInjectorWinDelegate(nullptr, nullptr, nullptr) {}
  ~TouchInjectorWinDelegateMock() override {}

  MOCK_METHOD2(InitializeTouchInjection, BOOL(UINT32 max_count, DWORD dw_mode));
  MOCK_METHOD2(InjectTouchInput,
               DWORD(UINT32 count, const POINTER_TOUCH_INFO* contacts));
};

}  // namespace

// A test to make sure that the touch event is converted correctly to
// POINTER_TOUCH_INFO.
TEST(TouchInjectorWinTest, CheckConversionWithPressure) {
  std::unique_ptr<TouchInjectorWinDelegateMock> delegate_mock(
      new ::testing::StrictMock<TouchInjectorWinDelegateMock>());

  TouchEvent event;
  event.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point = event.add_touch_points();
  point->set_id(1234u);
  point->set_x(321.0f);
  point->set_y(123.0f);
  point->set_radius_x(10.0f);
  point->set_radius_y(20.0f);
  point->set_pressure(0.5f);
  point->set_angle(45.0f);

  POINTER_TOUCH_INFO expected_touch_info;
  expected_touch_info.touchMask =
      TOUCH_MASK_CONTACTAREA | TOUCH_MASK_ORIENTATION | TOUCH_MASK_PRESSURE;
  expected_touch_info.rcContact.left = 311;
  expected_touch_info.rcContact.top = 103;
  expected_touch_info.rcContact.right = 331;
  expected_touch_info.rcContact.bottom = 143;
  expected_touch_info.orientation = 0;
  expected_touch_info.pressure = 512;
  expected_touch_info.orientation = 45;

  expected_touch_info.pointerInfo.pointerType = PT_TOUCH;
  expected_touch_info.pointerInfo.pointerId = 1234u;
  expected_touch_info.pointerInfo.ptPixelLocation.x = 321;
  expected_touch_info.pointerInfo.ptPixelLocation.y = 123;

  InSequence s;
  EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
      .WillOnce(Return(1));
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
      .WillOnce(Return(1));

  // Check pressure clamping as well.
  expected_touch_info.pressure = 1024;  // Max
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
      .WillOnce(Return(1));

  expected_touch_info.pressure = 0;  // Min
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
      .WillOnce(Return(1));

  TouchInjectorWin injector;
  injector.SetInjectorDelegateForTest(std::move(delegate_mock));
  EXPECT_TRUE(injector.Init());
  injector.InjectTouchEvent(event);

  // Change to MOVE so that there still only one point.
  event.set_event_type(TouchEvent::TOUCH_POINT_MOVE);
  point->set_pressure(2.0f);
  injector.InjectTouchEvent(event);

  point->set_pressure(-3.0f);
  injector.InjectTouchEvent(event);
}

// Some devices don't detect pressure. This test is a conversion check for
// such devices.
TEST(TouchInjectorWinTest, CheckConversionNoPressure) {
  std::unique_ptr<TouchInjectorWinDelegateMock> delegate_mock(
      new ::testing::StrictMock<TouchInjectorWinDelegateMock>());

  TouchEvent event;
  event.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point = event.add_touch_points();
  point->set_id(1234u);
  point->set_x(321.0f);
  point->set_y(123.0f);
  point->set_radius_x(10.0f);
  point->set_radius_y(20.0f);
  point->set_angle(45.0f);

  POINTER_TOUCH_INFO expected_touch_info;
  expected_touch_info.touchMask =
      TOUCH_MASK_CONTACTAREA | TOUCH_MASK_ORIENTATION;
  expected_touch_info.rcContact.left = 311;
  expected_touch_info.rcContact.top = 103;
  expected_touch_info.rcContact.right = 331;
  expected_touch_info.rcContact.bottom = 143;
  expected_touch_info.orientation = 0;
  expected_touch_info.pressure = 0;
  expected_touch_info.orientation = 45;

  expected_touch_info.pointerInfo.pointerType = PT_TOUCH;
  expected_touch_info.pointerInfo.pointerId = 1234u;
  expected_touch_info.pointerInfo.ptPixelLocation.x = 321;
  expected_touch_info.pointerInfo.ptPixelLocation.y = 123;

  InSequence s;
  EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
      .WillOnce(Return(1));
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsSinglePointerTouchInfo(expected_touch_info)))
      .WillOnce(Return(1));

  TouchInjectorWin injector;
  injector.SetInjectorDelegateForTest(std::move(delegate_mock));
  EXPECT_TRUE(injector.Init());
  injector.InjectTouchEvent(event);
}

// If initialization fails, it should not call any touch injection functions.
TEST(TouchInjectorWinTest, InitFailed) {
  std::unique_ptr<TouchInjectorWinDelegateMock> delegate_mock(
      new ::testing::StrictMock<TouchInjectorWinDelegateMock>());

  TouchEvent event;
  event.set_event_type(TouchEvent::TOUCH_POINT_START);

  InSequence s;
  EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
      .WillOnce(Return(0));
  EXPECT_CALL(*delegate_mock, InjectTouchInput(_, _)).Times(0);

  TouchInjectorWin injector;
  injector.SetInjectorDelegateForTest(std::move(delegate_mock));
  EXPECT_FALSE(injector.Init());
  injector.InjectTouchEvent(event);
}

// Deinitialize and initialize should clean the state.
TEST(TouchInjectorWinTest, Reinitialize) {
  std::unique_ptr<TouchInjectorWinDelegateMock>
      delegate_mock_before_deinitialize(
          new ::testing::StrictMock<TouchInjectorWinDelegateMock>());
  std::unique_ptr<TouchInjectorWinDelegateMock>
      delegate_mock_after_deinitialize(
          new ::testing::StrictMock<TouchInjectorWinDelegateMock>());

  TouchEvent first_event;
  first_event.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point0 = first_event.add_touch_points();
  point0->set_id(0u);

  TouchEvent second_event;
  second_event.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point1 = second_event.add_touch_points();
  point1->set_id(1u);

  InSequence s;
  EXPECT_CALL(*delegate_mock_before_deinitialize,
              InitializeTouchInjection(_, _)).WillOnce(Return(1));

  IdFlagMap id_to_flags;
  id_to_flags[0u] = kStartFlag;
  EXPECT_CALL(
      *delegate_mock_before_deinitialize,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  EXPECT_CALL(*delegate_mock_after_deinitialize,
              InitializeTouchInjection(_, _)).WillOnce(Return(1));

  // After deinitializing and then initializing, previous touch points should be
  // gone.
  id_to_flags.clear();
  id_to_flags[1u] = kStartFlag;
  EXPECT_CALL(
      *delegate_mock_after_deinitialize,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  TouchInjectorWin injector;
  injector.SetInjectorDelegateForTest(
      std::move(delegate_mock_before_deinitialize));

  EXPECT_TRUE(injector.Init());
  injector.InjectTouchEvent(first_event);
  injector.Deinitialize();

  injector.SetInjectorDelegateForTest(
      std::move(delegate_mock_after_deinitialize));
  EXPECT_TRUE(injector.Init());
  injector.InjectTouchEvent(second_event);
}

// Make sure that the flag is set to kStartFlag.
TEST(TouchInjectorWinTest, StartTouchPoint) {
  std::unique_ptr<TouchInjectorWinDelegateMock> delegate_mock(
      new ::testing::StrictMock<TouchInjectorWinDelegateMock>());

  TouchEvent event;
  event.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point = event.add_touch_points();
  point->set_id(0u);

  InSequence s;
  EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
      .WillOnce(Return(1));

  IdFlagMap id_to_flags;
  id_to_flags[0u] = kStartFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  TouchInjectorWin injector;
  injector.SetInjectorDelegateForTest(std::move(delegate_mock));
  EXPECT_TRUE(injector.Init());
  injector.InjectTouchEvent(event);
}

// Start a point and then move, make sure the flag is set to kMoveFlag.
TEST(TouchInjectorWinTest, MoveTouchPoint) {
  std::unique_ptr<TouchInjectorWinDelegateMock> delegate_mock(
      new ::testing::StrictMock<TouchInjectorWinDelegateMock>());

  TouchEvent event;
  event.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point = event.add_touch_points();
  point->set_id(0u);


  InSequence s;
  EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
      .WillOnce(Return(1));

  IdFlagMap id_to_flags;
  id_to_flags[0u] = kStartFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  id_to_flags[0u] = kMoveFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  TouchInjectorWin injector;
  injector.SetInjectorDelegateForTest(std::move(delegate_mock));
  EXPECT_TRUE(injector.Init());
  injector.InjectTouchEvent(event);
  event.set_event_type(TouchEvent::TOUCH_POINT_MOVE);
  injector.InjectTouchEvent(event);
}

// Start a point and then move, make sure the flag is set to kEndFlag.
TEST(TouchInjectorWinTest, EndTouchPoint) {
  std::unique_ptr<TouchInjectorWinDelegateMock> delegate_mock(
      new ::testing::StrictMock<TouchInjectorWinDelegateMock>());

  TouchEvent event;
  event.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point = event.add_touch_points();
  point->set_id(0u);

  InSequence s;
  EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
      .WillOnce(Return(1));

  IdFlagMap id_to_flags;
  id_to_flags[0u] = kStartFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  id_to_flags[0u] = kEndFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  TouchInjectorWin injector;
  injector.SetInjectorDelegateForTest(std::move(delegate_mock));
  EXPECT_TRUE(injector.Init());
  injector.InjectTouchEvent(event);
  event.set_event_type(TouchEvent::TOUCH_POINT_END);
  injector.InjectTouchEvent(event);
}

// Start a point and then move, make sure the flag is set to kCancelFlag.
TEST(TouchInjectorWinTest, CancelTouchPoint) {
  std::unique_ptr<TouchInjectorWinDelegateMock> delegate_mock(
      new ::testing::StrictMock<TouchInjectorWinDelegateMock>());

  TouchEvent event;
  event.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point = event.add_touch_points();
  point->set_id(0u);

  InSequence s;
  EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
      .WillOnce(Return(1));

  IdFlagMap id_to_flags;
  id_to_flags[0u] = kStartFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  id_to_flags[0u] = kCancelFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  TouchInjectorWin injector;
  injector.SetInjectorDelegateForTest(std::move(delegate_mock));
  EXPECT_TRUE(injector.Init());
  injector.InjectTouchEvent(event);
  event.set_event_type(TouchEvent::TOUCH_POINT_CANCEL);
  injector.InjectTouchEvent(event);
}

// Note that points that haven't changed should be injected as MOVE.
// This tests:
// 1. Start first touch point.
// 2. Start second touch point.
// 3. Move both touch points.
// 4. Start third touch point.
// 5. End second touch point.
// 6. Cancel remaining (first and third) touch points.
TEST(TouchInjectorWinTest, MultiTouch) {
  std::unique_ptr<TouchInjectorWinDelegateMock> delegate_mock(
      new ::testing::StrictMock<TouchInjectorWinDelegateMock>());

  InSequence s;
  EXPECT_CALL(*delegate_mock, InitializeTouchInjection(_, _))
      .WillOnce(Return(1));

  IdFlagMap id_to_flags;
  id_to_flags[0u] = kStartFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(1, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  id_to_flags[0u] = kMoveFlag;
  id_to_flags[1u] = kStartFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(2, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  id_to_flags[0u] = kMoveFlag;
  id_to_flags[1u] = kMoveFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(2, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  id_to_flags[0u] = kMoveFlag;
  id_to_flags[1u] = kMoveFlag;
  id_to_flags[2u] = kStartFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(3, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  id_to_flags[0u] = kMoveFlag;
  id_to_flags[1u] = kEndFlag;
  id_to_flags[2u] = kMoveFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(3, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  id_to_flags.erase(1u);
  id_to_flags[0u] = kCancelFlag;
  id_to_flags[2u] = kCancelFlag;
  EXPECT_CALL(
      *delegate_mock,
      InjectTouchInput(2, EqualsPointerTouchInfoFlag(id_to_flags)))
      .WillOnce(Return(1));

  TouchInjectorWin injector;
  injector.SetInjectorDelegateForTest(std::move(delegate_mock));
  EXPECT_TRUE(injector.Init());

  // Start first touch point.
  TouchEvent first_touch_start;
  first_touch_start.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point0 = first_touch_start.add_touch_points();
  point0->set_id(0u);
  injector.InjectTouchEvent(first_touch_start);

  // Add second touch point.
  TouchEvent second_touch_start;
  second_touch_start.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point1 = second_touch_start.add_touch_points();
  point1->set_id(1u);
  injector.InjectTouchEvent(second_touch_start);

  // Move both touch points.
  TouchEvent move_both;
  move_both.set_event_type(TouchEvent::TOUCH_POINT_MOVE);
  point0 = second_touch_start.add_touch_points();
  point1 = second_touch_start.add_touch_points();
  point0->set_id(0u);
  point1->set_id(1u);
  injector.InjectTouchEvent(move_both);

  // Add another.
  TouchEvent third_touch_start;
  third_touch_start.set_event_type(TouchEvent::TOUCH_POINT_START);
  TouchEventPoint* point2 = third_touch_start.add_touch_points();
  point2->set_id(2u);
  injector.InjectTouchEvent(third_touch_start);

  // Release second touch point.
  TouchEvent release_second;
  release_second.set_event_type(TouchEvent::TOUCH_POINT_END);
  point1 = release_second.add_touch_points();
  point1->set_id(1u);
  injector.InjectTouchEvent(release_second);

  // Cancel the remaining two points.
  TouchEvent cancel_rest;
  cancel_rest.set_event_type(TouchEvent::TOUCH_POINT_CANCEL);
  point0 = cancel_rest.add_touch_points();
  point0->set_id(0u);
  point2 = cancel_rest.add_touch_points();
  point2->set_id(2u);
  injector.InjectTouchEvent(cancel_rest);
}

}  // namespace remoting
