Ozone integration from chromium @ https://crrev.com/336230

Adds linux direct rendering capability via mesa gbm.

Refactored gpu_platform_support (and _host) to allow different
implementations of messaging transport between host and gpu.

drm_cursor is stubbed out.

Removed ScopedAllowIO in drm_host_display_manager and added
header documentation indicating where IO is performed.

Removed unused files:
 ui/ozone/common/gpu/ozone_gpu_message_generator*
 ui/ozone/common/gpu/ozone_gpu_messages.h

BUG=
R=jamesr@chromium.org, spang@chromium.org

Review URL: https://codereview.chromium.org/1285183008 .
diff --git a/device/udev_linux/BUILD.gn b/device/udev_linux/BUILD.gn
new file mode 100644
index 0000000..6a3c831
--- /dev/null
+++ b/device/udev_linux/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/features.gni")
+
+if (use_udev) {
+  source_set("udev_linux") {
+    sources = [
+      "scoped_udev.h",
+      "udev.cc",
+      "udev.h",
+      "udev0_loader.cc",
+      "udev0_loader.h",
+      "udev1_loader.cc",
+      "udev1_loader.h",
+      "udev_loader.cc",
+      "udev_loader.h",
+    ]
+
+    deps = [
+      "//base",
+      "//build/config/linux:udev",
+    ]
+  }
+}
diff --git a/device/udev_linux/scoped_udev.h b/device/udev_linux/scoped_udev.h
new file mode 100644
index 0000000..06e3926
--- /dev/null
+++ b/device/udev_linux/scoped_udev.h
@@ -0,0 +1,45 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_UDEV_LINUX_SCOPED_UDEV_H_
+#define DEVICE_UDEV_LINUX_SCOPED_UDEV_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "device/udev_linux/udev.h"
+
+#if !defined(USE_UDEV)
+#error "USE_UDEV not defined"
+#endif
+
+namespace device {
+
+struct UdevDeleter {
+  void operator()(udev* dev) const {
+    udev_unref(dev);
+  }
+};
+struct UdevEnumerateDeleter {
+  void operator()(udev_enumerate* enumerate) const {
+    udev_enumerate_unref(enumerate);
+  }
+};
+struct UdevDeviceDeleter {
+  void operator()(udev_device* device) const {
+    udev_device_unref(device);
+  }
+};
+struct UdevMonitorDeleter {
+  void operator()(udev_monitor* monitor) const {
+    udev_monitor_unref(monitor);
+  }
+};
+
+typedef scoped_ptr<udev, UdevDeleter> ScopedUdevPtr;
+typedef scoped_ptr<udev_enumerate, UdevEnumerateDeleter> ScopedUdevEnumeratePtr;
+typedef scoped_ptr<udev_device, UdevDeviceDeleter> ScopedUdevDevicePtr;
+typedef scoped_ptr<udev_monitor, UdevMonitorDeleter> ScopedUdevMonitorPtr;
+
+}  // namespace device
+
+#endif  // DEVICE_UDEV_LINUX_SCOPED_UDEV_H_
diff --git a/device/udev_linux/udev.cc b/device/udev_linux/udev.cc
new file mode 100644
index 0000000..e2b93d2
--- /dev/null
+++ b/device/udev_linux/udev.cc
@@ -0,0 +1,183 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/udev_linux/udev.h"
+
+#include "base/strings/string_util.h"
+#include "device/udev_linux/udev_loader.h"
+
+namespace device {
+
+namespace {
+
+std::string StringOrEmptyIfNull(const char* value) {
+  return value ? value : std::string();
+}
+
+}  // namespace
+
+const char* udev_device_get_action(udev_device* udev_device) {
+  return UdevLoader::Get()->udev_device_get_action(udev_device);
+}
+
+const char* udev_device_get_devnode(udev_device* udev_device) {
+  return UdevLoader::Get()->udev_device_get_devnode(udev_device);
+}
+
+udev_device* udev_device_get_parent(udev_device* udev_device) {
+  return UdevLoader::Get()->udev_device_get_parent(udev_device);
+}
+
+udev_device* udev_device_get_parent_with_subsystem_devtype(
+    udev_device* udev_device,
+    const char* subsystem,
+    const char* devtype) {
+  return UdevLoader::Get()->udev_device_get_parent_with_subsystem_devtype(
+      udev_device, subsystem, devtype);
+}
+
+const char* udev_device_get_property_value(udev_device* udev_device,
+                                           const char* key) {
+  return UdevLoader::Get()->udev_device_get_property_value(udev_device, key);
+}
+
+const char* udev_device_get_subsystem(udev_device* udev_device) {
+  return UdevLoader::Get()->udev_device_get_subsystem(udev_device);
+}
+
+const char* udev_device_get_sysattr_value(udev_device* udev_device,
+                                          const char* sysattr) {
+  return UdevLoader::Get()->udev_device_get_sysattr_value(udev_device, sysattr);
+}
+
+const char* udev_device_get_sysname(udev_device* udev_device) {
+  return UdevLoader::Get()->udev_device_get_sysname(udev_device);
+}
+
+const char* udev_device_get_syspath(udev_device* udev_device) {
+  return UdevLoader::Get()->udev_device_get_syspath(udev_device);
+}
+
+udev_device* udev_device_new_from_devnum(udev* udev, char type, dev_t devnum) {
+  return UdevLoader::Get()->udev_device_new_from_devnum(udev, type, devnum);
+}
+
+udev_device* udev_device_new_from_subsystem_sysname(
+    udev* udev,
+    const char* subsystem,
+    const char* sysname) {
+  return UdevLoader::Get()->udev_device_new_from_subsystem_sysname(
+      udev, subsystem, sysname);
+}
+
+udev_device* udev_device_new_from_syspath(udev* udev, const char* syspath) {
+  return UdevLoader::Get()->udev_device_new_from_syspath(udev, syspath);
+}
+
+void udev_device_unref(udev_device* udev_device) {
+  UdevLoader::Get()->udev_device_unref(udev_device);
+}
+
+int udev_enumerate_add_match_subsystem(udev_enumerate* udev_enumerate,
+                                       const char* subsystem) {
+  return UdevLoader::Get()->udev_enumerate_add_match_subsystem(udev_enumerate,
+                                                               subsystem);
+}
+
+udev_list_entry* udev_enumerate_get_list_entry(udev_enumerate* udev_enumerate) {
+  return UdevLoader::Get()->udev_enumerate_get_list_entry(udev_enumerate);
+}
+
+udev_enumerate* udev_enumerate_new(udev* udev) {
+  return UdevLoader::Get()->udev_enumerate_new(udev);
+}
+
+int udev_enumerate_scan_devices(udev_enumerate* udev_enumerate) {
+  return UdevLoader::Get()->udev_enumerate_scan_devices(udev_enumerate);
+}
+
+void udev_enumerate_unref(udev_enumerate* udev_enumerate) {
+  UdevLoader::Get()->udev_enumerate_unref(udev_enumerate);
+}
+
+udev_list_entry* udev_list_entry_get_next(udev_list_entry* list_entry) {
+  return UdevLoader::Get()->udev_list_entry_get_next(list_entry);
+}
+
+const char* udev_list_entry_get_name(udev_list_entry* list_entry) {
+  return UdevLoader::Get()->udev_list_entry_get_name(list_entry);
+}
+
+int udev_monitor_enable_receiving(udev_monitor* udev_monitor) {
+  return UdevLoader::Get()->udev_monitor_enable_receiving(udev_monitor);
+}
+
+int udev_monitor_filter_add_match_subsystem_devtype(udev_monitor* udev_monitor,
+                                                    const char* subsystem,
+                                                    const char* devtype) {
+  return UdevLoader::Get()->udev_monitor_filter_add_match_subsystem_devtype(
+      udev_monitor, subsystem, devtype);
+}
+
+int udev_monitor_get_fd(udev_monitor* udev_monitor) {
+  return UdevLoader::Get()->udev_monitor_get_fd(udev_monitor);
+}
+
+udev_monitor* udev_monitor_new_from_netlink(udev* udev, const char* name) {
+  return UdevLoader::Get()->udev_monitor_new_from_netlink(udev, name);
+}
+
+udev_device* udev_monitor_receive_device(udev_monitor* udev_monitor) {
+  return UdevLoader::Get()->udev_monitor_receive_device(udev_monitor);
+}
+
+void udev_monitor_unref(udev_monitor* udev_monitor) {
+  UdevLoader::Get()->udev_monitor_unref(udev_monitor);
+}
+
+udev* udev_new() {
+  return UdevLoader::Get()->udev_new();
+}
+
+void udev_set_log_fn(
+    struct udev* udev,
+    void (*log_fn)(struct udev* udev, int priority, const char* file, int line,
+                   const char* fn, const char* format, va_list args)) {
+  return UdevLoader::Get()->udev_set_log_fn(udev, log_fn);
+}
+
+void udev_set_log_priority(struct udev* udev, int priority) {
+  return UdevLoader::Get()->udev_set_log_priority(udev, priority);
+}
+
+void udev_unref(udev* udev) {
+  UdevLoader::Get()->udev_unref(udev);
+}
+
+std::string UdevDeviceGetPropertyValue(udev_device* udev_device,
+                                       const char* key) {
+  return StringOrEmptyIfNull(udev_device_get_property_value(udev_device, key));
+}
+
+std::string UdevDeviceGetSysattrValue(udev_device* udev_device,
+                                      const char* key) {
+  return StringOrEmptyIfNull(udev_device_get_sysattr_value(udev_device, key));
+}
+
+std::string UdevDecodeString(const std::string& encoded) {
+  std::string decoded;
+  const size_t size = encoded.size();
+  for (size_t i = 0; i < size; ++i) {
+    char c = encoded[i];
+    if ((i + 3 < size) && c == '\\' && encoded[i + 1] == 'x') {
+      c = (HexDigitToInt(encoded[i + 2]) << 4) +
+          HexDigitToInt(encoded[i + 3]);
+      i += 3;
+    }
+    decoded.push_back(c);
+  }
+  return decoded;
+}
+
+}  // namespace device
diff --git a/device/udev_linux/udev.h b/device/udev_linux/udev.h
new file mode 100644
index 0000000..c40603d
--- /dev/null
+++ b/device/udev_linux/udev.h
@@ -0,0 +1,92 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_UDEV_LINUX_UDEV_H_
+#define DEVICE_UDEV_LINUX_UDEV_H_
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <string>
+
+#if !defined(USE_UDEV)
+#error "USE_UDEV not defined"
+#endif
+
+// Adapted from libudev.h.
+#define udev_list_entry_foreach(list_entry, first_entry) \
+  for (list_entry = first_entry; list_entry != NULL;     \
+       list_entry = ::device::udev_list_entry_get_next(list_entry))
+
+// Forward declarations of opaque structs.
+struct udev;
+struct udev_device;
+struct udev_enumerate;
+struct udev_list_entry;
+struct udev_monitor;
+
+namespace device {
+
+const char* udev_device_get_action(udev_device* udev_device);
+const char* udev_device_get_devnode(udev_device* udev_device);
+udev_device* udev_device_get_parent(udev_device* udev_device);
+udev_device* udev_device_get_parent_with_subsystem_devtype(
+    udev_device* udev_device,
+    const char* subsystem,
+    const char* devtype);
+const char* udev_device_get_property_value(udev_device* udev_device,
+                                           const char* key);
+const char* udev_device_get_subsystem(udev_device* udev_device);
+const char* udev_device_get_sysattr_value(udev_device* udev_device,
+                                          const char* sysattr);
+const char* udev_device_get_sysname(udev_device* udev_device);
+const char* udev_device_get_syspath(udev_device* udev_device);
+udev_device* udev_device_new_from_devnum(udev* udev, char type, dev_t devnum);
+udev_device* udev_device_new_from_subsystem_sysname(
+    udev* udev,
+    const char* subsystem,
+    const char* sysname);
+udev_device* udev_device_new_from_syspath(udev* udev, const char* syspath);
+void udev_device_unref(udev_device* udev_device);
+int udev_enumerate_add_match_subsystem(udev_enumerate* udev_enumerate,
+                                       const char* subsystem);
+udev_list_entry* udev_enumerate_get_list_entry(udev_enumerate* udev_enumerate);
+udev_enumerate* udev_enumerate_new(udev* udev);
+int udev_enumerate_scan_devices(udev_enumerate* udev_enumerate);
+void udev_enumerate_unref(udev_enumerate* udev_enumerate);
+udev_list_entry* udev_list_entry_get_next(udev_list_entry* list_entry);
+const char* udev_list_entry_get_name(udev_list_entry* list_entry);
+int udev_monitor_enable_receiving(udev_monitor* udev_monitor);
+int udev_monitor_filter_add_match_subsystem_devtype(udev_monitor* udev_monitor,
+                                                    const char* subsystem,
+                                                    const char* devtype);
+int udev_monitor_get_fd(udev_monitor* udev_monitor);
+udev_monitor* udev_monitor_new_from_netlink(udev* udev, const char* name);
+udev_device* udev_monitor_receive_device(udev_monitor* udev_monitor);
+void udev_monitor_unref(udev_monitor* udev_monitor);
+udev* udev_new();
+void udev_set_log_fn(
+    struct udev* udev,
+    void (*log_fn)(struct udev* udev, int priority, const char* file, int line,
+                   const char* fn, const char* format, va_list args));
+void udev_set_log_priority(struct udev* udev, int priority);
+void udev_unref(udev* udev);
+
+// Calls udev_device_get_property_value() and replaces missing values with
+// the empty string.
+std::string UdevDeviceGetPropertyValue(udev_device* udev_device,
+                                       const char* key);
+
+// Calls udev_device_get_sysattr_value() and replaces missing values with
+// the empty string.
+std::string UdevDeviceGetSysattrValue(udev_device* udev_device,
+                                      const char* key);
+
+// Decodes udev-encoded string. Useful for decoding "*_ENC" udev properties.
+std::string UdevDecodeString(const std::string& encoded);
+
+}  // namespace device
+
+#endif  // DEVICE_UDEV_LINUX_UDEV_H_
diff --git a/device/udev_linux/udev0_loader.cc b/device/udev_linux/udev0_loader.cc
new file mode 100644
index 0000000..9b0276c
--- /dev/null
+++ b/device/udev_linux/udev0_loader.cc
@@ -0,0 +1,173 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/udev_linux/udev0_loader.h"
+
+#include "library_loaders/libudev0.h"
+
+namespace device {
+
+Udev0Loader::Udev0Loader() {
+}
+
+Udev0Loader::~Udev0Loader() {
+}
+
+bool Udev0Loader::Init() {
+  if (lib_loader_)
+    return lib_loader_->loaded();
+  lib_loader_.reset(new LibUdev0Loader);
+  return lib_loader_->Load("libudev.so.0");
+}
+
+const char* Udev0Loader::udev_device_get_action(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_action(udev_device);
+}
+
+const char* Udev0Loader::udev_device_get_devnode(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_devnode(udev_device);
+}
+
+udev_device* Udev0Loader::udev_device_get_parent(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_parent(udev_device);
+}
+
+udev_device* Udev0Loader::udev_device_get_parent_with_subsystem_devtype(
+    udev_device* udev_device,
+    const char* subsystem,
+    const char* devtype) {
+  return lib_loader_->udev_device_get_parent_with_subsystem_devtype(
+      udev_device, subsystem, devtype);
+}
+
+const char* Udev0Loader::udev_device_get_property_value(
+    udev_device* udev_device,
+    const char* key) {
+  return lib_loader_->udev_device_get_property_value(udev_device, key);
+}
+
+const char* Udev0Loader::udev_device_get_subsystem(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_subsystem(udev_device);
+}
+
+const char* Udev0Loader::udev_device_get_sysattr_value(udev_device* udev_device,
+                                                       const char* sysattr) {
+  return lib_loader_->udev_device_get_sysattr_value(udev_device, sysattr);
+}
+
+const char* Udev0Loader::udev_device_get_sysname(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_sysname(udev_device);
+}
+
+const char* Udev0Loader::udev_device_get_syspath(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_syspath(udev_device);
+}
+
+udev_device* Udev0Loader::udev_device_new_from_devnum(udev* udev,
+                                                      char type,
+                                                      dev_t devnum) {
+  return lib_loader_->udev_device_new_from_devnum(udev, type, devnum);
+}
+
+udev_device* Udev0Loader::udev_device_new_from_subsystem_sysname(
+    udev* udev,
+    const char* subsystem,
+    const char* sysname) {
+  return lib_loader_->udev_device_new_from_subsystem_sysname(
+      udev, subsystem, sysname);
+}
+
+udev_device* Udev0Loader::udev_device_new_from_syspath(udev* udev,
+                                                       const char* syspath) {
+  return lib_loader_->udev_device_new_from_syspath(udev, syspath);
+}
+
+void Udev0Loader::udev_device_unref(udev_device* udev_device) {
+  lib_loader_->udev_device_unref(udev_device);
+}
+
+int Udev0Loader::udev_enumerate_add_match_subsystem(
+    udev_enumerate* udev_enumerate,
+    const char* subsystem) {
+  return lib_loader_->udev_enumerate_add_match_subsystem(udev_enumerate,
+                                                         subsystem);
+}
+
+udev_list_entry* Udev0Loader::udev_enumerate_get_list_entry(
+    udev_enumerate* udev_enumerate) {
+  return lib_loader_->udev_enumerate_get_list_entry(udev_enumerate);
+}
+
+udev_enumerate* Udev0Loader::udev_enumerate_new(udev* udev) {
+  return lib_loader_->udev_enumerate_new(udev);
+}
+
+int Udev0Loader::udev_enumerate_scan_devices(udev_enumerate* udev_enumerate) {
+  return lib_loader_->udev_enumerate_scan_devices(udev_enumerate);
+}
+
+void Udev0Loader::udev_enumerate_unref(udev_enumerate* udev_enumerate) {
+  lib_loader_->udev_enumerate_unref(udev_enumerate);
+}
+
+udev_list_entry* Udev0Loader::udev_list_entry_get_next(
+    udev_list_entry* list_entry) {
+  return lib_loader_->udev_list_entry_get_next(list_entry);
+}
+
+const char* Udev0Loader::udev_list_entry_get_name(udev_list_entry* list_entry) {
+  return lib_loader_->udev_list_entry_get_name(list_entry);
+}
+
+int Udev0Loader::udev_monitor_enable_receiving(udev_monitor* udev_monitor) {
+  return lib_loader_->udev_monitor_enable_receiving(udev_monitor);
+}
+
+int Udev0Loader::udev_monitor_filter_add_match_subsystem_devtype(
+    udev_monitor* udev_monitor,
+    const char* subsystem,
+    const char* devtype) {
+  return lib_loader_->udev_monitor_filter_add_match_subsystem_devtype(
+      udev_monitor, subsystem, devtype);
+}
+
+int Udev0Loader::udev_monitor_get_fd(udev_monitor* udev_monitor) {
+  return lib_loader_->udev_monitor_get_fd(udev_monitor);
+}
+
+udev_monitor* Udev0Loader::udev_monitor_new_from_netlink(udev* udev,
+                                                         const char* name) {
+  return lib_loader_->udev_monitor_new_from_netlink(udev, name);
+}
+
+udev_device* Udev0Loader::udev_monitor_receive_device(
+    udev_monitor* udev_monitor) {
+  return lib_loader_->udev_monitor_receive_device(udev_monitor);
+}
+
+void Udev0Loader::udev_monitor_unref(udev_monitor* udev_monitor) {
+  lib_loader_->udev_monitor_unref(udev_monitor);
+}
+
+udev* Udev0Loader::udev_new() {
+  return lib_loader_->udev_new();
+}
+
+void Udev0Loader::udev_set_log_fn(
+      struct udev* udev,
+      void (*log_fn)(struct udev* udev, int priority,
+                     const char* file, int line,
+                     const char* fn, const char* format, va_list args)) {
+  return lib_loader_->udev_set_log_fn(udev, log_fn);
+}
+
+void Udev0Loader::udev_set_log_priority(struct udev* udev, int priority) {
+  return lib_loader_->udev_set_log_priority(udev, priority);
+}
+
+void Udev0Loader::udev_unref(udev* udev) {
+  lib_loader_->udev_unref(udev);
+}
+
+}  // namespace device
diff --git a/device/udev_linux/udev0_loader.h b/device/udev_linux/udev0_loader.h
new file mode 100644
index 0000000..8108ff9
--- /dev/null
+++ b/device/udev_linux/udev0_loader.h
@@ -0,0 +1,83 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_UDEV_LINUX_UDEV0_LOADER_H_
+#define DEVICE_UDEV_LINUX_UDEV0_LOADER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "device/udev_linux/udev_loader.h"
+
+class LibUdev0Loader;
+
+namespace device {
+
+class Udev0Loader : public UdevLoader {
+ public:
+  Udev0Loader();
+  ~Udev0Loader() override;
+
+ private:
+  bool Init() override;
+  const char* udev_device_get_action(udev_device* udev_device) override;
+  const char* udev_device_get_devnode(udev_device* udev_device) override;
+  udev_device* udev_device_get_parent(udev_device* udev_device) override;
+  udev_device* udev_device_get_parent_with_subsystem_devtype(
+      udev_device* udev_device,
+      const char* subsystem,
+      const char* devtype) override;
+  const char* udev_device_get_property_value(udev_device* udev_device,
+                                             const char* key) override;
+  const char* udev_device_get_subsystem(udev_device* udev_device) override;
+  const char* udev_device_get_sysattr_value(udev_device* udev_device,
+                                            const char* sysattr) override;
+  const char* udev_device_get_sysname(udev_device* udev_device) override;
+  const char* udev_device_get_syspath(udev_device* udev_device) override;
+  udev_device* udev_device_new_from_devnum(udev* udev,
+                                           char type,
+                                           dev_t devnum) override;
+  udev_device* udev_device_new_from_subsystem_sysname(
+      udev* udev,
+      const char* subsystem,
+      const char* sysname) override;
+  udev_device* udev_device_new_from_syspath(udev* udev,
+                                            const char* syspath) override;
+  void udev_device_unref(udev_device* udev_device) override;
+  int udev_enumerate_add_match_subsystem(udev_enumerate* udev_enumerate,
+                                         const char* subsystem) override;
+  udev_list_entry* udev_enumerate_get_list_entry(
+      udev_enumerate* udev_enumerate) override;
+  udev_enumerate* udev_enumerate_new(udev* udev) override;
+  int udev_enumerate_scan_devices(udev_enumerate* udev_enumerate) override;
+  void udev_enumerate_unref(udev_enumerate* udev_enumerate) override;
+  udev_list_entry* udev_list_entry_get_next(
+      udev_list_entry* list_entry) override;
+  const char* udev_list_entry_get_name(udev_list_entry* list_entry) override;
+  int udev_monitor_enable_receiving(udev_monitor* udev_monitor) override;
+  int udev_monitor_filter_add_match_subsystem_devtype(
+      udev_monitor* udev_monitor,
+      const char* subsystem,
+      const char* devtype) override;
+  int udev_monitor_get_fd(udev_monitor* udev_monitor) override;
+  udev_monitor* udev_monitor_new_from_netlink(udev* udev,
+                                              const char* name) override;
+  udev_device* udev_monitor_receive_device(udev_monitor* udev_monitor) override;
+  void udev_monitor_unref(udev_monitor* udev_monitor) override;
+  udev* udev_new() override;
+  void udev_set_log_fn(
+      struct udev* udev,
+      void (*log_fn)(struct udev* udev, int priority,
+                     const char* file, int line,
+                     const char* fn, const char* format,
+                     va_list args)) override;
+  void udev_set_log_priority(struct udev* udev, int priority) override;
+  void udev_unref(udev* udev) override;
+
+  scoped_ptr<LibUdev0Loader> lib_loader_;
+
+  DISALLOW_COPY_AND_ASSIGN(Udev0Loader);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_UDEV_LINUX_UDEV0_LOADER_H_
diff --git a/device/udev_linux/udev1_loader.cc b/device/udev_linux/udev1_loader.cc
new file mode 100644
index 0000000..34c2848
--- /dev/null
+++ b/device/udev_linux/udev1_loader.cc
@@ -0,0 +1,173 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/udev_linux/udev1_loader.h"
+
+#include "library_loaders/libudev1.h"
+
+namespace device {
+
+Udev1Loader::Udev1Loader() {
+}
+
+Udev1Loader::~Udev1Loader() {
+}
+
+bool Udev1Loader::Init() {
+  if (lib_loader_)
+    return lib_loader_->loaded();
+  lib_loader_.reset(new LibUdev1Loader);
+  return lib_loader_->Load("libudev.so.1");
+}
+
+const char* Udev1Loader::udev_device_get_action(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_action(udev_device);
+}
+
+const char* Udev1Loader::udev_device_get_devnode(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_devnode(udev_device);
+}
+
+udev_device* Udev1Loader::udev_device_get_parent(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_parent(udev_device);
+}
+
+udev_device* Udev1Loader::udev_device_get_parent_with_subsystem_devtype(
+    udev_device* udev_device,
+    const char* subsystem,
+    const char* devtype) {
+  return lib_loader_->udev_device_get_parent_with_subsystem_devtype(
+      udev_device, subsystem, devtype);
+}
+
+const char* Udev1Loader::udev_device_get_property_value(
+    udev_device* udev_device,
+    const char* key) {
+  return lib_loader_->udev_device_get_property_value(udev_device, key);
+}
+
+const char* Udev1Loader::udev_device_get_subsystem(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_subsystem(udev_device);
+}
+
+const char* Udev1Loader::udev_device_get_sysattr_value(udev_device* udev_device,
+                                                       const char* sysattr) {
+  return lib_loader_->udev_device_get_sysattr_value(udev_device, sysattr);
+}
+
+const char* Udev1Loader::udev_device_get_sysname(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_sysname(udev_device);
+}
+
+const char* Udev1Loader::udev_device_get_syspath(udev_device* udev_device) {
+  return lib_loader_->udev_device_get_syspath(udev_device);
+}
+
+udev_device* Udev1Loader::udev_device_new_from_devnum(udev* udev,
+                                                      char type,
+                                                      dev_t devnum) {
+  return lib_loader_->udev_device_new_from_devnum(udev, type, devnum);
+}
+
+udev_device* Udev1Loader::udev_device_new_from_subsystem_sysname(
+    udev* udev,
+    const char* subsystem,
+    const char* sysname) {
+  return lib_loader_->udev_device_new_from_subsystem_sysname(
+      udev, subsystem, sysname);
+}
+
+udev_device* Udev1Loader::udev_device_new_from_syspath(udev* udev,
+                                                       const char* syspath) {
+  return lib_loader_->udev_device_new_from_syspath(udev, syspath);
+}
+
+void Udev1Loader::udev_device_unref(udev_device* udev_device) {
+  lib_loader_->udev_device_unref(udev_device);
+}
+
+int Udev1Loader::udev_enumerate_add_match_subsystem(
+    udev_enumerate* udev_enumerate,
+    const char* subsystem) {
+  return lib_loader_->udev_enumerate_add_match_subsystem(udev_enumerate,
+                                                         subsystem);
+}
+
+udev_list_entry* Udev1Loader::udev_enumerate_get_list_entry(
+    udev_enumerate* udev_enumerate) {
+  return lib_loader_->udev_enumerate_get_list_entry(udev_enumerate);
+}
+
+udev_enumerate* Udev1Loader::udev_enumerate_new(udev* udev) {
+  return lib_loader_->udev_enumerate_new(udev);
+}
+
+int Udev1Loader::udev_enumerate_scan_devices(udev_enumerate* udev_enumerate) {
+  return lib_loader_->udev_enumerate_scan_devices(udev_enumerate);
+}
+
+void Udev1Loader::udev_enumerate_unref(udev_enumerate* udev_enumerate) {
+  lib_loader_->udev_enumerate_unref(udev_enumerate);
+}
+
+udev_list_entry* Udev1Loader::udev_list_entry_get_next(
+    udev_list_entry* list_entry) {
+  return lib_loader_->udev_list_entry_get_next(list_entry);
+}
+
+const char* Udev1Loader::udev_list_entry_get_name(udev_list_entry* list_entry) {
+  return lib_loader_->udev_list_entry_get_name(list_entry);
+}
+
+int Udev1Loader::udev_monitor_enable_receiving(udev_monitor* udev_monitor) {
+  return lib_loader_->udev_monitor_enable_receiving(udev_monitor);
+}
+
+int Udev1Loader::udev_monitor_filter_add_match_subsystem_devtype(
+    udev_monitor* udev_monitor,
+    const char* subsystem,
+    const char* devtype) {
+  return lib_loader_->udev_monitor_filter_add_match_subsystem_devtype(
+      udev_monitor, subsystem, devtype);
+}
+
+int Udev1Loader::udev_monitor_get_fd(udev_monitor* udev_monitor) {
+  return lib_loader_->udev_monitor_get_fd(udev_monitor);
+}
+
+udev_monitor* Udev1Loader::udev_monitor_new_from_netlink(udev* udev,
+                                                         const char* name) {
+  return lib_loader_->udev_monitor_new_from_netlink(udev, name);
+}
+
+udev_device* Udev1Loader::udev_monitor_receive_device(
+    udev_monitor* udev_monitor) {
+  return lib_loader_->udev_monitor_receive_device(udev_monitor);
+}
+
+void Udev1Loader::udev_monitor_unref(udev_monitor* udev_monitor) {
+  lib_loader_->udev_monitor_unref(udev_monitor);
+}
+
+udev* Udev1Loader::udev_new() {
+  return lib_loader_->udev_new();
+}
+
+void Udev1Loader::udev_set_log_fn(
+      struct udev* udev,
+      void (*log_fn)(struct udev* udev, int priority,
+                     const char* file, int line,
+                     const char* fn, const char* format, va_list args)) {
+  return lib_loader_->udev_set_log_fn(udev, log_fn);
+}
+
+void Udev1Loader::udev_set_log_priority(struct udev* udev, int priority) {
+  return lib_loader_->udev_set_log_priority(udev, priority);
+}
+
+void Udev1Loader::udev_unref(udev* udev) {
+  lib_loader_->udev_unref(udev);
+}
+
+}  // namespace device
diff --git a/device/udev_linux/udev1_loader.h b/device/udev_linux/udev1_loader.h
new file mode 100644
index 0000000..c765671
--- /dev/null
+++ b/device/udev_linux/udev1_loader.h
@@ -0,0 +1,83 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_UDEV_LINUX_UDEV1_LOADER_H_
+#define DEVICE_UDEV_LINUX_UDEV1_LOADER_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "device/udev_linux/udev_loader.h"
+
+class LibUdev1Loader;
+
+namespace device {
+
+class Udev1Loader : public UdevLoader {
+ public:
+  Udev1Loader();
+  ~Udev1Loader() override;
+
+ private:
+  bool Init() override;
+  const char* udev_device_get_action(udev_device* udev_device) override;
+  const char* udev_device_get_devnode(udev_device* udev_device) override;
+  udev_device* udev_device_get_parent(udev_device* udev_device) override;
+  udev_device* udev_device_get_parent_with_subsystem_devtype(
+      udev_device* udev_device,
+      const char* subsystem,
+      const char* devtype) override;
+  const char* udev_device_get_property_value(udev_device* udev_device,
+                                             const char* key) override;
+  const char* udev_device_get_subsystem(udev_device* udev_device) override;
+  const char* udev_device_get_sysattr_value(udev_device* udev_device,
+                                            const char* sysattr) override;
+  const char* udev_device_get_sysname(udev_device* udev_device) override;
+  const char* udev_device_get_syspath(udev_device* udev_device) override;
+  udev_device* udev_device_new_from_devnum(udev* udev,
+                                           char type,
+                                           dev_t devnum) override;
+  udev_device* udev_device_new_from_subsystem_sysname(
+      udev* udev,
+      const char* subsystem,
+      const char* sysname) override;
+  udev_device* udev_device_new_from_syspath(udev* udev,
+                                            const char* syspath) override;
+  void udev_device_unref(udev_device* udev_device) override;
+  int udev_enumerate_add_match_subsystem(udev_enumerate* udev_enumerate,
+                                         const char* subsystem) override;
+  udev_list_entry* udev_enumerate_get_list_entry(
+      udev_enumerate* udev_enumerate) override;
+  udev_enumerate* udev_enumerate_new(udev* udev) override;
+  int udev_enumerate_scan_devices(udev_enumerate* udev_enumerate) override;
+  void udev_enumerate_unref(udev_enumerate* udev_enumerate) override;
+  udev_list_entry* udev_list_entry_get_next(
+      udev_list_entry* list_entry) override;
+  const char* udev_list_entry_get_name(udev_list_entry* list_entry) override;
+  int udev_monitor_enable_receiving(udev_monitor* udev_monitor) override;
+  int udev_monitor_filter_add_match_subsystem_devtype(
+      udev_monitor* udev_monitor,
+      const char* subsystem,
+      const char* devtype) override;
+  int udev_monitor_get_fd(udev_monitor* udev_monitor) override;
+  udev_monitor* udev_monitor_new_from_netlink(udev* udev,
+                                              const char* name) override;
+  udev_device* udev_monitor_receive_device(udev_monitor* udev_monitor) override;
+  void udev_monitor_unref(udev_monitor* udev_monitor) override;
+  udev* udev_new() override;
+  void udev_set_log_fn(
+      struct udev* udev,
+      void (*log_fn)(struct udev* udev, int priority,
+                     const char* file, int line,
+                     const char* fn, const char* format,
+                     va_list args)) override;
+  void udev_set_log_priority(struct udev* udev, int priority) override;
+  void udev_unref(udev* udev) override;
+
+  scoped_ptr<LibUdev1Loader> lib_loader_;
+
+  DISALLOW_COPY_AND_ASSIGN(Udev1Loader);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_UDEV_LINUX_UDEV1_LOADER_H_
diff --git a/device/udev_linux/udev_loader.cc b/device/udev_linux/udev_loader.cc
new file mode 100644
index 0000000..88b64e1
--- /dev/null
+++ b/device/udev_linux/udev_loader.cc
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/udev_linux/udev_loader.h"
+
+#include "base/logging.h"
+#include "device/udev_linux/udev0_loader.h"
+#include "device/udev_linux/udev1_loader.h"
+
+namespace device {
+
+namespace {
+
+UdevLoader* g_udev_loader = NULL;
+
+}  // namespace
+
+// static
+UdevLoader* UdevLoader::Get() {
+  if (g_udev_loader)
+    return g_udev_loader;
+
+  scoped_ptr<UdevLoader> udev_loader;
+  udev_loader.reset(new Udev1Loader);
+  if (udev_loader->Init()) {
+    g_udev_loader = udev_loader.release();
+    return g_udev_loader;
+  }
+
+  udev_loader.reset(new Udev0Loader);
+  if (udev_loader->Init()) {
+    g_udev_loader = udev_loader.release();
+    return g_udev_loader;
+  }
+  CHECK(false);
+  return NULL;
+}
+
+UdevLoader::~UdevLoader() {
+}
+
+}  // namespace device
diff --git a/device/udev_linux/udev_loader.h b/device/udev_linux/udev_loader.h
new file mode 100644
index 0000000..9d3837d
--- /dev/null
+++ b/device/udev_linux/udev_loader.h
@@ -0,0 +1,95 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_UDEV_LINUX_UDEV_LOADER_H_
+#define DEVICE_UDEV_LINUX_UDEV_LOADER_H_
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if !defined(USE_UDEV)
+#error "USE_UDEV not defined"
+#endif
+
+struct udev;
+struct udev_device;
+struct udev_enumerate;
+struct udev_list_entry;
+struct udev_monitor;
+
+namespace device {
+
+// Interface to libudev. Accessed through the static Get() function, which
+// will try to load libudev1 first and then libudev0 on first use. If neither
+// libraries load successfully, the program will fail with a crash.
+//
+// All the methods have the same signatures as libudev's functions. e.g.
+// udev_monitor_get_fd(mon) simply becomes device::udev_monitor_get_fd(mon).
+class UdevLoader {
+ public:
+  static UdevLoader* Get();
+
+  virtual ~UdevLoader();
+
+  virtual bool Init() = 0;
+
+  virtual const char* udev_device_get_action(udev_device* udev_device) = 0;
+  virtual const char* udev_device_get_devnode(udev_device* udev_device) = 0;
+  virtual udev_device* udev_device_get_parent(udev_device* udev_device) = 0;
+  virtual udev_device* udev_device_get_parent_with_subsystem_devtype(
+      udev_device* udev_device,
+      const char* subsystem,
+      const char* devtype) = 0;
+  virtual const char* udev_device_get_property_value(udev_device* udev_device,
+                                                     const char* key) = 0;
+  virtual const char* udev_device_get_subsystem(udev_device* udev_device) = 0;
+  virtual const char* udev_device_get_sysattr_value(udev_device* udev_device,
+                                                    const char* sysattr) = 0;
+  virtual const char* udev_device_get_sysname(udev_device* udev_device) = 0;
+  virtual const char* udev_device_get_syspath(udev_device* udev_device) = 0;
+  virtual udev_device* udev_device_new_from_devnum(udev* udev,
+                                                   char type,
+                                                   dev_t devnum) = 0;
+  virtual udev_device* udev_device_new_from_subsystem_sysname(
+      udev* udev,
+      const char* subsystem,
+      const char* sysname) = 0;
+  virtual udev_device* udev_device_new_from_syspath(udev* udev,
+                                                    const char* syspath) = 0;
+  virtual void udev_device_unref(udev_device* udev_device) = 0;
+  virtual int udev_enumerate_add_match_subsystem(udev_enumerate* udev_enumerate,
+                                                 const char* subsystem) = 0;
+  virtual udev_list_entry* udev_enumerate_get_list_entry(
+      udev_enumerate* udev_enumerate) = 0;
+  virtual udev_enumerate* udev_enumerate_new(udev* udev) = 0;
+  virtual int udev_enumerate_scan_devices(udev_enumerate* udev_enumerate) = 0;
+  virtual void udev_enumerate_unref(udev_enumerate* udev_enumerate) = 0;
+  virtual udev_list_entry* udev_list_entry_get_next(
+      udev_list_entry* list_entry) = 0;
+  virtual const char* udev_list_entry_get_name(udev_list_entry* list_entry) = 0;
+  virtual int udev_monitor_enable_receiving(udev_monitor* udev_monitor) = 0;
+  virtual int udev_monitor_filter_add_match_subsystem_devtype(
+      udev_monitor* udev_monitor,
+      const char* subsystem,
+      const char* devtype) = 0;
+  virtual int udev_monitor_get_fd(udev_monitor* udev_monitor) = 0;
+  virtual udev_monitor* udev_monitor_new_from_netlink(udev* udev,
+                                                      const char* name) = 0;
+  virtual udev_device* udev_monitor_receive_device(
+      udev_monitor* udev_monitor) = 0;
+  virtual void udev_monitor_unref(udev_monitor* udev_monitor) = 0;
+  virtual udev* udev_new() = 0;
+  virtual void udev_set_log_fn(
+      struct udev* udev,
+      void (*log_fn)(struct udev* udev, int priority,
+                     const char* file, int line,
+                     const char* fn, const char* format, va_list args)) = 0;
+  virtual void udev_set_log_priority(struct udev* udev, int priority) = 0;
+  virtual void udev_unref(udev* udev) = 0;
+};
+
+}  // namespace device
+
+#endif  // DEVICE_UDEV_LINUX_UDEV_LOADER_H_
diff --git a/device/udev_linux/udev_unittest.cc b/device/udev_linux/udev_unittest.cc
new file mode 100644
index 0000000..244cd8e
--- /dev/null
+++ b/device/udev_linux/udev_unittest.cc
@@ -0,0 +1,21 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/udev_linux/udev.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace device {
+
+TEST(UdevTest, DecodeString) {
+  ASSERT_EQ("", UdevDecodeString(""));
+  ASSERT_EQ("\\", UdevDecodeString("\\x5c"));
+  ASSERT_EQ("\\x5", UdevDecodeString("\\x5"));
+  ASSERT_EQ("049f", UdevDecodeString("049f"));
+  ASSERT_EQ(
+      "HD Pro Webcam C920", UdevDecodeString("HD\\x20Pro\\x20Webcam\\x20C920"));
+  ASSERT_EQ("E-MU Systems,Inc.", UdevDecodeString("E-MU\\x20Systems\\x2cInc."));
+}
+
+}  // namespace device