diff options
author | kpschoedel <kpschoedel@chromium.org> | 2015-04-17 10:23:26 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-17 17:24:09 +0000 |
commit | 711f2fc883c05bb10466fb65fdaf9bc10c909b23 (patch) | |
tree | 64400f2de06d8e7457273fa5be5ebae3f6013dbc | |
parent | a3918ade366d69a50c0c7a65ee8215b87c61326a (diff) | |
download | chromium_src-711f2fc883c05bb10466fb65fdaf9bc10c909b23.zip chromium_src-711f2fc883c05bb10466fb65fdaf9bc10c909b23.tar.gz chromium_src-711f2fc883c05bb10466fb65fdaf9bc10c909b23.tar.bz2 |
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
Review URL: https://codereview.chromium.org/1073573002
Cr-Commit-Position: refs/heads/master@{#325660}
30 files changed, 367 insertions, 256 deletions
diff --git a/ash/test/virtual_keyboard_test_helper.cc b/ash/test/virtual_keyboard_test_helper.cc index 5cb39db..c920213 100644 --- a/ash/test/virtual_keyboard_test_helper.cc +++ b/ash/test/virtual_keyboard_test_helper.cc @@ -17,13 +17,14 @@ void VirtualKeyboardTestHelper::SuppressKeyboard() { ui::DeviceHotplugEventObserver* manager = ui::DeviceDataManager::GetInstance(); std::vector<ui::TouchscreenDevice> screens; - screens.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); + screens.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + "Touchscreen", gfx::Size(1024, 768), 0)); manager->OnTouchscreenDevicesUpdated(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); manager->OnKeyboardDevicesUpdated(keyboards); } diff --git a/ash/touch/touch_transformer_controller_unittest.cc b/ash/touch/touch_transformer_controller_unittest.cc index 2a5131a..7662346 100644 --- a/ash/touch/touch_transformer_controller_unittest.cc +++ b/ash/touch/touch_transformer_controller_unittest.cc @@ -33,7 +33,7 @@ DisplayInfo CreateDisplayInfo(int64 id, ui::TouchscreenDevice CreateTouchscreenDevice(unsigned int id, const gfx::Size& size) { return ui::TouchscreenDevice(id, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, - size, 0); + std::string(), size, 0); } } // namespace diff --git a/ash/touch/touchscreen_util_unittest.cc b/ash/touch/touchscreen_util_unittest.cc index ea88753..ce14702 100644 --- a/ash/touch/touchscreen_util_unittest.cc +++ b/ash/touch/touchscreen_util_unittest.cc @@ -76,10 +76,12 @@ TEST_F(TouchscreenUtilTest, NoTouchscreens) { TEST_F(TouchscreenUtilTest, OneToOneMapping) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(800, 600), 0)); - devices.push_back(ui::TouchscreenDevice( - 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1024, 768), 0)); + devices.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", + gfx::Size(800, 600), 0)); + devices.push_back( + ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", + gfx::Size(1024, 768), 0)); AssociateTouchscreens(&displays_, devices); @@ -91,8 +93,9 @@ TEST_F(TouchscreenUtilTest, OneToOneMapping) { TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back(ui::TouchscreenDevice( - 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); @@ -104,10 +107,12 @@ TEST_F(TouchscreenUtilTest, MapToCorrectDisplaySize) { TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(801, 600), 0)); - devices.push_back(ui::TouchscreenDevice( - 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1023, 768), 0)); + devices.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", + gfx::Size(801, 600), 0)); + devices.push_back( + ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", + gfx::Size(1023, 768), 0)); AssociateTouchscreens(&displays_, devices); @@ -119,10 +124,12 @@ TEST_F(TouchscreenUtilTest, MapWhenSizeDiffersByOne) { TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1022, 768), 0)); - devices.push_back(ui::TouchscreenDevice( - 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(802, 600), 0)); + devices.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", + gfx::Size(1022, 768), 0)); + devices.push_back( + ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", + gfx::Size(802, 600), 0)); AssociateTouchscreens(&displays_, devices); @@ -134,10 +141,12 @@ TEST_F(TouchscreenUtilTest, MapWhenSizesDoNotMatch) { TEST_F(TouchscreenUtilTest, MapInternalTouchscreen) { std::vector<ui::TouchscreenDevice> devices; - devices.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(1920, 1080), 0)); - devices.push_back(ui::TouchscreenDevice( - 2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(9999, 888), 0)); + devices.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "", + gfx::Size(1920, 1080), 0)); + devices.push_back( + ui::TouchscreenDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "", + gfx::Size(9999, 888), 0)); AssociateTouchscreens(&displays_, devices); diff --git a/ash/virtual_keyboard_controller_unittest.cc b/ash/virtual_keyboard_controller_unittest.cc index 7ca7a2a..f7a59ef 100644 --- a/ash/virtual_keyboard_controller_unittest.cc +++ b/ash/virtual_keyboard_controller_unittest.cc @@ -46,9 +46,8 @@ class VirtualKeyboardControllerTest : public AshTestBase { // Sets the event blocker on the maximized window controller. void SetEventBlocker( scoped_ptr<ScopedDisableInternalMouseAndKeyboard> blocker) { - Shell::GetInstance() - ->maximize_mode_controller() - ->event_blocker_ = blocker.Pass(); + Shell::GetInstance()->maximize_mode_controller()->event_blocker_ = + blocker.Pass(); } void SetUp() override { @@ -84,8 +83,8 @@ class MockEventBlocker : public ScopedDisableInternalMouseAndKeyboard { MockEventBlocker() {} ~MockEventBlocker() override { std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard")); ui::DeviceHotplugEventObserver* manager = ui::DeviceDataManager::GetInstance(); manager->OnKeyboardDevicesUpdated(keyboards); @@ -102,8 +101,8 @@ TEST_F(VirtualKeyboardControllerTest, RestoreKeyboardDevices) { Shell::GetInstance() ->maximize_mode_controller() ->EnableMaximizeModeWindowManager(true); - scoped_ptr<ScopedDisableInternalMouseAndKeyboard> - blocker(new MockEventBlocker); + scoped_ptr<ScopedDisableInternalMouseAndKeyboard> blocker( + new MockEventBlocker); SetEventBlocker(blocker.Pass()); } @@ -157,12 +156,13 @@ class VirtualKeyboardControllerAutoTest : public VirtualKeyboardControllerTest, // present and maximized mode is disabled. TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfInternalKeyboardPresent) { std::vector<ui::TouchscreenDevice> screens; - screens.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); + screens.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + "Touchscreen", gfx::Size(1024, 768), 0)); UpdateTouchscreenDevices(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard")); UpdateKeyboardDevices(keyboards); ASSERT_FALSE(keyboard::IsKeyboardEnabled()); // Remove the internal keyboard. Virtual keyboard should now show. @@ -176,8 +176,9 @@ TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfInternalKeyboardPresent) { TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfNoTouchScreen) { std::vector<ui::TouchscreenDevice> devices; // Add a touchscreen. Keyboard should deploy. - devices.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, gfx::Size(800, 600), 0)); + devices.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, + "Touchscreen", gfx::Size(800, 600), 0)); UpdateTouchscreenDevices(devices); EXPECT_TRUE(keyboard::IsKeyboardEnabled()); // Remove touchscreen. Keyboard should hide. @@ -187,12 +188,13 @@ TEST_F(VirtualKeyboardControllerAutoTest, DisabledIfNoTouchScreen) { TEST_F(VirtualKeyboardControllerAutoTest, SuppressedIfExternalKeyboardPresent) { std::vector<ui::TouchscreenDevice> screens; - screens.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); + screens.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + "Touchscreen", gfx::Size(1024, 768), 0)); UpdateTouchscreenDevices(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); UpdateKeyboardDevices(keyboards); ASSERT_FALSE(keyboard::IsKeyboardEnabled()); ASSERT_TRUE(notified()); @@ -225,12 +227,12 @@ TEST_F(VirtualKeyboardControllerAutoTest, SuppressedIfExternalKeyboardPresent) { // Tests handling multiple keyboards. Catches crbug.com/430252 TEST_F(VirtualKeyboardControllerAutoTest, HandleMultipleKeyboardsPresent) { std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); - keyboards.push_back( - ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); - keyboards.push_back( - ui::KeyboardDevice(3, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "keyboard")); + keyboards.push_back(ui::KeyboardDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); + keyboards.push_back(ui::KeyboardDevice( + 3, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); UpdateKeyboardDevices(keyboards); ASSERT_FALSE(keyboard::IsKeyboardEnabled()); } @@ -238,12 +240,13 @@ TEST_F(VirtualKeyboardControllerAutoTest, HandleMultipleKeyboardsPresent) { // Tests maximized mode interaction without disabling the internal keyboard. TEST_F(VirtualKeyboardControllerAutoTest, EnabledDuringMaximizeMode) { std::vector<ui::TouchscreenDevice> screens; - screens.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); + screens.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + "Touchscreen", gfx::Size(1024, 768), 0)); UpdateTouchscreenDevices(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); UpdateKeyboardDevices(keyboards); ASSERT_FALSE(keyboard::IsKeyboardEnabled()); // Toggle maximized mode on. @@ -261,14 +264,15 @@ TEST_F(VirtualKeyboardControllerAutoTest, EnabledDuringMaximizeMode) { // Tests that keyboard gets suppressed in maximized mode. TEST_F(VirtualKeyboardControllerAutoTest, SuppressedInMaximizedMode) { std::vector<ui::TouchscreenDevice> screens; - screens.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); + screens.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + "Touchscreen", gfx::Size(1024, 768), 0)); UpdateTouchscreenDevices(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); - keyboards.push_back( - ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); + keyboards.push_back(ui::KeyboardDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "Keyboard")); UpdateKeyboardDevices(keyboards); // Toggle maximized mode on. Shell::GetInstance() @@ -329,12 +333,13 @@ class VirtualKeyboardControllerAlwaysEnabledTest // keyboard always enabled flag is active. TEST_F(VirtualKeyboardControllerAlwaysEnabledTest, DoesNotSuppressKeyboard) { std::vector<ui::TouchscreenDevice> screens; - screens.push_back(ui::TouchscreenDevice( - 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, gfx::Size(1024, 768), 0)); + screens.push_back( + ui::TouchscreenDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + "Touchscreen", gfx::Size(1024, 768), 0)); UpdateTouchscreenDevices(screens); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_EXTERNAL, "keyboard")); UpdateKeyboardDevices(keyboards); ASSERT_TRUE(keyboard::IsKeyboardEnabled()); } diff --git a/chrome/browser/chromeos/events/event_rewriter.cc b/chrome/browser/chromeos/events/event_rewriter.cc index b0b8531..e35bdae 100644 --- a/chrome/browser/chromeos/events/event_rewriter.cc +++ b/chrome/browser/chromeos/events/event_rewriter.cc @@ -23,6 +23,7 @@ #include "components/user_manager/user_manager.h" #include "ui/base/ime/chromeos/ime_keyboard.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_utils.h" #include "ui/events/keycodes/keyboard_code_conversion.h" @@ -30,13 +31,8 @@ #if defined(USE_X11) #include <X11/extensions/XInput2.h> -#include <X11/Xatom.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. #undef RootWindow #undef Status @@ -936,73 +932,17 @@ EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal( } EventRewriter::DeviceType EventRewriter::KeyboardDeviceAdded(int device_id) { -#if defined(USE_X11) - 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."; + if (!ui::DeviceDataManager::HasInstance()) return kDeviceUnknown; - } - - DeviceType dev_type = kDeviceUnknown; - DCHECK_EQ(1, ndevices_return); - for (int i = 0; i < ndevices_return; ++i) { - // Get keyboard product and vendor 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]; + const std::vector<ui::KeyboardDevice>& keyboards = + ui::DeviceDataManager::GetInstance()->keyboard_devices(); + for (const auto& keyboard : keyboards) { + if (keyboard.id == device_id) { + return KeyboardDeviceAddedInternal( + keyboard.id, keyboard.name, keyboard.vendor_id, keyboard.product_id); } - - DCHECK_EQ(device_id, device_info[i].deviceid); // see the comment above. - 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 + } + return kDeviceUnknown; } } // namespace chromeos diff --git a/ui/events/devices/input_device.cc b/ui/events/devices/input_device.cc index d08aa51..11058e7 100644 --- a/ui/events/devices/input_device.cc +++ b/ui/events/devices/input_device.cc @@ -15,8 +15,16 @@ InputDevice::InputDevice() : id(kInvalidId), type(InputDeviceType::INPUT_DEVICE_UNKNOWN) { } -InputDevice::InputDevice(int id, InputDeviceType type) - : id(id), type(type) { +InputDevice::InputDevice(int id, InputDeviceType type, const std::string& name) + : 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() { diff --git a/ui/events/devices/input_device.h b/ui/events/devices/input_device.h index ee493ea..1114dcf 100644 --- a/ui/events/devices/input_device.h +++ b/ui/events/devices/input_device.h @@ -5,6 +5,7 @@ #ifndef UI_EVENTS_DEVICES_INPUT_DEVICE_H_ #define UI_EVENTS_DEVICES_INPUT_DEVICE_H_ +#include <stdint.h> #include <string> #include "ui/events/devices/events_devices_export.h" @@ -24,7 +25,12 @@ struct EVENTS_DEVICES_EXPORT InputDevice { // Creates an invalid input device. 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(); // ID of the device. This ID is unique between all input devices. @@ -32,6 +38,13 @@ struct EVENTS_DEVICES_EXPORT InputDevice { // The type of the input device. 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 diff --git a/ui/events/devices/keyboard_device.cc b/ui/events/devices/keyboard_device.cc index 0774548..9e00340 100644 --- a/ui/events/devices/keyboard_device.cc +++ b/ui/events/devices/keyboard_device.cc @@ -10,8 +10,14 @@ namespace ui { -KeyboardDevice::KeyboardDevice(int id, InputDeviceType type) - : InputDevice(id, type) { +KeyboardDevice::KeyboardDevice(int id, + InputDeviceType type, + const std::string& name) + : InputDevice(id, type, name) { +} + +KeyboardDevice::KeyboardDevice(const InputDevice& input_device) + : InputDevice(input_device) { } } // namespace ui diff --git a/ui/events/devices/keyboard_device.h b/ui/events/devices/keyboard_device.h index fa1c4b7..12c3504 100644 --- a/ui/events/devices/keyboard_device.h +++ b/ui/events/devices/keyboard_device.h @@ -14,7 +14,8 @@ namespace ui { // Represents a Keyboard device state. 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 diff --git a/ui/events/devices/touchscreen_device.cc b/ui/events/devices/touchscreen_device.cc index c5a0570..9d7276c 100644 --- a/ui/events/devices/touchscreen_device.cc +++ b/ui/events/devices/touchscreen_device.cc @@ -15,9 +15,16 @@ TouchscreenDevice::TouchscreenDevice() : touch_points(0) { TouchscreenDevice::TouchscreenDevice(int id, InputDeviceType type, + const std::string& name, const gfx::Size& size, 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 diff --git a/ui/events/devices/touchscreen_device.h b/ui/events/devices/touchscreen_device.h index 7502f68..f3a26e6 100644 --- a/ui/events/devices/touchscreen_device.h +++ b/ui/events/devices/touchscreen_device.h @@ -20,6 +20,11 @@ struct EVENTS_DEVICES_EXPORT TouchscreenDevice : public InputDevice { TouchscreenDevice(int id, InputDeviceType type, + const std::string& name, + const gfx::Size& size, + int touch_points); + + TouchscreenDevice(const InputDevice& input_device, const gfx::Size& size, int touch_points); diff --git a/ui/events/devices/x11/device_data_manager_x11_unittest.cc b/ui/events/devices/x11/device_data_manager_x11_unittest.cc index 3cce253f..75a4503 100644 --- a/ui/events/devices/x11/device_data_manager_x11_unittest.cc +++ b/ui/events/devices/x11/device_data_manager_x11_unittest.cc @@ -77,10 +77,10 @@ TEST_F(DeviceDataManagerX11Test, NotifyOnDisable) { DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance(); TestInputDeviceObserver observer(manager); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); - keyboards.push_back( - ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); + keyboards.push_back(ui::KeyboardDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); SetKeyboardDevices(keyboards); EXPECT_TRUE(observer.change_notified()); std::vector<KeyboardDevice> devices = manager->keyboard_devices(); @@ -108,10 +108,10 @@ TEST_F(DeviceDataManagerX11Test, TestMultipleDisable) { DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance(); TestInputDeviceObserver observer(manager); std::vector<ui::KeyboardDevice> keyboards; - keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); - keyboards.push_back( - ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); + keyboards.push_back(ui::KeyboardDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); SetKeyboardDevices(keyboards); EXPECT_TRUE(observer.change_notified()); std::vector<KeyboardDevice> devices = manager->keyboard_devices(); @@ -147,10 +147,10 @@ TEST_F(DeviceDataManagerX11Test, UnblockOnDeviceUnplugged) { DeviceDataManagerX11* manager = DeviceDataManagerX11::GetInstance(); TestInputDeviceObserver observer(manager); std::vector<ui::KeyboardDevice> all_keyboards; - all_keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); - all_keyboards.push_back( - ui::KeyboardDevice(2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + all_keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); + all_keyboards.push_back(ui::KeyboardDevice( + 2, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); SetKeyboardDevices(all_keyboards); EXPECT_TRUE(observer.change_notified()); std::vector<KeyboardDevice> devices = manager->keyboard_devices(); @@ -165,8 +165,8 @@ TEST_F(DeviceDataManagerX11Test, UnblockOnDeviceUnplugged) { // Unplug the disabled device. Should not be notified, since the active list // did not change. std::vector<ui::KeyboardDevice> subset_keyboards; - subset_keyboards.push_back( - ui::KeyboardDevice(1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL)); + subset_keyboards.push_back(ui::KeyboardDevice( + 1, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, "Keyboard")); SetKeyboardDevices(subset_keyboards); EXPECT_FALSE(observer.change_notified()); // Replug in the first device. Should be notified of the new device. diff --git a/ui/events/devices/x11/touch_factory_x11.cc b/ui/events/devices/x11/touch_factory_x11.cc index 40c5624..a971b10 100644 --- a/ui/events/devices/x11/touch_factory_x11.cc +++ b/ui/events/devices/x11/touch_factory_x11.cc @@ -129,7 +129,7 @@ void TouchFactory::UpdateDeviceList(Display* display) { reinterpret_cast<XITouchClassInfo*>(xiclassinfo); // Only care direct touch device (such as touch screen) right now if (tci->mode == XIDirectTouch) - CacheTouchscreenIds(display, devinfo.deviceid); + CacheTouchscreenIds(devinfo.deviceid); } } } @@ -292,43 +292,19 @@ void TouchFactory::SetPointerDeviceForTest( } } -void TouchFactory::CacheTouchscreenIds(Display* display, int device_id) { - XDevice* device = XOpenDevice(display, device_id); - if (!device) +void TouchFactory::CacheTouchscreenIds(int device_id) { + if (!DeviceDataManager::HasInstance()) return; - - Atom actual_type_return; - int actual_format_return; - unsigned long nitems_return; - unsigned long bytes_after_return; - unsigned char *prop_return; - - const char kDeviceProductIdString[] = "Device Product ID"; - Atom device_product_id_atom = - XInternAtom(display, kDeviceProductIdString, false); - - 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); + std::vector<TouchscreenDevice> touchscreens = + DeviceDataManager::GetInstance()->touchscreen_devices(); + const auto it = + std::find_if(touchscreens.begin(), touchscreens.end(), + [device_id](const TouchscreenDevice& touchscreen) { + return touchscreen.id == device_id; + }); + // Internal displays will have a vid and pid of 0. Ignore them. + if (it != touchscreens.end() && it->vendor_id && it->product_id) + touchscreen_ids_.insert(std::make_pair(it->vendor_id, it->product_id)); } } // namespace ui diff --git a/ui/events/devices/x11/touch_factory_x11.h b/ui/events/devices/x11/touch_factory_x11.h index 146b2a6..43174a7 100644 --- a/ui/events/devices/x11/touch_factory_x11.h +++ b/ui/events/devices/x11/touch_factory_x11.h @@ -98,7 +98,7 @@ class EVENTS_DEVICES_EXPORT TouchFactory { // Requirement for Singleton 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 // to quickly decide if a device is a touch device or not. We also maintain a diff --git a/ui/events/event.cc b/ui/events/event.cc index 0cdf70d..5444019 100644 --- a/ui/events/event.cc +++ b/ui/events/event.cc @@ -246,6 +246,10 @@ Event::Event(const base::NativeEvent& native_event, source_device_id_ = xiev->sourceid; } #endif +#if defined(USE_OZONE) + source_device_id_ = + static_cast<const Event*>(native_event)->source_device_id(); +#endif } Event::Event(const Event& copy) diff --git a/ui/events/ozone/evdev/event_converter_evdev.cc b/ui/events/ozone/evdev/event_converter_evdev.cc index fce8e9c..f7662d2 100644 --- a/ui/events/ozone/evdev/event_converter_evdev.cc +++ b/ui/events/ozone/evdev/event_converter_evdev.cc @@ -16,8 +16,14 @@ namespace ui { EventConverterEvdev::EventConverterEvdev(int fd, const base::FilePath& path, int id, - InputDeviceType type) - : fd_(fd), path_(path), id_(id), type_(type), ignore_events_(false) { + InputDeviceType type, + 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() { diff --git a/ui/events/ozone/evdev/event_converter_evdev.h b/ui/events/ozone/evdev/event_converter_evdev.h index eaa4059..ea7b7bd 100644 --- a/ui/events/ozone/evdev/event_converter_evdev.h +++ b/ui/events/ozone/evdev/event_converter_evdev.h @@ -26,14 +26,19 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev EventConverterEvdev(int fd, const base::FilePath& path, int id, - InputDeviceType type); + InputDeviceType type, + const std::string& name, + uint16_t vendor_id, + uint16_t product_id); ~EventConverterEvdev() override; - int id() const { return id_; } + int id() const { return input_device_.id; } 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; } @@ -91,11 +96,9 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev // Path to input device. base::FilePath path_; - // Uniquely identifies an event converter. - int id_; - - // Type (internal or external). - InputDeviceType type_; + // Input device information, including id (which uniquely identifies an + // event converter) and type. + InputDevice input_device_; // Whether events from the device should be ignored. bool ignore_events_; diff --git a/ui/events/ozone/evdev/event_converter_evdev_impl.cc b/ui/events/ozone/evdev/event_converter_evdev_impl.cc index f6bb266..0e7c7f1 100644 --- a/ui/events/ozone/evdev/event_converter_evdev_impl.cc +++ b/ui/events/ozone/evdev/event_converter_evdev_impl.cc @@ -31,7 +31,13 @@ EventConverterEvdevImpl::EventConverterEvdevImpl( const EventDeviceInfo& devinfo, CursorDelegateEvdev* cursor, 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_touchpad_(devinfo.HasTouchpad()), has_caps_lock_led_(devinfo.HasLedEvent(LED_CAPSL)), @@ -178,7 +184,8 @@ void EventConverterEvdevImpl::OnKeyChange(unsigned int key, // State transition: !(down) -> (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() { @@ -223,9 +230,9 @@ void EventConverterEvdevImpl::OnButtonChange(int code, mouse_button_state_.set(button_offset, down); - dispatcher_->DispatchMouseButtonEvent( - MouseButtonEventParams(id_, cursor_->GetLocation(), code, down, - /* allow_remap */ true, timestamp)); + dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams( + input_device_.id, cursor_->GetLocation(), code, down, + /* allow_remap */ true, timestamp)); } 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_)); - dispatcher_->DispatchMouseMoveEvent(MouseMoveEventParams( - id_, cursor_->GetLocation(), TimeDeltaFromInputEvent(input))); + dispatcher_->DispatchMouseMoveEvent( + MouseMoveEventParams(input_device_.id, cursor_->GetLocation(), + TimeDeltaFromInputEvent(input))); x_offset_ = 0; y_offset_ = 0; diff --git a/ui/events/ozone/evdev/event_device_info.cc b/ui/events/ozone/evdev/event_device_info.cc index dd29779..e3c9f73 100644 --- a/ui/events/ozone/evdev/event_device_info.cc +++ b/ui/events/ozone/evdev/event_device_info.cc @@ -17,6 +17,11 @@ namespace ui { 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) { if (ioctl(fd, EVIOCGBIT(type, size), buf) < 0) { PLOG(ERROR) << "EVIOCGBIT(" << type << ", " << size << ") on fd " << fd; @@ -43,6 +48,27 @@ bool GetAbsInfo(int fd, int code, struct input_absinfo* absinfo) { 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: // struct input_mt_request_layout { // uint32_t code; @@ -135,6 +161,12 @@ bool EventDeviceInfo::Initialize(int fd) { 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; } diff --git a/ui/events/ozone/evdev/event_device_info.h b/ui/events/ozone/evdev/event_device_info.h index c5a69c5..73503fd 100644 --- a/ui/events/ozone/evdev/event_device_info.h +++ b/ui/events/ozone/evdev/event_device_info.h @@ -8,6 +8,7 @@ #include <limits.h> #include <linux/input.h> +#include <string> #include <vector> #include "base/basictypes.h" @@ -80,6 +81,11 @@ class EVENTS_OZONE_EVDEV_EXPORT EventDeviceInfo { unsigned int slot, 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. bool HasProp(unsigned int code) const; @@ -150,6 +156,11 @@ class EVENTS_OZONE_EVDEV_EXPORT EventDeviceInfo { // Store the values for the multi-touch properties for each slot. 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); }; diff --git a/ui/events/ozone/evdev/event_factory_evdev.cc b/ui/events/ozone/evdev/event_factory_evdev.cc index 54b3cb6..e9098db 100644 --- a/ui/events/ozone/evdev/event_factory_evdev.cc +++ b/ui/events/ozone/evdev/event_factory_evdev.cc @@ -150,7 +150,8 @@ scoped_ptr<SystemInputInjector> EventFactoryEvdev::CreateSystemInputInjector() { } void EventFactoryEvdev::DispatchKeyEvent(const KeyEventParams& params) { - keyboard_.OnKeyChange(params.code, params.down, params.timestamp); + keyboard_.OnKeyChange(params.code, params.down, params.timestamp, + params.device_id); } void EventFactoryEvdev::DispatchMouseMoveEvent( diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index 988047b..d8997ca 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc @@ -101,7 +101,7 @@ scoped_ptr<EventConverterEvdev> CreateConverter( // Touchscreen: use TouchEventConverterEvdev. if (devinfo.HasTouchscreen()) { 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); return converter.Pass(); } @@ -423,8 +423,7 @@ void InputDeviceFactoryEvdev::NotifyTouchscreensUpdated() { std::vector<TouchscreenDevice> touchscreens; for (auto it = converters_.begin(); it != converters_.end(); ++it) { if (it->second->HasTouchscreen()) { - touchscreens.push_back(TouchscreenDevice( - it->second->id(), it->second->type(), + touchscreens.push_back(TouchscreenDevice(it->second->input_device(), it->second->GetTouchscreenSize(), it->second->GetTouchPoints())); } } @@ -436,7 +435,7 @@ void InputDeviceFactoryEvdev::NotifyKeyboardsUpdated() { std::vector<KeyboardDevice> keyboards; for (auto it = converters_.begin(); it != converters_.end(); ++it) { 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() { void InputDeviceFactoryEvdev::NotifyMouseDevicesUpdated() { std::vector<InputDevice> mice; for (auto it = converters_.begin(); it != converters_.end(); ++it) { - if (it->second->HasMouse()) - mice.push_back(InputDevice(it->second->id(), it->second->type())); + if (it->second->HasMouse()) { + mice.push_back(it->second->input_device()); + } } dispatcher_->DispatchMouseDevicesUpdated(mice); @@ -456,8 +456,9 @@ void InputDeviceFactoryEvdev::NotifyMouseDevicesUpdated() { void InputDeviceFactoryEvdev::NotifyTouchpadDevicesUpdated() { std::vector<InputDevice> touchpads; for (auto it = converters_.begin(); it != converters_.end(); ++it) { - if (it->second->HasTouchpad()) - touchpads.push_back(InputDevice(it->second->id(), it->second->type())); + if (it->second->HasTouchpad()) { + touchpads.push_back(it->second->input_device()); + } } dispatcher_->DispatchTouchpadDevicesUpdated(touchpads); diff --git a/ui/events/ozone/evdev/keyboard_evdev.cc b/ui/events/ozone/evdev/keyboard_evdev.cc index 1d4a5af..2c14f600 100644 --- a/ui/events/ozone/evdev/keyboard_evdev.cc +++ b/ui/events/ozone/evdev/keyboard_evdev.cc @@ -63,6 +63,7 @@ KeyboardEvdev::KeyboardEvdev(EventModifiersEvdev* modifiers, repeat_enabled_(true), repeat_key_(KEY_RESERVED), repeat_sequence_(0), + repeat_device_id_(0), weak_ptr_factory_(this) { repeat_delay_ = base::TimeDelta::FromMilliseconds(kRepeatDelayMs); repeat_interval_ = base::TimeDelta::FromMilliseconds(kRepeatIntervalMs); @@ -73,7 +74,8 @@ KeyboardEvdev::~KeyboardEvdev() { void KeyboardEvdev::OnKeyChange(unsigned int key, bool down, - base::TimeDelta timestamp) { + base::TimeDelta timestamp, + int device_id) { if (key > KEY_MAX) return; @@ -86,8 +88,8 @@ void KeyboardEvdev::OnKeyChange(unsigned int key, else key_state_.reset(key); - UpdateKeyRepeat(key, down); - DispatchKey(key, down, false /* repeat */, timestamp); + UpdateKeyRepeat(key, down, device_id); + DispatchKey(key, down, false /* repeat */, timestamp, device_id); } void KeyboardEvdev::SetCapsLockEnabled(bool enabled) { @@ -139,17 +141,20 @@ void KeyboardEvdev::UpdateModifier(int modifier_flag, bool 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_) StopKeyRepeat(); else if (key != repeat_key_ && down) - StartKeyRepeat(key); + StartKeyRepeat(key, device_id); else if (key == repeat_key_ && !down) StopKeyRepeat(); } -void KeyboardEvdev::StartKeyRepeat(unsigned int key) { +void KeyboardEvdev::StartKeyRepeat(unsigned int key, int device_id) { repeat_key_ = key; + repeat_device_id_ = device_id; repeat_sequence_++; ScheduleKeyRepeat(repeat_delay_); @@ -172,7 +177,7 @@ void KeyboardEvdev::OnRepeatTimeout(unsigned int sequence) { return; DispatchKey(repeat_key_, true /* down */, true /* repeat */, - EventTimeForNow()); + EventTimeForNow(), repeat_device_id_); ScheduleKeyRepeat(repeat_interval_); } @@ -180,7 +185,8 @@ void KeyboardEvdev::OnRepeatTimeout(unsigned int sequence) { void KeyboardEvdev::DispatchKey(unsigned int key, bool down, bool repeat, - base::TimeDelta timestamp) { + base::TimeDelta timestamp, + int device_id) { DomCode dom_code = KeycodeConverter::NativeKeycodeToDomCode(EvdevCodeToNativeCode(key)); // DomCode constants are not included here because of conflicts with @@ -201,6 +207,7 @@ void KeyboardEvdev::DispatchKey(unsigned int key, KeyEvent event(down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code, dom_code, modifiers_->GetModifierFlags(), dom_key, character, timestamp); + event.set_source_device_id(device_id); if (platform_keycode) event.set_platform_keycode(platform_keycode); callback_.Run(&event); diff --git a/ui/events/ozone/evdev/keyboard_evdev.h b/ui/events/ozone/evdev/keyboard_evdev.h index 8b49ebb..2dd0792 100644 --- a/ui/events/ozone/evdev/keyboard_evdev.h +++ b/ui/events/ozone/evdev/keyboard_evdev.h @@ -34,7 +34,10 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev { ~KeyboardEvdev(); // 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. void SetCapsLockEnabled(bool enabled); @@ -50,15 +53,16 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev { private: void UpdateModifier(int modifier_flag, bool down); void UpdateCapsLockLed(); - void UpdateKeyRepeat(unsigned int key, bool down); - void StartKeyRepeat(unsigned int key); + void UpdateKeyRepeat(unsigned int key, bool down, int device_id); + void StartKeyRepeat(unsigned int key, int device_id); void StopKeyRepeat(); void ScheduleKeyRepeat(const base::TimeDelta& delay); void OnRepeatTimeout(unsigned int sequence); void DispatchKey(unsigned int key, bool down, 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 // attempt to count presses of the same key on multiple keyboards. @@ -82,6 +86,7 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev { bool repeat_enabled_; unsigned int repeat_key_; unsigned int repeat_sequence_; + int repeat_device_id_; base::TimeDelta repeat_delay_; base::TimeDelta repeat_interval_; diff --git a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc index a9709f80..6d44ada 100644 --- a/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc +++ b/ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.cc @@ -31,7 +31,13 @@ EventReaderLibevdevCros::EventReaderLibevdevCros(int fd, InputDeviceType type, const EventDeviceInfo& devinfo, 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_mouse_(devinfo.HasMouse()), has_touchpad_(devinfo.HasTouchpad()), diff --git a/ui/events/ozone/evdev/tablet_event_converter_evdev.cc b/ui/events/ozone/evdev/tablet_event_converter_evdev.cc index 24b01fc..3c265e0 100644 --- a/ui/events/ozone/evdev/tablet_event_converter_evdev.cc +++ b/ui/events/ozone/evdev/tablet_event_converter_evdev.cc @@ -21,7 +21,13 @@ TabletEventConverterEvdev::TabletEventConverterEvdev( CursorDelegateEvdev* cursor, const EventDeviceInfo& info, DeviceEventDispatcherEvdev* dispatcher) - : EventConverterEvdev(fd, path, id, type), + : EventConverterEvdev(fd, + path, + id, + type, + info.name(), + info.vendor_id(), + info.product_id()), cursor_(cursor), dispatcher_(dispatcher), stylus_(0), @@ -145,8 +151,8 @@ void TabletEventConverterEvdev::DispatchMouseButton(const input_event& input) { bool down = input.value; dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams( - id_, cursor_->GetLocation(), button, down, false /* allow_remap */, - TimeDeltaFromInputEvent(input))); + input_device_.id, cursor_->GetLocation(), button, down, + false /* allow_remap */, TimeDeltaFromInputEvent(input))); } void TabletEventConverterEvdev::FlushEvents(const input_event& input) { @@ -164,8 +170,9 @@ void TabletEventConverterEvdev::FlushEvents(const input_event& input) { UpdateCursor(); - dispatcher_->DispatchMouseMoveEvent(MouseMoveEventParams( - id_, cursor_->GetLocation(), TimeDeltaFromInputEvent(input))); + dispatcher_->DispatchMouseMoveEvent( + MouseMoveEventParams(input_device_.id, cursor_->GetLocation(), + TimeDeltaFromInputEvent(input))); abs_value_dirty_ = false; } diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc index 95d0d77..d61f10e 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc @@ -83,8 +83,15 @@ TouchEventConverterEvdev::TouchEventConverterEvdev( base::FilePath path, int id, InputDeviceType type, + const EventDeviceInfo& devinfo, DeviceEventDispatcherEvdev* dispatcher) - : EventConverterEvdev(fd, path, id, type), + : EventConverterEvdev(fd, + path, + id, + type, + devinfo.name(), + devinfo.vendor_id(), + devinfo.product_id()), dispatcher_(dispatcher), syn_dropped_(false), has_mt_(false), @@ -358,7 +365,7 @@ void TouchEventConverterEvdev::ReportEvent(const InProgressTouchEvdev& event, EventType event_type, const base::TimeDelta& timestamp) { 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, timestamp)); } diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.h b/ui/events/ozone/evdev/touch_event_converter_evdev.h index c1b7894..6012f86 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev.h +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.h @@ -30,6 +30,7 @@ class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev base::FilePath path, int id, InputDeviceType type, + const EventDeviceInfo& devinfo, DeviceEventDispatcherEvdev* dispatcher); ~TouchEventConverterEvdev() override; diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc index 87c25e8..59a5f48 100644 --- a/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc +++ b/ui/events/ozone/evdev/touch_event_converter_evdev_unittest.cc @@ -53,6 +53,7 @@ class MockTouchEventConverterEvdev : public TouchEventConverterEvdev { public: MockTouchEventConverterEvdev(int fd, base::FilePath path, + const EventDeviceInfo& devinfo, DeviceEventDispatcherEvdev* dispatcher); ~MockTouchEventConverterEvdev() override {} @@ -111,8 +112,14 @@ class MockDeviceEventDispatcherEvdev : public DeviceEventDispatcherEvdev { MockTouchEventConverterEvdev::MockTouchEventConverterEvdev( int fd, base::FilePath path, + const EventDeviceInfo& devinfo, DeviceEventDispatcherEvdev* dispatcher) - : TouchEventConverterEvdev(fd, path, 1, INPUT_DEVICE_UNKNOWN, dispatcher) { + : TouchEventConverterEvdev(fd, + path, + 1, + INPUT_DEVICE_UNKNOWN, + devinfo, + dispatcher) { int fds[2]; if (pipe(fds)) @@ -157,11 +164,13 @@ class TouchEventConverterEvdevTest : public testing::Test { // Device creation happens on a worker thread since it may involve blocking // operations. Simulate that by creating it before creating a UI message // loop. + EventDeviceInfo devinfo; dispatcher_.reset(new ui::MockDeviceEventDispatcherEvdev( base::Bind(&TouchEventConverterEvdevTest::DispatchCallback, base::Unretained(this)))); device_ = new ui::MockTouchEventConverterEvdev( - events_in_, base::FilePath(kTestDevicePath), dispatcher_.get()); + events_in_, base::FilePath(kTestDevicePath), devinfo, + dispatcher_.get()); loop_ = new base::MessageLoopForUI; ui::DeviceDataManager::CreateInstance(); @@ -180,9 +189,7 @@ class TouchEventConverterEvdevTest : public testing::Test { return dispatched_events_[index]; } - void ClearDispatchedEvents() { - dispatched_events_.clear(); - } + void ClearDispatchedEvents() { dispatched_events_.clear(); } private: base::MessageLoop* loop_; diff --git a/ui/events/platform/x11/x11_hotplug_event_handler.cc b/ui/events/platform/x11/x11_hotplug_event_handler.cc index 5e69c23..b415058 100644 --- a/ui/events/platform/x11/x11_hotplug_event_handler.cc +++ b/ui/events/platform/x11/x11_hotplug_event_handler.cc @@ -32,6 +32,10 @@ #include "ui/events/devices/touchscreen_device.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 { @@ -52,6 +56,7 @@ const char* kCachedAtomList[] = { XI_MOUSE, XI_TOUCHPAD, XI_TOUCHSCREEN, + XI_PROP_PRODUCT_ID, NULL, }; @@ -113,9 +118,13 @@ struct TouchClassInfo { struct DeviceInfo { DeviceInfo(const XIDeviceInfo& device, DeviceType type, - const base::FilePath& path) + const base::FilePath& path, + uint16_t vendor, + uint16_t product) : id(device.deviceid), name(device.name), + vendor_id(vendor), + product_id(product), use(device.use), type(type), path(path) { @@ -144,6 +153,10 @@ struct DeviceInfo { // Internal device name. std::string name; + // USB-style device identifiers. + uint16_t vendor_id; + uint16_t product_id; + // Device type (ie: XIMasterPointer) int use; @@ -246,7 +259,8 @@ void HandleKeyboardDevicesInWorker( if (IsKnownInvalidKeyboardDevice(device_info.name)) continue; // Skip invalid devices. 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)); @@ -265,7 +279,7 @@ void HandleMouseDevicesInWorker(const std::vector<DeviceInfo>& device_infos, } 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)); @@ -284,7 +298,7 @@ void HandleTouchpadDevicesInWorker(const std::vector<DeviceInfo>& device_infos, } 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)); @@ -337,9 +351,10 @@ void HandleTouchscreenDevicesInWorker( InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path); // |max_x| and |max_y| are inclusive values, so we need to add 1 to get // the size. - devices.push_back(TouchscreenDevice( - device_info.id, type, gfx::Size(max_x + 1, max_y + 1), - device_info.touch_class_info.num_touches)); + devices.push_back( + TouchscreenDevice(device_info.id, type, device_info.name, + gfx::Size(max_x + 1, max_y + 1), + device_info.touch_class_info.num_touches)); } } @@ -428,8 +443,29 @@ void X11HotplugEventHandler::OnHotplugEvent() { (device.deviceid >= 0 && device.deviceid < kMaxDeviceNum) ? device_types[device.deviceid] : 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) { + 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. @@ -446,13 +482,11 @@ void X11HotplugEventHandler::OnHotplugEvent() { // Parsing the device information may block, so delegate the operation to a // worker thread. Once the device information is extracted the parsed devices // will be returned via the callbacks. - base::WorkerPool::PostTask(FROM_HERE, - base::Bind(&HandleHotplugEventInWorker, - device_infos, - display_state, - base::ThreadTaskRunnerHandle::Get(), - callbacks), - true /* task_is_slow */); + base::WorkerPool::PostTask( + FROM_HERE, + base::Bind(&HandleHotplugEventInWorker, device_infos, display_state, + base::ThreadTaskRunnerHandle::Get(), callbacks), + true /* task_is_slow */); } } // namespace ui |