Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(573)

Side by Side Diff: device/core/device_monitor_linux.cc

Issue 2417043002: Move device/core files to device/base directory. (Closed)
Patch Set: Fix ChromeOS build Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/core/device_monitor_linux.h ('k') | device/core/device_monitor_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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/core/device_monitor_linux.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/lazy_instance.h"
11 #include "base/logging.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "device/udev_linux/udev.h"
14
15 namespace device {
16
17 namespace {
18
19 const char kUdevName[] = "udev";
20 const char kUdevActionAdd[] = "add";
21 const char kUdevActionRemove[] = "remove";
22
23 // The instance will be reset when message loop destroys.
24 base::LazyInstance<std::unique_ptr<DeviceMonitorLinux>>::Leaky
25 g_device_monitor_linux_ptr = LAZY_INSTANCE_INITIALIZER;
26
27 } // namespace
28
29 DeviceMonitorLinux::DeviceMonitorLinux() : monitor_fd_(-1) {
30 base::ThreadRestrictions::AssertIOAllowed();
31 base::MessageLoop::current()->AddDestructionObserver(this);
32
33 udev_.reset(udev_new());
34 if (!udev_) {
35 LOG(ERROR) << "Failed to create udev.";
36 return;
37 }
38 monitor_.reset(udev_monitor_new_from_netlink(udev_.get(), kUdevName));
39 if (!monitor_) {
40 LOG(ERROR) << "Failed to create udev monitor.";
41 return;
42 }
43
44 int ret = udev_monitor_enable_receiving(monitor_.get());
45 if (ret != 0) {
46 LOG(ERROR) << "Failed to start udev monitoring.";
47 return;
48 }
49
50 monitor_fd_ = udev_monitor_get_fd(monitor_.get());
51 if (monitor_fd_ <= 0) {
52 LOG(ERROR) << "Failed to start udev monitoring.";
53 return;
54 }
55
56 monitor_watch_controller_ = base::FileDescriptorWatcher::WatchReadable(
57 monitor_fd_,
58 base::Bind(&DeviceMonitorLinux::OnMonitorCanReadWithoutBlocking,
59 base::Unretained(this)));
60 }
61
62 // static
63 DeviceMonitorLinux* DeviceMonitorLinux::GetInstance() {
64 if (!g_device_monitor_linux_ptr.Get().get())
65 g_device_monitor_linux_ptr.Get().reset(new DeviceMonitorLinux());
66 return g_device_monitor_linux_ptr.Get().get();
67 }
68
69 void DeviceMonitorLinux::AddObserver(Observer* observer) {
70 DCHECK(thread_checker_.CalledOnValidThread());
71 observers_.AddObserver(observer);
72 }
73
74 void DeviceMonitorLinux::RemoveObserver(Observer* observer) {
75 DCHECK(thread_checker_.CalledOnValidThread());
76 observers_.RemoveObserver(observer);
77 }
78
79 ScopedUdevDevicePtr DeviceMonitorLinux::GetDeviceFromPath(
80 const std::string& path) {
81 DCHECK(thread_checker_.CalledOnValidThread());
82 ScopedUdevDevicePtr device(
83 udev_device_new_from_syspath(udev_.get(), path.c_str()));
84 return device;
85 }
86
87 void DeviceMonitorLinux::Enumerate(const EnumerateCallback& callback) {
88 DCHECK(thread_checker_.CalledOnValidThread());
89 ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev_.get()));
90
91 if (!enumerate) {
92 LOG(ERROR) << "Failed to enumerate devices.";
93 return;
94 }
95
96 if (udev_enumerate_scan_devices(enumerate.get()) != 0) {
97 LOG(ERROR) << "Failed to enumerate devices.";
98 return;
99 }
100
101 // This list is managed by |enumerate|.
102 udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate.get());
103 for (udev_list_entry* i = devices; i != nullptr;
104 i = udev_list_entry_get_next(i)) {
105 ScopedUdevDevicePtr device(
106 udev_device_new_from_syspath(udev_.get(), udev_list_entry_get_name(i)));
107 if (device)
108 callback.Run(device.get());
109 }
110 }
111
112 void DeviceMonitorLinux::WillDestroyCurrentMessageLoop() {
113 DCHECK(thread_checker_.CalledOnValidThread());
114 FOR_EACH_OBSERVER(Observer, observers_, WillDestroyMonitorMessageLoop());
115 g_device_monitor_linux_ptr.Get().reset(nullptr);
116 }
117
118 DeviceMonitorLinux::~DeviceMonitorLinux() {
119 DCHECK(thread_checker_.CalledOnValidThread());
120 base::MessageLoop::current()->RemoveDestructionObserver(this);
121 close(monitor_fd_);
122 }
123
124 void DeviceMonitorLinux::OnMonitorCanReadWithoutBlocking() {
125 DCHECK(thread_checker_.CalledOnValidThread());
126
127 ScopedUdevDevicePtr device(udev_monitor_receive_device(monitor_.get()));
128 if (!device)
129 return;
130
131 std::string action(udev_device_get_action(device.get()));
132 if (action == kUdevActionAdd)
133 FOR_EACH_OBSERVER(Observer, observers_, OnDeviceAdded(device.get()));
134 else if (action == kUdevActionRemove)
135 FOR_EACH_OBSERVER(Observer, observers_, OnDeviceRemoved(device.get()));
136 }
137
138 } // namespace device
OLDNEW
« no previous file with comments | « device/core/device_monitor_linux.h ('k') | device/core/device_monitor_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698