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..9bb30f4723dfcfbb5efe856ebe3d5ba6dce56296 |
| --- /dev/null |
| +++ b/ui/events/ozone/evdev/gamepad_event_converter_evdev_unittest.cc |
| @@ -0,0 +1,234 @@ |
| +// 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/gmock/include/gmock/gmock.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/gamepad/gamepad_event.h" |
| +#include "ui/events/ozone/gamepad/gamepad_observer.h" |
| +#include "ui/events/ozone/gamepad/gamepad_provider_ozone.h" |
| +#include "ui/events/ozone/gamepad/webgamepad_constants.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" |
| + |
| +namespace { |
| + |
| +const char kTestDevicePath[] = "/dev/input/test-device"; |
| + |
| +class TestGamepadObserver : public ui::GamepadObserver { |
| + public: |
| + TestGamepadObserver() { |
| + ui::GamepadProviderOzone::GetInstance()->AddGamepadObserver(this); |
| + } |
| + |
| + ~TestGamepadObserver() override { |
| + ui::GamepadProviderOzone::GetInstance()->RemoveGamepadObserver(this); |
| + } |
| + void OnGamepadEvent(const ui::GamepadEvent& event) override { |
| + events.push_back(event); |
| + } |
| + |
| + std::vector<ui::GamepadEvent> events; |
| +}; |
| + |
| +// xbox controller with wrong abs_info. |
| +const ui::DeviceAbsoluteAxis kWrongAbsGamepadAbsAxes[] = { |
|
spang
2017/04/21 05:38:46
I'm confused by this - why is it different from th
jkwang
2017/04/25 21:16:41
Sure. I am removing this and will add some other g
|
| + {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()); |
| + } |
| + |
| + private: |
| + void DispatchEventForTest(ui::Event* 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_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(GamepadEventConverterEvdevTest); |
| +}; |
| + |
| +TEST_F(GamepadEventConverterEvdevTest, GamepadButton) { |
| + TestGamepadObserver observer; |
| + std::unique_ptr<ui::GamepadEventConverterEvdev> dev = |
| + base::WrapUnique(CreateDevice(kXboxGamepad)); |
| + // Generial key mapping test. |
| + struct input_event mock_kernel_queue[] = { |
| + {{0, 0}, EV_KEY, BTN_A, 1}, {{0, 0}, EV_KEY, BTN_B, 1}, |
|
spang
2017/04/21 05:38:46
Please prefer real data for tests. To capture data
|
| + {{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}, |
| + }; |
| + |
| + size_t event_size = arraysize(mock_kernel_queue); |
| + for (unsigned i = 0; i < event_size; ++i) { |
| + dev->ProcessEvent(mock_kernel_queue[i]); |
| + EXPECT_EQ(observer.events.size(), i + 1); |
| + EXPECT_EQ(observer.events[i].get_type(), GamepadEventType::BUTTON); |
| + EXPECT_EQ(observer.events[i].get_code(), i); |
| + EXPECT_EQ(observer.events[i].get_value(), mock_kernel_queue[i].value); |
| + } |
| +} |
| + |
| +struct ExpectedEvent { |
| + GamepadEventType type; |
| + uint16_t code; |
| + double value; |
| +}; |
| + |
| +TEST_F(GamepadEventConverterEvdevTest, GamepadAbs) { |
| + TestGamepadObserver observer; |
| + std::unique_ptr<ui::GamepadEventConverterEvdev> dev = |
| + base::WrapUnique(CreateDevice(kXboxGamepad)); |
| + |
| + 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}, |
| + }; |
| + |
| + struct ExpectedEvent expected_events[] = { |
| + {GamepadEventType::BUTTON, 14, -1}, {GamepadEventType::BUTTON, 14, 0}, |
| + {GamepadEventType::BUTTON, 15, 1}, {GamepadEventType::BUTTON, 15, 0}, |
| + {GamepadEventType::BUTTON, 12, -1}, {GamepadEventType::BUTTON, 12, 0}, |
| + {GamepadEventType::BUTTON, 13, 1}, {GamepadEventType::BUTTON, 13, 0}, |
| + {GamepadEventType::AXIS, 0, -1}, {GamepadEventType::AXIS, 0, 1}, |
| + {GamepadEventType::AXIS, 0, 0}}; |
| + |
| + for (unsigned i = 0; i < arraysize(mock_kernel_queue); ++i) { |
| + dev->ProcessEvent(mock_kernel_queue[i]); |
| + EXPECT_EQ(observer.events.size(), i + 1); |
| + EXPECT_EQ(observer.events[i].get_type(), expected_events[i].type); |
| + EXPECT_EQ(observer.events[i].get_code(), expected_events[i].code); |
| + EXPECT_EQ(observer.events[i].get_value(), expected_events[i].value); |
| + } |
| +} |
| + |
| +TEST_F(GamepadEventConverterEvdevTest, GamepadAbsWithWrongAbsInfo) { |
| + TestGamepadObserver observer; |
| + 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}, |
| + }; |
| + |
| + struct ExpectedEvent expected_events[] = { |
| + {GamepadEventType::BUTTON, 14, -1}, {GamepadEventType::BUTTON, 14, 0}, |
| + {GamepadEventType::BUTTON, 15, 1}, {GamepadEventType::BUTTON, 15, 0}, |
| + {GamepadEventType::BUTTON, 12, -1}, {GamepadEventType::BUTTON, 12, 0}, |
| + {GamepadEventType::BUTTON, 13, 1}, {GamepadEventType::BUTTON, 13, 0}, |
| + {GamepadEventType::AXIS, 0, -1}, {GamepadEventType::AXIS, 0, 0}, |
| + {GamepadEventType::AXIS, 0, 1}}; |
| + |
| + for (unsigned i = 0; i < arraysize(mock_kernel_queue); ++i) { |
| + dev->ProcessEvent(mock_kernel_queue[i]); |
| + EXPECT_EQ(observer.events.size(), i + 1); |
| + EXPECT_EQ(observer.events[i].get_type(), expected_events[i].type); |
| + EXPECT_EQ(observer.events[i].get_code(), expected_events[i].code); |
| + EXPECT_EQ(observer.events[i].get_value(), expected_events[i].value); |
| + } |
| +} |
| + |
| +} // namespace ui |