From 9d2063687c80931e2c0e683a8b959129efc8956a Mon Sep 17 00:00:00 2001 From: mcasas Date: Thu, 11 Feb 2016 14:12:39 -0800 Subject: move from content/browser: UDevLinux -> device/udev; DeviceMonitorUdev -> media/capture BrowserMainLoop uses DeviceMonitorUdev to monitor for audio/video device changes. This CL moves that monitor to media/capture so it can be used from other sources (concretely components/video_capture). DeviceMonitorUdev uses content/browser/UDevLinux, which is also used by GamepadPlatformDataFetcherLinux: This CL also moves this UDevLinux to device/udev_linux. to join its peers in Note that this CL doesn't really add any dependencies that were not there to start with. Also rewritten two fors in DeviceMonitorLinux as range-fors, and passing a ref to |io_task_runner| for thread checking. For the rest, no new code. ** note that use_udev implies os==linux [1] BUG=584817 [1] https://code.google.com/p/chromium/codesearch#chromium/src/build/common.gypi&l=758 Review URL: https://codereview.chromium.org/1674353003 Cr-Commit-Position: refs/heads/master@{#375014} --- device/udev_linux/BUILD.gn | 2 + device/udev_linux/udev.gyp | 2 + device/udev_linux/udev_linux.cc | 62 +++++++++++++++++++++++++++ device/udev_linux/udev_linux.h | 95 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 device/udev_linux/udev_linux.cc create mode 100644 device/udev_linux/udev_linux.h (limited to 'device') diff --git a/device/udev_linux/BUILD.gn b/device/udev_linux/BUILD.gn index 4799aab..8eea55b 100644 --- a/device/udev_linux/BUILD.gn +++ b/device/udev_linux/BUILD.gn @@ -14,6 +14,8 @@ if (use_udev) { "udev0_loader.h", "udev1_loader.cc", "udev1_loader.h", + "udev_linux.cc", + "udev_linux.h", "udev_loader.cc", "udev_loader.h", ] diff --git a/device/udev_linux/udev.gyp b/device/udev_linux/udev.gyp index 4769d83..bcf56c9 100644 --- a/device/udev_linux/udev.gyp +++ b/device/udev_linux/udev.gyp @@ -27,6 +27,8 @@ 'udev0_loader.h', 'udev1_loader.cc', 'udev1_loader.h', + 'udev_linux.cc', + 'udev_linux.h', 'udev_loader.cc', 'udev_loader.h', ], diff --git a/device/udev_linux/udev_linux.cc b/device/udev_linux/udev_linux.cc new file mode 100644 index 0000000..7fbd3b3 --- /dev/null +++ b/device/udev_linux/udev_linux.cc @@ -0,0 +1,62 @@ +// 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. + +#include "device/udev_linux/udev_linux.h" + +#include + +#include "base/message_loop/message_loop.h" + +namespace device { + +UdevLinux::UdevLinux(const std::vector& filters, + const UdevNotificationCallback& callback) + : udev_(udev_new()), + monitor_(udev_monitor_new_from_netlink(udev_.get(), "udev")), + monitor_fd_(-1), + callback_(callback) { + CHECK(udev_); + CHECK(monitor_); + CHECK_EQ(base::MessageLoop::TYPE_IO, base::MessageLoop::current()->type()); + + for (const UdevMonitorFilter& filter : filters) { + const int ret = udev_monitor_filter_add_match_subsystem_devtype( + monitor_.get(), filter.subsystem, filter.devtype); + CHECK_EQ(0, ret); + } + + const int ret = udev_monitor_enable_receiving(monitor_.get()); + CHECK_EQ(0, ret); + monitor_fd_ = udev_monitor_get_fd(monitor_.get()); + CHECK_GE(monitor_fd_, 0); + + bool success = base::MessageLoopForIO::current()->WatchFileDescriptor( + monitor_fd_, true, base::MessageLoopForIO::WATCH_READ, &monitor_watcher_, + this); + CHECK(success); +} + +UdevLinux::~UdevLinux() { + monitor_watcher_.StopWatchingFileDescriptor(); +} + +udev* UdevLinux::udev_handle() { + return udev_.get(); +} + +void UdevLinux::OnFileCanReadWithoutBlocking(int fd) { + // Events occur when devices attached to the system are added, removed, or + // 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); + ScopedUdevDevicePtr dev(udev_monitor_receive_device(monitor_.get())); + if (!dev) + return; + + callback_.Run(dev.get()); +} + +void UdevLinux::OnFileCanWriteWithoutBlocking(int fd) {} + +} // namespace device diff --git a/device/udev_linux/udev_linux.h b/device/udev_linux/udev_linux.h new file mode 100644 index 0000000..cd65abe --- /dev/null +++ b/device/udev_linux/udev_linux.h @@ -0,0 +1,95 @@ +// 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. + +// UdevLinux listens for device change notifications from udev and runs +// callbacks when notifications occur. +// +// UdevLinux must be created on a MessageLoop of TYPE_IO. +// UdevLinux is not thread-safe. +// +// Example usage: +// +// class UdevLinux; +// +// class Foo { +// public: +// Foo() { +// std::vector filters; +// filters.push_back(UdevLinux::UdevMonitorFilter("block", NULL)); +// udev_.reset(new UdevLinux(filters, +// base::Bind(&Foo::Notify, this))); +// } +// +// // Called when a "block" device attaches/detaches. +// // To hold on to |device|, call udev_device_ref(device). +// void Notify(udev_device* device) { +// // Do something with |device|. +// } +// +// private: +// scoped_ptr udev_; +// +// DISALLOW_COPY_AND_ASSIGN(Foo); +// }; + +#ifndef DEVICE_UDEV_LINUX_UDEV_LINUX_H_ +#define DEVICE_UDEV_LINUX_UDEV_LINUX_H_ + +#include + +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/message_loop/message_pump_libevent.h" +#include "device/udev_linux/scoped_udev.h" + +extern "C" { +struct udev; +struct udev_device; +struct udev_monitor; +} + +namespace device { + +class UdevLinux : public base::MessagePumpLibevent::Watcher { + public: + typedef base::Callback UdevNotificationCallback; + + // subsystem and devtype parameter for + // udev_monitor_filter_add_match_subsystem_devtype(). + struct UdevMonitorFilter { + UdevMonitorFilter(const char* subsystem_in, const char* devtype_in) + : subsystem(subsystem_in), devtype(devtype_in) {} + const char* subsystem; + const char* devtype; + }; + + // Filter incoming devices based on |filters|. + // Calls |callback| upon device change events. + UdevLinux(const std::vector& filters, + const UdevNotificationCallback& callback); + ~UdevLinux() override; + + // Returns the udev handle to be passed into other udev_*() functions. + udev* udev_handle(); + + private: + // base::MessagePump:Libevent::Watcher implementation. + void OnFileCanReadWithoutBlocking(int fd) override; + void OnFileCanWriteWithoutBlocking(int fd) override; + + // libudev-related items, the main context, and the monitoring context to be + // notified about changes to device states. + const ScopedUdevPtr udev_; + const ScopedUdevMonitorPtr monitor_; + int monitor_fd_; + base::MessagePumpLibevent::FileDescriptorWatcher monitor_watcher_; + const UdevNotificationCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(UdevLinux); +}; + +} // namespace device + +#endif // DEVICE_UDEV_LINUX_UDEV_LINUX_H_ -- cgit v1.1