diff --git a/chromium/build/linux/system.gyp b/chromium/build/linux/system.gyp index 628357d10e4efc640de107cb6fe4f4b9e35d4d11..2fb38927e86eb563d1d9e79ba4f33a12f312713e 100644 --- a/chromium/build/linux/system.gyp +++ b/chromium/build/linux/system.gyp @@ -1042,14 +1042,6 @@ '<!@(<(pkg-config) --cflags libudev)' ], }, - 'link_settings': { - 'ldflags': [ - '<!@(<(pkg-config) --libs-only-L --libs-only-other libudev)', - ], - 'libraries': [ - '<!@(<(pkg-config) --libs-only-l libudev)', - ], - }, }], ], }, diff --git a/chromium/content/browser/device_monitor_udev.cc b/chromium/content/browser/device_monitor_udev.cc index ddfe053eae2348217141ca34084346cc5a3455aa..4f272dfbcffdb4ec94e9ffaa2a59eb337240dfa4 100644 --- a/chromium/content/browser/device_monitor_udev.cc +++ b/chromium/content/browser/device_monitor_udev.cc @@ -6,13 +6,12 @@ #include "content/browser/device_monitor_udev.h" -#include <libudev.h> - #include <string> #include "base/system_monitor/system_monitor.h" #include "content/browser/udev_linux.h" #include "content/public/browser/browser_thread.h" +#include "device/udev_linux/udev.h" namespace { @@ -72,7 +71,7 @@ void DeviceMonitorLinux::OnDevicesChanged(udev_device* device) { base::SystemMonitor::DeviceType device_type = base::SystemMonitor::DEVTYPE_UNKNOWN; - std::string subsystem(udev_device_get_subsystem(device)); + std::string subsystem(libudev.udev_device_get_subsystem(device)); for (size_t i = 0; i < arraysize(kSubsystemMap); ++i) { if (subsystem == kSubsystemMap[i].subsystem) { device_type = kSubsystemMap[i].device_type; diff --git a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc index a211bb67df1444114db0a83b5406b4b977e38cc1..17870c830a286150b0680192cd24ca171366c752 100644 --- a/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc +++ b/chromium/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc @@ -5,7 +5,6 @@ #include "content/browser/gamepad/gamepad_platform_data_fetcher_linux.h" #include <fcntl.h> -#include <libudev.h> #include <linux/joystick.h> #include <string.h> #include <sys/stat.h> @@ -20,6 +19,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "content/browser/udev_linux.h" +#include "device/udev_linux/udev.h" namespace { @@ -34,10 +34,10 @@ void CloseFileDescriptorIfValid(int fd) { } bool IsGamepad(udev_device* dev, int* index, std::string* path) { - if (!udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK")) + if (!libudev.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK")) return false; - const char* node_path = udev_device_get_devnode(dev); + const char* node_path = libudev.udev_device_get_devnode(dev); if (!node_path) return false; @@ -125,7 +125,7 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { // joystick device. In order to get the information about the physical // hardware, get the parent device that is also in the "input" subsystem. // This function should just walk up the tree one level. - dev = udev_device_get_parent_with_subsystem_devtype( + dev = libudev.udev_device_get_parent_with_subsystem_devtype( dev, kInputSubsystem, NULL); @@ -143,34 +143,34 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { return; } - const char* vendor_id = udev_device_get_sysattr_value(dev, "id/vendor"); - const char* product_id = udev_device_get_sysattr_value(dev, "id/product"); + const char* vendor_id = libudev.udev_device_get_sysattr_value(dev, "id/vendor"); + const char* product_id = libudev.udev_device_get_sysattr_value(dev, "id/product"); mapper = GetGamepadStandardMappingFunction(vendor_id, product_id); // Driver returns utf-8 strings here, so combine in utf-8 first and // convert to WebUChar later once we've picked an id string. - const char* name = udev_device_get_sysattr_value(dev, "name"); + const char* name = libudev.udev_device_get_sysattr_value(dev, "name"); std::string name_string = base::StringPrintf("%s", name); // In many cases the information the input subsystem contains isn't // as good as the information that the device bus has, walk up further // to the subsystem/device type "usb"/"usb_device" and if this device // has the same vendor/product id, prefer the description from that. - struct udev_device *usb_dev = udev_device_get_parent_with_subsystem_devtype( + struct udev_device *usb_dev = libudev.udev_device_get_parent_with_subsystem_devtype( dev, kUsbSubsystem, kUsbDeviceType); if (usb_dev) { const char* usb_vendor_id = - udev_device_get_sysattr_value(usb_dev, "idVendor"); + libudev.udev_device_get_sysattr_value(usb_dev, "idVendor"); const char* usb_product_id = - udev_device_get_sysattr_value(usb_dev, "idProduct"); + libudev.udev_device_get_sysattr_value(usb_dev, "idProduct"); if (strcmp(vendor_id, usb_vendor_id) == 0 && strcmp(product_id, usb_product_id) == 0) { const char* manufacturer = - udev_device_get_sysattr_value(usb_dev, "manufacturer"); - const char* product = udev_device_get_sysattr_value(usb_dev, "product"); + libudev.udev_device_get_sysattr_value(usb_dev, "manufacturer"); + const char* product = libudev.udev_device_get_sysattr_value(usb_dev, "product"); // Replace the previous name string with one containing the better // information, again driver returns utf-8 strings here so combine @@ -207,31 +207,31 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { } void GamepadPlatformDataFetcherLinux::EnumerateDevices() { - udev_enumerate* enumerate = udev_enumerate_new(udev_->udev_handle()); + udev_enumerate* enumerate = libudev.udev_enumerate_new(udev_->udev_handle()); if (!enumerate) return; - int ret = udev_enumerate_add_match_subsystem(enumerate, kInputSubsystem); + int ret = libudev.udev_enumerate_add_match_subsystem(enumerate, kInputSubsystem); if (ret != 0) return; - ret = udev_enumerate_scan_devices(enumerate); + ret = libudev.udev_enumerate_scan_devices(enumerate); if (ret != 0) return; - udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); + udev_list_entry* devices = libudev.udev_enumerate_get_list_entry(enumerate); for (udev_list_entry* dev_list_entry = devices; dev_list_entry != NULL; - dev_list_entry = udev_list_entry_get_next(dev_list_entry)) { + dev_list_entry = libudev.udev_list_entry_get_next(dev_list_entry)) { // Get the filename of the /sys entry for the device and create a // udev_device object (dev) representing it - const char* path = udev_list_entry_get_name(dev_list_entry); - udev_device* dev = udev_device_new_from_syspath(udev_->udev_handle(), path); + const char* path = libudev.udev_list_entry_get_name(dev_list_entry); + udev_device* dev = libudev.udev_device_new_from_syspath(udev_->udev_handle(), path); if (!dev) continue; RefreshDevice(dev); - udev_device_unref(dev); + libudev.udev_device_unref(dev); } // Free the enumerator object - udev_enumerate_unref(enumerate); + libudev.udev_enumerate_unref(enumerate); } void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) { diff --git a/chromium/content/browser/udev_linux.cc b/chromium/content/browser/udev_linux.cc index f6f9443ab3f66ac82316e77fc01c272b6100547f..106ab16b621b6ea9b86692a83a84b0db4ee7e6dc 100644 --- a/chromium/content/browser/udev_linux.cc +++ b/chromium/content/browser/udev_linux.cc @@ -3,8 +3,7 @@ // found in the LICENSE file. #include "content/browser/udev_linux.h" - -#include <libudev.h> +#include "device/udev_linux/udev.h" #include "base/message_loop/message_loop.h" @@ -12,24 +11,24 @@ namespace content { UdevLinux::UdevLinux(const std::vector<UdevMonitorFilter>& filters, const UdevNotificationCallback& callback) - : udev_(udev_new()), + : udev_(libudev.udev_new()), monitor_(NULL), monitor_fd_(-1), callback_(callback) { CHECK(udev_); - monitor_ = udev_monitor_new_from_netlink(udev_, "udev"); + monitor_ = libudev.udev_monitor_new_from_netlink(udev_, "udev"); CHECK(monitor_); for (size_t i = 0; i < filters.size(); ++i) { - int ret = udev_monitor_filter_add_match_subsystem_devtype( + int ret = libudev.udev_monitor_filter_add_match_subsystem_devtype( monitor_, filters[i].subsystem, filters[i].devtype); CHECK_EQ(0, ret); } - int ret = udev_monitor_enable_receiving(monitor_); + int ret = libudev.udev_monitor_enable_receiving(monitor_); CHECK_EQ(0, ret); - monitor_fd_ = udev_monitor_get_fd(monitor_); + monitor_fd_ = libudev.udev_monitor_get_fd(monitor_); CHECK_GE(monitor_fd_, 0); bool success = base::MessageLoopForIO::current()->WatchFileDescriptor( @@ -43,8 +42,8 @@ UdevLinux::UdevLinux(const std::vector<UdevMonitorFilter>& filters, UdevLinux::~UdevLinux() { monitor_watcher_.StopWatchingFileDescriptor(); - udev_monitor_unref(monitor_); - udev_unref(udev_); + libudev.udev_monitor_unref(monitor_); + libudev.udev_unref(udev_); } udev* UdevLinux::udev_handle() { @@ -56,12 +55,12 @@ void UdevLinux::OnFileCanReadWithoutBlocking(int fd) { // change state. udev_monitor_receive_device() will return a device object // representing the device which changed and what type of change occured. DCHECK_EQ(monitor_fd_, fd); - udev_device* dev = udev_monitor_receive_device(monitor_); + udev_device* dev = libudev.udev_monitor_receive_device(monitor_); if (!dev) return; callback_.Run(dev); - udev_device_unref(dev); + libudev.udev_device_unref(dev); } void UdevLinux::OnFileCanWriteWithoutBlocking(int fd) { diff --git a/chromium/content/content_browser.gypi b/chromium/content/content_browser.gypi index 4f13c10ef931f8c79285d6906e4c3745b6a62b29..fdf4397dccc9c7c0c5fe0ec543af81577a815001 100644 --- a/chromium/content/content_browser.gypi +++ b/chromium/content/content_browser.gypi @@ -1777,6 +1777,11 @@ 'browser/geolocation/wifi_data_provider_linux.cc', ], }], + ['use_udev==1', { + 'dependencies': [ + '../device/udev_linux/udev.gyp:udev_linux', + ], + }], ['enable_browser_cdms==1', { 'sources': [ 'browser/media/cdm/browser_cdm_manager.cc', diff --git a/chromium/device/udev_linux/udev.cc b/chromium/device/udev_linux/udev.cc index e10074b5aa74c54daf77f38ee4262d71f243b0d6..e00fb068f10b7801239a9e842d562dabd78d8186 100644 --- a/chromium/device/udev_linux/udev.cc +++ b/chromium/device/udev_linux/udev.cc @@ -6,22 +6,24 @@ #include "device/udev_linux/udev.h" +device::LibUdevWrapper libudev; + namespace device { void UdevDeleter::operator()(udev* dev) const { - udev_unref(dev); + libudev.udev_unref(dev); } void UdevEnumerateDeleter::operator()(udev_enumerate* enumerate) const { - udev_enumerate_unref(enumerate); + libudev.udev_enumerate_unref(enumerate); } void UdevDeviceDeleter::operator()(udev_device* device) const { - udev_device_unref(device); + libudev.udev_device_unref(device); } void UdevMonitorDeleter::operator()(udev_monitor* monitor) const { - udev_monitor_unref(monitor); + libudev.udev_monitor_unref(monitor); } } // namespace device diff --git a/chromium/device/udev_linux/udev.h b/chromium/device/udev_linux/udev.h index cffb6723cc40eeec0f0ec424f5e9adaed0c87efb..0c7a2ae1704059964c5ab25704f7e18f7b7e6a62 100644 --- a/chromium/device/udev_linux/udev.h +++ b/chromium/device/udev_linux/udev.h @@ -13,6 +13,8 @@ #error "USE_UDEV not defined" #endif +#include <dlfcn.h> + namespace device { struct UdevDeleter { @@ -33,6 +35,113 @@ typedef scoped_ptr<udev_enumerate, UdevEnumerateDeleter> ScopedUdevEnumeratePtr; typedef scoped_ptr<udev_device, UdevDeviceDeleter> ScopedUdevDevicePtr; typedef scoped_ptr<udev_monitor, UdevMonitorDeleter> ScopedUdevMonitorPtr; + +class LibUdevWrapper { +public: + LibUdevWrapper() : m_libUdev(0), m_loaded(false) + { + load(); + } + + virtual ~LibUdevWrapper() + { + if (m_libUdev) + dlclose(m_libUdev); + } + +private: + void* m_libUdev; + bool m_loaded; + void load() + { + m_libUdev = dlopen("libudev.so.1", RTLD_NOW); + m_loaded = m_libUdev; + if (resolveMethods()) + return; + if (!m_libUdev) + m_libUdev = dlopen("libudev.so.0", RTLD_NOW); + m_loaded = m_libUdev; + resolveMethods(); + } + + void* resolve(const char* name) + { + void* ptr = dlsym(m_libUdev, name); + if (!ptr) { + m_loaded = false; + } + return ptr; + } + + bool resolveMethods() + { + if (!m_loaded) + return false; + udev_new = (udev* (*)())resolve("udev_new"); + udev_unref = (void (*)(udev*))resolve("udev_unref"); + udev_monitor_new_from_netlink = (udev_monitor* (*)(udev*, const char*))resolve("udev_monitor_new_from_netlink"); + udev_monitor_unref = (void (*)(udev_monitor*))resolve("udev_monitor_unref"); + udev_monitor_enable_receiving = (int (*)(udev_monitor*))resolve("udev_monitor_enable_receiving"); + udev_monitor_get_fd = (int (*)(udev_monitor*))resolve("udev_monitor_get_fd"); + udev_monitor_filter_add_match_subsystem_devtype = (int (*)(udev_monitor*, const char*, const char*))resolve("udev_monitor_filter_add_match_subsystem_devtype"); + udev_monitor_receive_device = (udev_device* (*)(udev_monitor*))resolve("udev_monitor_receive_device"); + udev_enumerate_new = (udev_enumerate* (*)(udev*))resolve("udev_enumerate_new"); + udev_enumerate_unref = (void (*)(udev_enumerate*))resolve("udev_enumerate_unref"); + udev_enumerate_add_match_subsystem = (int (*)(udev_enumerate*, const char*))resolve("udev_enumerate_add_match_subsystem"); + udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))resolve("udev_enumerate_add_match_property"); + udev_enumerate_scan_devices = (int (*)(udev_enumerate*))resolve("udev_enumerate_scan_devices"); + udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))resolve("udev_enumerate_get_list_entry"); + udev_list_entry_get_next = (udev_list_entry* (*)(udev_list_entry*))resolve("udev_list_entry_get_next"); + udev_list_entry_get_name = (const char* (*)(udev_list_entry*))resolve("udev_list_entry_get_name"); + udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))resolve("udev_device_new_from_syspath"); + udev_device_unref = (void (*)(udev_device*))resolve("udev_device_unref"); + udev_device_get_syspath = (const char* (*)(udev_device*))resolve("udev_device_get_syspath"); + udev_device_get_devnode = (const char* (*)(udev_device*))resolve("udev_device_get_devnode"); + udev_device_get_property_value = (const char* (*)(udev_device*, const char*))resolve("udev_device_get_property_value"); + udev_device_get_action = (const char* (*)(udev_device*))resolve("udev_device_get_action"); + udev_device_get_subsystem = (const char* (*)(udev_device*))resolve("udev_device_get_subsystem"); + udev_device_get_sysattr_value = (const char* (*)(udev_device*, const char*))resolve("udev_device_get_sysattr_value"); + udev_device_get_parent_with_subsystem_devtype = + (struct udev_device* (*)(struct udev_device*, const char*, const char*))resolve("udev_device_get_parent_with_subsystem_devtype"); + + return m_loaded; + } + +public: + struct udev* (*udev_new)(); + void (*udev_unref)(struct udev*); + + struct udev_monitor* (*udev_monitor_new_from_netlink)(struct udev*, const char *name); + void (*udev_monitor_unref)(struct udev_monitor*); + int (*udev_monitor_enable_receiving)(struct udev_monitor*); + int (*udev_monitor_get_fd)(struct udev_monitor*); + int (*udev_monitor_filter_add_match_subsystem_devtype)(struct udev_monitor*, const char *subsystem, const char *devtype); + struct udev_device* (*udev_monitor_receive_device)(struct udev_monitor*); + + struct udev_enumerate* (*udev_enumerate_new)(struct udev*); + void (*udev_enumerate_unref)(struct udev_enumerate*); + int (*udev_enumerate_add_match_subsystem)(struct udev_enumerate*, const char *subsystem); + int (*udev_enumerate_add_match_property)(struct udev_enumerate*, const char *property, const char *value); + int (*udev_enumerate_scan_devices)(struct udev_enumerate*); + struct udev_list_entry* (*udev_enumerate_get_list_entry)(struct udev_enumerate*); + + struct udev_list_entry* (*udev_list_entry_get_next)(struct udev_list_entry*); + const char* (*udev_list_entry_get_name)(struct udev_list_entry*); + + struct udev_device* (*udev_device_new_from_syspath)(struct udev *udev, const char *syspath); + void (*udev_device_unref)(struct udev_device *udev_device); + const char* (*udev_device_get_syspath)(struct udev_device *udev_device); + const char* (*udev_device_get_devnode)(struct udev_device *udev_device); + const char* (*udev_device_get_property_value)(struct udev_device *udev_device, const char *key); + const char* (*udev_device_get_action)(struct udev_device *udev_device); + const char* (*udev_device_get_subsystem)(struct udev_device *udev_device); + const char* (*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr); + struct udev_device* (*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device, + const char *subsystem, const char *devtype); +}; + } // namespace device +extern device::LibUdevWrapper libudev; + #endif // DEVICE_UDEV_LINUX_UDEV_H_