Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(708)

Unified Diff: ui/events/ozone/evdev/gamepad_event_converter_evdev_unittest.cc

Issue 2805793002: ozone: evdev: Add gamepad support (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698