OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "device/udev_linux/udev_watcher.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/memory/ptr_util.h" |
| 9 |
| 10 namespace device { |
| 11 |
| 12 UdevWatcher::Observer::~Observer() = default; |
| 13 |
| 14 void UdevWatcher::Observer::OnDeviceAdded(ScopedUdevDevicePtr device) {} |
| 15 |
| 16 void UdevWatcher::Observer::OnDeviceRemoved(ScopedUdevDevicePtr device) {} |
| 17 |
| 18 std::unique_ptr<UdevWatcher> UdevWatcher::StartWatching(Observer* observer) { |
| 19 ScopedUdevPtr udev(udev_new()); |
| 20 if (!udev) { |
| 21 LOG(ERROR) << "Failed to initialize udev."; |
| 22 return nullptr; |
| 23 } |
| 24 |
| 25 ScopedUdevMonitorPtr udev_monitor( |
| 26 udev_monitor_new_from_netlink(udev.get(), "udev")); |
| 27 if (!udev_monitor) { |
| 28 LOG(ERROR) << "Failed to initialize a udev monitor."; |
| 29 return nullptr; |
| 30 } |
| 31 |
| 32 if (udev_monitor_enable_receiving(udev_monitor.get()) != 0) { |
| 33 LOG(ERROR) << "Failed to enable receiving udev events."; |
| 34 return nullptr; |
| 35 } |
| 36 |
| 37 int monitor_fd = udev_monitor_get_fd(udev_monitor.get()); |
| 38 if (monitor_fd < 0) { |
| 39 LOG(ERROR) << "Udev monitor file descriptor unavailable."; |
| 40 return nullptr; |
| 41 } |
| 42 |
| 43 return base::WrapUnique(new UdevWatcher( |
| 44 std::move(udev), std::move(udev_monitor), monitor_fd, observer)); |
| 45 } |
| 46 |
| 47 UdevWatcher::~UdevWatcher() { |
| 48 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 49 }; |
| 50 |
| 51 void UdevWatcher::EnumerateExistingDevices() { |
| 52 DCHECK(sequence_checker_.CalledOnValidSequence()); |
| 53 ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev_.get())); |
| 54 if (!enumerate) { |
| 55 LOG(ERROR) << "Failed to initialize a udev enumerator."; |
| 56 return; |
| 57 } |
| 58 |
| 59 if (udev_enumerate_scan_devices(enumerate.get()) != 0) { |
| 60 LOG(ERROR) << "Failed to begin udev enumeration."; |
| 61 return; |
| 62 } |
| 63 |
| 64 udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate.get()); |
| 65 for (udev_list_entry* i = devices; i != nullptr; |
| 66 i = udev_list_entry_get_next(i)) { |
| 67 ScopedUdevDevicePtr device( |
| 68 udev_device_new_from_syspath(udev_.get(), udev_list_entry_get_name(i))); |
| 69 if (device) |
| 70 observer_->OnDeviceAdded(std::move(device)); |
| 71 } |
| 72 } |
| 73 |
| 74 UdevWatcher::UdevWatcher(ScopedUdevPtr udev, |
| 75 ScopedUdevMonitorPtr udev_monitor, |
| 76 int monitor_fd, |
| 77 Observer* observer) |
| 78 : udev_(std::move(udev)), |
| 79 udev_monitor_(std::move(udev_monitor)), |
| 80 observer_(observer) { |
| 81 file_watcher_ = base::FileDescriptorWatcher::WatchReadable( |
| 82 monitor_fd, |
| 83 base::Bind(&UdevWatcher::OnMonitorReadable, base::Unretained(this))); |
| 84 } |
| 85 |
| 86 void UdevWatcher::OnMonitorReadable() { |
| 87 ScopedUdevDevicePtr device(udev_monitor_receive_device(udev_monitor_.get())); |
| 88 if (!device) |
| 89 return; |
| 90 |
| 91 std::string action(udev_device_get_action(device.get())); |
| 92 if (action == "add") |
| 93 observer_->OnDeviceAdded(std::move(device)); |
| 94 else if (action == "remove") |
| 95 observer_->OnDeviceRemoved(std::move(device)); |
| 96 } |
| 97 |
| 98 } // namespace device |
OLD | NEW |