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

Side by Side Diff: ui/events/ozone/device/udev/device_manager_udev.cc

Issue 1287103004: Sync ui/events to chromium @ https://codereview.chromium.org/1210203002 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 4 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
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 "ui/events/ozone/device/udev/device_manager_udev.h"
6
7 #include "base/strings/stringprintf.h"
8 #include "base/trace_event/trace_event.h"
9 #include "ui/events/ozone/device/device_event.h"
10 #include "ui/events/ozone/device/device_event_observer.h"
11
12 namespace ui {
13
14 namespace {
15
16 const char* const kSubsystems[] = {
17 "input",
18 "drm",
19 };
20
21 // Severity levels from syslog.h. We can't include it directly as it
22 // conflicts with base/logging.h
23 enum {
24 SYS_LOG_EMERG = 0,
25 SYS_LOG_ALERT = 1,
26 SYS_LOG_CRIT = 2,
27 SYS_LOG_ERR = 3,
28 SYS_LOG_WARNING = 4,
29 SYS_LOG_NOTICE = 5,
30 SYS_LOG_INFO = 6,
31 SYS_LOG_DEBUG = 7,
32 };
33
34 // Log handler for messages generated from libudev.
35 void UdevLog(struct udev* udev,
36 int priority,
37 const char* file,
38 int line,
39 const char* fn,
40 const char* format,
41 va_list args) {
42 if (priority <= SYS_LOG_ERR)
43 LOG(ERROR) << "libudev: " << fn << ": " << base::StringPrintV(format, args);
44 else if (priority <= SYS_LOG_INFO)
45 VLOG(1) << "libudev: " << fn << ": " << base::StringPrintV(format, args);
46 else // SYS_LOG_DEBUG
47 VLOG(2) << "libudev: " << fn << ": " << base::StringPrintV(format, args);
48 }
49
50 // Create libudev context.
51 device::ScopedUdevPtr UdevCreate() {
52 struct udev* udev = device::udev_new();
53 if (udev) {
54 device::udev_set_log_fn(udev, UdevLog);
55 device::udev_set_log_priority(udev, SYS_LOG_DEBUG);
56 }
57 return device::ScopedUdevPtr(udev);
58 }
59
60 // Start monitoring input device changes.
61 device::ScopedUdevMonitorPtr UdevCreateMonitor(struct udev* udev) {
62 struct udev_monitor* monitor =
63 device::udev_monitor_new_from_netlink(udev, "udev");
64 if (monitor) {
65 for (size_t i = 0; i < arraysize(kSubsystems); ++i)
66 device::udev_monitor_filter_add_match_subsystem_devtype(
67 monitor, kSubsystems[i], NULL);
68
69 if (device::udev_monitor_enable_receiving(monitor))
70 LOG(ERROR) << "Failed to start receiving events from udev";
71 } else {
72 LOG(ERROR) << "Failed to create udev monitor";
73 }
74
75 return device::ScopedUdevMonitorPtr(monitor);
76 }
77
78 } // namespace
79
80 DeviceManagerUdev::DeviceManagerUdev() : udev_(UdevCreate()) {
81 }
82
83 DeviceManagerUdev::~DeviceManagerUdev() {
84 }
85
86 void DeviceManagerUdev::CreateMonitor() {
87 if (monitor_)
88 return;
89 monitor_ = UdevCreateMonitor(udev_.get());
90 if (monitor_) {
91 int fd = device::udev_monitor_get_fd(monitor_.get());
92 CHECK_GT(fd, 0);
93 base::MessageLoopForUI::current()->WatchFileDescriptor(
94 fd, true, base::MessagePumpLibevent::WATCH_READ, &controller_, this);
95 }
96 }
97
98 void DeviceManagerUdev::ScanDevices(DeviceEventObserver* observer) {
99 CreateMonitor();
100
101 device::ScopedUdevEnumeratePtr enumerate(
102 device::udev_enumerate_new(udev_.get()));
103 if (!enumerate)
104 return;
105
106 for (size_t i = 0; i < arraysize(kSubsystems); ++i)
107 device::udev_enumerate_add_match_subsystem(enumerate.get(), kSubsystems[i]);
108 device::udev_enumerate_scan_devices(enumerate.get());
109
110 struct udev_list_entry* devices =
111 device::udev_enumerate_get_list_entry(enumerate.get());
112 struct udev_list_entry* entry;
113
114 udev_list_entry_foreach(entry, devices) {
115 device::ScopedUdevDevicePtr device(device::udev_device_new_from_syspath(
116 udev_.get(), device::udev_list_entry_get_name(entry)));
117 if (!device)
118 continue;
119
120 scoped_ptr<DeviceEvent> event = ProcessMessage(device.get());
121 if (event)
122 observer->OnDeviceEvent(*event.get());
123 }
124 }
125
126 void DeviceManagerUdev::AddObserver(DeviceEventObserver* observer) {
127 observers_.AddObserver(observer);
128 }
129
130 void DeviceManagerUdev::RemoveObserver(DeviceEventObserver* observer) {
131 observers_.RemoveObserver(observer);
132 }
133
134 void DeviceManagerUdev::OnFileCanReadWithoutBlocking(int fd) {
135 // The netlink socket should never become disconnected. There's no need
136 // to handle broken connections here.
137 TRACE_EVENT1("evdev", "UdevDeviceChange", "socket", fd);
138
139 device::ScopedUdevDevicePtr device(
140 device::udev_monitor_receive_device(monitor_.get()));
141 if (!device)
142 return;
143
144 scoped_ptr<DeviceEvent> event = ProcessMessage(device.get());
145 if (event)
146 FOR_EACH_OBSERVER(
147 DeviceEventObserver, observers_, OnDeviceEvent(*event.get()));
148 }
149
150 void DeviceManagerUdev::OnFileCanWriteWithoutBlocking(int fd) {
151 NOTREACHED();
152 }
153
154 scoped_ptr<DeviceEvent> DeviceManagerUdev::ProcessMessage(udev_device* device) {
155 const char* path = device::udev_device_get_devnode(device);
156 const char* action = device::udev_device_get_action(device);
157 const char* subsystem =
158 device::udev_device_get_property_value(device, "SUBSYSTEM");
159
160 if (!path || !subsystem)
161 return nullptr;
162
163 DeviceEvent::DeviceType device_type;
164 if (!strcmp(subsystem, "input") &&
165 base::StartsWithASCII(path, "/dev/input/event", true))
166 device_type = DeviceEvent::INPUT;
167 else if (!strcmp(subsystem, "drm") &&
168 base::StartsWithASCII(path, "/dev/dri/card", true))
169 device_type = DeviceEvent::DISPLAY;
170 else
171 return nullptr;
172
173 DeviceEvent::ActionType action_type;
174 if (!action || !strcmp(action, "add"))
175 action_type = DeviceEvent::ADD;
176 else if (!strcmp(action, "remove"))
177 action_type = DeviceEvent::REMOVE;
178 else if (!strcmp(action, "change"))
179 action_type = DeviceEvent::CHANGE;
180 else
181 return nullptr;
182
183 return make_scoped_ptr(
184 new DeviceEvent(device_type, action_type, base::FilePath(path)));
185 }
186
187 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/device/udev/device_manager_udev.h ('k') | ui/events/ozone/evdev/capture_device_capabilities.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698