// Copyright (c) 2012 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 "ui/events/event.h"

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

#include <memory>

#include "base/macros.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/test/events_test_utils.h"
#include "ui/events/test/keyboard_layout.h"
#include "ui/events/test/test_event_target.h"
#include "ui/gfx/transform.h"

#if defined(USE_X11)
#include "ui/events/test/events_test_utils_x11.h"
#include "ui/gfx/x/x11.h"        // nogncheck
#include "ui/gfx/x/x11_types.h"  // nogncheck
#endif

namespace ui {

TEST(EventTest, NoNativeEvent) {
  KeyEvent keyev(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
  EXPECT_FALSE(keyev.HasNativeEvent());
}

TEST(EventTest, NativeEvent) {
#if defined(OS_WIN)
  MSG native_event = { NULL, WM_KEYUP, VKEY_A, 0 };
  KeyEvent keyev(native_event);
  EXPECT_TRUE(keyev.HasNativeEvent());
#elif defined(USE_X11)
  ScopedXI2Event event;
  event.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, EF_NONE);
  KeyEvent keyev(event);
  EXPECT_TRUE(keyev.HasNativeEvent());
#endif
}

TEST(EventTest, GetCharacter) {
  // Check if Control+Enter returns 10.
  KeyEvent keyev1(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN);
  EXPECT_EQ(10, keyev1.GetCharacter());
  // Check if Enter returns 13.
  KeyEvent keyev2(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE);
  EXPECT_EQ(13, keyev2.GetCharacter());

#if defined(USE_X11)
  // For X11, test the functions with native_event() as well. crbug.com/107837
  ScopedXI2Event event;
  event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN);
  KeyEvent keyev3(event);
  EXPECT_EQ(10, keyev3.GetCharacter());

  event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE);
  KeyEvent keyev4(event);
  EXPECT_EQ(13, keyev4.GetCharacter());
#endif

  // Check if expected Unicode character was returned for a key combination
  // contains Control.
  // e.g. Control+Shift+2 produces U+200C on "Persian" keyboard.
  // http://crbug.com/582453
  KeyEvent keyev5(0x200C, VKEY_UNKNOWN, EF_CONTROL_DOWN | EF_SHIFT_DOWN);
  EXPECT_EQ(0x200C, keyev5.GetCharacter());
}

TEST(EventTest, ClickCount) {
  const gfx::Point origin(0, 0);
  MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
  for (int i = 1; i <=3 ; ++i) {
    mouseev.SetClickCount(i);
    EXPECT_EQ(i, mouseev.GetClickCount());
  }
}

TEST(EventTest, RepeatedClick) {
  const gfx::Point origin(0, 0);
  MouseEvent event1(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
  MouseEvent event2(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
  LocatedEventTestApi test_event1(&event1);
  LocatedEventTestApi test_event2(&event2);

  base::TimeTicks start = base::TimeTicks();
  base::TimeTicks soon = start + base::TimeDelta::FromMilliseconds(1);
  base::TimeTicks later = start + base::TimeDelta::FromMilliseconds(1000);

  // Same time stamp (likely the same native event).
  test_event1.set_location(gfx::Point(0, 0));
  test_event2.set_location(gfx::Point(1, 0));
  test_event1.set_time_stamp(start);
  test_event2.set_time_stamp(start);
  EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, event2));
  MouseEvent mouse_ev3(event1);
  EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, mouse_ev3));

  // Close point.
  test_event1.set_location(gfx::Point(0, 0));
  test_event2.set_location(gfx::Point(1, 0));
  test_event1.set_time_stamp(start);
  test_event2.set_time_stamp(soon);
  EXPECT_TRUE(MouseEvent::IsRepeatedClickEvent(event1, event2));

  // Too far.
  test_event1.set_location(gfx::Point(0, 0));
  test_event2.set_location(gfx::Point(10, 0));
  test_event1.set_time_stamp(start);
  test_event2.set_time_stamp(soon);
  EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, event2));

  // Too long a time between clicks.
  test_event1.set_location(gfx::Point(0, 0));
  test_event2.set_location(gfx::Point(0, 0));
  test_event1.set_time_stamp(start);
  test_event2.set_time_stamp(later);
  EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(event1, event2));
}

// Tests that re-processing the same mouse press event (detected by timestamp)
// does not yield a double click event: http://crbug.com/389162
TEST(EventTest, DoubleClickRequiresUniqueTimestamp) {
  const gfx::Point point(0, 0);
  base::TimeTicks time1 = base::TimeTicks();
  base::TimeTicks time2 = time1 + base::TimeDelta::FromMilliseconds(1);

  // Re-processing the same press doesn't yield a double-click.
  MouseEvent event(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  // Processing a press with the same timestamp doesn't yield a double-click.
  event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  // Processing a press with a later timestamp does yield a double-click.
  event = MouseEvent(ET_MOUSE_PRESSED, point, point, time2, 0, 0);
  EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
  MouseEvent::ResetLastClickForTest();

  // Test processing a double press and release sequence with one timestamp.
  event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  event = MouseEvent(ET_MOUSE_RELEASED, point, point, time1, 0, 0);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  event = MouseEvent(ET_MOUSE_RELEASED, point, point, time1, 0, 0);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  MouseEvent::ResetLastClickForTest();

  // Test processing a double press and release sequence with two timestamps.
  event = MouseEvent(ET_MOUSE_PRESSED, point, point, time1, 0, 0);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  event = MouseEvent(ET_MOUSE_RELEASED, point, point, time1, 0, 0);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  event = MouseEvent(ET_MOUSE_PRESSED, point, point, time2, 0, 0);
  EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
  event = MouseEvent(ET_MOUSE_RELEASED, point, point, time2, 0, 0);
  EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
  MouseEvent::ResetLastClickForTest();
}

// Tests that right clicking, then left clicking does not yield double clicks.
TEST(EventTest, SingleClickRightLeft) {
  const gfx::Point point(0, 0);
  base::TimeTicks time1 = base::TimeTicks();
  base::TimeTicks time2 = time1 + base::TimeDelta::FromMilliseconds(1);
  base::TimeTicks time3 = time1 + base::TimeDelta::FromMilliseconds(2);

  MouseEvent event(ET_MOUSE_PRESSED, point, point, time1,
                   ui::EF_RIGHT_MOUSE_BUTTON, ui::EF_RIGHT_MOUSE_BUTTON);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  event = MouseEvent(ET_MOUSE_PRESSED, point, point, time2,
                     ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  event = MouseEvent(ET_MOUSE_RELEASED, point, point, time2,
                     ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
  EXPECT_EQ(1, MouseEvent::GetRepeatCount(event));
  event = MouseEvent(ET_MOUSE_PRESSED, point, point, time3,
                     ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
  EXPECT_EQ(2, MouseEvent::GetRepeatCount(event));
  MouseEvent::ResetLastClickForTest();
}

TEST(EventTest, KeyEvent) {
  static const struct {
    KeyboardCode key_code;
    int flags;
    uint16_t character;
  } kTestData[] = {
    { VKEY_A, 0, 'a' },
    { VKEY_A, EF_SHIFT_DOWN, 'A' },
    { VKEY_A, EF_CAPS_LOCK_ON, 'A' },
    { VKEY_A, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, 'a' },
    { VKEY_A, EF_CONTROL_DOWN, 0x01 },
    { VKEY_A, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x01' },
    { VKEY_Z, 0, 'z' },
    { VKEY_Z, EF_SHIFT_DOWN, 'Z' },
    { VKEY_Z, EF_CAPS_LOCK_ON, 'Z' },
    { VKEY_Z, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, 'z' },
    { VKEY_Z, EF_CONTROL_DOWN, '\x1A' },
    { VKEY_Z, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1A' },

    { VKEY_2, EF_CONTROL_DOWN, '\x12' },
    { VKEY_2, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\0' },
    { VKEY_6, EF_CONTROL_DOWN, '\x16' },
    { VKEY_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1E' },
    { VKEY_OEM_MINUS, EF_CONTROL_DOWN, '\x0D' },
    { VKEY_OEM_MINUS, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1F' },
    { VKEY_OEM_4, EF_CONTROL_DOWN, '\x1B' },
    { VKEY_OEM_4, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1B' },
    { VKEY_OEM_5, EF_CONTROL_DOWN, '\x1C' },
    { VKEY_OEM_5, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1C' },
    { VKEY_OEM_6, EF_CONTROL_DOWN, '\x1D' },
    { VKEY_OEM_6, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x1D' },
    { VKEY_RETURN, EF_CONTROL_DOWN, '\x0A' },

    { VKEY_0, 0, '0' },
    { VKEY_0, EF_SHIFT_DOWN, ')' },
    { VKEY_0, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, ')' },
    { VKEY_0, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x09' },

    { VKEY_9, 0, '9' },
    { VKEY_9, EF_SHIFT_DOWN, '(' },
    { VKEY_9, EF_SHIFT_DOWN | EF_CAPS_LOCK_ON, '(' },
    { VKEY_9, EF_SHIFT_DOWN | EF_CONTROL_DOWN, '\x08' },

    { VKEY_NUMPAD0, EF_CONTROL_DOWN, '\x10' },
    { VKEY_NUMPAD0, EF_SHIFT_DOWN, '0' },

    { VKEY_NUMPAD9, EF_CONTROL_DOWN, '\x19' },
    { VKEY_NUMPAD9, EF_SHIFT_DOWN, '9' },

    { VKEY_TAB, EF_NONE, '\t' },
    { VKEY_TAB, EF_CONTROL_DOWN, '\t' },
    { VKEY_TAB, EF_SHIFT_DOWN, '\t' },

    { VKEY_MULTIPLY, EF_CONTROL_DOWN, '\x0A' },
    { VKEY_MULTIPLY, EF_SHIFT_DOWN, '*' },
    { VKEY_ADD, EF_CONTROL_DOWN, '\x0B' },
    { VKEY_ADD, EF_SHIFT_DOWN, '+' },
    { VKEY_SUBTRACT, EF_CONTROL_DOWN, '\x0D' },
    { VKEY_SUBTRACT, EF_SHIFT_DOWN, '-' },
    { VKEY_DECIMAL, EF_CONTROL_DOWN, '\x0E' },
    { VKEY_DECIMAL, EF_SHIFT_DOWN, '.' },
    { VKEY_DIVIDE, EF_CONTROL_DOWN, '\x0F' },
    { VKEY_DIVIDE, EF_SHIFT_DOWN, '/' },

    { VKEY_OEM_1, EF_CONTROL_DOWN, '\x1B' },
    { VKEY_OEM_1, EF_SHIFT_DOWN, ':' },
    { VKEY_OEM_PLUS, EF_CONTROL_DOWN, '\x1D' },
    { VKEY_OEM_PLUS, EF_SHIFT_DOWN, '+' },
    { VKEY_OEM_COMMA, EF_CONTROL_DOWN, '\x0C' },
    { VKEY_OEM_COMMA, EF_SHIFT_DOWN, '<' },
    { VKEY_OEM_PERIOD, EF_CONTROL_DOWN, '\x0E' },
    { VKEY_OEM_PERIOD, EF_SHIFT_DOWN, '>' },
    { VKEY_OEM_3, EF_CONTROL_DOWN, '\x0' },
    { VKEY_OEM_3, EF_SHIFT_DOWN, '~' },
  };

  for (size_t i = 0; i < arraysize(kTestData); ++i) {
    KeyEvent key(ET_KEY_PRESSED,
                 kTestData[i].key_code,
                 kTestData[i].flags);
    EXPECT_EQ(kTestData[i].character, key.GetCharacter())
        << " Index:" << i << " key_code:" << kTestData[i].key_code;
  }
}

TEST(EventTest, KeyEventDirectUnicode) {
  KeyEvent key(0x1234U, ui::VKEY_UNKNOWN, ui::EF_NONE);
  EXPECT_EQ(0x1234U, key.GetCharacter());
  EXPECT_EQ(ET_KEY_PRESSED, key.type());
  EXPECT_TRUE(key.is_char());
}

TEST(EventTest, NormalizeKeyEventFlags) {
#if defined(USE_X11)
  // Normalize flags when KeyEvent is created from XEvent.
  ScopedXI2Event event;
  {
    event.InitKeyEvent(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN);
    KeyEvent keyev(event);
    EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
  }
  {
    event.InitKeyEvent(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN);
    KeyEvent keyev(event);
    EXPECT_EQ(EF_NONE, keyev.flags());
  }
  {
    event.InitKeyEvent(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN);
    KeyEvent keyev(event);
    EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
  }
  {
    event.InitKeyEvent(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN);
    KeyEvent keyev(event);
    EXPECT_EQ(EF_NONE, keyev.flags());
  }
  {
    event.InitKeyEvent(ET_KEY_PRESSED, VKEY_MENU,  EF_ALT_DOWN);
    KeyEvent keyev(event);
    EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
  }
  {
    event.InitKeyEvent(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN);
    KeyEvent keyev(event);
    EXPECT_EQ(EF_NONE, keyev.flags());
  }
#endif

  // Do not normalize flags for synthesized events without
  // KeyEvent::NormalizeFlags called explicitly.
  {
    KeyEvent keyev(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN);
    EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
  }
  {
    KeyEvent keyev(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN);
    EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags());
    keyev.NormalizeFlags();
    EXPECT_EQ(EF_NONE, keyev.flags());
  }
  {
    KeyEvent keyev(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN);
    EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
  }
  {
    KeyEvent keyev(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN);
    EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags());
    keyev.NormalizeFlags();
    EXPECT_EQ(EF_NONE, keyev.flags());
  }
  {
    KeyEvent keyev(ET_KEY_PRESSED, VKEY_MENU,  EF_ALT_DOWN);
    EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
  }
  {
    KeyEvent keyev(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN);
    EXPECT_EQ(EF_ALT_DOWN, keyev.flags());
    keyev.NormalizeFlags();
    EXPECT_EQ(EF_NONE, keyev.flags());
  }
}

TEST(EventTest, KeyEventCopy) {
  KeyEvent key(ET_KEY_PRESSED, VKEY_A, EF_NONE);
  std::unique_ptr<KeyEvent> copied_key(new KeyEvent(key));
  EXPECT_EQ(copied_key->type(), key.type());
  EXPECT_EQ(copied_key->key_code(), key.key_code());
}

TEST(EventTest, KeyEventCode) {
  const DomCode kDomCodeForSpace = DomCode::SPACE;
  const char kCodeForSpace[] = "Space";
  ASSERT_EQ(kDomCodeForSpace,
            ui::KeycodeConverter::CodeStringToDomCode(kCodeForSpace));
  const uint16_t kNativeCodeSpace =
      ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace);
  ASSERT_NE(ui::KeycodeConverter::InvalidNativeKeycode(), kNativeCodeSpace);
  ASSERT_EQ(kNativeCodeSpace,
            ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace));

  {
    KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, kDomCodeForSpace, EF_NONE);
    EXPECT_EQ(kCodeForSpace, key.GetCodeString());
  }
  {
    // Regardless the KeyEvent.key_code (VKEY_RETURN), code should be
    // the specified value.
    KeyEvent key(ET_KEY_PRESSED, VKEY_RETURN, kDomCodeForSpace, EF_NONE);
    EXPECT_EQ(kCodeForSpace, key.GetCodeString());
  }
  {
    // If the synthetic event is initialized without code, the code is
    // determined from the KeyboardCode assuming a US keyboard layout.
    KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE);
    EXPECT_EQ(kCodeForSpace, key.GetCodeString());
  }
#if defined(USE_X11)
  {
    // KeyEvent converts from the native keycode (XKB) to the code.
    ScopedXI2Event xevent;
    xevent.InitKeyEvent(ET_KEY_PRESSED, VKEY_SPACE, kNativeCodeSpace);
    KeyEvent key(xevent);
    EXPECT_EQ(kCodeForSpace, key.GetCodeString());
  }
#endif  // USE_X11
#if defined(OS_WIN)
  {
    // Test a non extended key.
    ASSERT_EQ((kNativeCodeSpace & 0xFF), kNativeCodeSpace);

    const LPARAM lParam = GetLParamFromScanCode(kNativeCodeSpace);
    MSG native_event = { NULL, WM_KEYUP, VKEY_SPACE, lParam };
    KeyEvent key(native_event);

    // KeyEvent converts from the native keycode (scan code) to the code.
    EXPECT_EQ(kCodeForSpace, key.GetCodeString());
  }
  {
    const char kCodeForHome[]  = "Home";
    const uint16_t kNativeCodeHome = 0xe047;

    // 'Home' is an extended key with 0xe000 bits.
    ASSERT_NE((kNativeCodeHome & 0xFF), kNativeCodeHome);
    const LPARAM lParam = GetLParamFromScanCode(kNativeCodeHome);

    MSG native_event = { NULL, WM_KEYUP, VKEY_HOME, lParam };
    KeyEvent key(native_event);

    // KeyEvent converts from the native keycode (scan code) to the code.
    EXPECT_EQ(kCodeForHome, key.GetCodeString());
  }
#endif  // OS_WIN
}

#if defined(USE_X11)
namespace {

void SetKeyEventTimestamp(XEvent* event, int64_t time) {
  event->xkey.time = time & UINT32_MAX;
}

void AdvanceKeyEventTimestamp(XEvent* event) {
  event->xkey.time++;
}

}  // namespace

TEST(EventTest, AutoRepeat) {
  const uint16_t kNativeCodeA =
      ui::KeycodeConverter::DomCodeToNativeKeycode(DomCode::US_A);
  const uint16_t kNativeCodeB =
      ui::KeycodeConverter::DomCodeToNativeKeycode(DomCode::US_B);

  ScopedXI2Event native_event_a_pressed;
  native_event_a_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
  ScopedXI2Event native_event_a_pressed_1500;
  native_event_a_pressed_1500.InitKeyEvent(
      ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
  ScopedXI2Event native_event_a_pressed_3000;
  native_event_a_pressed_3000.InitKeyEvent(
      ET_KEY_PRESSED, VKEY_A, kNativeCodeA);

  ScopedXI2Event native_event_a_released;
  native_event_a_released.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, kNativeCodeA);
  ScopedXI2Event native_event_b_pressed;
  native_event_b_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_B, kNativeCodeB);
  ScopedXI2Event native_event_a_pressed_nonstandard_state;
  native_event_a_pressed_nonstandard_state.InitKeyEvent(
      ET_KEY_PRESSED, VKEY_A, kNativeCodeA);
  // IBUS-GTK uses the mask (1 << 25) to detect reposted event.
  static_cast<XEvent*>(native_event_a_pressed_nonstandard_state)->xkey.state |=
      1 << 25;

  int64_t ticks_base =
      (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds() - 5000;
  SetKeyEventTimestamp(native_event_a_pressed, ticks_base);
  SetKeyEventTimestamp(native_event_a_pressed_1500, ticks_base + 1500);
  SetKeyEventTimestamp(native_event_a_pressed_3000, ticks_base + 3000);

  {
    KeyEvent key_a1(native_event_a_pressed);
    EXPECT_FALSE(key_a1.is_repeat());

    KeyEvent key_a1_released(native_event_a_released);
    EXPECT_FALSE(key_a1_released.is_repeat());

    KeyEvent key_a2(native_event_a_pressed);
    EXPECT_FALSE(key_a2.is_repeat());

    AdvanceKeyEventTimestamp(native_event_a_pressed);
    KeyEvent key_a2_repeated(native_event_a_pressed);
    EXPECT_TRUE(key_a2_repeated.is_repeat());

    KeyEvent key_a2_released(native_event_a_released);
    EXPECT_FALSE(key_a2_released.is_repeat());
  }

  // Interleaved with different key press.
  {
    KeyEvent key_a3(native_event_a_pressed);
    EXPECT_FALSE(key_a3.is_repeat());

    KeyEvent key_b(native_event_b_pressed);
    EXPECT_FALSE(key_b.is_repeat());

    AdvanceKeyEventTimestamp(native_event_a_pressed);
    KeyEvent key_a3_again(native_event_a_pressed);
    EXPECT_FALSE(key_a3_again.is_repeat());

    AdvanceKeyEventTimestamp(native_event_a_pressed);
    KeyEvent key_a3_repeated(native_event_a_pressed);
    EXPECT_TRUE(key_a3_repeated.is_repeat());

    AdvanceKeyEventTimestamp(native_event_a_pressed);
    KeyEvent key_a3_repeated2(native_event_a_pressed);
    EXPECT_TRUE(key_a3_repeated2.is_repeat());

    KeyEvent key_a3_released(native_event_a_released);
    EXPECT_FALSE(key_a3_released.is_repeat());
  }

  // Hold the key longer than max auto repeat timeout.
  {
    KeyEvent key_a4_0(native_event_a_pressed);
    EXPECT_FALSE(key_a4_0.is_repeat());

    KeyEvent key_a4_1500(native_event_a_pressed_1500);
    EXPECT_TRUE(key_a4_1500.is_repeat());

    KeyEvent key_a4_3000(native_event_a_pressed_3000);
    EXPECT_TRUE(key_a4_3000.is_repeat());

    KeyEvent key_a4_released(native_event_a_released);
    EXPECT_FALSE(key_a4_released.is_repeat());
  }

  {
    KeyEvent key_a4_pressed(native_event_a_pressed);
    EXPECT_FALSE(key_a4_pressed.is_repeat());

    KeyEvent key_a4_pressed_nonstandard_state(
        native_event_a_pressed_nonstandard_state);
    EXPECT_FALSE(key_a4_pressed_nonstandard_state.is_repeat());
  }

  {
    KeyEvent key_a1(native_event_a_pressed);
    EXPECT_FALSE(key_a1.is_repeat());

    KeyEvent key_a1_with_same_event(native_event_a_pressed);
    EXPECT_FALSE(key_a1_with_same_event.is_repeat());
  }
}
#endif  // USE_X11

TEST(EventTest, TouchEventRadiusDefaultsToOtherAxis) {
  const base::TimeTicks time = base::TimeTicks();
  const float non_zero_length1 = 30;
  const float non_zero_length2 = 46;

  TouchEvent event1(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
                    PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                                   /* pointer_id*/ 0,
                                   /* radius_x */ non_zero_length1,
                                   /* radius_y */ 0.0f,
                                   /* force */ 0));
  EXPECT_EQ(non_zero_length1, event1.pointer_details().radius_x);
  EXPECT_EQ(non_zero_length1, event1.pointer_details().radius_y);

  TouchEvent event2(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
                    PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                                   /* pointer_id*/ 0,
                                   /* radius_x */ 0.0f,
                                   /* radius_y */ non_zero_length2,
                                   /* force */ 0));
  EXPECT_EQ(non_zero_length2, event2.pointer_details().radius_x);
  EXPECT_EQ(non_zero_length2, event2.pointer_details().radius_y);
}

TEST(EventTest, TouchEventRotationAngleFixing) {
  const base::TimeTicks time = base::TimeTicks();
  const float radius_x = 20;
  const float radius_y = 10;

  {
    const float angle_in_range = 0;
    TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
                     PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                                    /* pointer_id*/ 0, radius_x, radius_y,
                                    /* force */ 0),
                     0, angle_in_range);
    EXPECT_FLOAT_EQ(angle_in_range, event.ComputeRotationAngle());
  }

  {
    const float angle_in_range = 179.9f;
    TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
                     PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                                    /* pointer_id*/ 0, radius_x, radius_y,
                                    /* force */ 0),
                     0, angle_in_range);
    EXPECT_FLOAT_EQ(angle_in_range, event.ComputeRotationAngle());
  }

  {
    const float angle_negative = -0.1f;
    TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
                     PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                                    /* pointer_id*/ 0, radius_x, radius_y,
                                    /* force */ 0),
                     0, angle_negative);
    EXPECT_FLOAT_EQ(180 - 0.1f, event.ComputeRotationAngle());
  }

  {
    const float angle_negative = -200;
    TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
                     PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                                    /* pointer_id*/ 0, radius_x, radius_y,
                                    /* force */ 0),
                     0, angle_negative);
    EXPECT_FLOAT_EQ(360 - 200, event.ComputeRotationAngle());
  }

  {
    const float angle_too_big = 180;
    TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
                     PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                                    /* pointer_id*/ 0, radius_x, radius_y,
                                    /* force */ 0),
                     0, angle_too_big);
    EXPECT_FLOAT_EQ(0, event.ComputeRotationAngle());
  }

  {
    const float angle_too_big = 400;
    TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), time,
                     PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                                    /* pointer_id*/ 0, radius_x, radius_y,
                                    /* force */ 0),
                     0, angle_too_big);
    EXPECT_FLOAT_EQ(400 - 360, event.ComputeRotationAngle());
  }
}

TEST(EventTest, PointerDetailsTouch) {
  ui::TouchEvent touch_event_plain(
      ET_TOUCH_PRESSED, gfx::Point(0, 0), ui::EventTimeForNow(),
      PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));

  EXPECT_EQ(EventPointerType::POINTER_TYPE_TOUCH,
            touch_event_plain.pointer_details().pointer_type);
  EXPECT_EQ(0.0f, touch_event_plain.pointer_details().radius_x);
  EXPECT_EQ(0.0f, touch_event_plain.pointer_details().radius_y);
  EXPECT_TRUE(std::isnan(touch_event_plain.pointer_details().force));
  EXPECT_EQ(0.0f, touch_event_plain.pointer_details().tilt_x);
  EXPECT_EQ(0.0f, touch_event_plain.pointer_details().tilt_y);

  ui::TouchEvent touch_event_with_details(
      ET_TOUCH_PRESSED, gfx::Point(0, 0), ui::EventTimeForNow(),
      PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                     /* pointer_id*/ 0,
                     /* radius_x */ 10.0f,
                     /* radius_y */ 5.0f,
                     /* force */ 15.0f));

  EXPECT_EQ(EventPointerType::POINTER_TYPE_TOUCH,
            touch_event_with_details.pointer_details().pointer_type);
  EXPECT_EQ(10.0f, touch_event_with_details.pointer_details().radius_x);
  EXPECT_EQ(5.0f, touch_event_with_details.pointer_details().radius_y);
  EXPECT_EQ(15.0f, touch_event_with_details.pointer_details().force);
  EXPECT_EQ(0.0f, touch_event_with_details.pointer_details().tilt_x);
  EXPECT_EQ(0.0f, touch_event_with_details.pointer_details().tilt_y);

  ui::TouchEvent touch_event_copy(touch_event_with_details);
  EXPECT_EQ(touch_event_with_details.pointer_details(),
            touch_event_copy.pointer_details());
}

TEST(EventTest, PointerDetailsMouse) {
  ui::MouseEvent mouse_event(ET_MOUSE_PRESSED, gfx::Point(0, 0),
                             gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0);

  EXPECT_EQ(EventPointerType::POINTER_TYPE_MOUSE,
            mouse_event.pointer_details().pointer_type);
  EXPECT_EQ(0.0f, mouse_event.pointer_details().radius_x);
  EXPECT_EQ(0.0f, mouse_event.pointer_details().radius_y);
  EXPECT_TRUE(std::isnan(mouse_event.pointer_details().force));
  EXPECT_EQ(0.0f, mouse_event.pointer_details().tilt_x);
  EXPECT_EQ(0.0f, mouse_event.pointer_details().tilt_y);

  ui::MouseEvent mouse_event_copy(mouse_event);
  EXPECT_EQ(mouse_event.pointer_details(), mouse_event_copy.pointer_details());
}

TEST(EventTest, PointerDetailsStylus) {
  ui::PointerDetails pointer_details(EventPointerType::POINTER_TYPE_PEN,
                                     /* pointer_id*/ 0,
                                     /* radius_x */ 0.0f,
                                     /* radius_y */ 0.0f,
                                     /* force */ 21.0f,
                                     /* twist */ 196,
                                     /* tilt_x */ 45.0f,
                                     /* tilt_y */ -45.0f,
                                     /* tangential_pressure */ 0.7f);

  ui::MouseEvent stylus_event(ET_MOUSE_PRESSED, gfx::Point(0, 0),
                              gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0,
                              pointer_details);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            stylus_event.pointer_details().pointer_type);
  EXPECT_EQ(21.0f, stylus_event.pointer_details().force);
  EXPECT_EQ(45.0f, stylus_event.pointer_details().tilt_x);
  EXPECT_EQ(-45.0f, stylus_event.pointer_details().tilt_y);
  EXPECT_EQ(0.0f, stylus_event.pointer_details().radius_x);
  EXPECT_EQ(0.0f, stylus_event.pointer_details().radius_y);
  EXPECT_EQ(0.7f, stylus_event.pointer_details().tangential_pressure);
  EXPECT_EQ(196, stylus_event.pointer_details().twist);

  ui::MouseEvent stylus_event_copy(stylus_event);
  EXPECT_EQ(stylus_event.pointer_details(),
            stylus_event_copy.pointer_details());
}

TEST(EventTest, PointerDetailsCustomTouch) {
  ui::TouchEvent touch_event(
      ET_TOUCH_PRESSED, gfx::Point(0, 0), ui::EventTimeForNow(),
      PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));

  EXPECT_EQ(EventPointerType::POINTER_TYPE_TOUCH,
            touch_event.pointer_details().pointer_type);
  EXPECT_EQ(0.0f, touch_event.pointer_details().radius_x);
  EXPECT_EQ(0.0f, touch_event.pointer_details().radius_y);
  EXPECT_TRUE(std::isnan(touch_event.pointer_details().force));
  EXPECT_EQ(0.0f, touch_event.pointer_details().tilt_x);
  EXPECT_EQ(0.0f, touch_event.pointer_details().tilt_y);

  ui::PointerDetails pointer_details(EventPointerType::POINTER_TYPE_PEN,
                                     /* pointer_id*/ 0,
                                     /* radius_x */ 5.0f,
                                     /* radius_y */ 6.0f,
                                     /* force */ 21.0f,
                                     /* twist */ 196,
                                     /* tilt_x */ 45.0f,
                                     /* tilt_y */ -45.0f,
                                     /* tangential_pressure */ 0.7f);
  touch_event.SetPointerDetailsForTest(pointer_details);

  EXPECT_EQ(EventPointerType::POINTER_TYPE_PEN,
            touch_event.pointer_details().pointer_type);
  EXPECT_EQ(21.0f, touch_event.pointer_details().force);
  EXPECT_EQ(45.0f, touch_event.pointer_details().tilt_x);
  EXPECT_EQ(-45.0f, touch_event.pointer_details().tilt_y);
  EXPECT_EQ(5.0f, touch_event.pointer_details().radius_x);
  EXPECT_EQ(6.0f, touch_event.pointer_details().radius_y);
  EXPECT_EQ(0.7f, touch_event.pointer_details().tangential_pressure);
  EXPECT_EQ(196, touch_event.pointer_details().twist);

  ui::TouchEvent touch_event_copy(touch_event);
  EXPECT_EQ(touch_event.pointer_details(), touch_event_copy.pointer_details());
}

TEST(EventTest, PointerEventCanConvertFrom) {
  const gfx::Point point;
  const base::TimeTicks time;

  // Common mouse events can be converted.
  const EventType mouse_allowed[] = {
      ET_MOUSE_PRESSED,         ET_MOUSE_DRAGGED, ET_MOUSE_MOVED,
      ET_MOUSE_ENTERED,         ET_MOUSE_EXITED,  ET_MOUSE_RELEASED,
      ET_MOUSE_CAPTURE_CHANGED,
  };
  for (size_t i = 0; i < arraysize(mouse_allowed); i++) {
    MouseEvent event(mouse_allowed[i], point, point, time, 0, 0);
    EXPECT_TRUE(PointerEvent::CanConvertFrom(event));
  }
  // Mouse wheel events can be converted.
  MouseWheelEvent event(gfx::Vector2d(), point, point, time, 0, 0);
  EXPECT_TRUE(PointerEvent::CanConvertFrom(event));

  // Common touch events can be converted.
  const EventType touch_allowed[] = {
      ET_TOUCH_PRESSED,
      ET_TOUCH_MOVED,
      ET_TOUCH_RELEASED,
      ET_TOUCH_CANCELLED
  };
  for (size_t i = 0; i < arraysize(touch_allowed); i++) {
    TouchEvent event(
        touch_allowed[i], point, time,
        PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
    EXPECT_TRUE(PointerEvent::CanConvertFrom(event));
  }

  // Non-mouse non-touch events cannot be converted.
  EXPECT_FALSE(
      PointerEvent::CanConvertFrom(
          KeyEvent(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE)));
}

TEST(EventTest, PointerEventType) {
  const ui::EventType kMouseTypeMap[][2] = {
      {ui::ET_MOUSE_PRESSED, ui::ET_POINTER_DOWN},
      {ui::ET_MOUSE_DRAGGED, ui::ET_POINTER_MOVED},
      {ui::ET_MOUSE_MOVED, ui::ET_POINTER_MOVED},
      {ui::ET_MOUSE_ENTERED, ui::ET_POINTER_ENTERED},
      {ui::ET_MOUSE_EXITED, ui::ET_POINTER_EXITED},
      {ui::ET_MOUSE_RELEASED, ui::ET_POINTER_UP},
  };
  const ui::EventType kTouchTypeMap[][2] = {
      {ui::ET_TOUCH_PRESSED, ui::ET_POINTER_DOWN},
      {ui::ET_TOUCH_MOVED, ui::ET_POINTER_MOVED},
      {ui::ET_TOUCH_RELEASED, ui::ET_POINTER_UP},
      {ui::ET_TOUCH_CANCELLED, ui::ET_POINTER_CANCELLED},
  };

  for (size_t i = 0; i < arraysize(kMouseTypeMap); i++) {
    ui::MouseEvent mouse_event(kMouseTypeMap[i][0], gfx::Point(0, 0),
                               gfx::Point(0, 0), base::TimeTicks(), 0, 0);
    ui::PointerEvent pointer_event(mouse_event);
    EXPECT_EQ(kMouseTypeMap[i][1], pointer_event.type());
    EXPECT_FALSE(pointer_event.IsMouseEvent());
    EXPECT_FALSE(pointer_event.IsTouchEvent());
    EXPECT_TRUE(pointer_event.IsPointerEvent());
  }

  for (size_t i = 0; i < arraysize(kTouchTypeMap); i++) {
    ui::TouchEvent touch_event(
        kTouchTypeMap[i][0], gfx::Point(0, 0), base::TimeTicks(),
        PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
    ui::PointerEvent pointer_event(touch_event);
    EXPECT_EQ(kTouchTypeMap[i][1], pointer_event.type());
    EXPECT_FALSE(pointer_event.IsMouseEvent());
    EXPECT_FALSE(pointer_event.IsTouchEvent());
    EXPECT_TRUE(pointer_event.IsPointerEvent());
  }
}

TEST(EventTest, PointerEventId) {
  {
    ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED, gfx::Point(0, 0),
                               gfx::Point(0, 0), base::TimeTicks(), 0, 0);
    ui::PointerEvent pointer_event(mouse_event);
    EXPECT_EQ(pointer_event.pointer_details().id,
              ui::MouseEvent::kMousePointerId);
  }

  for (int touch_id = 0; touch_id < 8; touch_id++) {
    ui::TouchEvent touch_event(
        ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), base::TimeTicks(),
        PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, touch_id));
    ui::PointerEvent pointer_event(touch_event);
    EXPECT_EQ(pointer_event.pointer_details().id, touch_id);
  }
}

TEST(EventTest, PointerDetailsPointer) {
  const float kRadiusX = 10.0f;
  const float kRadiusY = 5.0f;
  const float kForce = 15.0f;
  ui::TouchEvent touch_event(
      ET_TOUCH_PRESSED, gfx::Point(0, 0), ui::EventTimeForNow(),
      PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                     /* pointer_id*/ 0,
                     /* radius_x */ kRadiusX,
                     /* radius_y */ kRadiusY,
                     /* force */ kForce));
  ui::PointerEvent pointer_event_from_touch(touch_event);
  EXPECT_EQ(kRadiusX, pointer_event_from_touch.pointer_details().radius_x);
  EXPECT_EQ(kRadiusY, pointer_event_from_touch.pointer_details().radius_y);
  EXPECT_EQ(kForce, pointer_event_from_touch.pointer_details().force);
  EXPECT_EQ(kRadiusX, pointer_event_from_touch.pointer_details().radius_x);
  EXPECT_EQ(0.0f, pointer_event_from_touch.pointer_details().tilt_x);
  EXPECT_EQ(0.0f, pointer_event_from_touch.pointer_details().tilt_y);
  EXPECT_EQ(EventPointerType::POINTER_TYPE_TOUCH,
            pointer_event_from_touch.pointer_details().pointer_type);

  ui::MouseEvent mouse_event(ET_MOUSE_PRESSED, gfx::Point(0, 0),
                             gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0);
  ui::PointerEvent pointer_event_from_mouse(mouse_event);
  EXPECT_EQ(mouse_event.pointer_details(),
            pointer_event_from_mouse.pointer_details());
}

TEST(EventTest, PointerEventClone) {
  {
    ui::PointerEvent ptr_event(ui::TouchEvent(
        ET_TOUCH_PRESSED, gfx::Point(0, 0), ui::EventTimeForNow(),
        PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                       /* pointer_id*/ 0,
                       /* radius_x */ 10.0f,
                       /* radius_y */ 5.0f,
                       /* force */ 15.0f)));
    std::unique_ptr<ui::Event> clone(ui::Event::Clone(ptr_event));
    EXPECT_TRUE(clone->IsPointerEvent());
    ui::PointerEvent* clone_as_ptr = clone->AsPointerEvent();

    EXPECT_EQ(ptr_event.type(), clone_as_ptr->type());
    EXPECT_EQ(ptr_event.pointer_details().id,
              clone_as_ptr->pointer_details().id);
    EXPECT_EQ(ptr_event.pointer_details(), clone_as_ptr->pointer_details());
    EXPECT_EQ(ptr_event.location(), clone_as_ptr->location());
    EXPECT_EQ(ptr_event.root_location(), clone_as_ptr->root_location());
  }

  {
    ui::PointerEvent ptr_event(
        ui::MouseEvent(ET_MOUSE_PRESSED, gfx::Point(0, 0), gfx::Point(0, 0),
                       ui::EventTimeForNow(), 0, 0));
    std::unique_ptr<ui::Event> clone(ui::Event::Clone(ptr_event));
    EXPECT_TRUE(clone->IsPointerEvent());
    ui::PointerEvent* clone_as_ptr = clone->AsPointerEvent();

    EXPECT_EQ(ptr_event.type(), clone_as_ptr->type());
    EXPECT_EQ(ptr_event.pointer_details().id,
              clone_as_ptr->pointer_details().id);
    EXPECT_EQ(ptr_event.pointer_details(), clone_as_ptr->pointer_details());
    EXPECT_EQ(ptr_event.location(), clone_as_ptr->location());
    EXPECT_EQ(ptr_event.root_location(), clone_as_ptr->root_location());
  }
}

TEST(EventTest, MouseEventLatencyUIComponentExists) {
  const gfx::Point origin(0, 0);
  MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0);
  EXPECT_TRUE(mouseev.latency()->FindLatency(
      ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));
}

TEST(EventTest, MouseWheelEventLatencyUIComponentExists) {
  const gfx::Point origin(0, 0);
  MouseWheelEvent mouseWheelev(gfx::Vector2d(), origin, origin,
                               EventTimeForNow(), 0, 0);
  EXPECT_TRUE(mouseWheelev.latency()->FindLatency(
      ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));
}

TEST(EventTest, PointerEventToMouseEvent) {
  const struct {
    ui::EventType in_type;
    ui::EventType out_type;
    gfx::Point location;
    gfx::Point root_location;
    int flags;
    int changed_button_flags;
  } kTestData[] = {
      {ui::ET_POINTER_DOWN, ui::ET_MOUSE_PRESSED, gfx::Point(10, 20),
       gfx::Point(110, 120), 0, 0},
      {ui::ET_POINTER_MOVED, ui::ET_MOUSE_MOVED, gfx::Point(20, 10),
       gfx::Point(1, 2), 0, 0},
      {ui::ET_POINTER_MOVED, ui::ET_MOUSE_DRAGGED, gfx::Point(20, 10),
       gfx::Point(1, 2), EF_LEFT_MOUSE_BUTTON, 0},
      {ui::ET_POINTER_MOVED, ui::ET_MOUSE_DRAGGED, gfx::Point(20, 10),
       gfx::Point(1, 2), EF_RIGHT_MOUSE_BUTTON, 0},
      {ui::ET_POINTER_MOVED, ui::ET_MOUSE_DRAGGED, gfx::Point(20, 10),
       gfx::Point(1, 2), EF_MIDDLE_MOUSE_BUTTON, 0},
      {ui::ET_POINTER_ENTERED, ui::ET_MOUSE_ENTERED, gfx::Point(), gfx::Point(),
       EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON, 0},
      {ui::ET_POINTER_EXITED, ui::ET_MOUSE_EXITED, gfx::Point(5, 1),
       gfx::Point(1, 5), EF_RIGHT_MOUSE_BUTTON, 0},
      {ui::ET_POINTER_UP, ui::ET_MOUSE_RELEASED, gfx::Point(1000, 1000),
       gfx::Point(14, 15), EF_MIDDLE_MOUSE_BUTTON, EF_MIDDLE_MOUSE_BUTTON}};

  for (size_t i = 0; i < arraysize(kTestData); i++) {
    ui::PointerEvent pointer_event(
        kTestData[i].in_type, kTestData[i].location, kTestData[i].root_location,
        kTestData[i].flags, kTestData[i].changed_button_flags,
        ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0),
        base::TimeTicks());
    ui::MouseEvent mouse_event(pointer_event);

    EXPECT_EQ(kTestData[i].out_type, mouse_event.type());
    EXPECT_EQ(kTestData[i].location, mouse_event.location());
    EXPECT_EQ(kTestData[i].root_location, mouse_event.root_location());
    EXPECT_EQ(kTestData[i].flags, mouse_event.flags());
    EXPECT_EQ(kTestData[i].changed_button_flags,
              mouse_event.changed_button_flags());
  }
}

TEST(EventTest, PointerEventToTouchEventType) {
  ui::EventType kTouchTypeMap[][2] = {
      {ui::ET_POINTER_DOWN, ui::ET_TOUCH_PRESSED},
      {ui::ET_POINTER_MOVED, ui::ET_TOUCH_MOVED},
      {ui::ET_POINTER_UP, ui::ET_TOUCH_RELEASED},
      {ui::ET_POINTER_CANCELLED, ui::ET_TOUCH_CANCELLED},
  };

  for (size_t i = 0; i < arraysize(kTouchTypeMap); i++) {
    ui::PointerEvent pointer_event(
        kTouchTypeMap[i][0], gfx::Point(), gfx::Point(), 0, 0,
        ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0),
        base::TimeTicks());
    ui::TouchEvent touch_event(pointer_event);

    EXPECT_EQ(kTouchTypeMap[i][1], touch_event.type());
  }
}

TEST(EventTest, PointerEventToTouchEventDetails) {
  ui::PointerEvent pointer_event(ui::TouchEvent(
      ui::ET_TOUCH_PRESSED, gfx::Point(12, 14), EventTimeForNow(),
      PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH,
                     /* pointer_id*/ 15,
                     /* radius_x */ 11.5,
                     /* radius_y */ 13.5,
                     /* force */ 0.5),
      0, 13.0));
  ui::TouchEvent touch_event(pointer_event);

  EXPECT_EQ(pointer_event.location(), touch_event.location());
  EXPECT_EQ(pointer_event.flags(), touch_event.flags());
  EXPECT_EQ(pointer_event.pointer_details().id,
            touch_event.pointer_details().id);
  EXPECT_EQ(pointer_event.pointer_details(), touch_event.pointer_details());
  EXPECT_EQ(pointer_event.time_stamp(), touch_event.time_stamp());
}

TEST(EventTest, PointerEventSourceEventTypeExistsInLatencyInfo) {
  ui::PointerEvent wheel_poniter_event(
      ui::ET_POINTER_WHEEL_CHANGED, gfx::Point(), gfx::Point(), 0, 0,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0),
      ui::EventTimeForNow());
  EXPECT_EQ(wheel_poniter_event.latency()->source_event_type(),
            ui::SourceEventType::WHEEL);

  ui::PointerEvent touch_poniter_event(
      ui::ET_TOUCH_PRESSED, gfx::Point(), gfx::Point(), 0, 0,
      ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0),
      ui::EventTimeForNow());
  EXPECT_EQ(touch_poniter_event.latency()->source_event_type(),
            ui::SourceEventType::TOUCH);
}

// Checks that Event.Latency.OS.TOUCH_PRESSED, TOUCH_MOVED,
// and TOUCH_RELEASED histograms are computed properly.
#if defined(USE_X11)
TEST(EventTest, EventLatencyOSTouchHistograms) {
  base::HistogramTester histogram_tester;
  ScopedXI2Event scoped_xevent;

  // SetUp for test
  DeviceDataManagerX11::CreateInstance();
  std::vector<int> devices;
  devices.push_back(0);
  ui::SetUpTouchDevicesForTest(devices);

  // Init touch begin, update, and end events with tracking id 5, touch id 0.
  scoped_xevent.InitTouchEvent(
      0, XI_TouchBegin, 5, gfx::Point(10, 10), std::vector<Valuator>());
  TouchEvent touch_begin(scoped_xevent);
  histogram_tester.ExpectTotalCount("Event.Latency.OS.TOUCH_PRESSED", 1);
  scoped_xevent.InitTouchEvent(
      0, XI_TouchUpdate, 5, gfx::Point(20, 20), std::vector<Valuator>());
  TouchEvent touch_update(scoped_xevent);
  histogram_tester.ExpectTotalCount("Event.Latency.OS.TOUCH_MOVED", 1);
  scoped_xevent.InitTouchEvent(
      0, XI_TouchEnd, 5, gfx::Point(30, 30), std::vector<Valuator>());
  TouchEvent touch_end(scoped_xevent);
  histogram_tester.ExpectTotalCount("Event.Latency.OS.TOUCH_RELEASED", 1);
}
#endif

// Checks that Event.Latency.OS.MOUSE_WHEEL histogram is computed properly.
TEST(EventTest, EventLatencyOSMouseWheelHistogram) {
#if defined(OS_WIN)
  base::HistogramTester histogram_tester;
  MSG event = { nullptr, WM_MOUSEWHEEL, 0, 0 };
  MouseWheelEvent mouseWheelEvent(event);
  histogram_tester.ExpectTotalCount("Event.Latency.OS.MOUSE_WHEEL", 1);
#elif defined(USE_X11)
  base::HistogramTester histogram_tester;
  DeviceDataManagerX11::CreateInstance();

  // Initializes a native event and uses it to generate a MouseWheel event.
  XEvent native_event;
  memset(&native_event, 0, sizeof(XEvent));
  XButtonEvent* button_event = &(native_event.xbutton);
  button_event->type = ButtonPress;
  button_event->button = 4; // A valid wheel button number between min and max.
  MouseWheelEvent mouse_ev(&native_event);

  histogram_tester.ExpectTotalCount("Event.Latency.OS.MOUSE_WHEEL", 1);
#endif
}

TEST(EventTest, UpdateForRootTransformation) {
  gfx::Transform identity_transform;
  const gfx::Point location(10, 10);
  const gfx::Point root_location(20, 20);

  // A mouse event that is untargeted should reset the root location when
  // transformed. Though the events start out with different locations and
  // root_locations, they should be equal afterwards.
  ui::MouseEvent untargeted(ET_MOUSE_PRESSED, location, root_location,
                            EventTimeForNow(), 0, 0);
  untargeted.UpdateForRootTransform(identity_transform, identity_transform);
  EXPECT_EQ(location, untargeted.location());
  EXPECT_EQ(location, untargeted.root_location());

  ui::test::TestEventTarget target;

  // A mouse event that is targeted should not set the root location to the
  // local location. They start with different locations and should stay
  // unequal after a transform is applied.
  {
    ui::MouseEvent targeted(ET_MOUSE_PRESSED, location, root_location,
                            EventTimeForNow(), 0, 0);
    Event::DispatcherApi(&targeted).set_target(&target);
    targeted.UpdateForRootTransform(identity_transform, identity_transform);
    EXPECT_EQ(location, targeted.location());
    EXPECT_EQ(root_location, targeted.root_location());
  }

  {
    // Targeted event with 2x and 3x scales.
    gfx::Transform transform2x;
    transform2x.Scale(2, 2);
    gfx::Transform transform3x;
    transform3x.Scale(3, 3);
    ui::MouseEvent targeted(ET_MOUSE_PRESSED, location, root_location,
                            EventTimeForNow(), 0, 0);
    Event::DispatcherApi(&targeted).set_target(&target);
    targeted.UpdateForRootTransform(transform2x, transform3x);
    EXPECT_EQ(gfx::Point(30, 30), targeted.location());
    EXPECT_EQ(gfx::Point(40, 40), targeted.root_location());
  }
}

#if defined(OS_WIN)
namespace {

const struct AltGraphEventTestCase {
  KeyboardCode key_code;
  KeyboardLayout layout;
  std::vector<KeyboardCode> modifier_key_codes;
  int expected_flags;
} kAltGraphEventTestCases[] = {
    // US English -> AltRight never behaves as AltGraph.
    {VKEY_C,
     KEYBOARD_LAYOUT_ENGLISH_US,
     {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
     EF_ALT_DOWN | EF_CONTROL_DOWN},
    {VKEY_E,
     KEYBOARD_LAYOUT_ENGLISH_US,
     {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
     EF_ALT_DOWN | EF_CONTROL_DOWN},

    // French -> Always expect AltGraph if VKEY_RMENU is pressed.
    {VKEY_C,
     KEYBOARD_LAYOUT_FRENCH,
     {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
     EF_ALTGR_DOWN},
    {VKEY_E,
     KEYBOARD_LAYOUT_FRENCH,
     {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
     EF_ALTGR_DOWN},

    // French -> Expect Control+Alt is AltGraph on AltGraph-shifted keys.
    {VKEY_C,
     KEYBOARD_LAYOUT_FRENCH,
     {VKEY_LMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
     EF_ALT_DOWN | EF_CONTROL_DOWN},
    {VKEY_E,
     KEYBOARD_LAYOUT_FRENCH,
     {VKEY_LMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
     EF_ALTGR_DOWN},
};

class AltGraphEventTest
    : public testing::TestWithParam<std::tuple<UINT, AltGraphEventTestCase>> {
 public:
  AltGraphEventTest()
      : msg_({nullptr, message_type(),
              static_cast<WPARAM>(test_case().key_code)}) {
    // Save the current keyboard layout and state, to restore later.
    CHECK(GetKeyboardState(original_keyboard_state_));
    original_keyboard_layout_ = GetKeyboardLayout(0);

    // Configure specified layout, and update keyboard state for specified
    // modifier keys.
    CHECK(ActivateKeyboardLayout(GetPlatformKeyboardLayout(test_case().layout),
                                 0));
    BYTE test_keyboard_state[256] = {};
    for (const auto& key_code : test_case().modifier_key_codes)
      test_keyboard_state[key_code] = 0x80;
    CHECK(SetKeyboardState(test_keyboard_state));
  }

  ~AltGraphEventTest() {
    // Restore the original keyboard layout & key states.
    CHECK(ActivateKeyboardLayout(original_keyboard_layout_, 0));
    CHECK(SetKeyboardState(original_keyboard_state_));
  }

 protected:
  UINT message_type() const { return std::get<0>(GetParam()); }
  const AltGraphEventTestCase& test_case() const {
    return std::get<1>(GetParam());
  }

  const MSG msg_;
  BYTE original_keyboard_state_[256] = {};
  HKL original_keyboard_layout_ = nullptr;
};

}  // namespace

TEST_P(AltGraphEventTest, KeyEventAltGraphModifer) {
  KeyEvent event(msg_);
  if (message_type() == WM_CHAR) {
    // By definition, if we receive a WM_CHAR message when Control and Alt are
    // pressed, it indicates AltGraph.
    EXPECT_EQ(event.flags() & (EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN),
              EF_ALTGR_DOWN);
  } else {
    EXPECT_EQ(event.flags() & (EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN),
              test_case().expected_flags);
  }
}

INSTANTIATE_TEST_CASE_P(
    WM_KEY,
    AltGraphEventTest,
    ::testing::Combine(::testing::Values(WM_KEYDOWN, WM_KEYUP),
                       ::testing::ValuesIn(kAltGraphEventTestCases)));
INSTANTIATE_TEST_CASE_P(
    WM_CHAR,
    AltGraphEventTest,
    ::testing::Combine(::testing::Values(WM_CHAR),
                       ::testing::ValuesIn(kAltGraphEventTestCases)));

#endif  // defined(OS_WIN)

}  // namespace ui
