Chromium Code Reviews| Index: ui/events/ozone/evdev/gamepad_event_converter_evdev_unittest.cc |
| diff --git a/ui/events/ozone/evdev/gamepad_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/gamepad_event_converter_evdev_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..00f6aa3055247a470e95b5cacda39027097fc0c8 |
| --- /dev/null |
| +++ b/ui/events/ozone/evdev/gamepad_event_converter_evdev_unittest.cc |
| @@ -0,0 +1,329 @@ |
| +// Copyright 2014 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/ozone/evdev/gamepad_event_converter_evdev.h" |
| + |
| +#include <errno.h> |
| +#include <fcntl.h> |
| +#include <linux/input.h> |
| +#include <unistd.h> |
| + |
| +#include <memory> |
| +#include <queue> |
| +#include <utility> |
| +#include <vector> |
| + |
| +#include "base/bind.h" |
| +#include "base/files/file_util.h" |
| +#include "base/macros.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/posix/eintr_wrapper.h" |
| +#include "base/run_loop.h" |
| +#include "base/time/time.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "ui/events/event.h" |
| +#include "ui/events/ozone/device/device_manager.h" |
| +#include "ui/events/ozone/evdev/event_converter_test_util.h" |
| +#include "ui/events/ozone/evdev/event_device_test_util.h" |
| +#include "ui/events/ozone/evdev/event_factory_evdev.h" |
| +#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" |
| +#include "ui/events/platform/platform_event_dispatcher.h" |
| +#include "ui/events/platform/platform_event_source.h" |
| +#include "ui/events/webgamepad_constants.h" |
| + |
| +namespace { |
| + |
| +const char kTestDevicePath[] = "/dev/input/test-device"; |
| + |
| +// xbox controller with wrong abs_info. |
|
spang
2017/04/13 00:52:20
What does "wrong" mean here?
jkwang
2017/04/19 19:42:23
Done.
|
| +const ui::DeviceAbsoluteAxis kWrongAbsGamepadAbsAxes[] = { |
| + {ABS_X, {127, 0, 255, 0, 255}}, |
| + {ABS_Y, {0, 0, 255, 0, 10}}, |
| + {ABS_Z, {0, 0, 255, 0, 0}}, |
| + {ABS_RX, {0, -32768, 32767, 16, 128}}, |
| + {ABS_RY, {0, -32768, 32767, 16, 128}}, |
| + {ABS_RZ, {0, 0, 255, 0, 0}}, |
| + {ABS_HAT0X, {0, -1, 1, 0, 0}}, |
| + {ABS_HAT0Y, {0, -1, 1, 0, 0}}}; |
| + |
| +const ui::DeviceCapabilities kWrongAbsGamepad = { |
| + /* path */ |
| + "/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.2/1-2.2:1.0/" |
| + "input/input38/event11", |
| + /* name */ "Microsoft X-Box 360 pad", |
| + /* phys */ "usb-0000:00:14.0-2.2/input0", |
| + /* uniq */ "", |
| + /* bustype */ "0011", |
| + /* vendor */ "045e", |
| + /* product */ "028e", |
| + /* version */ "0114", |
| + /* prop */ "0", |
| + /* ev */ "20000b", |
| + /* key */ "7cdb000000000000 0 0 0 0", |
| + /* rel */ "0", |
| + /* abs */ "3003f", |
| + /* msc */ "0", |
| + /* sw */ "0", |
| + /* led */ "0", |
| + /* ff */ "0", |
| + kWrongAbsGamepadAbsAxes, |
| + arraysize(kWrongAbsGamepadAbsAxes), |
| +}; |
| + |
| +} // namespace |
| + |
| +namespace ui { |
| +class GamepadEventConverterEvdevTest : public testing::Test { |
| + public: |
| + GamepadEventConverterEvdevTest() {} |
| + |
| + // Overriden from testing::Test: |
| + void SetUp() override { |
| + device_manager_ = ui::CreateDeviceManagerForTest(); |
| + event_factory_ = ui::CreateEventFactoryEvdevForTest( |
| + nullptr, device_manager_.get(), |
| + ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine(), |
| + base::Bind(&GamepadEventConverterEvdevTest::DispatchEventForTest, |
| + base::Unretained(this))); |
| + dispatcher_ = |
| + ui::CreateDeviceEventDispatcherEvdevForTest(event_factory_.get()); |
| + } |
| + |
| + ui::GamepadEventConverterEvdev* CreateDevice( |
| + const ui::DeviceCapabilities& caps) { |
| + int evdev_io[2]; |
| + if (pipe(evdev_io)) |
| + PLOG(FATAL) << "failed pipe"; |
| + ui::ScopedInputDevice events_in(evdev_io[0]); |
| + ui::ScopedInputDevice events_out(evdev_io[1]); |
| + |
| + ui::EventDeviceInfo devinfo; |
| + CapabilitiesToDeviceInfo(caps, &devinfo); |
| + return new ui::GamepadEventConverterEvdev(std::move(events_in), |
| + base::FilePath(kTestDevicePath), |
| + 1, devinfo, dispatcher_.get()); |
| + } |
| + |
| + unsigned DispatchedEventSize() { return dispatched_events_.size(); } |
| + |
| + std::unique_ptr<ui::GamepadEvent> GetNextEventAndPop() { |
| + auto* event = dispatched_events_.front(); |
| + EXPECT_TRUE(event->IsGamepadEvent()); |
| + dispatched_events_.pop(); |
| + return base::WrapUnique<GamepadEvent>(event->AsGamepadEvent()); |
| + } |
| + |
| + private: |
| + void DispatchEventForTest(ui::Event* event) { |
| + ui::Event* cloned_event = ui::Event::Clone(*event).release(); |
| + dispatched_events_.push(cloned_event); |
| + } |
| + |
| + std::unique_ptr<ui::GamepadEventConverterEvdev> gamepad_evdev_; |
| + std::unique_ptr<ui::DeviceManager> device_manager_; |
| + std::unique_ptr<ui::EventFactoryEvdev> event_factory_; |
| + std::unique_ptr<ui::DeviceEventDispatcherEvdev> dispatcher_; |
| + |
| + std::queue<ui::Event*> dispatched_events_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(GamepadEventConverterEvdevTest); |
| +}; |
| + |
| +TEST_F(GamepadEventConverterEvdevTest, GamepadButton) { |
| + std::unique_ptr<ui::GamepadEventConverterEvdev> dev = |
| + base::WrapUnique(CreateDevice(kLinkGamepad)); |
| + |
| + // Generial key mapping test. |
| + struct input_event mock_kernel_queue[] = { |
| + {{0, 0}, EV_KEY, BTN_A, 1}, {{0, 0}, EV_KEY, BTN_B, 1}, |
| + {{0, 0}, EV_KEY, BTN_X, 1}, {{0, 0}, EV_KEY, BTN_Y, 1}, |
| + {{0, 0}, EV_KEY, BTN_TL, 1}, {{0, 0}, EV_KEY, BTN_TR, 1}, |
| + {{0, 0}, EV_KEY, BTN_TL2, 1}, {{0, 0}, EV_KEY, BTN_TR2, 1}, |
| + {{0, 0}, EV_KEY, BTN_SELECT, 1}, {{0, 0}, EV_KEY, BTN_START, 1}, |
| + {{0, 0}, EV_KEY, BTN_THUMBL, 1}, {{0, 0}, EV_KEY, BTN_THUMBR, 1}, |
| + {{0, 0}, EV_ABS, ABS_HAT0Y, -1}, {{0, 0}, EV_ABS, ABS_HAT0Y, 1}, |
| + {{0, 0}, EV_ABS, ABS_HAT0X, -1}, {{0, 0}, EV_ABS, ABS_HAT0X, 1}, |
| + {{0, 0}, EV_KEY, BTN_MODE, 1}, |
| + }; |
| + |
| + for (unsigned i = 0; i < arraysize(mock_kernel_queue); ++i) { |
| + dev->ProcessEvent(mock_kernel_queue[i]); |
| + } |
| + EXPECT_EQ(arraysize(mock_kernel_queue), DispatchedEventSize()); |
| + for (uint16_t i = 0; i < ui::kWebGamepadBtnCnt; ++i) { |
| + EXPECT_EQ(GetNextEventAndPop()->get_code(), i); |
| + } |
| +} |
| + |
| +TEST_F(GamepadEventConverterEvdevTest, GamepadAbs) { |
| + std::unique_ptr<ui::GamepadEventConverterEvdev> dev = |
| + base::WrapUnique(CreateDevice(kLinkGamepad)); |
| + |
| + struct input_event mock_kernel_queue[] = { |
| + {{0, 0}, EV_ABS, ABS_HAT0X, -1}, {{0, 0}, EV_ABS, ABS_HAT0X, 0}, |
| + {{0, 0}, EV_ABS, ABS_HAT0X, 1}, {{0, 0}, EV_ABS, ABS_HAT0X, 0}, |
| + {{0, 0}, EV_ABS, ABS_HAT0Y, -1}, {{0, 0}, EV_ABS, ABS_HAT0Y, 0}, |
| + {{0, 0}, EV_ABS, ABS_HAT0Y, 1}, {{0, 0}, EV_ABS, ABS_HAT0Y, 0}, |
| + {{0, 0}, EV_ABS, ABS_X, -32767}, {{0, 0}, EV_ABS, ABS_X, 32767}, |
| + {{0, 0}, EV_ABS, ABS_X, -3}, |
| + }; |
| + |
| + for (unsigned i = 0; i < arraysize(mock_kernel_queue); ++i) { |
| + dev->ProcessEvent(mock_kernel_queue[i]); |
| + } |
| + EXPECT_EQ(11u, DispatchedEventSize()); |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_PRESSED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_LEFT); |
| + EXPECT_EQ(event->get_value(), -1); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_RELEASED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_LEFT); |
| + EXPECT_EQ(event->get_value(), 0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_PRESSED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_RIGHT); |
| + EXPECT_EQ(event->get_value(), 1); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_RELEASED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_RIGHT); |
| + EXPECT_EQ(event->get_value(), 0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_PRESSED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_UP); |
| + EXPECT_EQ(event->get_value(), -1); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_RELEASED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_UP); |
| + EXPECT_EQ(event->get_value(), 0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_PRESSED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_DOWN); |
| + EXPECT_EQ(event->get_value(), 1); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_RELEASED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_DOWN); |
| + EXPECT_EQ(event->get_value(), 0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_ABS_MOVED); |
| + EXPECT_EQ(event->get_code(), WG_ABS_X); |
| + EXPECT_EQ(event->get_value(), -1.0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_ABS_MOVED); |
| + EXPECT_EQ(event->get_code(), WG_ABS_X); |
| + EXPECT_EQ(event->get_value(), 1.0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_ABS_MOVED); |
| + EXPECT_EQ(event->get_code(), WG_ABS_X); |
| + EXPECT_EQ(event->get_value(), 0.0); |
| + } |
| +} |
| + |
| +TEST_F(GamepadEventConverterEvdevTest, GamepadAbsWithWrongAbsInfo) { |
| + std::unique_ptr<ui::GamepadEventConverterEvdev> dev = |
| + base::WrapUnique(CreateDevice(kWrongAbsGamepad)); |
| + |
| + struct input_event mock_kernel_queue[] = { |
| + {{0, 0}, EV_ABS, ABS_HAT0X, -1}, {{0, 0}, EV_ABS, ABS_HAT0X, 0}, |
| + {{0, 0}, EV_ABS, ABS_HAT0X, 1}, {{0, 0}, EV_ABS, ABS_HAT0X, 0}, |
| + {{0, 0}, EV_ABS, ABS_HAT0Y, -1}, {{0, 0}, EV_ABS, ABS_HAT0Y, 0}, |
| + {{0, 0}, EV_ABS, ABS_HAT0Y, 1}, {{0, 0}, EV_ABS, ABS_HAT0Y, 0}, |
| + {{0, 0}, EV_ABS, ABS_X, 1}, {{0, 0}, EV_ABS, ABS_X, 128}, |
| + {{0, 0}, EV_ABS, ABS_X, 255}, |
| + }; |
| + |
| + for (unsigned i = 0; i < arraysize(mock_kernel_queue); ++i) { |
| + dev->ProcessEvent(mock_kernel_queue[i]); |
| + } |
| + EXPECT_EQ(11u, DispatchedEventSize()); |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_PRESSED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_LEFT); |
| + EXPECT_EQ(event->get_value(), -1); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_RELEASED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_LEFT); |
| + EXPECT_EQ(event->get_value(), 0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_PRESSED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_RIGHT); |
| + EXPECT_EQ(event->get_value(), 1); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_RELEASED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_RIGHT); |
| + EXPECT_EQ(event->get_value(), 0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_PRESSED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_UP); |
| + EXPECT_EQ(event->get_value(), -1); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_RELEASED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_UP); |
| + EXPECT_EQ(event->get_value(), 0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_PRESSED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_DOWN); |
| + EXPECT_EQ(event->get_value(), 1); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_BTN_RELEASED); |
| + EXPECT_EQ(event->get_code(), WG_BUTTON_DPAD_DOWN); |
| + EXPECT_EQ(event->get_value(), 0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_ABS_MOVED); |
| + EXPECT_EQ(event->get_code(), WG_ABS_X); |
| + EXPECT_EQ(event->get_value(), -1.0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_ABS_MOVED); |
| + EXPECT_EQ(event->get_code(), WG_ABS_X); |
| + EXPECT_EQ(event->get_value(), 0); |
| + } |
| + { |
| + auto event = GetNextEventAndPop(); |
| + EXPECT_EQ(event->type(), ET_GAMEPAD_ABS_MOVED); |
| + EXPECT_EQ(event->get_code(), WG_ABS_X); |
| + EXPECT_EQ(event->get_value(), 1); |
| + } |
| +} |
| + |
| +} // namespace ui |