Commit 6f440efc authored by pkotwicz's avatar pkotwicz Committed by Commit bot

Make PointerDeviceObserver use ui::InputDeviceEventObserver on X11

This CL:
- Makes PointerDeviceObserver use ui::InputDeviceEventObserver on X11 (it is
  already used on Ozone)
- Makes X11HotplugEventObserver notify ui::DeviceDataManager when a mouse /
  touchpad is plugged in / unplugged
- Removes DeviceHierarchyObserver

BUG=440503
TEST=Manual

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

Cr-Commit-Position: refs/heads/master@{#318997}
parent cc241280
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_DEVICE_HIERARCHY_OBSERVER_H_
#define CHROME_BROWSER_CHROMEOS_DEVICE_HIERARCHY_OBSERVER_H_
namespace chromeos {
// Observers receive notifications when a device has been added/removed.
class DeviceHierarchyObserver {
public:
virtual void DeviceHierarchyChanged() = 0;
// Called when a new device (e.g. an external USB keyboard) is attached or
// detached.
virtual void DeviceAdded(int device_id) = 0;
virtual void DeviceRemoved(int device_id) = 0;
protected:
virtual ~DeviceHierarchyObserver() {}
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_DEVICE_HIERARCHY_OBSERVER_H_
...@@ -16,9 +16,7 @@ namespace chromeos { ...@@ -16,9 +16,7 @@ namespace chromeos {
namespace { namespace {
// Checks the |event| and asynchronously sets the XKB layout when necessary. // Checks the |event| and asynchronously sets the XKB layout when necessary.
void HandleHierarchyChangedEvent( void HandleHierarchyChangedEvent(XIHierarchyEvent* event) {
XIHierarchyEvent* event,
ObserverList<DeviceHierarchyObserver>* observer_list) {
if (!(event->flags & (XISlaveAdded | XISlaveRemoved))) if (!(event->flags & (XISlaveAdded | XISlaveRemoved)))
return; return;
...@@ -26,15 +24,8 @@ void HandleHierarchyChangedEvent( ...@@ -26,15 +24,8 @@ void HandleHierarchyChangedEvent(
for (int i = 0; i < event->num_info; ++i) { for (int i = 0; i < event->num_info; ++i) {
XIHierarchyInfo* info = &event->info[i]; XIHierarchyInfo* info = &event->info[i];
if ((info->flags & XISlaveAdded) && (info->use == XIFloatingSlave)) { if ((info->flags & XISlaveAdded) && (info->use == XIFloatingSlave)) {
FOR_EACH_OBSERVER(DeviceHierarchyObserver,
*observer_list,
DeviceAdded(info->deviceid));
update_keyboard_status = true; update_keyboard_status = true;
} else if (info->flags & XISlaveRemoved) { break;
// Can't check info->use here; it appears to always be 0.
FOR_EACH_OBSERVER(DeviceHierarchyObserver,
*observer_list,
DeviceRemoved(info->deviceid));
} }
} }
...@@ -73,16 +64,6 @@ void XInputHierarchyChangedEventListener::Stop() { ...@@ -73,16 +64,6 @@ void XInputHierarchyChangedEventListener::Stop() {
stopped_ = true; stopped_ = true;
} }
void XInputHierarchyChangedEventListener::AddObserver(
DeviceHierarchyObserver* observer) {
observer_list_.AddObserver(observer);
}
void XInputHierarchyChangedEventListener::RemoveObserver(
DeviceHierarchyObserver* observer) {
observer_list_.RemoveObserver(observer);
}
void XInputHierarchyChangedEventListener::WillProcessEvent( void XInputHierarchyChangedEventListener::WillProcessEvent(
const ui::PlatformEvent& event) { const ui::PlatformEvent& event) {
ProcessedXEvent(event); ProcessedXEvent(event);
...@@ -100,16 +81,8 @@ void XInputHierarchyChangedEventListener::ProcessedXEvent(XEvent* xevent) { ...@@ -100,16 +81,8 @@ void XInputHierarchyChangedEventListener::ProcessedXEvent(XEvent* xevent) {
if (cookie->evtype == XI_HierarchyChanged) { if (cookie->evtype == XI_HierarchyChanged) {
XIHierarchyEvent* event = static_cast<XIHierarchyEvent*>(cookie->data); XIHierarchyEvent* event = static_cast<XIHierarchyEvent*>(cookie->data);
HandleHierarchyChangedEvent(event, &observer_list_); HandleHierarchyChangedEvent(event);
if (event->flags & XIDeviceEnabled || event->flags & XIDeviceDisabled)
NotifyDeviceHierarchyChanged();
} }
} }
void XInputHierarchyChangedEventListener::NotifyDeviceHierarchyChanged() {
FOR_EACH_OBSERVER(DeviceHierarchyObserver,
observer_list_,
DeviceHierarchyChanged());
}
} // namespace chromeos } // namespace chromeos
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "chrome/browser/chromeos/device_hierarchy_observer.h"
#include "ui/events/platform/platform_event_observer.h" #include "ui/events/platform/platform_event_observer.h"
typedef union _XEvent XEvent; typedef union _XEvent XEvent;
...@@ -24,9 +23,6 @@ class XInputHierarchyChangedEventListener : public ui::PlatformEventObserver { ...@@ -24,9 +23,6 @@ class XInputHierarchyChangedEventListener : public ui::PlatformEventObserver {
void Stop(); void Stop();
void AddObserver(DeviceHierarchyObserver* observer);
void RemoveObserver(DeviceHierarchyObserver* observer);
private: private:
// Defines the delete on exit Singleton traits we like. Best to have this // Defines the delete on exit Singleton traits we like. Best to have this
// and const/dest private as recommended for Singletons. // and const/dest private as recommended for Singletons.
...@@ -42,13 +38,8 @@ class XInputHierarchyChangedEventListener : public ui::PlatformEventObserver { ...@@ -42,13 +38,8 @@ class XInputHierarchyChangedEventListener : public ui::PlatformEventObserver {
// Returns true if the event was processed, false otherwise. // Returns true if the event was processed, false otherwise.
void ProcessedXEvent(XEvent* xevent); void ProcessedXEvent(XEvent* xevent);
// Notify observers that a device has been added/removed.
void NotifyDeviceHierarchyChanged();
bool stopped_; bool stopped_;
ObserverList<DeviceHierarchyObserver> observer_list_;
DISALLOW_COPY_AND_ASSIGN(XInputHierarchyChangedEventListener); DISALLOW_COPY_AND_ASSIGN(XInputHierarchyChangedEventListener);
}; };
......
...@@ -11,10 +11,6 @@ ...@@ -11,10 +11,6 @@
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "ui/events/devices/device_data_manager.h" #include "ui/events/devices/device_data_manager.h"
#if defined(USE_X11)
#include "chrome/browser/chromeos/events/xinput_hierarchy_changed_event_listener.h"
#endif
using content::BrowserThread; using content::BrowserThread;
namespace chromeos { namespace chromeos {
...@@ -25,21 +21,11 @@ PointerDeviceObserver::PointerDeviceObserver() ...@@ -25,21 +21,11 @@ PointerDeviceObserver::PointerDeviceObserver()
} }
PointerDeviceObserver::~PointerDeviceObserver() { PointerDeviceObserver::~PointerDeviceObserver() {
#if defined(USE_X11)
XInputHierarchyChangedEventListener::GetInstance()
->RemoveObserver(this);
#elif defined(USE_OZONE)
ui::DeviceDataManager::GetInstance()->RemoveObserver(this); ui::DeviceDataManager::GetInstance()->RemoveObserver(this);
#endif
} }
void PointerDeviceObserver::Init() { void PointerDeviceObserver::Init() {
#if defined(USE_X11)
XInputHierarchyChangedEventListener::GetInstance()
->AddObserver(this);
#elif defined(USE_OZONE)
ui::DeviceDataManager::GetInstance()->AddObserver(this); ui::DeviceDataManager::GetInstance()->AddObserver(this);
#endif
} }
void PointerDeviceObserver::CheckDevices() { void PointerDeviceObserver::CheckDevices() {
...@@ -55,10 +41,6 @@ void PointerDeviceObserver::RemoveObserver(Observer* observer) { ...@@ -55,10 +41,6 @@ void PointerDeviceObserver::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer); observers_.RemoveObserver(observer);
} }
void PointerDeviceObserver::DeviceHierarchyChanged() {
CheckDevices();
}
void PointerDeviceObserver::OnMouseDeviceConfigurationChanged() { void PointerDeviceObserver::OnMouseDeviceConfigurationChanged() {
CheckDevices(); CheckDevices();
} }
......
...@@ -7,14 +7,12 @@ ...@@ -7,14 +7,12 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "chrome/browser/chromeos/device_hierarchy_observer.h"
#include "ui/events/devices/input_device_event_observer.h" #include "ui/events/devices/input_device_event_observer.h"
namespace chromeos { namespace chromeos {
namespace system { namespace system {
class PointerDeviceObserver : public DeviceHierarchyObserver, class PointerDeviceObserver : public ui::InputDeviceEventObserver {
public ui::InputDeviceEventObserver {
public: public:
PointerDeviceObserver(); PointerDeviceObserver();
~PointerDeviceObserver() override; ~PointerDeviceObserver() override;
...@@ -38,11 +36,6 @@ class PointerDeviceObserver : public DeviceHierarchyObserver, ...@@ -38,11 +36,6 @@ class PointerDeviceObserver : public DeviceHierarchyObserver,
void RemoveObserver(Observer* observer); void RemoveObserver(Observer* observer);
private: private:
// DeviceHierarchyObserver:
void DeviceHierarchyChanged() override;
void DeviceAdded(int device_id) override {}
void DeviceRemoved(int device_id) override {}
// InputDeviceEventObserver: // InputDeviceEventObserver:
void OnMouseDeviceConfigurationChanged() override; void OnMouseDeviceConfigurationChanged() override;
void OnTouchpadDeviceConfigurationChanged() override; void OnTouchpadDeviceConfigurationChanged() override;
......
...@@ -85,7 +85,6 @@ ...@@ -85,7 +85,6 @@
'browser/chromeos/dbus/screen_lock_service_provider.h', 'browser/chromeos/dbus/screen_lock_service_provider.h',
'browser/chromeos/device/input_service_proxy.cc', 'browser/chromeos/device/input_service_proxy.cc',
'browser/chromeos/device/input_service_proxy.h', 'browser/chromeos/device/input_service_proxy.h',
'browser/chromeos/device_hierarchy_observer.h',
'browser/chromeos/device_uma.cc', 'browser/chromeos/device_uma.cc',
'browser/chromeos/device_uma.h', 'browser/chromeos/device_uma.h',
'browser/chromeos/display/display_configuration_observer.cc', 'browser/chromeos/display/display_configuration_observer.cc',
......
...@@ -151,6 +151,14 @@ void DeviceDataManager::OnKeyboardDevicesUpdated( ...@@ -151,6 +151,14 @@ void DeviceDataManager::OnKeyboardDevicesUpdated(
void DeviceDataManager::OnMouseDevicesUpdated( void DeviceDataManager::OnMouseDevicesUpdated(
const std::vector<InputDevice>& devices) { const std::vector<InputDevice>& devices) {
if (devices.size() == mouse_devices_.size() &&
std::equal(devices.begin(),
devices.end(),
mouse_devices_.begin(),
InputDeviceEquals)) {
return;
}
mouse_devices_ = devices;
FOR_EACH_OBSERVER(InputDeviceEventObserver, FOR_EACH_OBSERVER(InputDeviceEventObserver,
observers_, observers_,
OnMouseDeviceConfigurationChanged()); OnMouseDeviceConfigurationChanged());
...@@ -158,6 +166,14 @@ void DeviceDataManager::OnMouseDevicesUpdated( ...@@ -158,6 +166,14 @@ void DeviceDataManager::OnMouseDevicesUpdated(
void DeviceDataManager::OnTouchpadDevicesUpdated( void DeviceDataManager::OnTouchpadDevicesUpdated(
const std::vector<InputDevice>& devices) { const std::vector<InputDevice>& devices) {
if (devices.size() == touchpad_devices_.size() &&
std::equal(devices.begin(),
devices.end(),
touchpad_devices_.begin(),
InputDeviceEquals)) {
return;
}
touchpad_devices_ = devices;
FOR_EACH_OBSERVER(InputDeviceEventObserver, FOR_EACH_OBSERVER(InputDeviceEventObserver,
observers_, observers_,
OnTouchpadDeviceConfigurationChanged()); OnTouchpadDeviceConfigurationChanged());
......
...@@ -83,6 +83,8 @@ class EVENTS_DEVICES_EXPORT DeviceDataManager ...@@ -83,6 +83,8 @@ class EVENTS_DEVICES_EXPORT DeviceDataManager
std::vector<TouchscreenDevice> touchscreen_devices_; std::vector<TouchscreenDevice> touchscreen_devices_;
std::vector<KeyboardDevice> keyboard_devices_; std::vector<KeyboardDevice> keyboard_devices_;
std::vector<InputDevice> mouse_devices_;
std::vector<InputDevice> touchpad_devices_;
ObserverList<InputDeviceEventObserver> observers_; ObserverList<InputDeviceEventObserver> observers_;
......
...@@ -46,20 +46,37 @@ const char* kKnownInvalidKeyboardDeviceNames[] = {"Power Button", ...@@ -46,20 +46,37 @@ const char* kKnownInvalidKeyboardDeviceNames[] = {"Power Button",
const char* kCachedAtomList[] = { const char* kCachedAtomList[] = {
"Abs MT Position X", "Abs MT Position X",
"Abs MT Position Y", "Abs MT Position Y",
XI_KEYBOARD,
XI_MOUSE,
XI_TOUCHPAD,
XI_TOUCHSCREEN,
NULL, NULL,
}; };
enum DeviceType {
DEVICE_TYPE_KEYBOARD,
DEVICE_TYPE_MOUSE,
DEVICE_TYPE_TOUCHPAD,
DEVICE_TYPE_TOUCHSCREEN,
DEVICE_TYPE_OTHER
};
typedef base::Callback<void(const std::vector<KeyboardDevice>&)> typedef base::Callback<void(const std::vector<KeyboardDevice>&)>
KeyboardDeviceCallback; KeyboardDeviceCallback;
typedef base::Callback<void(const std::vector<TouchscreenDevice>&)> typedef base::Callback<void(const std::vector<TouchscreenDevice>&)>
TouchscreenDeviceCallback; TouchscreenDeviceCallback;
typedef base::Callback<void(const std::vector<InputDevice>&)>
InputDeviceCallback;
// Used for updating the state on the UI thread once device information is // Used for updating the state on the UI thread once device information is
// parsed on helper threads. // parsed on helper threads.
struct UiCallbacks { struct UiCallbacks {
KeyboardDeviceCallback keyboard_callback; KeyboardDeviceCallback keyboard_callback;
TouchscreenDeviceCallback touchscreen_callback; TouchscreenDeviceCallback touchscreen_callback;
InputDeviceCallback mouse_callback;
InputDeviceCallback touchpad_callback;
}; };
// Stores a copy of the XIValuatorClassInfo values so X11 device processing can // Stores a copy of the XIValuatorClassInfo values so X11 device processing can
...@@ -92,11 +109,13 @@ struct TouchClassInfo { ...@@ -92,11 +109,13 @@ struct TouchClassInfo {
}; };
struct DeviceInfo { struct DeviceInfo {
DeviceInfo(const XIDeviceInfo& device, const base::FilePath& path) DeviceInfo(const XIDeviceInfo& device,
DeviceType type,
const base::FilePath& path)
: id(device.deviceid), : id(device.deviceid),
name(device.name), name(device.name),
use(device.use), use(device.use),
enabled(device.enabled), type(type),
path(path) { path(path) {
for (int i = 0; i < device.num_classes; ++i) { for (int i = 0; i < device.num_classes; ++i) {
switch (device.classes[i]->type) { switch (device.classes[i]->type) {
...@@ -126,8 +145,8 @@ struct DeviceInfo { ...@@ -126,8 +145,8 @@ struct DeviceInfo {
// Device type (ie: XIMasterPointer) // Device type (ie: XIMasterPointer)
int use; int use;
// Specifies if the device is enabled and can send events. // Specifies the type of the device.
bool enabled; DeviceType type;
// Path to the actual device (ie: /dev/input/eventXX) // Path to the actual device (ie: /dev/input/eventXX)
base::FilePath path; base::FilePath path;
...@@ -147,8 +166,10 @@ struct DisplayState { ...@@ -147,8 +166,10 @@ struct DisplayState {
// Returns true if |name| is the name of a known invalid keyboard device. Note, // Returns true if |name| is the name of a known invalid keyboard device. Note,
// this may return false negatives. // this may return false negatives.
bool IsKnownInvalidKeyboardDevice(const std::string& name) { bool IsKnownInvalidKeyboardDevice(const std::string& name) {
std::string trimmed(name);
base::TrimWhitespaceASCII(name, base::TRIM_TRAILING, &trimmed);
for (const char* device_name : kKnownInvalidKeyboardDeviceNames) { for (const char* device_name : kKnownInvalidKeyboardDeviceNames) {
if (name == device_name) if (trimmed == device_name)
return true; return true;
} }
return false; return false;
...@@ -156,7 +177,7 @@ bool IsKnownInvalidKeyboardDevice(const std::string& name) { ...@@ -156,7 +177,7 @@ bool IsKnownInvalidKeyboardDevice(const std::string& name) {
// Returns true if |name| is the name of a known XTEST device. Note, this may // Returns true if |name| is the name of a known XTEST device. Note, this may
// return false negatives. // return false negatives.
bool IsTestKeyboard(const std::string& name) { bool IsTestDevice(const std::string& name) {
return name.find("XTEST") != std::string::npos; return name.find("XTEST") != std::string::npos;
} }
...@@ -216,13 +237,11 @@ void HandleKeyboardDevicesInWorker( ...@@ -216,13 +237,11 @@ void HandleKeyboardDevicesInWorker(
std::vector<KeyboardDevice> devices; std::vector<KeyboardDevice> devices;
for (const DeviceInfo& device_info : device_infos) { for (const DeviceInfo& device_info : device_infos) {
if (!device_info.enabled || device_info.use != XISlaveKeyboard) if (device_info.type != DEVICE_TYPE_KEYBOARD)
continue;
if (device_info.use != XISlaveKeyboard)
continue; // Assume all keyboards are keyboard slaves continue; // Assume all keyboards are keyboard slaves
std::string device_name(device_info.name); if (IsKnownInvalidKeyboardDevice(device_info.name))
base::TrimWhitespaceASCII(device_name, base::TRIM_TRAILING, &device_name);
if (IsTestKeyboard(device_name))
continue; // Skip test devices.
if (IsKnownInvalidKeyboardDevice(device_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)); devices.push_back(KeyboardDevice(device_info.id, type));
...@@ -231,6 +250,44 @@ void HandleKeyboardDevicesInWorker( ...@@ -231,6 +250,44 @@ void HandleKeyboardDevicesInWorker(
reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
} }
// Helper used to parse mouse information. When it is done it uses
// |reply_runner| and |callback| to update the state on the UI thread.
void HandleMouseDevicesInWorker(const std::vector<DeviceInfo>& device_infos,
scoped_refptr<base::TaskRunner> reply_runner,
const InputDeviceCallback& callback) {
std::vector<InputDevice> devices;
for (const DeviceInfo& device_info : device_infos) {
if (device_info.type != DEVICE_TYPE_MOUSE ||
device_info.use != XISlavePointer) {
continue;
}
InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
devices.push_back(InputDevice(device_info.id, type));
}
reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
}
// Helper used to parse touchpad information. When it is done it uses
// |reply_runner| and |callback| to update the state on the UI thread.
void HandleTouchpadDevicesInWorker(const std::vector<DeviceInfo>& device_infos,
scoped_refptr<base::TaskRunner> reply_runner,
const InputDeviceCallback& callback) {
std::vector<InputDevice> devices;
for (const DeviceInfo& device_info : device_infos) {
if (device_info.type != DEVICE_TYPE_TOUCHPAD ||
device_info.use != XISlavePointer) {
continue;
}
InputDeviceType type = GetInputDeviceTypeFromPath(device_info.path);
devices.push_back(InputDevice(device_info.id, type));
}
reply_runner->PostTask(FROM_HERE, base::Bind(callback, devices));
}
// Helper used to parse touchscreen information. When it is done it uses // Helper used to parse touchscreen information. When it is done it uses
// |reply_runner| and |callback| to update the state on the UI thread. // |reply_runner| and |callback| to update the state on the UI thread.
void HandleTouchscreenDevicesInWorker( void HandleTouchscreenDevicesInWorker(
...@@ -243,15 +300,19 @@ void HandleTouchscreenDevicesInWorker( ...@@ -243,15 +300,19 @@ void HandleTouchscreenDevicesInWorker(
display_state.mt_position_y == None) display_state.mt_position_y == None)
return; return;
std::set<int> no_match_touchscreen;
for (const DeviceInfo& device_info : device_infos) { for (const DeviceInfo& device_info : device_infos) {
if (!device_info.enabled || (device_info.use != XIFloatingSlave if (device_info.type != DEVICE_TYPE_TOUCHSCREEN ||
&& device_info.use != XISlavePointer)) (device_info.use != XIFloatingSlave &&
device_info.use != XISlavePointer)) {
continue;
}
// Touchscreens should be direct touch devices.
if (device_info.touch_class_info.mode != XIDirectTouch)
continue; continue;
double max_x = -1.0; double max_x = -1.0;
double max_y = -1.0; double max_y = -1.0;
bool is_direct_touch = false;
for (const ValuatorClassInfo& valuator : device_info.valuator_class_infos) { for (const ValuatorClassInfo& valuator : device_info.valuator_class_infos) {
if (display_state.mt_position_x == valuator.label) { if (display_state.mt_position_x == valuator.label) {
...@@ -269,12 +330,8 @@ void HandleTouchscreenDevicesInWorker( ...@@ -269,12 +330,8 @@ void HandleTouchscreenDevicesInWorker(
} }
} }
if (device_info.touch_class_info.mode) // Touchscreens should have absolute X and Y axes.
is_direct_touch = device_info.touch_class_info.mode == XIDirectTouch; if (max_x > 0.0 && max_y > 0.0) {
// Touchscreens should have absolute X and Y axes, and be direct touch
// devices.
if (max_x > 0.0 && max_y > 0.0 && is_direct_touch) {
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.
...@@ -297,6 +354,9 @@ void HandleHotplugEventInWorker( ...@@ -297,6 +354,9 @@ void HandleHotplugEventInWorker(
devices, display_state, reply_runner, callbacks.touchscreen_callback); devices, display_state, reply_runner, callbacks.touchscreen_callback);
HandleKeyboardDevicesInWorker( HandleKeyboardDevicesInWorker(
devices, reply_runner, callbacks.keyboard_callback); devices, reply_runner, callbacks.keyboard_callback);
HandleMouseDevicesInWorker(devices, reply_runner, callbacks.mouse_callback);
HandleTouchpadDevicesInWorker(devices, reply_runner,
callbacks.touchpad_callback);
} }
DeviceHotplugEventObserver* GetHotplugEventObserver() { DeviceHotplugEventObserver* GetHotplugEventObserver() {
...@@ -311,6 +371,14 @@ void OnTouchscreenDevices(const std::vector<TouchscreenDevice>& devices) { ...@@ -311,6 +371,14 @@ void OnTouchscreenDevices(const std::vector<TouchscreenDevice>& devices) {
GetHotplugEventObserver()->OnTouchscreenDevicesUpdated(devices); GetHotplugEventObserver()->OnTouchscreenDevicesUpdated(devices);
} }
void OnMouseDevices(const std::vector<InputDevice>& devices) {
GetHotplugEventObserver()->OnMouseDevicesUpdated(devices);
}
void OnTouchpadDevices(const std::vector<InputDevice>& devices) {
GetHotplugEventObserver()->OnTouchpadDevicesUpdated(devices);
}
} // namespace } // namespace
X11HotplugEventHandler::X11HotplugEventHandler() X11HotplugEventHandler::X11HotplugEventHandler()
...@@ -321,14 +389,45 @@ X11HotplugEventHandler::~X11HotplugEventHandler() { ...@@ -321,14 +389,45 @@ X11HotplugEventHandler::~X11HotplugEventHandler() {
} }
void X11HotplugEventHandler::OnHotplugEvent() { void X11HotplugEventHandler::OnHotplugEvent() {
const XIDeviceList& device_list =
DeviceListCacheX11::GetInstance()->GetXI2DeviceList(gfx::GetXDisplay());
Display* display = gfx::GetXDisplay(); Display* display = gfx::GetXDisplay();
const XDeviceList& device_list_xi =
DeviceListCacheX11::GetInstance()->GetXDeviceList(display);
const XIDeviceList& device_list_xi2 =
DeviceListCacheX11::GetInstance()->GetXI2DeviceList(display);
const int kMaxDeviceNum = 128;
DeviceType device_types[kMaxDeviceNum];
for (int i = 0; i < kMaxDeviceNum; ++i)
device_types[i] = DEVICE_TYPE_OTHER;
for (int i = 0; i < device_list_xi.count; ++i) {
int id = device_list_xi[i].id;
if (id < 0 || id >= kMaxDeviceNum)
continue;
Atom type = device_list_xi[i].type;
if (type == atom_cache_.GetAtom(XI_KEYBOARD))
device_types[id] = DEVICE_TYPE_KEYBOARD;
else if (type == atom_cache_.GetAtom(XI_MOUSE))
device_types[id] = DEVICE_TYPE_MOUSE;
else if (type == atom_cache_.GetAtom(XI_TOUCHPAD))
device_types[id] = DEVICE_TYPE_TOUCHPAD;
else if (type == atom_cache_.GetAtom(XI_TOUCHSCREEN))
device_types[id] = DEVICE_TYPE_TOUCHSCREEN;
}
std::vector<DeviceInfo> device_infos; std::vector<DeviceInfo> device_infos;
for (int i = 0; i < device_list.count; ++i) { for (int i = 0; i < device_list_xi2.count; ++i) {
const XIDeviceInfo& device = device_list[i]; const XIDeviceInfo& device = device_list_xi2[i];
device_infos.push_back(DeviceInfo(device, GetDevicePath(display, device))); if (!device.enabled || IsTestDevice(device.name))
continue;
DeviceType device_type =
(device.deviceid >= 0 && device.deviceid < kMaxDeviceNum)
? device_types[device.deviceid]
: DEVICE_TYPE_OTHER;
device_infos.push_back(
DeviceInfo(device, device_type, GetDevicePath(display, device)));
} }
// X11 is not thread safe, so first get all the required state. // X11 is not thread safe, so first get all the required state.
...@@ -339,8 +438,8 @@ void X11HotplugEventHandler::OnHotplugEvent() { ...@@ -339,8 +438,8 @@ void X11HotplugEventHandler::OnHotplugEvent() {
UiCallbacks callbacks; UiCallbacks callbacks;
callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices); callbacks.keyboard_callback = base::Bind(&OnKeyboardDevices);
callbacks.touchscreen_callback = base::Bind(&OnTouchscreenDevices); callbacks.touchscreen_callback = base::Bind(&OnTouchscreenDevices);
// TODO(pkotwicz): Compute the lists of mice and touchpads and send the new callbacks.mouse_callback = base::Bind(&OnMouseDevices);
// lists to DeviceHotplugEventObserver. callbacks.touchpad_callback = base::Bind(&OnTouchpadDevices);
// 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
......
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