Commit 16ce3d88 authored by kpschoedel's avatar kpschoedel Committed by Commit bot

Ozone support for device special cases in keyboard event rewriting.

Keyboard event rewriting has some special cases keyed on the device
name (Apple keyboards) or USB VID/PID (Hotrod remote), which had been
handled by special-case device inspection under X11, and not handled
at all under Ozone. This moves the properties to ui::DeviceDataManager
and makes the use in chromeos::EventRewriter platform-independent.

BUG=471753

Committed: https://crrev.com/711f2fc883c05bb10466fb65fdaf9bc10c909b23
Cr-Commit-Position: refs/heads/master@{#325660}

Review URL: https://codereview.chromium.org/1073573002

Cr-Commit-Position: refs/heads/master@{#327060}
parent aea81ada
...@@ -17,13 +17,14 @@ void VirtualKeyboardTestHelper::SuppressKeyboard() { ...@@ -17,13 +17,14 @@ void VirtualKeyboardTestHelper::SuppressKeyboard() {
ui::DeviceHotplugEventObserver* manager = ui::DeviceHotplugEventObserver* manager =
ui::DeviceDataManager::GetInstance(); ui::DeviceDataManager::GetInstance();
std::vector<ui::TouchscreenDevice> screens; std::vector<ui::TouchscreenDevice> screens;
screens.push_back(ui::TouchscreenDevice( screens.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
"Touchscreen", gfx::Size(1024, 768), 0));
manager->OnTouchscreenDevicesUpdated(screens); manager->OnTouchscreenDevicesUpdated(screens);
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard"));
manager->OnKeyboardDevicesUpdated(keyboards); manager->OnKeyboardDevicesUpdated(keyboards);
} }
......
...@@ -33,7 +33,7 @@ DisplayInfo CreateDisplayInfo(int64 id, ...@@ -33,7 +33,7 @@ DisplayInfo CreateDisplayInfo(int64 id,
ui::TouchscreenDevice CreateTouchscreenDevice(unsigned int id, ui::TouchscreenDevice CreateTouchscreenDevice(unsigned int id,
const gfx::Size& size) { const gfx::Size& size) {
return ui::TouchscreenDevice(id, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, return ui::TouchscreenDevice(id, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL,
size, 0); std::string(), size, 0);
} }
} // namespace } // namespace
......
...@@ -76,10 +76,12 @@ TEST_F(TouchscreenUtilTest, NoTouchscreens) { ...@@ -76,10 +76,12 @@ TEST_F(TouchscreenUtilTest, NoTouchscreens) {
TEST_F(TouchscreenUtilTest, OneToOneMapping) { TEST_F(TouchscreenUtilTest, OneToOneMapping) {
std::vector<ui::TouchscreenDevice> devices; std::vector<ui::TouchscreenDevice> devices;
devices.push_back(ui::TouchscreenDevice( devices.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(800, 600), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "",
devices.push_back(ui::TouchscreenDevice( gfx::Size(800, 600), 0));
2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1024, 768), 0)); devices.push_back(
ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "",
gfx::Size(1024, 768), 0));
AssociateTouchscreens(&displays_, devices); AssociateTouchscreens(&displays_, devices);
...@@ -91,8 +93,9 @@ TEST_F(TouchscreenUtilTest, OneToOneMapping) { ...@@ -91,8 +93,9 @@ TEST_F(TouchscreenUtilTest, OneToOneMapping) {
TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) { TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) {
std::vector<ui::TouchscreenDevice> devices; std::vector<ui::TouchscreenDevice> devices;
devices.push_back(ui::TouchscreenDevice( devices.push_back(
2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1024, 768), 0)); ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "",
gfx::Size(1024, 768), 0));
AssociateTouchscreens(&displays_, devices); AssociateTouchscreens(&displays_, devices);
...@@ -104,10 +107,12 @@ TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) { ...@@ -104,10 +107,12 @@ TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) {
TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) { TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) {
std::vector<ui::TouchscreenDevice> devices; std::vector<ui::TouchscreenDevice> devices;
devices.push_back(ui::TouchscreenDevice( devices.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(801, 600), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "",
devices.push_back(ui::TouchscreenDevice( gfx::Size(801, 600), 0));
2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1023, 768), 0)); devices.push_back(
ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "",
gfx::Size(1023, 768), 0));
AssociateTouchscreens(&displays_, devices); AssociateTouchscreens(&displays_, devices);
...@@ -119,10 +124,12 @@ TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) { ...@@ -119,10 +124,12 @@ TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) {
TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) { TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) {
std::vector<ui::TouchscreenDevice> devices; std::vector<ui::TouchscreenDevice> devices;
devices.push_back(ui::TouchscreenDevice( devices.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1022, 768), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "",
devices.push_back(ui::TouchscreenDevice( gfx::Size(1022, 768), 0));
2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(802, 600), 0)); devices.push_back(
ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "",
gfx::Size(802, 600), 0));
AssociateTouchscreens(&displays_, devices); AssociateTouchscreens(&displays_, devices);
...@@ -134,10 +141,12 @@ TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) { ...@@ -134,10 +141,12 @@ TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) {
TEST_F(TouchscreenUtilTest, MapInternalTouchscreen) { TEST_F(TouchscreenUtilTest, MapInternalTouchscreen) {
std::vector<ui::TouchscreenDevice> devices; std::vector<ui::TouchscreenDevice> devices;
devices.push_back(ui::TouchscreenDevice( devices.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1920, 1080), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "",
devices.push_back(ui::TouchscreenDevice( gfx::Size(1920, 1080), 0));
2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(9999, 888), 0)); devices.push_back(
ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "",
gfx::Size(9999, 888), 0));
AssociateTouchscreens(&displays_, devices); AssociateTouchscreens(&displays_, devices);
......
...@@ -46,9 +46,8 @@ class VirtualKeyboardControllerTest : public AshTestBase { ...@@ -46,9 +46,8 @@ class VirtualKeyboardControllerTest : public AshTestBase {
// Sets the event blocker on the maximized window controller. // Sets the event blocker on the maximized window controller.
void SetEventBlocker( void SetEventBlocker(
scoped_ptr<ScopedDisableInternalMouseAndKeyboard> blocker) { scoped_ptr<ScopedDisableInternalMouseAndKeyboard> blocker) {
Shell::GetInstance() Shell::GetInstance()->maximize_mode_controller()->event_blocker_ =
->maximize_mode_controller() blocker.Pass();
->event_blocker_ = blocker.Pass();
} }
void SetUp() override { void SetUp() override {
...@@ -84,8 +83,8 @@ class MockEventBlocker : public ScopedDisableInternalMouseAndKeyboard { ...@@ -84,8 +83,8 @@ class MockEventBlocker : public ScopedDisableInternalMouseAndKeyboard {
MockEventBlocker() {} MockEventBlocker() {}
~MockEventBlocker() override { ~MockEventBlocker() override {
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard"));
ui::DeviceHotplugEventObserver* manager = ui::DeviceHotplugEventObserver* manager =
ui::DeviceDataManager::GetInstance(); ui::DeviceDataManager::GetInstance();
manager->OnKeyboardDevicesUpdated(keyboards); manager->OnKeyboardDevicesUpdated(keyboards);
...@@ -102,8 +101,8 @@ TEST_F(VirtualKeyboardControllerTest, RestoreKeyboardDevices) { ...@@ -102,8 +101,8 @@ TEST_F(VirtualKeyboardControllerTest, RestoreKeyboardDevices) {
Shell::GetInstance() Shell::GetInstance()
->maximize_mode_controller() ->maximize_mode_controller()
->EnableMaximizeModeWindowManager(true); ->EnableMaximizeModeWindowManager(true);
scoped_ptr<ScopedDisableInternalMouseAndKeyboard> scoped_ptr<ScopedDisableInternalMouseAndKeyboard> blocker(
blocker(new MockEventBlocker); new MockEventBlocker);
SetEventBlocker(blocker.Pass()); SetEventBlocker(blocker.Pass());
} }
...@@ -157,12 +156,13 @@ class VirtualKeyboardControllerAutoTest : public VirtualKeyboardControllerTest, ...@@ -157,12 +156,13 @@ class VirtualKeyboardControllerAutoTest : public VirtualKeyboardControllerTest,
// present and maximized mode is disabled. // present and maximized mode is disabled.
TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfInternalKeyboardPresent) { TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfInternalKeyboardPresent) {
std::vector<ui::TouchscreenDevice> screens; std::vector<ui::TouchscreenDevice> screens;
screens.push_back(ui::TouchscreenDevice( screens.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
"Touchscreen", gfx::Size(1024, 768), 0));
UpdateTouchscreenDevices(screens); UpdateTouchscreenDevices(screens);
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard"));
UpdateKeyboardDevices(keyboards); UpdateKeyboardDevices(keyboards);
ASSERT_FALSE(keyboard::IsKeyboardEnabled()); ASSERT_FALSE(keyboard::IsKeyboardEnabled());
// Remove the internal keyboard. Virtual keyboard should now show. // Remove the internal keyboard. Virtual keyboard should now show.
...@@ -176,8 +176,9 @@ TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfInternalKeyboardPresent) { ...@@ -176,8 +176,9 @@ TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfInternalKeyboardPresent) {
TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfNoTouchScreen) { TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfNoTouchScreen) {
std::vector<ui::TouchscreenDevice> devices; std::vector<ui::TouchscreenDevice> devices;
// Add a touchscreen. Keyboard should deploy. // Add a touchscreen. Keyboard should deploy.
devices.push_back(ui::TouchscreenDevice( devices.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(800, 600), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL,
"Touchscreen", gfx::Size(800, 600), 0));
UpdateTouchscreenDevices(devices); UpdateTouchscreenDevices(devices);
EXPECT_TRUE(keyboard::IsKeyboardEnabled()); EXPECT_TRUE(keyboard::IsKeyboardEnabled());
// Remove touchscreen. Keyboard should hide. // Remove touchscreen. Keyboard should hide.
...@@ -187,12 +188,13 @@ TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfNoTouchScreen) { ...@@ -187,12 +188,13 @@ TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfNoTouchScreen) {
TEST_F(VirtualKeyboardControllerAutoTest, SuppressedIfExternalKeyboardPresent) { TEST_F(VirtualKeyboardControllerAutoTest, SuppressedIfExternalKeyboardPresent) {
std::vector<ui::TouchscreenDevice> screens; std::vector<ui::TouchscreenDevice> screens;
screens.push_back(ui::TouchscreenDevice( screens.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
"Touchscreen", gfx::Size(1024, 768), 0));
UpdateTouchscreenDevices(screens); UpdateTouchscreenDevices(screens);
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard"));
UpdateKeyboardDevices(keyboards); UpdateKeyboardDevices(keyboards);
ASSERT_FALSE(keyboard::IsKeyboardEnabled()); ASSERT_FALSE(keyboard::IsKeyboardEnabled());
ASSERT_TRUE(notified()); ASSERT_TRUE(notified());
...@@ -225,12 +227,12 @@ TEST_F(VirtualKeyboardControllerAutoTest, SuppressedIfExternalKeyboardPresent) { ...@@ -225,12 +227,12 @@ TEST_F(VirtualKeyboardControllerAutoTest, SuppressedIfExternalKeyboardPresent) {
// Tests handling multiple keyboards. Catches crbug.com/430252 // Tests handling multiple keyboards. Catches crbug.com/430252
TEST_F(VirtualKeyboardControllerAutoTest, HandleMultipleKeyboardsPresent) { TEST_F(VirtualKeyboardControllerAutoTest, HandleMultipleKeyboardsPresent) {
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard"));
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard"));
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(3, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); 3, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard"));
UpdateKeyboardDevices(keyboards); UpdateKeyboardDevices(keyboards);
ASSERT_FALSE(keyboard::IsKeyboardEnabled()); ASSERT_FALSE(keyboard::IsKeyboardEnabled());
} }
...@@ -238,12 +240,13 @@ TEST_F(VirtualKeyboardControllerAutoTest, HandleMultipleKeyboardsPresent) { ...@@ -238,12 +240,13 @@ TEST_F(VirtualKeyboardControllerAutoTest, HandleMultipleKeyboardsPresent) {
// Tests maximized mode interaction without disabling the internal keyboard. // Tests maximized mode interaction without disabling the internal keyboard.
TEST_F(VirtualKeyboardControllerAutoTest, EnabledDuringMaximizeMode) { TEST_F(VirtualKeyboardControllerAutoTest, EnabledDuringMaximizeMode) {
std::vector<ui::TouchscreenDevice> screens; std::vector<ui::TouchscreenDevice> screens;
screens.push_back(ui::TouchscreenDevice( screens.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
"Touchscreen", gfx::Size(1024, 768), 0));
UpdateTouchscreenDevices(screens); UpdateTouchscreenDevices(screens);
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
UpdateKeyboardDevices(keyboards); UpdateKeyboardDevices(keyboards);
ASSERT_FALSE(keyboard::IsKeyboardEnabled()); ASSERT_FALSE(keyboard::IsKeyboardEnabled());
// Toggle maximized mode on. // Toggle maximized mode on.
...@@ -261,14 +264,15 @@ TEST_F(VirtualKeyboardControllerAutoTest, EnabledDuringMaximizeMode) { ...@@ -261,14 +264,15 @@ TEST_F(VirtualKeyboardControllerAutoTest, EnabledDuringMaximizeMode) {
// Tests that keyboard gets suppressed in maximized mode. // Tests that keyboard gets suppressed in maximized mode.
TEST_F(VirtualKeyboardControllerAutoTest, SuppressedInMaximizedMode) { TEST_F(VirtualKeyboardControllerAutoTest, SuppressedInMaximizedMode) {
std::vector<ui::TouchscreenDevice> screens; std::vector<ui::TouchscreenDevice> screens;
screens.push_back(ui::TouchscreenDevice( screens.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
"Touchscreen", gfx::Size(1024, 768), 0));
UpdateTouchscreenDevices(screens); UpdateTouchscreenDevices(screens);
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "Keyboard"));
UpdateKeyboardDevices(keyboards); UpdateKeyboardDevices(keyboards);
// Toggle maximized mode on. // Toggle maximized mode on.
Shell::GetInstance() Shell::GetInstance()
...@@ -329,12 +333,13 @@ class VirtualKeyboardControllerAlwaysEnabledTest ...@@ -329,12 +333,13 @@ class VirtualKeyboardControllerAlwaysEnabledTest
// keyboard always enabled flag is active. // keyboard always enabled flag is active.
TEST_F(VirtualKeyboardControllerAlwaysEnabledTest, DoesNotSuppressKeyboard) { TEST_F(VirtualKeyboardControllerAlwaysEnabledTest, DoesNotSuppressKeyboard) {
std::vector<ui::TouchscreenDevice> screens; std::vector<ui::TouchscreenDevice> screens;
screens.push_back(ui::TouchscreenDevice( screens.push_back(
1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL,
"Touchscreen", gfx::Size(1024, 768), 0));
UpdateTouchscreenDevices(screens); UpdateTouchscreenDevices(screens);
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard"));
UpdateKeyboardDevices(keyboards); UpdateKeyboardDevices(keyboards);
ASSERT_TRUE(keyboard::IsKeyboardEnabled()); ASSERT_TRUE(keyboard::IsKeyboardEnabled());
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "ui/base/ime/chromeos/ime_keyboard.h" #include "ui/base/ime/chromeos/ime_keyboard.h"
#include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/chromeos/input_method_manager.h"
#include "ui/events/devices/device_data_manager.h"
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/events/event_utils.h" #include "ui/events/event_utils.h"
#include "ui/events/keycodes/keyboard_code_conversion.h" #include "ui/events/keycodes/keyboard_code_conversion.h"
...@@ -30,13 +31,8 @@ ...@@ -30,13 +31,8 @@
#if defined(USE_X11) #if defined(USE_X11)
#include <X11/extensions/XInput2.h> #include <X11/extensions/XInput2.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#ifndef XI_PROP_PRODUCT_ID
#define XI_PROP_PRODUCT_ID "Device Product ID"
#endif
// Get rid of macros from Xlib.h that conflicts with other parts of the code. // Get rid of macros from Xlib.h that conflicts with other parts of the code.
#undef RootWindow #undef RootWindow
#undef Status #undef Status
...@@ -936,73 +932,17 @@ EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal( ...@@ -936,73 +932,17 @@ EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal(
} }
EventRewriter::DeviceType EventRewriter::KeyboardDeviceAdded(int device_id) { EventRewriter::DeviceType EventRewriter::KeyboardDeviceAdded(int device_id) {
#if defined(USE_X11) if (!ui::DeviceDataManager::HasInstance())
DCHECK_NE(XIAllDevices, device_id);
DCHECK_NE(XIAllMasterDevices, device_id);
if (device_id == XIAllDevices || device_id == XIAllMasterDevices) {
LOG(ERROR) << "Unexpected device_id passed: " << device_id;
return kDeviceUnknown;
}
Atom product_id_atom =
XInternAtom(gfx::GetXDisplay(), XI_PROP_PRODUCT_ID, 1);
int ndevices_return = 0;
XIDeviceInfo* device_info =
XIQueryDevice(gfx::GetXDisplay(), device_id, &ndevices_return);
// Since |device_id| is neither XIAllDevices nor XIAllMasterDevices,
// the number of devices found should be either 0 (not found) or 1.
if (!device_info) {
LOG(ERROR) << "XIQueryDevice: Device ID " << device_id << " is unknown.";
return kDeviceUnknown; return kDeviceUnknown;
} const std::vector<ui::KeyboardDevice>& keyboards =
ui::DeviceDataManager::GetInstance()->keyboard_devices();
DeviceType dev_type = kDeviceUnknown; for (const auto& keyboard : keyboards) {
DCHECK_EQ(1, ndevices_return); if (keyboard.id == device_id) {
for (int i = 0; i < ndevices_return; ++i) { return KeyboardDeviceAddedInternal(
// Get keyboard product and vendor id. keyboard.id, keyboard.name, keyboard.vendor_id, keyboard.product_id);
int vendor_id = kUnknownVendorId;
int product_id = kUnknownProductId;
uint32* product_info = NULL;
Atom type;
int format_return;
unsigned long num_items_return;
unsigned long bytes_after_return;
if (XIGetProperty(gfx::GetXDisplay(),
device_info[i].deviceid,
product_id_atom,
0,
2,
0,
XA_INTEGER,
&type,
&format_return,
&num_items_return,
&bytes_after_return,
reinterpret_cast<unsigned char **>(&product_info)) == 0 &&
product_info) {
vendor_id = product_info[0];
product_id = product_info[1];
} }
}
DCHECK_EQ(device_id, device_info[i].deviceid); // see the comment above. return kDeviceUnknown;
DCHECK(device_info[i].name);
dev_type = KeyboardDeviceAddedInternal(device_info[i].deviceid,
device_info[i].name,
vendor_id,
product_id);
}
XIFreeDeviceInfo(device_info);
return dev_type;
#else
// TODO(spang): Figure out where we can get keyboard vendor/product id from in
// Ozone/Freon version.
return KeyboardDeviceAddedInternal(device_id,
"keyboard",
kUnknownVendorId,
kUnknownProductId);
#endif
} }
} // namespace chromeos } // namespace chromeos
...@@ -15,8 +15,16 @@ InputDevice::InputDevice() ...@@ -15,8 +15,16 @@ InputDevice::InputDevice()
: id(kInvalidId), type(InputDeviceType::INPUT_DEVICE_UNKNOWN) { : id(kInvalidId), type(InputDeviceType::INPUT_DEVICE_UNKNOWN) {
} }
InputDevice::InputDevice(int id, InputDeviceType type) InputDevice::InputDevice(int id, InputDeviceType type, const std::string& name)
: id(id), type(type) { : id(id), type(type), name(name), vendor_id(0), product_id(0) {
}
InputDevice::InputDevice(int id,
InputDeviceType type,
const std::string& name,
uint16_t vendor,
uint16_t product)
: id(id), type(type), name(name), vendor_id(vendor), product_id(product) {
} }
InputDevice::~InputDevice() { InputDevice::~InputDevice() {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef UI_EVENTS_DEVICES_INPUT_DEVICE_H_ #ifndef UI_EVENTS_DEVICES_INPUT_DEVICE_H_
#define UI_EVENTS_DEVICES_INPUT_DEVICE_H_ #define UI_EVENTS_DEVICES_INPUT_DEVICE_H_
#include <stdint.h>
#include <string> #include <string>
#include "ui/events/devices/events_devices_export.h" #include "ui/events/devices/events_devices_export.h"
...@@ -24,7 +25,12 @@ struct EVENTS_DEVICES_EXPORT InputDevice { ...@@ -24,7 +25,12 @@ struct EVENTS_DEVICES_EXPORT InputDevice {
// Creates an invalid input device. // Creates an invalid input device.
InputDevice(); InputDevice();
InputDevice(int id, InputDeviceType type); InputDevice(int id, InputDeviceType type, const std::string& name);
InputDevice(int id,
InputDeviceType type,
const std::string& name,
uint16_t vendor,
uint16_t product);
virtual ~InputDevice(); virtual ~InputDevice();
// ID of the device. This ID is unique between all input devices. // ID of the device. This ID is unique between all input devices.
...@@ -32,6 +38,13 @@ struct EVENTS_DEVICES_EXPORT InputDevice { ...@@ -32,6 +38,13 @@ struct EVENTS_DEVICES_EXPORT InputDevice {
// The type of the input device. // The type of the input device.
InputDeviceType type; InputDeviceType type;
// Name of the device.
std::string name;
// USB-style device identifiers, where available, or 0 if unavailable.
uint16_t vendor_id;
uint16_t product_id;
}; };
} // namespace ui } // namespace ui
......
...@@ -10,8 +10,14 @@ ...@@ -10,8 +10,14 @@
namespace ui { namespace ui {
KeyboardDevice::KeyboardDevice(int id, InputDeviceType type) KeyboardDevice::KeyboardDevice(int id,
: InputDevice(id, type) { InputDeviceType type,
const std::string& name)
: InputDevice(id, type, name) {
}
KeyboardDevice::KeyboardDevice(const InputDevice& input_device)
: InputDevice(input_device) {
} }
} // namespace ui } // namespace ui
...@@ -14,7 +14,8 @@ namespace ui { ...@@ -14,7 +14,8 @@ namespace ui {
// Represents a Keyboard device state. // Represents a Keyboard device state.
struct EVENTS_DEVICES_EXPORT KeyboardDevice : public InputDevice { struct EVENTS_DEVICES_EXPORT KeyboardDevice : public InputDevice {
KeyboardDevice(int id, InputDeviceType type); KeyboardDevice(int id, InputDeviceType type, const std::string& name);
explicit KeyboardDevice(const InputDevice& input_device);
}; };
} // namespace ui } // namespace ui
......
...@@ -15,9 +15,16 @@ TouchscreenDevice::TouchscreenDevice() : touch_points(0) { ...@@ -15,9 +15,16 @@ TouchscreenDevice::TouchscreenDevice() : touch_points(0) {
TouchscreenDevice::TouchscreenDevice(int id, TouchscreenDevice::TouchscreenDevice(int id,
InputDeviceType type, InputDeviceType type,
const std::string& name,
const gfx::Size& size, const gfx::Size& size,
int touch_points) int touch_points)
: InputDevice(id, type), size(size), touch_points(touch_points) { : InputDevice(id, type, name), size(size), touch_points(touch_points) {
}
TouchscreenDevice::TouchscreenDevice(const InputDevice& input_device,
const gfx::Size& size,
int touch_points)
: InputDevice(input_device), size(size), touch_points(touch_points) {
} }
} // namespace ui } // namespace ui
...@@ -20,6 +20,11 @@ struct EVENTS_DEVICES_EXPORT TouchscreenDevice : public InputDevice { ...@@ -20,6 +20,11 @@ struct EVENTS_DEVICES_EXPORT TouchscreenDevice : public InputDevice {
TouchscreenDevice(int id, TouchscreenDevice(int id,
InputDeviceType type, InputDeviceType type,
const std::string& name,
const gfx::Size& size,
int touch_points);
TouchscreenDevice(const InputDevice& input_device,
const gfx::Size& size, const gfx::Size& size,
int touch_points); int touch_points);
......
...@@ -77,10 +77,10 @@ TEST_F(DeviceDataManagerX11Test, NotifyOnDisable) { ...@@ -77,10 +77,10 @@ TEST_F(DeviceDataManagerX11Test, NotifyOnDisable) {
DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance(); DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance();
TestInputDeviceObserver observer(manager); TestInputDeviceObserver observer(manager);
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
SetKeyboardDevices(keyboards); SetKeyboardDevices(keyboards);
EXPECT_TRUE(observer.change_notified()); EXPECT_TRUE(observer.change_notified());
std::vector<KeyboardDevice> devices = manager->keyboard_devices(); std::vector<KeyboardDevice> devices = manager->keyboard_devices();
...@@ -108,10 +108,10 @@ TEST_F(DeviceDataManagerX11Test, TestMultipleDisable) { ...@@ -108,10 +108,10 @@ TEST_F(DeviceDataManagerX11Test, TestMultipleDisable) {
DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance(); DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance();
TestInputDeviceObserver observer(manager); TestInputDeviceObserver observer(manager);
std::vector<ui::KeyboardDevice> keyboards; std::vector<ui::KeyboardDevice> keyboards;
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
keyboards.push_back( keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
SetKeyboardDevices(keyboards); SetKeyboardDevices(keyboards);
EXPECT_TRUE(observer.change_notified()); EXPECT_TRUE(observer.change_notified());
std::vector<KeyboardDevice> devices = manager->keyboard_devices(); std::vector<KeyboardDevice> devices = manager->keyboard_devices();
...@@ -147,10 +147,10 @@ TEST_F(DeviceDataManagerX11Test, UnblockOnDeviceUnplugged) { ...@@ -147,10 +147,10 @@ TEST_F(DeviceDataManagerX11Test, UnblockOnDeviceUnplugged) {
DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance(); DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance();
TestInputDeviceObserver observer(manager); TestInputDeviceObserver observer(manager);
std::vector<ui::KeyboardDevice> all_keyboards; std::vector<ui::KeyboardDevice> all_keyboards;
all_keyboards.push_back( all_keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
all_keyboards.push_back( all_keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
SetKeyboardDevices(all_keyboards); SetKeyboardDevices(all_keyboards);
EXPECT_TRUE(observer.change_notified()); EXPECT_TRUE(observer.change_notified());
std::vector<KeyboardDevice> devices = manager->keyboard_devices(); std::vector<KeyboardDevice> devices = manager->keyboard_devices();
...@@ -165,8 +165,8 @@ TEST_F(DeviceDataManagerX11Test, UnblockOnDeviceUnplugged) { ...@@ -165,8 +165,8 @@ TEST_F(DeviceDataManagerX11Test, UnblockOnDeviceUnplugged) {
// Unplug the disabled device. Should not be notified, since the active list // Unplug the disabled device. Should not be notified, since the active list
// did not change. // did not change.
std::vector<ui::KeyboardDevice> subset_keyboards; std::vector<ui::KeyboardDevice> subset_keyboards;
subset_keyboards.push_back( subset_keyboards.push_back(ui::KeyboardDevice(
ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard"));
SetKeyboardDevices(subset_keyboards); SetKeyboardDevices(subset_keyboards);
EXPECT_FALSE(observer.change_notified()); EXPECT_FALSE(observer.change_notified());
// Replug in the first device. Should be notified of the new device. // Replug in the first device. Should be notified of the new device.
......
...@@ -129,7 +129,7 @@ void TouchFactory::UpdateDeviceList(Display* display) { ...@@ -129,7 +129,7 @@ void TouchFactory::UpdateDeviceList(Display* display) {
reinterpret_cast<XITouchClassInfo*>(xiclassinfo); reinterpret_cast<XITouchClassInfo*>(xiclassinfo);
// Only care direct touch device (such as touch screen) right now // Only care direct touch device (such as touch screen) right now
if (tci->mode == XIDirectTouch) if (tci->mode == XIDirectTouch)
CacheTouchscreenIds(display, devinfo.deviceid); CacheTouchscreenIds(devinfo.deviceid);
} }
} }
} }
...@@ -292,43 +292,19 @@ void TouchFactory::SetPointerDeviceForTest( ...@@ -292,43 +292,19 @@ void TouchFactory::SetPointerDeviceForTest(
} }
} }
void TouchFactory::CacheTouchscreenIds(Display* display, int device_id) { void TouchFactory::CacheTouchscreenIds(int device_id) {
XDevice* device = XOpenDevice(display, device_id); if (!DeviceDataManager::HasInstance())
if (!device)
return; return;
std::vector<TouchscreenDevice> touchscreens =
Atom actual_type_return; DeviceDataManager::GetInstance()->touchscreen_devices();
int actual_format_return; const auto it =
unsigned long nitems_return; std::find_if(touchscreens.begin(), touchscreens.end(),
unsigned long bytes_after_return; [device_id](const TouchscreenDevice& touchscreen) {
unsigned char *prop_return; return touchscreen.id == device_id;
});
const char kDeviceProductIdString[] = "Device Product ID"; // Internal displays will have a vid and pid of 0. Ignore them.
Atom device_product_id_atom = if (it != touchscreens.end() && it->vendor_id && it->product_id)
XInternAtom(display, kDeviceProductIdString, false); touchscreen_ids_.insert(std::make_pair(it->vendor_id, it->product_id));
if (device_product_id_atom != None &&
XGetDeviceProperty(display, device, device_product_id_atom, 0, 2,
False, XA_INTEGER, &actual_type_return,
&actual_format_return, &nitems_return,
&bytes_after_return, &prop_return) == Success) {
if (actual_type_return == XA_INTEGER &&
actual_format_return == 32 &&
nitems_return == 2) {
// An actual_format_return of 32 implies that the returned data is an
// array of longs. See the description of |prop_return| in `man
// XGetDeviceProperty` for details.
long* ptr = reinterpret_cast<long*>(prop_return);
// Internal displays will have a vid and pid of 0. Ignore them.
// ptr[0] is the vid, and ptr[1] is the pid.
if (ptr[0] || ptr[1])
touchscreen_ids_.insert(std::make_pair(ptr[0], ptr[1]));
}
XFree(prop_return);
}
XCloseDevice(display, device);
} }
} // namespace ui } // namespace ui
...@@ -98,7 +98,7 @@ class EVENTS_DEVICES_EXPORT TouchFactory { ...@@ -98,7 +98,7 @@ class EVENTS_DEVICES_EXPORT TouchFactory {
// Requirement for Singleton // Requirement for Singleton
friend struct DefaultSingletonTraits<TouchFactory>; friend struct DefaultSingletonTraits<TouchFactory>;
void CacheTouchscreenIds(Display* display, int id); void CacheTouchscreenIds(int id);
// NOTE: To keep track of touch devices, we currently maintain a lookup table // NOTE: To keep track of touch devices, we currently maintain a lookup table
// to quickly decide if a device is a touch device or not. We also maintain a // to quickly decide if a device is a touch device or not. We also maintain a
......
...@@ -246,6 +246,10 @@ Event::Event(const base::NativeEvent& native_event, ...@@ -246,6 +246,10 @@ Event::Event(const base::NativeEvent& native_event,
source_device_id_ = xiev->sourceid; source_device_id_ = xiev->sourceid;
} }
#endif #endif
#if defined(USE_OZONE)
source_device_id_ =
static_cast<const Event*>(native_event)->source_device_id();
#endif
} }
Event::Event(const Event& copy) Event::Event(const Event& copy)
......
...@@ -16,8 +16,14 @@ namespace ui { ...@@ -16,8 +16,14 @@ namespace ui {
EventConverterEvdev::EventConverterEvdev(int fd, EventConverterEvdev::EventConverterEvdev(int fd,
const base::FilePath& path, const base::FilePath& path,
int id, int id,
InputDeviceType type) InputDeviceType type,
: fd_(fd), path_(path), id_(id), type_(type), ignore_events_(false) { const std::string& name,
uint16_t vendor_id,
uint16_t product_id)
: fd_(fd),
path_(path),
input_device_(id, type, name, vendor_id, product_id),
ignore_events_(false) {
} }
EventConverterEvdev::~EventConverterEvdev() { EventConverterEvdev::~EventConverterEvdev() {
......
...@@ -26,14 +26,19 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev ...@@ -26,14 +26,19 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev
EventConverterEvdev(int fd, EventConverterEvdev(int fd,
const base::FilePath& path, const base::FilePath& path,
int id, int id,
InputDeviceType type); InputDeviceType type,
const std::string& name,
uint16_t vendor_id,
uint16_t product_id);
~EventConverterEvdev() override; ~EventConverterEvdev() override;
int id() const { return id_; } int id() const { return input_device_.id; }
const base::FilePath& path() const { return path_; } const base::FilePath& path() const { return path_; }
InputDeviceType type() const { return type_; } InputDeviceType type() const { return input_device_.type; }
const InputDevice& input_device() const { return input_device_; }
void set_ignore_events(bool ignore_events) { ignore_events_ = ignore_events; } void set_ignore_events(bool ignore_events) { ignore_events_ = ignore_events; }
...@@ -91,11 +96,9 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev ...@@ -91,11 +96,9 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev
// Path to input device. // Path to input device.
base::FilePath path_; base::FilePath path_;
// Uniquely identifies an event converter. // Input device information, including id (which uniquely identifies an
int id_; // event converter) and type.
InputDevice input_device_;
// Type (internal or external).
InputDeviceType type_;
// Whether events from the device should be ignored. // Whether events from the device should be ignored.
bool ignore_events_; bool ignore_events_;
......
...@@ -31,7 +31,13 @@ EventConverterEvdevImpl::EventConverterEvdevImpl( ...@@ -31,7 +31,13 @@ EventConverterEvdevImpl::EventConverterEvdevImpl(
const EventDeviceInfo& devinfo, const EventDeviceInfo& devinfo,
CursorDelegateEvdev* cursor, CursorDelegateEvdev* cursor,
DeviceEventDispatcherEvdev* dispatcher) DeviceEventDispatcherEvdev* dispatcher)
: EventConverterEvdev(fd, path, id, type), : EventConverterEvdev(fd,
path,
id,
type,
devinfo.name(),
devinfo.vendor_id(),
devinfo.product_id()),
has_keyboard_(devinfo.HasKeyboard()), has_keyboard_(devinfo.HasKeyboard()),
has_touchpad_(devinfo.HasTouchpad()), has_touchpad_(devinfo.HasTouchpad()),
has_caps_lock_led_(devinfo.HasLedEvent(LED_CAPSL)), has_caps_lock_led_(devinfo.HasLedEvent(LED_CAPSL)),
...@@ -178,7 +184,8 @@ void EventConverterEvdevImpl::OnKeyChange(unsigned int key, ...@@ -178,7 +184,8 @@ void EventConverterEvdevImpl::OnKeyChange(unsigned int key,
// State transition: !(down) -> (down) // State transition: !(down) -> (down)
key_state_.set(key, down); key_state_.set(key, down);
dispatcher_->DispatchKeyEvent(KeyEventParams(id_, key, down, timestamp)); dispatcher_->DispatchKeyEvent(
KeyEventParams(input_device_.id, key, down, timestamp));
} }
void EventConverterEvdevImpl::ReleaseKeys() { void EventConverterEvdevImpl::ReleaseKeys() {
...@@ -223,9 +230,9 @@ void EventConverterEvdevImpl::OnButtonChange(int code, ...@@ -223,9 +230,9 @@ void EventConverterEvdevImpl::OnButtonChange(int code,
mouse_button_state_.set(button_offset, down); mouse_button_state_.set(button_offset, down);
dispatcher_->DispatchMouseButtonEvent( dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams(
MouseButtonEventParams(id_, cursor_->GetLocation(), code, down, input_device_.id, cursor_->GetLocation(), code, down,
/* allow_remap */ true, timestamp)); /* allow_remap */ true, timestamp));
} }
void EventConverterEvdevImpl::FlushEvents(const input_event& input) { void EventConverterEvdevImpl::FlushEvents(const input_event& input) {
...@@ -234,8 +241,9 @@ void EventConverterEvdevImpl::FlushEvents(const input_event& input) { ...@@ -234,8 +241,9 @@ void EventConverterEvdevImpl::FlushEvents(const input_event& input) {
cursor_->MoveCursor(gfx::Vector2dF(x_offset_, y_offset_)); cursor_->MoveCursor(gfx::Vector2dF(x_offset_, y_offset_));
dispatcher_->DispatchMouseMoveEvent(MouseMoveEventParams( dispatcher_->DispatchMouseMoveEvent(
id_, cursor_->GetLocation(), TimeDeltaFromInputEvent(input))); MouseMoveEventParams(input_device_.id, cursor_->GetLocation(),
TimeDeltaFromInputEvent(input)));
x_offset_ = 0; x_offset_ = 0;
y_offset_ = 0; y_offset_ = 0;
......
...@@ -17,6 +17,11 @@ namespace ui { ...@@ -17,6 +17,11 @@ namespace ui {
namespace { namespace {
// USB vendor and product strings are pragmatically limited to 126
// characters each, so device names more than twice that should be
// unusual.
const size_t kMaximumDeviceNameLength = 256;
bool GetEventBits(int fd, unsigned int type, void* buf, unsigned int size) { bool GetEventBits(int fd, unsigned int type, void* buf, unsigned int size) {
if (ioctl(fd, EVIOCGBIT(type, size), buf) < 0) { if (ioctl(fd, EVIOCGBIT(type, size), buf) < 0) {
PLOG(ERROR) << "EVIOCGBIT(" << type << ", " << size << ") on fd " << fd; PLOG(ERROR) << "EVIOCGBIT(" << type << ", " << size << ") on fd " << fd;
...@@ -43,6 +48,27 @@ bool GetAbsInfo(int fd, int code, struct input_absinfo* absinfo) { ...@@ -43,6 +48,27 @@ bool GetAbsInfo(int fd, int code, struct input_absinfo* absinfo) {
return true; return true;
} }
bool GetDeviceName(int fd, std::string* name) {
char device_name[kMaximumDeviceNameLength];
if (ioctl(fd, EVIOCGNAME(kMaximumDeviceNameLength - 1), &device_name) < 0) {
PLOG(INFO) << "Can't read device name on fd " << fd;
return false;
}
*name = device_name;
return true;
}
bool GetDeviceIdentifiers(int fd, uint16_t* vendor, uint16_t* product) {
struct input_id evdev_id;
if (ioctl(fd, EVIOCGID, &evdev_id) < 0) {
PLOG(INFO) << "Can't read device name on fd " << fd;
return false;
}
*vendor = evdev_id.vendor;
*product = evdev_id.product;
return true;
}
// |request| needs to be the equivalent to: // |request| needs to be the equivalent to:
// struct input_mt_request_layout { // struct input_mt_request_layout {
// uint32_t code; // uint32_t code;
...@@ -135,6 +161,12 @@ bool EventDeviceInfo::Initialize(int fd) { ...@@ -135,6 +161,12 @@ bool EventDeviceInfo::Initialize(int fd) {
slots->assign(request_slots, request_slots + max_num_slots); slots->assign(request_slots, request_slots + max_num_slots);
} }
if (!GetDeviceName(fd, &name_))
return false;
if (!GetDeviceIdentifiers(fd, &vendor_id_, &product_id_))
return false;
return true; return true;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <limits.h> #include <limits.h>
#include <linux/input.h> #include <linux/input.h>
#include <string>
#include <vector> #include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
...@@ -80,6 +81,11 @@ class EVENTS_OZONE_EVDEV_EXPORT EventDeviceInfo { ...@@ -80,6 +81,11 @@ class EVENTS_OZONE_EVDEV_EXPORT EventDeviceInfo {
unsigned int slot, unsigned int slot,
int32_t default_value) const; int32_t default_value) const;
// Device identification.
const std::string& name() const { return name_; }
uint16_t vendor_id() const { return vendor_id_; }
uint16_t product_id() const { return product_id_; }
// Check input device properties. // Check input device properties.
bool HasProp(unsigned int code) const; bool HasProp(unsigned int code) const;
...@@ -150,6 +156,11 @@ class EVENTS_OZONE_EVDEV_EXPORT EventDeviceInfo { ...@@ -150,6 +156,11 @@ class EVENTS_OZONE_EVDEV_EXPORT EventDeviceInfo {
// Store the values for the multi-touch properties for each slot. // Store the values for the multi-touch properties for each slot.
std::vector<int32_t> slot_values_[EVDEV_ABS_MT_COUNT]; std::vector<int32_t> slot_values_[EVDEV_ABS_MT_COUNT];
// Device identification.
std::string name_;
uint16_t vendor_id_;
uint16_t product_id_;
DISALLOW_COPY_AND_ASSIGN(EventDeviceInfo); DISALLOW_COPY_AND_ASSIGN(EventDeviceInfo);
}; };
......
...@@ -152,7 +152,8 @@ scoped_ptr<SystemInputInjector> EventFactoryEvdev::CreateSystemInputInjector() { ...@@ -152,7 +152,8 @@ scoped_ptr<SystemInputInjector> EventFactoryEvdev::CreateSystemInputInjector() {
void EventFactoryEvdev::DispatchKeyEvent(const KeyEventParams& params) { void EventFactoryEvdev::DispatchKeyEvent(const KeyEventParams& params) {
TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchKeyEvent", "device", TRACE_EVENT1("evdev", "EventFactoryEvdev::DispatchKeyEvent", "device",
params.device_id); params.device_id);
keyboard_.OnKeyChange(params.code, params.down, params.timestamp); keyboard_.OnKeyChange(params.code, params.down, params.timestamp,
params.device_id);
} }
void EventFactoryEvdev::DispatchMouseMoveEvent( void EventFactoryEvdev::DispatchMouseMoveEvent(
......
...@@ -101,7 +101,7 @@ scoped_ptr<EventConverterEvdev> CreateConverter( ...@@ -101,7 +101,7 @@ scoped_ptr<EventConverterEvdev> CreateConverter(
// Touchscreen: use TouchEventConverterEvdev. // Touchscreen: use TouchEventConverterEvdev.
if (devinfo.HasTouchscreen()) { if (devinfo.HasTouchscreen()) {
scoped_ptr<TouchEventConverterEvdev> converter(new TouchEventConverterEvdev( scoped_ptr<TouchEventConverterEvdev> converter(new TouchEventConverterEvdev(
fd, params.path, params.id, type, params.dispatcher)); fd, params.path, params.id, type, devinfo, params.dispatcher));
converter->Initialize(devinfo); converter->Initialize(devinfo);
return converter.Pass(); return converter.Pass();
} }
...@@ -423,8 +423,7 @@ void InputDeviceFactoryEvdev::NotifyTouchscreensUpdated() { ...@@ -423,8 +423,7 @@ void InputDeviceFactoryEvdev::NotifyTouchscreensUpdated() {
std::vector<TouchscreenDevice> touchscreens; std::vector<TouchscreenDevice> touchscreens;
for (auto it = converters_.begin(); it != converters_.end(); ++it) { for (auto it = converters_.begin(); it != converters_.end(); ++it) {
if (it->second->HasTouchscreen()) { if (it->second->HasTouchscreen()) {
touchscreens.push_back(TouchscreenDevice( touchscreens.push_back(TouchscreenDevice(it->second->input_device(),
it->second->id(), it->second->type(),
it->second->GetTouchscreenSize(), it->second->GetTouchPoints())); it->second->GetTouchscreenSize(), it->second->GetTouchPoints()));
} }
} }
...@@ -436,7 +435,7 @@ void InputDeviceFactoryEvdev::NotifyKeyboardsUpdated() { ...@@ -436,7 +435,7 @@ void InputDeviceFactoryEvdev::NotifyKeyboardsUpdated() {
std::vector<KeyboardDevice> keyboards; std::vector<KeyboardDevice> keyboards;
for (auto it = converters_.begin(); it != converters_.end(); ++it) { for (auto it = converters_.begin(); it != converters_.end(); ++it) {
if (it->second->HasKeyboard()) { if (it->second->HasKeyboard()) {
keyboards.push_back(KeyboardDevice(it->second->id(), it->second->type())); keyboards.push_back(KeyboardDevice(it->second->input_device()));
} }
} }
...@@ -446,8 +445,9 @@ void InputDeviceFactoryEvdev::NotifyKeyboardsUpdated() { ...@@ -446,8 +445,9 @@ void InputDeviceFactoryEvdev::NotifyKeyboardsUpdated() {
void InputDeviceFactoryEvdev::NotifyMouseDevicesUpdated() { void InputDeviceFactoryEvdev::NotifyMouseDevicesUpdated() {
std::vector<InputDevice> mice; std::vector<InputDevice> mice;
for (auto it = converters_.begin(); it != converters_.end(); ++it) { for (auto it = converters_.begin(); it != converters_.end(); ++it) {
if (it->second->HasMouse()) if (it->second->HasMouse()) {
mice.push_back(InputDevice(it->second->id(), it->second->type())); mice.push_back(it->second->input_device());
}
} }
dispatcher_->DispatchMouseDevicesUpdated(mice); dispatcher_->DispatchMouseDevicesUpdated(mice);
...@@ -456,8 +456,9 @@ void InputDeviceFactoryEvdev::NotifyMouseDevicesUpdated() { ...@@ -456,8 +456,9 @@ void InputDeviceFactoryEvdev::NotifyMouseDevicesUpdated() {
void InputDeviceFactoryEvdev::NotifyTouchpadDevicesUpdated() { void InputDeviceFactoryEvdev::NotifyTouchpadDevicesUpdated() {
std::vector<InputDevice> touchpads; std::vector<InputDevice> touchpads;
for (auto it = converters_.begin(); it != converters_.end(); ++it) { for (auto it = converters_.begin(); it != converters_.end(); ++it) {
if (it->second->HasTouchpad()) if (it->second->HasTouchpad()) {
touchpads.push_back(InputDevice(it->second->id(), it->second->type())); touchpads.push_back(it->second->input_device());
}
} }
dispatcher_->DispatchTouchpadDevicesUpdated(touchpads); dispatcher_->DispatchTouchpadDevicesUpdated(touchpads);
......
...@@ -63,6 +63,7 @@ KeyboardEvdev::KeyboardEvdev(EventModifiersEvdev* modifiers, ...@@ -63,6 +63,7 @@ KeyboardEvdev::KeyboardEvdev(EventModifiersEvdev* modifiers,
repeat_enabled_(true), repeat_enabled_(true),
repeat_key_(KEY_RESERVED), repeat_key_(KEY_RESERVED),
repeat_sequence_(0), repeat_sequence_(0),
repeat_device_id_(0),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
repeat_delay_ = base::TimeDelta::FromMilliseconds(kRepeatDelayMs); repeat_delay_ = base::TimeDelta::FromMilliseconds(kRepeatDelayMs);
repeat_interval_ = base::TimeDelta::FromMilliseconds(kRepeatIntervalMs); repeat_interval_ = base::TimeDelta::FromMilliseconds(kRepeatIntervalMs);
...@@ -73,7 +74,8 @@ KeyboardEvdev::~KeyboardEvdev() { ...@@ -73,7 +74,8 @@ KeyboardEvdev::~KeyboardEvdev() {
void KeyboardEvdev::OnKeyChange(unsigned int key, void KeyboardEvdev::OnKeyChange(unsigned int key,
bool down, bool down,
base::TimeDelta timestamp) { base::TimeDelta timestamp,
int device_id) {
if (key > KEY_MAX) if (key > KEY_MAX)
return; return;
...@@ -86,8 +88,8 @@ void KeyboardEvdev::OnKeyChange(unsigned int key, ...@@ -86,8 +88,8 @@ void KeyboardEvdev::OnKeyChange(unsigned int key,
else else
key_state_.reset(key); key_state_.reset(key);
UpdateKeyRepeat(key, down); UpdateKeyRepeat(key, down, device_id);
DispatchKey(key, down, false /* repeat */, timestamp); DispatchKey(key, down, false /* repeat */, timestamp, device_id);
} }
void KeyboardEvdev::SetCapsLockEnabled(bool enabled) { void KeyboardEvdev::SetCapsLockEnabled(bool enabled) {
...@@ -139,17 +141,20 @@ void KeyboardEvdev::UpdateModifier(int modifier_flag, bool down) { ...@@ -139,17 +141,20 @@ void KeyboardEvdev::UpdateModifier(int modifier_flag, bool down) {
modifiers_->UpdateModifier(modifier, down); modifiers_->UpdateModifier(modifier, down);
} }
void KeyboardEvdev::UpdateKeyRepeat(unsigned int key, bool down) { void KeyboardEvdev::UpdateKeyRepeat(unsigned int key,
bool down,
int device_id) {
if (!repeat_enabled_) if (!repeat_enabled_)
StopKeyRepeat(); StopKeyRepeat();
else if (key != repeat_key_ && down) else if (key != repeat_key_ && down)
StartKeyRepeat(key); StartKeyRepeat(key, device_id);
else if (key == repeat_key_ && !down) else if (key == repeat_key_ && !down)
StopKeyRepeat(); StopKeyRepeat();
} }
void KeyboardEvdev::StartKeyRepeat(unsigned int key) { void KeyboardEvdev::StartKeyRepeat(unsigned int key, int device_id) {
repeat_key_ = key; repeat_key_ = key;
repeat_device_id_ = device_id;
repeat_sequence_++; repeat_sequence_++;
ScheduleKeyRepeat(repeat_delay_); ScheduleKeyRepeat(repeat_delay_);
...@@ -172,7 +177,7 @@ void KeyboardEvdev::OnRepeatTimeout(unsigned int sequence) { ...@@ -172,7 +177,7 @@ void KeyboardEvdev::OnRepeatTimeout(unsigned int sequence) {
return; return;
DispatchKey(repeat_key_, true /* down */, true /* repeat */, DispatchKey(repeat_key_, true /* down */, true /* repeat */,
EventTimeForNow()); EventTimeForNow(), repeat_device_id_);
ScheduleKeyRepeat(repeat_interval_); ScheduleKeyRepeat(repeat_interval_);
} }
...@@ -180,7 +185,8 @@ void KeyboardEvdev::OnRepeatTimeout(unsigned int sequence) { ...@@ -180,7 +185,8 @@ void KeyboardEvdev::OnRepeatTimeout(unsigned int sequence) {
void KeyboardEvdev::DispatchKey(unsigned int key, void KeyboardEvdev::DispatchKey(unsigned int key,
bool down, bool down,
bool repeat, bool repeat,
base::TimeDelta timestamp) { base::TimeDelta timestamp,
int device_id) {
DomCode dom_code = DomCode dom_code =
KeycodeConverter::NativeKeycodeToDomCode(EvdevCodeToNativeCode(key)); KeycodeConverter::NativeKeycodeToDomCode(EvdevCodeToNativeCode(key));
// DomCode constants are not included here because of conflicts with // DomCode constants are not included here because of conflicts with
...@@ -201,6 +207,7 @@ void KeyboardEvdev::DispatchKey(unsigned int key, ...@@ -201,6 +207,7 @@ void KeyboardEvdev::DispatchKey(unsigned int key,
KeyEvent event(down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code, dom_code, KeyEvent event(down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code, dom_code,
modifiers_->GetModifierFlags(), dom_key, character, timestamp); modifiers_->GetModifierFlags(), dom_key, character, timestamp);
event.set_source_device_id(device_id);
if (platform_keycode) if (platform_keycode)
event.set_platform_keycode(platform_keycode); event.set_platform_keycode(platform_keycode);
callback_.Run(&event); callback_.Run(&event);
......
...@@ -34,7 +34,10 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev { ...@@ -34,7 +34,10 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev {
~KeyboardEvdev(); ~KeyboardEvdev();
// Handlers for raw key presses & releases. // Handlers for raw key presses & releases.
void OnKeyChange(unsigned int code, bool down, base::TimeDelta timestamp); void OnKeyChange(unsigned int code,
bool down,
base::TimeDelta timestamp,
int device_id);
// Handle Caps Lock modifier. // Handle Caps Lock modifier.
void SetCapsLockEnabled(bool enabled); void SetCapsLockEnabled(bool enabled);
...@@ -50,15 +53,16 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev { ...@@ -50,15 +53,16 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev {
private: private:
void UpdateModifier(int modifier_flag, bool down); void UpdateModifier(int modifier_flag, bool down);
void UpdateCapsLockLed(); void UpdateCapsLockLed();
void UpdateKeyRepeat(unsigned int key, bool down); void UpdateKeyRepeat(unsigned int key, bool down, int device_id);
void StartKeyRepeat(unsigned int key); void StartKeyRepeat(unsigned int key, int device_id);
void StopKeyRepeat(); void StopKeyRepeat();
void ScheduleKeyRepeat(const base::TimeDelta& delay); void ScheduleKeyRepeat(const base::TimeDelta& delay);
void OnRepeatTimeout(unsigned int sequence); void OnRepeatTimeout(unsigned int sequence);
void DispatchKey(unsigned int key, void DispatchKey(unsigned int key,
bool down, bool down,
bool repeat, bool repeat,
base::TimeDelta timestamp); base::TimeDelta timestamp,
int device_id);
// Aggregated key state. There is only one bit of state per key; we do not // Aggregated key state. There is only one bit of state per key; we do not
// attempt to count presses of the same key on multiple keyboards. // attempt to count presses of the same key on multiple keyboards.
...@@ -82,6 +86,7 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev { ...@@ -82,6 +86,7 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev {
bool repeat_enabled_; bool repeat_enabled_;
unsigned int repeat_key_; unsigned int repeat_key_;
unsigned int repeat_sequence_; unsigned int repeat_sequence_;
int repeat_device_id_;
base::TimeDelta repeat_delay_; base::TimeDelta repeat_delay_;
base::TimeDelta repeat_interval_; base::TimeDelta repeat_interval_;
......
...@@ -31,7 +31,13 @@ EventReaderLibevdevCros::EventReaderLibevdevCros(int fd, ...@@ -31,7 +31,13 @@ EventReaderLibevdevCros::EventReaderLibevdevCros(int fd,
InputDeviceType type, InputDeviceType type,
const EventDeviceInfo& devinfo, const EventDeviceInfo& devinfo,
scoped_ptr<Delegate> delegate) scoped_ptr<Delegate> delegate)
: EventConverterEvdev(fd, path, id, type), : EventConverterEvdev(fd,
path,
id,
type,
devinfo.name(),
devinfo.vendor_id(),
devinfo.product_id()),
has_keyboard_(devinfo.HasKeyboard()), has_keyboard_(devinfo.HasKeyboard()),
has_mouse_(devinfo.HasMouse()), has_mouse_(devinfo.HasMouse()),
has_touchpad_(devinfo.HasTouchpad()), has_touchpad_(devinfo.HasTouchpad()),
......
...@@ -21,7 +21,13 @@ TabletEventConverterEvdev::TabletEventConverterEvdev( ...@@ -21,7 +21,13 @@ TabletEventConverterEvdev::TabletEventConverterEvdev(
CursorDelegateEvdev* cursor, CursorDelegateEvdev* cursor,
const EventDeviceInfo& info, const EventDeviceInfo& info,
DeviceEventDispatcherEvdev* dispatcher) DeviceEventDispatcherEvdev* dispatcher)
: EventConverterEvdev(fd, path, id, type), : EventConverterEvdev(fd,
path,
id,
type,
info.name(),
info.vendor_id(),
info.product_id()),
cursor_(cursor), cursor_(cursor),
dispatcher_(dispatcher), dispatcher_(dispatcher),
stylus_(0), stylus_(0),
...@@ -145,8 +151,8 @@ void TabletEventConverterEvdev::DispatchMouseButton(const input_event& input) { ...@@ -145,8 +151,8 @@ void TabletEventConverterEvdev::DispatchMouseButton(const input_event& input) {
bool down = input.value; bool down = input.value;
dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams( dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams(
id_, cursor_->GetLocation(), button, down, false /* allow_remap */, input_device_.id, cursor_->GetLocation(), button, down,
TimeDeltaFromInputEvent(input))); false /* allow_remap */, TimeDeltaFromInputEvent(input)));
} }
void TabletEventConverterEvdev::FlushEvents(const input_event& input) { void TabletEventConverterEvdev::FlushEvents(const input_event& input) {
...@@ -164,8 +170,9 @@ void TabletEventConverterEvdev::FlushEvents(const input_event& input) { ...@@ -164,8 +170,9 @@ void TabletEventConverterEvdev::FlushEvents(const input_event& input) {
UpdateCursor(); UpdateCursor();
dispatcher_->DispatchMouseMoveEvent(MouseMoveEventParams( dispatcher_->DispatchMouseMoveEvent(
id_, cursor_->GetLocation(), TimeDeltaFromInputEvent(input))); MouseMoveEventParams(input_device_.id, cursor_->GetLocation(),
TimeDeltaFromInputEvent(input)));
abs_value_dirty_ = false; abs_value_dirty_ = false;
} }
......
...@@ -86,8 +86,15 @@ TouchEventConverterEvdev::TouchEventConverterEvdev( ...@@ -86,8 +86,15 @@ TouchEventConverterEvdev::TouchEventConverterEvdev(
base::FilePath path, base::FilePath path,
int id, int id,
InputDeviceType type, InputDeviceType type,
const EventDeviceInfo& devinfo,
DeviceEventDispatcherEvdev* dispatcher) DeviceEventDispatcherEvdev* dispatcher)
: EventConverterEvdev(fd, path, id, type), : EventConverterEvdev(fd,
path,
id,
type,
devinfo.name(),
devinfo.vendor_id(),
devinfo.product_id()),
dispatcher_(dispatcher), dispatcher_(dispatcher),
syn_dropped_(false), syn_dropped_(false),
has_mt_(false), has_mt_(false),
...@@ -361,7 +368,7 @@ void TouchEventConverterEvdev::ReportEvent(const InProgressTouchEvdev& event, ...@@ -361,7 +368,7 @@ void TouchEventConverterEvdev::ReportEvent(const InProgressTouchEvdev& event,
EventType event_type, EventType event_type,
const base::TimeDelta& timestamp) { const base::TimeDelta& timestamp) {
dispatcher_->DispatchTouchEvent(TouchEventParams( dispatcher_->DispatchTouchEvent(TouchEventParams(
id_, event.slot, event_type, gfx::PointF(event.x, event.y), input_device_.id, event.slot, event_type, gfx::PointF(event.x, event.y),
gfx::Vector2dF(event.radius_x, event.radius_y), event.pressure, gfx::Vector2dF(event.radius_x, event.radius_y), event.pressure,
timestamp)); timestamp));
} }
......
...@@ -30,6 +30,7 @@ class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev ...@@ -30,6 +30,7 @@ class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev
base::FilePath path, base::FilePath path,
int id, int id,
InputDeviceType type, InputDeviceType type,
const EventDeviceInfo& devinfo,
DeviceEventDispatcherEvdev* dispatcher); DeviceEventDispatcherEvdev* dispatcher);
~TouchEventConverterEvdev() override; ~TouchEventConverterEvdev() override;
......
...@@ -53,6 +53,7 @@ class MockTouchEventConverterEvdev : public TouchEventConverterEvdev { ...@@ -53,6 +53,7 @@ class MockTouchEventConverterEvdev : public TouchEventConverterEvdev {
public: public:
MockTouchEventConverterEvdev(int fd, MockTouchEventConverterEvdev(int fd,
base::FilePath path, base::FilePath path,
const EventDeviceInfo& devinfo,
DeviceEventDispatcherEvdev* dispatcher); DeviceEventDispatcherEvdev* dispatcher);
~MockTouchEventConverterEvdev() override {} ~MockTouchEventConverterEvdev() override {}
...@@ -111,8 +112,14 @@ class MockDeviceEventDispatcherEvdev : public DeviceEventDispatcherEvdev { ...@@ -111,8 +112,14 @@ class MockDeviceEventDispatcherEvdev : public DeviceEventDispatcherEvdev {
MockTouchEventConverterEvdev::MockTouchEventConverterEvdev( MockTouchEventConverterEvdev::MockTouchEventConverterEvdev(
int fd, int fd,
base::FilePath path, base::FilePath path,
const EventDeviceInfo& devinfo,
DeviceEventDispatcherEvdev* dispatcher) DeviceEventDispatcherEvdev* dispatcher)
: TouchEventConverterEvdev(fd, path, 1, INPUT_DEVICE_UNKNOWN, dispatcher) { : TouchEventConverterEvdev(fd,
path,
1,
INPUT_DEVICE_UNKNOWN,
devinfo,
dispatcher) {
int fds[2]; int fds[2];
if (pipe(fds)) if (pipe(fds))
...@@ -157,11 +164,13 @@ class TouchEventConverterEvdevTest : public testing::Test { ...@@ -157,11 +164,13 @@ class TouchEventConverterEvdevTest : public testing::Test {
// Device creation happens on a worker thread since it may involve blocking // Device creation happens on a worker thread since it may involve blocking
// operations. Simulate that by creating it before creating a UI message // operations. Simulate that by creating it before creating a UI message
// loop. // loop.
EventDeviceInfo devinfo;
dispatcher_.reset(new ui::MockDeviceEventDispatcherEvdev( dispatcher_.reset(new ui::MockDeviceEventDispatcherEvdev(
base::Bind(&TouchEventConverterEvdevTest::DispatchCallback, base::Bind(&TouchEventConverterEvdevTest::DispatchCallback,
base::Unretained(this)))); base::Unretained(this))));
device_.reset(new ui::MockTouchEventConverterEvdev( device_.reset(new ui::MockTouchEventConverterEvdev(
events_in_, base::FilePath(kTestDevicePath), dispatcher_.get())); events_in_, base::FilePath(kTestDevicePath), devinfo,
dispatcher_.get()));
loop_ = new base::MessageLoopForUI; loop_ = new base::MessageLoopForUI;
ui::DeviceDataManager::CreateInstance(); ui::DeviceDataManager::CreateInstance();
...@@ -180,9 +189,7 @@ class TouchEventConverterEvdevTest : public testing::Test { ...@@ -180,9 +189,7 @@ class TouchEventConverterEvdevTest : public testing::Test {
return dispatched_events_[index]; return dispatched_events_[index];
} }
void ClearDispatchedEvents() { void ClearDispatchedEvents() { dispatched_events_.clear(); }
dispatched_events_.clear();
}
void DestroyDevice() { device_.reset(); } void DestroyDevice() { device_.reset(); }
......
...@@ -32,6 +32,10 @@ ...@@ -32,6 +32,10 @@
#include "ui/events/devices/touchscreen_device.h" #include "ui/events/devices/touchscreen_device.h"
#include "ui/gfx/x/x11_types.h" #include "ui/gfx/x/x11_types.h"
#ifndef XI_PROP_PRODUCT_ID
#define XI_PROP_PRODUCT_ID "Device Product ID"
#endif
namespace ui { namespace ui {
namespace { namespace {
...@@ -52,6 +56,7 @@ const char* kCachedAtomList[] = { ...@@ -52,6 +56,7 @@ const char* kCachedAtomList[] = {
XI_MOUSE, XI_MOUSE,
XI_TOUCHPAD, XI_TOUCHPAD,
XI_TOUCHSCREEN, XI_TOUCHSCREEN,
XI_PROP_PRODUCT_ID,
NULL, NULL,
}; };
...@@ -113,9 +118,13 @@ struct TouchClassInfo { ...@@ -113,9 +118,13 @@ struct TouchClassInfo {
struct DeviceInfo { struct DeviceInfo {
DeviceInfo(const XIDeviceInfo& device, DeviceInfo(const XIDeviceInfo& device,
DeviceType type, DeviceType type,
const base::FilePath& path) const base::FilePath& path,
uint16_t vendor,
uint16_t product)
: id(device.deviceid), : id(device.deviceid),
name(device.name), name(device.name),
vendor_id(vendor),
product_id(product),
use(device.use), use(device.use),
type(type), type(type),
path(path) { path(path) {
...@@ -144,6 +153,10 @@ struct DeviceInfo { ...@@ -144,6 +153,10 @@ struct DeviceInfo {
// Internal device name. // Internal device name.
std::string name; std::string name;
// USB-style device identifiers.
uint16_t vendor_id;
uint16_t product_id;
// Device type (ie: XIMasterPointer) // Device type (ie: XIMasterPointer)
int use; int use;
...@@ -246,7 +259,8 @@ void HandleKeyboardDevicesInWorker( ...@@ -246,7 +259,8 @@ void HandleKeyboardDevicesInWorker(
if (IsKnownInvalidKeyboardDevice(device_info.name)) if (IsKnownInvalidKeyboardDevice(device_info.name))
continue; // Skip invalid devices. continue; // Skip invalid devices.
InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
devices.push_back(KeyboardDevice(device_info.id, type)); KeyboardDevice keyboard(device_info.id, type, device_info.name);
devices.push_back(keyboard);
} }
reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
...@@ -265,7 +279,7 @@ void HandleMouseDevicesInWorker(const std::vector<DeviceInfo>& device_infos, ...@@ -265,7 +279,7 @@ void HandleMouseDevicesInWorker(const std::vector<DeviceInfo>& device_infos,
} }
InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
devices.push_back(InputDevice(device_info.id, type)); devices.push_back(InputDevice(device_info.id, type, device_info.name));
} }
reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
...@@ -284,7 +298,7 @@ void HandleTouchpadDevicesInWorker(const std::vector<DeviceInfo>& device_infos, ...@@ -284,7 +298,7 @@ void HandleTouchpadDevicesInWorker(const std::vector<DeviceInfo>& device_infos,
} }
InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
devices.push_back(InputDevice(device_info.id, type)); devices.push_back(InputDevice(device_info.id, type, device_info.name));
} }
reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
...@@ -337,9 +351,10 @@ void HandleTouchscreenDevicesInWorker( ...@@ -337,9 +351,10 @@ void HandleTouchscreenDevicesInWorker(
InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
// |max_x| and |max_y| are inclusive values, so we need to add 1 to get // |max_x| and |max_y| are inclusive values, so we need to add 1 to get
// the size. // the size.
devices.push_back(TouchscreenDevice( devices.push_back(
device_info.id, type, gfx::Size(max_x + 1, max_y + 1), TouchscreenDevice(device_info.id, type, device_info.name,
device_info.touch_class_info.num_touches)); gfx::Size(max_x + 1, max_y + 1),
device_info.touch_class_info.num_touches));
} }
} }
...@@ -428,8 +443,31 @@ void X11HotplugEventHandler::OnHotplugEvent() { ...@@ -428,8 +443,31 @@ void X11HotplugEventHandler::OnHotplugEvent() {
(device.deviceid >= 0 && device.deviceid < kMaxDeviceNum) (device.deviceid >= 0 && device.deviceid < kMaxDeviceNum)
? device_types[device.deviceid] ? device_types[device.deviceid]
: DEVICE_TYPE_OTHER; : DEVICE_TYPE_OTHER;
device_infos.push_back(
DeviceInfo(device, device_type, GetDevicePath(display, device))); // Obtain the USB-style vendor and product identifiers.
// (On Linux, XI2 makes this available for all evdev devices.
uint32_t* product_info;
Atom type;
int format_return;
unsigned long num_items_return;
unsigned long bytes_after_return;
uint16_t vendor = 0;
uint16_t product = 0;
if (XIGetProperty(gfx::GetXDisplay(), device.deviceid,
atom_cache_.GetAtom(XI_PROP_PRODUCT_ID), 0, 2, 0,
XA_INTEGER, &type, &format_return, &num_items_return,
&bytes_after_return,
reinterpret_cast<unsigned char**>(&product_info)) == 0 &&
product_info) {
if (num_items_return == 2) {
vendor = product_info[0];
product = product_info[1];
}
XFree(product_info);
}
device_infos.push_back(DeviceInfo(
device, device_type, GetDevicePath(display, device), vendor, product));
} }
// X11 is not thread safe, so first get all the required state. // X11 is not thread safe, so first get all the required state.
...@@ -446,13 +484,11 @@ void X11HotplugEventHandler::OnHotplugEvent() { ...@@ -446,13 +484,11 @@ void X11HotplugEventHandler::OnHotplugEvent() {
// Parsing the device information may block, so delegate the operation to a // Parsing the device information may block, so delegate the operation to a
// worker thread. Once the device information is extracted the parsed devices // worker thread. Once the device information is extracted the parsed devices
// will be returned via the callbacks. // will be returned via the callbacks.
base::WorkerPool::PostTask(FROM_HERE, base::WorkerPool::PostTask(
base::Bind(&HandleHotplugEventInWorker, FROM_HERE,
device_infos, base::Bind(&HandleHotplugEventInWorker, device_infos, display_state,
display_state, base::ThreadTaskRunnerHandle::Get(), callbacks),
base::ThreadTaskRunnerHandle::Get(), true /* task_is_slow */);
callbacks),
true /* task_is_slow */);
} }
} // namespace ui } // namespace ui
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment