15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/udev_linux.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libudev.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UdevLinux::UdevLinux(const std::vector<UdevMonitorFilter>& filters, 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UdevNotificationCallback& callback) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : udev_(udev_new()), 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitor_(NULL), 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitor_fd_(-1), 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_(callback) { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(udev_); 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitor_ = udev_monitor_new_from_netlink(udev_, "udev"); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(monitor_); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < filters.size(); ++i) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = udev_monitor_filter_add_match_subsystem_devtype( 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitor_, filters[i].subsystem, filters[i].devtype); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(0, ret); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = udev_monitor_enable_receiving(monitor_); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(0, ret); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitor_fd_ = udev_monitor_get_fd(monitor_); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(monitor_fd_, 0); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success = base::MessageLoopForIO::current()->WatchFileDescriptor( 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) monitor_fd_, 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true, 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForIO::WATCH_READ, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &monitor_watcher_, 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UdevLinux::~UdevLinux() { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitor_watcher_.StopWatchingFileDescriptor(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) udev_monitor_unref(monitor_); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) udev_unref(udev_); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)udev* UdevLinux::udev_handle() { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return udev_; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UdevLinux::OnFileCanReadWithoutBlocking(int fd) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Events occur when devices attached to the system are added, removed, or 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change state. udev_monitor_receive_device() will return a device object 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // representing the device which changed and what type of change occured. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(monitor_fd_, fd); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) udev_device* dev = udev_monitor_receive_device(monitor_); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dev) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(dev); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) udev_device_unref(dev); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UdevLinux::OnFileCanWriteWithoutBlocking(int fd) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 71