13ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// Copyright (c) 2012 The Chromium Authors. All rights reserved.
23ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// Use of this source code is governed by a BSD-style license that can be
33ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// found in the LICENSE file.
43ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
53ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "ppapi/tests/test_input_event.h"
63ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
73ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "ppapi/c/pp_errors.h"
83ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "ppapi/c/ppb_input_event.h"
93ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "ppapi/cpp/input_event.h"
101eb4e64eed08837b85a375d6a953503daa844f07Daniel Dunbar#include "ppapi/cpp/module.h"
111eb4e64eed08837b85a375d6a953503daa844f07Daniel Dunbar#include "ppapi/tests/test_utils.h"
123ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "ppapi/tests/testing_instance.h"
133ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
143ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel DunbarREGISTER_TEST_CASE(InputEvent);
153ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
163ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbarnamespace {
172c6f6f3c170502c5b810102cf85f05732a2aa9d0Daniel Dunbar
18af20afb761a2426cd715fb8db36b90092e0bb6efDaniel Dunbarconst uint32_t kSpaceChar = 0x20;
19af20afb761a2426cd715fb8db36b90092e0bb6efDaniel Dunbarconst char* kSpaceString = " ";
202c6f6f3c170502c5b810102cf85f05732a2aa9d0Daniel Dunbarconst char* kSpaceCode = "Space";
21510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
223ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#define FINISHED_WAITING_MESSAGE "TEST_INPUT_EVENT_FINISHED_WAITING"
23dd98e2cad165ca73c769e4f105a4e47c2216387aDaniel Dunbar
248f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbarpp::Point GetCenter(const pp::Rect& rect) {
258f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  return pp::Point(
260de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      rect.x() + rect.width() / 2,
2730bc7e8e560941f730fd94109e81ac600767b0abChris Lattner      rect.y() + rect.height() / 2);
284ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar}
29af07f936b698575f2c91f1c1134c116f1ef0deddDaniel Dunbar
30365c02f65be026f90e67a8e00e7b827cee60e228Daniel Dunbar}  // namespace
313ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
324ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbarvoid TestInputEvent::RunTests(const std::string& filter) {
331b3bb6efc59a21f794b534078f9ae7e95393f510Daniel Dunbar  RUN_TEST(Events, filter);
343ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  RUN_TEST(EventsLatencyTracking, filter);
350f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola
360f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola  // The AcceptTouchEvent_N tests should not be run when the filter is empty;
370f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola  // they can only be run one at a time.
380f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola  // TODO(dmichael): Figure out a way to make these run in the same test fixture
39734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  //                 instance.
40734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  if (!ShouldRunAllTests(filter)) {
41734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar    RUN_TEST(AcceptTouchEvent_1, filter);
42734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar    RUN_TEST(AcceptTouchEvent_2, filter);
43734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar    RUN_TEST(AcceptTouchEvent_3, filter);
44734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar    RUN_TEST(AcceptTouchEvent_4, filter);
45237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  }
460de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar}
47ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar
48ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel DunbarTestInputEvent::TestInputEvent(TestingInstance* instance)
49ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar    : TestCase(instance),
50ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      input_event_interface_(NULL),
51ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      mouse_input_event_interface_(NULL),
52ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      wheel_input_event_interface_(NULL),
53ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      keyboard_input_event_interface_(NULL),
54ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      touch_input_event_interface_(NULL),
55ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      nested_event_(instance->pp_instance()),
56e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar      view_rect_(),
57e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar      expected_input_event_(0),
58ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      received_expected_event_(false),
59ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      received_finish_message_(false),
60ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      enable_latency_tracking_(false),
61ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      last_latency_tracking_successful_(false) {
620de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar}
630de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar
64ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel DunbarTestInputEvent::~TestInputEvent() {
65ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar  // Remove the special listener that only responds to a
66ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar  // FINISHED_WAITING_MESSAGE string. See Init for where it gets added.
67ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar  std::string js_code;
68ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar  js_code += "var plugin = document.getElementById('plugin');"
69ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar             "plugin.removeEventListener('message',"
70ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar             "                           plugin.wait_for_messages_handler);"
71ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar             "delete plugin.wait_for_messages_handler;";
72e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar  instance_->EvalScript(js_code);
73e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar}
74e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar
75e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbarbool TestInputEvent::Init() {
76e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar  input_event_interface_ = static_cast<const PPB_InputEvent*>(
7730bc7e8e560941f730fd94109e81ac600767b0abChris Lattner      pp::Module::Get()->GetBrowserInterface(PPB_INPUT_EVENT_INTERFACE));
7830bc7e8e560941f730fd94109e81ac600767b0abChris Lattner  input_event_private_interface_ = static_cast<const PPB_InputEvent_Private*>(
7930bc7e8e560941f730fd94109e81ac600767b0abChris Lattner      pp::Module::Get()->GetBrowserInterface(PPB_INPUTEVENT_PRIVATE_INTERFACE));
8030bc7e8e560941f730fd94109e81ac600767b0abChris Lattner  mouse_input_event_interface_ = static_cast<const PPB_MouseInputEvent*>(
81ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      pp::Module::Get()->GetBrowserInterface(
82ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar          PPB_MOUSE_INPUT_EVENT_INTERFACE));
83237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  wheel_input_event_interface_ = static_cast<const PPB_WheelInputEvent*>(
84237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar      pp::Module::Get()->GetBrowserInterface(
850de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar          PPB_WHEEL_INPUT_EVENT_INTERFACE));
86237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  keyboard_input_event_interface_ = static_cast<const PPB_KeyboardInputEvent*>(
87237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar      pp::Module::Get()->GetBrowserInterface(
88237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar          PPB_KEYBOARD_INPUT_EVENT_INTERFACE));
89237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  touch_input_event_interface_ = static_cast<const PPB_TouchInputEvent*>(
900de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      pp::Module::Get()->GetBrowserInterface(
91237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar          PPB_TOUCH_INPUT_EVENT_INTERFACE));
92237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar
930de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar  bool success =
940de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      input_event_interface_ &&
950de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      input_event_private_interface_ &&
960de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      mouse_input_event_interface_ &&
970de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      wheel_input_event_interface_ &&
980de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      keyboard_input_event_interface_ &&
990de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      touch_input_event_interface_ &&
1000de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      CheckTestingInterface();
1010de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar
1020de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar  // Set up a listener for our message that signals that all input events have
1030de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar  // been received.
1040de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar  std::string js_code;
1050de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar  // Note the following code is dependent on some features of test_case.html.
1060de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar  // E.g., it is assumed that the DOM element where the plugin is embedded has
107237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  // an id of 'plugin', and there is a function 'IsTestingMessage' that allows
108237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  // us to ignore the messages that are intended for use by the testing
109237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  // framework itself.
110237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  js_code += "var plugin = document.getElementById('plugin');"
111237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar             "var wait_for_messages_handler = function(message_event) {"
112237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar             "  if (!IsTestingMessage(message_event.data) &&"
113237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar             "      message_event.data === '" FINISHED_WAITING_MESSAGE "') {"
114237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar             "    plugin.postMessage('" FINISHED_WAITING_MESSAGE "');"
115237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar             "  }"
116237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar             "};"
117237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar             "plugin.addEventListener('message', wait_for_messages_handler);"
118237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar             // Stash it on the plugin so we can remove it in the destructor.
119237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar             "plugin.wait_for_messages_handler = wait_for_messages_handler;";
120237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  instance_->EvalScript(js_code);
121237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar
122237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  return success;
123237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar}
124237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar
125237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbarpp::InputEvent TestInputEvent::CreateMouseEvent(
126237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar    PP_InputEvent_Type type,
127237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar    PP_InputEvent_MouseButton buttons) {
128237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar  return pp::MouseInputEvent(
129237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar      instance_,
130237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar      type,
131237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar      100,  // time_stamp
132237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar      0,  // modifiers
133237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar      buttons,
134237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar      GetCenter(view_rect_),
135237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar      1,  // click count
1360de9a7beb107a4306d05cf3589f10c3e01cfcee2Daniel Dunbar      pp::Point());  // movement
137237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar}
138237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar
139237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbarpp::InputEvent TestInputEvent::CreateWheelEvent() {
140ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar  return pp::WheelInputEvent(
141ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      instance_,
142ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      100,  // time_stamp
143ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      0,  // modifiers
14430bc7e8e560941f730fd94109e81ac600767b0abChris Lattner      pp::FloatPoint(1, 2),
14530bc7e8e560941f730fd94109e81ac600767b0abChris Lattner      pp::FloatPoint(3, 4),
14630bc7e8e560941f730fd94109e81ac600767b0abChris Lattner      PP_TRUE);  // scroll_by_page
147e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar}
148237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar
149e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbarpp::InputEvent TestInputEvent::CreateKeyEvent(PP_InputEvent_Type type,
150e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar                                              uint32_t key_code,
151e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar                                              const std::string& code) {
152e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar  return pp::KeyboardInputEvent(
153e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar      instance_,
154e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar      type,
155ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      100,  // time_stamp
156ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      0,  // modifiers
157ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      key_code,
158ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      pp::Var(),
159ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      pp::Var(code));
160ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar}
161ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar
162ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbarpp::InputEvent TestInputEvent::CreateCharEvent(const std::string& text) {
163ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar  return pp::KeyboardInputEvent(
164e3d6023cbf99a24609f52adb0af1fa1c6dafefd7Daniel Dunbar      instance_,
165ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      PP_INPUTEVENT_TYPE_CHAR,
166ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      100,  // time_stamp
167ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      0,  // modifiers
168ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      0,  // keycode
169ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      pp::Var(text),
170ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      pp::Var());
171c88aa79a6bdfd445df800006f723f83f39934e98Daniel Dunbar}
172545c28117c64e78521b8b402caa060ba0b58a530Daniel Dunbar
173217acbfa3524d5805fda7900b26c1e779443588dDaniel Dunbarpp::InputEvent TestInputEvent::CreateTouchEvent(PP_InputEvent_Type type,
1743ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar                                                const pp::FloatPoint& point) {
1753ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  PP_TouchPoint touch_point = PP_MakeTouchPoint();
1768f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  touch_point.position = point;
1773ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
178c88aa79a6bdfd445df800006f723f83f39934e98Daniel Dunbar  pp::TouchInputEvent touch_event(instance_, type, 100, 0);
179c88aa79a6bdfd445df800006f723f83f39934e98Daniel Dunbar  touch_event.AddTouchPoint(PP_TOUCHLIST_TYPE_TOUCHES, touch_point);
180c88aa79a6bdfd445df800006f723f83f39934e98Daniel Dunbar  touch_event.AddTouchPoint(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES, touch_point);
181c88aa79a6bdfd445df800006f723f83f39934e98Daniel Dunbar  touch_event.AddTouchPoint(PP_TOUCHLIST_TYPE_TARGETTOUCHES, touch_point);
182c88aa79a6bdfd445df800006f723f83f39934e98Daniel Dunbar
1830f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola  return touch_event;
1840f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola}
1850f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola
1860f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindolavoid TestInputEvent::PostMessageBarrier() {
1870f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola  received_finish_message_ = false;
1880f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola  instance_->PostMessage(pp::Var(FINISHED_WAITING_MESSAGE));
1890f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola  testing_interface_->RunMessageLoop(instance_->pp_instance());
1900f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola  nested_event_.Wait();
1910f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola}
1920f4c59c3beae302b5a3ecea13f2e257bdaad3188Rafael Espindola
193af20afb761a2426cd715fb8db36b90092e0bb6efDaniel Dunbar// Simulates the input event and calls PostMessage to let us know when
194af20afb761a2426cd715fb8db36b90092e0bb6efDaniel Dunbar// we have received all resulting events from the browser.
195510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbarbool TestInputEvent::SimulateInputEvent(
1968e6e70928adebea871389febd9b54ca82821dc87Daniel Dunbar    const pp::InputEvent& input_event) {
197510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  expected_input_event_ = pp::InputEvent(input_event.pp_resource());
198f44c58563286bb448a72ed9c9af5f21718633230Daniel Dunbar  received_expected_event_ = false;
199240c734ee5a57000fdb870109e50102317b2cc3dKovarththanan Rajaratnam  testing_interface_->SimulateInputEvent(instance_->pp_instance(),
200f44c58563286bb448a72ed9c9af5f21718633230Daniel Dunbar                                         input_event.pp_resource());
201240c734ee5a57000fdb870109e50102317b2cc3dKovarththanan Rajaratnam  PostMessageBarrier();
202f44c58563286bb448a72ed9c9af5f21718633230Daniel Dunbar  return received_expected_event_;
203e3fdca2ee0346a41d9cc5ee417a75e66274216f5Jeffrey Yasskin}
204e3fdca2ee0346a41d9cc5ee417a75e66274216f5Jeffrey Yasskin
205f44c58563286bb448a72ed9c9af5f21718633230Daniel Dunbarbool TestInputEvent::AreEquivalentEvents(PP_Resource received,
206e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar                                         PP_Resource expected) {
2078fa01c8f98ff7c8f40fee5014c9c393d806381a4Daniel Dunbar  if (!input_event_interface_->IsInputEvent(received) ||
2088fa01c8f98ff7c8f40fee5014c9c393d806381a4Daniel Dunbar      !input_event_interface_->IsInputEvent(expected)) {
2098fa01c8f98ff7c8f40fee5014c9c393d806381a4Daniel Dunbar    return false;
2108fa01c8f98ff7c8f40fee5014c9c393d806381a4Daniel Dunbar  }
2118fa01c8f98ff7c8f40fee5014c9c393d806381a4Daniel Dunbar
212d5dc9f34ef2288ace0003e1fee011cc9e7d2d040Benjamin Kramer  // Test common fields, except modifiers and time stamp, which may be changed
213d5dc9f34ef2288ace0003e1fee011cc9e7d2d040Benjamin Kramer  // by the browser.
214d5dc9f34ef2288ace0003e1fee011cc9e7d2d040Benjamin Kramer  int32_t received_type = input_event_interface_->GetType(received);
215e26bd90e5f7c1e44dd2b74d84d2f158dc7b983fbDaniel Dunbar  int32_t expected_type = input_event_interface_->GetType(expected);
2160dea4be511706307849d83a89f56695444c718acDaniel Dunbar  if (received_type != expected_type) {
2178fa01c8f98ff7c8f40fee5014c9c393d806381a4Daniel Dunbar    // Allow key down events to match "raw" key down events.
2180dea4be511706307849d83a89f56695444c718acDaniel Dunbar    if (expected_type != PP_INPUTEVENT_TYPE_KEYDOWN &&
2190dea4be511706307849d83a89f56695444c718acDaniel Dunbar        received_type != PP_INPUTEVENT_TYPE_RAWKEYDOWN) {
2208fa01c8f98ff7c8f40fee5014c9c393d806381a4Daniel Dunbar      return false;
221e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar    }
222e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  }
2234c00fcdf98d3d7c4cb47b64f8b770f8f4bff1357Daniel Dunbar
2244c00fcdf98d3d7c4cb47b64f8b770f8f4bff1357Daniel Dunbar  // Test event type-specific fields.
2254c00fcdf98d3d7c4cb47b64f8b770f8f4bff1357Daniel Dunbar  switch (input_event_interface_->GetType(received)) {
2264c00fcdf98d3d7c4cb47b64f8b770f8f4bff1357Daniel Dunbar    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
2274c00fcdf98d3d7c4cb47b64f8b770f8f4bff1357Daniel Dunbar    case PP_INPUTEVENT_TYPE_MOUSEUP:
228ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
229ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar    case PP_INPUTEVENT_TYPE_MOUSEENTER:
230a1e2fd9b580ae583b91d3288d59c00ca9f6a56b8Daniel Dunbar    case PP_INPUTEVENT_TYPE_MOUSELEAVE:
231ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      // Check mouse fields, except position and movement, which may be
232ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      // modified by the renderer.
233ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar      return
234ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar          mouse_input_event_interface_->GetButton(received) ==
235ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar          mouse_input_event_interface_->GetButton(expected) &&
236ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar          mouse_input_event_interface_->GetClickCount(received) ==
237237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar          mouse_input_event_interface_->GetClickCount(expected);
2380311d47665bcdd186af6fc1bcfa40cf186ae7b9aDaniel Dunbar
239ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar    case PP_INPUTEVENT_TYPE_WHEEL:
240e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar      return
241e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          pp::FloatPoint(wheel_input_event_interface_->GetDelta(received)) ==
242e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          pp::FloatPoint(wheel_input_event_interface_->GetDelta(expected)) &&
243e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          pp::FloatPoint(wheel_input_event_interface_->GetTicks(received)) ==
244e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          pp::FloatPoint(wheel_input_event_interface_->GetTicks(expected)) &&
245e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          wheel_input_event_interface_->GetScrollByPage(received) ==
246e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          wheel_input_event_interface_->GetScrollByPage(expected);
247237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar
248e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar    case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
249ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar    case PP_INPUTEVENT_TYPE_KEYDOWN:
250ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar    case PP_INPUTEVENT_TYPE_KEYUP:
251e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar      return
252e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          keyboard_input_event_interface_->GetKeyCode(received) ==
253ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar          keyboard_input_event_interface_->GetKeyCode(expected);
254ec9587d5bed6149f6df8b57192bb787c62aedb1bDaniel Dunbar
255e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar    case PP_INPUTEVENT_TYPE_CHAR:
256e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar      return
257e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          keyboard_input_event_interface_->GetKeyCode(received) ==
258e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          keyboard_input_event_interface_->GetKeyCode(expected) &&
259e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar          pp::Var(pp::PASS_REF,
260e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar              keyboard_input_event_interface_->GetCharacterText(received)) ==
261237a31bf663c8c3783bd71dc7cfbdd0425a8ba69Daniel Dunbar          pp::Var(pp::PASS_REF,
2620311d47665bcdd186af6fc1bcfa40cf186ae7b9aDaniel Dunbar              keyboard_input_event_interface_->GetCharacterText(expected));
263e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar
2648e6e70928adebea871389febd9b54ca82821dc87Daniel Dunbar    case PP_INPUTEVENT_TYPE_TOUCHSTART:
2653ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar    case PP_INPUTEVENT_TYPE_TOUCHMOVE:
266af96def468042cfbed55a4cc12b1bb917ead4f33Daniel Dunbar    case PP_INPUTEVENT_TYPE_TOUCHEND:
267af96def468042cfbed55a4cc12b1bb917ead4f33Daniel Dunbar    case PP_INPUTEVENT_TYPE_TOUCHCANCEL: {
268c88a88f6f7672b6bb831dce9da4acfa0c846975fDaniel Dunbar      if (!touch_input_event_interface_->IsTouchInputEvent(received) ||
2698f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar          !touch_input_event_interface_->IsTouchInputEvent(expected))
27030bc7e8e560941f730fd94109e81ac600767b0abChris Lattner        return false;
27130bc7e8e560941f730fd94109e81ac600767b0abChris Lattner
27230bc7e8e560941f730fd94109e81ac600767b0abChris Lattner      uint32_t touch_count = touch_input_event_interface_->GetTouchCount(
27330bc7e8e560941f730fd94109e81ac600767b0abChris Lattner          received, PP_TOUCHLIST_TYPE_TOUCHES);
27430bc7e8e560941f730fd94109e81ac600767b0abChris Lattner      if (touch_count <= 0 ||
2758f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar          touch_count != touch_input_event_interface_->GetTouchCount(expected,
2768f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar              PP_TOUCHLIST_TYPE_TOUCHES))
277af96def468042cfbed55a4cc12b1bb917ead4f33Daniel Dunbar        return false;
2783ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
279      for (uint32_t i = 0; i < touch_count; ++i) {
280        PP_TouchPoint expected_point = touch_input_event_interface_->
281            GetTouchByIndex(expected, PP_TOUCHLIST_TYPE_TOUCHES, i);
282        PP_TouchPoint received_point = touch_input_event_interface_->
283            GetTouchByIndex(received, PP_TOUCHLIST_TYPE_TOUCHES, i);
284
285        if (expected_point.id != received_point.id ||
286            expected_point.radius != received_point.radius ||
287            expected_point.rotation_angle != received_point.rotation_angle ||
288            expected_point.pressure != received_point.pressure)
289          return false;
290
291        if (expected_point.position.x != received_point.position.x ||
292            expected_point.position.y != received_point.position.y)
293          return false;
294      }
295      return true;
296    }
297
298    default:
299      break;
300  }
301
302  return false;
303}
304
305bool TestInputEvent::HandleInputEvent(const pp::InputEvent& input_event) {
306  // Some events may cause extra events to be generated, so look for the
307  // first one that matches.
308  if (!received_expected_event_) {
309    received_expected_event_ = AreEquivalentEvents(
310        input_event.pp_resource(),
311        expected_input_event_.pp_resource());
312  }
313  // Handle all input events.
314  if (enable_latency_tracking_) {
315    pp::InputEventPrivate private_event(input_event);
316    last_latency_tracking_successful_ = private_event.TraceInputLatency(true);
317  }
318  return true;
319}
320
321void TestInputEvent::HandleMessage(const pp::Var& message_data) {
322  if (message_data.is_string() &&
323      (message_data.AsString() == FINISHED_WAITING_MESSAGE)) {
324    testing_interface_->QuitMessageLoop(instance_->pp_instance());
325    received_finish_message_ = true;
326    nested_event_.Signal();
327  }
328}
329
330void TestInputEvent::DidChangeView(const pp::View& view) {
331  view_rect_ = view.GetRect();
332}
333
334std::string TestInputEvent::TestEventsLatencyTracking() {
335  enable_latency_tracking_ = true;
336  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
337                                             PP_INPUTEVENT_CLASS_TOUCH);
338  PostMessageBarrier();
339
340  ASSERT_TRUE(SimulateInputEvent(CreateTouchEvent(PP_INPUTEVENT_TYPE_TOUCHSTART,
341                                                  pp::FloatPoint(12, 23))));
342  // Without calling StartTrackingLatency() first, TraceInputLatency() won't
343  // take effect and will return false;
344  ASSERT_FALSE(last_latency_tracking_successful_);
345
346  input_event_private_interface_->StartTrackingLatency(
347      instance_->pp_instance());
348
349  ASSERT_TRUE(SimulateInputEvent(CreateTouchEvent(PP_INPUTEVENT_TYPE_TOUCHSTART,
350                                                  pp::FloatPoint(12, 23))));
351  ASSERT_TRUE(last_latency_tracking_successful_);
352
353  PASS();
354}
355
356std::string TestInputEvent::TestEvents() {
357  // Request all input event classes.
358  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
359                                             PP_INPUTEVENT_CLASS_MOUSE |
360                                             PP_INPUTEVENT_CLASS_WHEEL |
361                                             PP_INPUTEVENT_CLASS_KEYBOARD |
362                                             PP_INPUTEVENT_CLASS_TOUCH);
363  PostMessageBarrier();
364
365  // Send the events and check that we received them.
366  ASSERT_TRUE(
367      SimulateInputEvent(CreateMouseEvent(PP_INPUTEVENT_TYPE_MOUSEDOWN,
368                                          PP_INPUTEVENT_MOUSEBUTTON_LEFT)));
369  ASSERT_TRUE(
370      SimulateInputEvent(CreateWheelEvent()));
371  ASSERT_TRUE(
372      SimulateInputEvent(CreateKeyEvent(PP_INPUTEVENT_TYPE_KEYDOWN,
373                                        kSpaceChar, kSpaceCode)));
374  ASSERT_TRUE(
375      SimulateInputEvent(CreateCharEvent(kSpaceString)));
376  ASSERT_TRUE(SimulateInputEvent(CreateTouchEvent(PP_INPUTEVENT_TYPE_TOUCHSTART,
377                                                  pp::FloatPoint(12, 23))));
378  // Request only mouse events.
379  input_event_interface_->ClearInputEventRequest(instance_->pp_instance(),
380                                                 PP_INPUTEVENT_CLASS_WHEEL |
381                                                 PP_INPUTEVENT_CLASS_KEYBOARD);
382  PostMessageBarrier();
383
384  // Check that we only receive mouse events.
385  ASSERT_TRUE(
386      SimulateInputEvent(CreateMouseEvent(PP_INPUTEVENT_TYPE_MOUSEDOWN,
387                                          PP_INPUTEVENT_MOUSEBUTTON_LEFT)));
388  ASSERT_FALSE(
389      SimulateInputEvent(CreateWheelEvent()));
390  ASSERT_FALSE(
391      SimulateInputEvent(CreateKeyEvent(PP_INPUTEVENT_TYPE_KEYDOWN,
392                                        kSpaceChar, kSpaceCode)));
393  ASSERT_FALSE(
394      SimulateInputEvent(CreateCharEvent(kSpaceString)));
395
396  PASS();
397}
398
399std::string TestInputEvent::TestAcceptTouchEvent_1() {
400  // The browser normally sends touch-events to the renderer only if the page
401  // has touch-event handlers. Since test-case.html does not have any
402  // touch-event handler, it would normally not receive any touch events from
403  // the browser. However, if a plugin in the page does accept touch events,
404  // then the browser should start sending touch-events to the page. In this
405  // test, the plugin simply registers for touch-events. The real test is to
406  // verify that the browser knows to send touch-events to the renderer.
407  // If the plugin is removed from the page, then there are no more touch-event
408  // handlers in the page, and browser stops sending touch-events. So to make
409  // it possible to test this properly, the plugin is not removed from the page
410  // at the end of the test.
411  instance_->set_remove_plugin(false);
412  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
413                                             PP_INPUTEVENT_CLASS_MOUSE |
414                                             PP_INPUTEVENT_CLASS_WHEEL |
415                                             PP_INPUTEVENT_CLASS_KEYBOARD |
416                                             PP_INPUTEVENT_CLASS_TOUCH);
417  PASS();
418}
419
420std::string TestInputEvent::TestAcceptTouchEvent_2() {
421  // See comment in TestAcceptTouchEvent_1.
422  instance_->set_remove_plugin(false);
423  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
424                                             PP_INPUTEVENT_CLASS_MOUSE |
425                                             PP_INPUTEVENT_CLASS_WHEEL |
426                                             PP_INPUTEVENT_CLASS_KEYBOARD |
427                                             PP_INPUTEVENT_CLASS_TOUCH);
428  input_event_interface_->ClearInputEventRequest(instance_->pp_instance(),
429                                                 PP_INPUTEVENT_CLASS_TOUCH);
430  PASS();
431}
432
433std::string TestInputEvent::TestAcceptTouchEvent_3() {
434  // See comment in TestAcceptTouchEvent_1.
435  instance_->set_remove_plugin(false);
436  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
437                                             PP_INPUTEVENT_CLASS_MOUSE |
438                                             PP_INPUTEVENT_CLASS_WHEEL |
439                                             PP_INPUTEVENT_CLASS_KEYBOARD);
440  input_event_interface_->RequestFilteringInputEvents(instance_->pp_instance(),
441      PP_INPUTEVENT_CLASS_TOUCH);
442  PASS();
443}
444
445std::string TestInputEvent::TestAcceptTouchEvent_4() {
446  // See comment in TestAcceptTouchEvent_1.
447  instance_->set_remove_plugin(false);
448  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
449                                             PP_INPUTEVENT_CLASS_MOUSE |
450                                             PP_INPUTEVENT_CLASS_WHEEL |
451                                             PP_INPUTEVENT_CLASS_KEYBOARD);
452  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
453                                             PP_INPUTEVENT_CLASS_TOUCH);
454  PASS();
455}
456