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

Side by Side Diff: content/browser/gamepad/platform_data_fetcher_linux.cc

Issue 10824036: Linux: Refactor udev device monitoring code into its own class so it can be reused more easily. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: fix typo Created 8 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 | Annotate | Revision Log
« no previous file with comments | « content/browser/gamepad/platform_data_fetcher_linux.h ('k') | content/browser/udev_linux.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/gamepad/platform_data_fetcher_linux.h" 5 #include "content/browser/gamepad/platform_data_fetcher_linux.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <libudev.h> 8 #include <libudev.h>
9 #include <linux/joystick.h> 9 #include <linux/joystick.h>
10 #include <string.h> 10 #include <string.h>
11 #include <sys/stat.h> 11 #include <sys/stat.h>
12 #include <sys/types.h> 12 #include <sys/types.h>
13 #include <unistd.h> 13 #include <unistd.h>
14 14
15 #include "base/debug/trace_event.h" 15 #include "base/debug/trace_event.h"
16 #include "base/eintr_wrapper.h" 16 #include "base/eintr_wrapper.h"
17 #include "base/message_loop.h" 17 #include "base/message_loop.h"
18 #include "base/string_number_conversions.h" 18 #include "base/string_number_conversions.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "base/stringprintf.h" 20 #include "base/stringprintf.h"
21 #include "base/utf_string_conversions.h" 21 #include "base/utf_string_conversions.h"
22 #include "content/browser/udev_linux.h"
22 23
23 namespace { 24 namespace {
24 25
25 const char kInputSubsystem[] = "input"; 26 const char kInputSubsystem[] = "input";
26 const char kUsbSubsystem[] = "usb"; 27 const char kUsbSubsystem[] = "usb";
27 const char kUsbDeviceType[] = "usb_device"; 28 const char kUsbDeviceType[] = "usb_device";
28 const float kMaxLinuxAxisValue = 32767.0; 29 const float kMaxLinuxAxisValue = 32767.0;
29 30
30 void CloseFileDescriptorIfValid(int fd) { 31 void CloseFileDescriptorIfValid(int fd) {
31 if (fd >= 0) 32 if (fd >= 0)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 namespace content { 65 namespace content {
65 66
66 using WebKit::WebGamepad; 67 using WebKit::WebGamepad;
67 using WebKit::WebGamepads; 68 using WebKit::WebGamepads;
68 69
69 GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() { 70 GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() {
70 for (size_t i = 0; i < arraysize(device_fds_); ++i) 71 for (size_t i = 0; i < arraysize(device_fds_); ++i)
71 device_fds_[i] = -1; 72 device_fds_[i] = -1;
72 memset(mappers_, 0, sizeof(mappers_)); 73 memset(mappers_, 0, sizeof(mappers_));
73 74
74 udev_ = udev_new(); 75 std::vector<UdevLinux::UdevMonitorFilter> filters;
75 CHECK(udev_); 76 filters.push_back(
76 77 content::UdevLinux::UdevMonitorFilter(kInputSubsystem, NULL));
77 monitor_ = udev_monitor_new_from_netlink(udev_, "udev"); 78 udev_.reset(
78 CHECK(monitor_); 79 new UdevLinux(filters,
79 int ret = udev_monitor_filter_add_match_subsystem_devtype(monitor_, 80 base::Bind(&GamepadPlatformDataFetcherLinux::RefreshDevice,
80 kInputSubsystem, 81 base::Unretained(this))));
81 NULL);
82 CHECK_EQ(0, ret);
83 ret = udev_monitor_enable_receiving(monitor_);
84 CHECK_EQ(0, ret);
85 monitor_fd_ = udev_monitor_get_fd(monitor_);
86 CHECK_GE(monitor_fd_, 0);
87 bool success = MessageLoopForIO::current()->WatchFileDescriptor(monitor_fd_,
88 true, MessageLoopForIO::WATCH_READ, &monitor_watcher_, this);
89 CHECK(success);
90 82
91 EnumerateDevices(); 83 EnumerateDevices();
92 } 84 }
93 85
94 GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() { 86 GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() {
95 monitor_watcher_.StopWatchingFileDescriptor();
96 udev_monitor_unref(monitor_);
97 udev_unref(udev_);
98 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) 87 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i)
99 CloseFileDescriptorIfValid(device_fds_[i]); 88 CloseFileDescriptorIfValid(device_fds_[i]);
100 } 89 }
101 90
102 void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) { 91 void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) {
103 TRACE_EVENT0("GAMEPAD", "GetGamepadData"); 92 TRACE_EVENT0("GAMEPAD", "GetGamepadData");
104 93
105 data_.length = WebGamepads::itemsLengthCap; 94 data_.length = WebGamepads::itemsLengthCap;
106 95
107 // Update our internal state. 96 // Update our internal state.
108 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { 97 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
109 if (device_fds_[i] >= 0) { 98 if (device_fds_[i] >= 0) {
110 ReadDeviceData(i); 99 ReadDeviceData(i);
111 } 100 }
112 } 101 }
113 102
114 // Copy to the current state to the output buffer, using the mapping 103 // Copy to the current state to the output buffer, using the mapping
115 // function, if there is one available. 104 // function, if there is one available.
116 pads->length = data_.length; 105 pads->length = data_.length;
117 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { 106 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) {
118 if (mappers_[i]) 107 if (mappers_[i])
119 mappers_[i](data_.items[i], &pads->items[i]); 108 mappers_[i](data_.items[i], &pads->items[i]);
120 else 109 else
121 pads->items[i] = data_.items[i]; 110 pads->items[i] = data_.items[i];
122 } 111 }
123 } 112 }
124 113
125 void GamepadPlatformDataFetcherLinux::OnFileCanReadWithoutBlocking(int fd) {
126 // Events occur when devices attached to the system are added, removed, or
127 // change state. udev_monitor_receive_device() will return a device object
128 // representing the device which changed and what type of change occured.
129 DCHECK_EQ(monitor_fd_, fd);
130 udev_device* dev = udev_monitor_receive_device(monitor_);
131 if (!dev)
132 return;
133 RefreshDevice(dev);
134 udev_device_unref(dev);
135 }
136
137 void GamepadPlatformDataFetcherLinux::OnFileCanWriteWithoutBlocking(int fd) {
138 }
139
140 // Used during enumeration, and monitor notifications. 114 // Used during enumeration, and monitor notifications.
141 void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { 115 void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) {
142 int index; 116 int index;
143 std::string node_path; 117 std::string node_path;
144 if (IsGamepad(dev, &index, &node_path)) { 118 if (IsGamepad(dev, &index, &node_path)) {
145 int& device_fd = device_fds_[index]; 119 int& device_fd = device_fds_[index];
146 WebGamepad& pad = data_.items[index]; 120 WebGamepad& pad = data_.items[index];
147 GamepadStandardMappingFunction& mapper = mappers_[index]; 121 GamepadStandardMappingFunction& mapper = mappers_[index];
148 122
149 CloseFileDescriptorIfValid(device_fd); 123 CloseFileDescriptorIfValid(device_fd);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 TruncateUTF8ToByteSize(id, WebGamepad::idLengthCap - 1, &id); 190 TruncateUTF8ToByteSize(id, WebGamepad::idLengthCap - 1, &id);
217 string16 tmp16 = UTF8ToUTF16(id); 191 string16 tmp16 = UTF8ToUTF16(id);
218 memset(pad.id, 0, sizeof(pad.id)); 192 memset(pad.id, 0, sizeof(pad.id));
219 tmp16.copy(pad.id, arraysize(pad.id) - 1); 193 tmp16.copy(pad.id, arraysize(pad.id) - 1);
220 194
221 pad.connected = true; 195 pad.connected = true;
222 } 196 }
223 } 197 }
224 198
225 void GamepadPlatformDataFetcherLinux::EnumerateDevices() { 199 void GamepadPlatformDataFetcherLinux::EnumerateDevices() {
226 udev_enumerate* enumerate = udev_enumerate_new(udev_); 200 udev_enumerate* enumerate = udev_enumerate_new(udev_->udev_handle());
227 if (!enumerate) 201 if (!enumerate)
228 return; 202 return;
229 int ret = udev_enumerate_add_match_subsystem(enumerate, kInputSubsystem); 203 int ret = udev_enumerate_add_match_subsystem(enumerate, kInputSubsystem);
230 if (ret != 0) 204 if (ret != 0)
231 return; 205 return;
232 ret = udev_enumerate_scan_devices(enumerate); 206 ret = udev_enumerate_scan_devices(enumerate);
233 if (ret != 0) 207 if (ret != 0)
234 return; 208 return;
235 209
236 udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate); 210 udev_list_entry* devices = udev_enumerate_get_list_entry(enumerate);
237 for (udev_list_entry* dev_list_entry = devices; 211 for (udev_list_entry* dev_list_entry = devices;
238 dev_list_entry != NULL; 212 dev_list_entry != NULL;
239 dev_list_entry = udev_list_entry_get_next(dev_list_entry)) { 213 dev_list_entry = udev_list_entry_get_next(dev_list_entry)) {
240 // Get the filename of the /sys entry for the device and create a 214 // Get the filename of the /sys entry for the device and create a
241 // udev_device object (dev) representing it 215 // udev_device object (dev) representing it
242 const char* path = udev_list_entry_get_name(dev_list_entry); 216 const char* path = udev_list_entry_get_name(dev_list_entry);
243 udev_device* dev = udev_device_new_from_syspath(udev_, path); 217 udev_device* dev = udev_device_new_from_syspath(udev_->udev_handle(), path);
244 if (!dev) 218 if (!dev)
245 continue; 219 continue;
246 RefreshDevice(dev); 220 RefreshDevice(dev);
247 udev_device_unref(dev); 221 udev_device_unref(dev);
248 } 222 }
249 // Free the enumerator object 223 // Free the enumerator object
250 udev_enumerate_unref(enumerate); 224 udev_enumerate_unref(enumerate);
251 } 225 }
252 226
253 void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) { 227 void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) {
(...skipping 21 matching lines...) Expand all
275 continue; 249 continue;
276 pad.buttons[item] = event.value ? 1.0 : 0.0; 250 pad.buttons[item] = event.value ? 1.0 : 0.0;
277 if (item >= pad.buttonsLength) 251 if (item >= pad.buttonsLength)
278 pad.buttonsLength = item + 1; 252 pad.buttonsLength = item + 1;
279 } 253 }
280 pad.timestamp = event.time; 254 pad.timestamp = event.time;
281 } 255 }
282 } 256 }
283 257
284 } // namespace content 258 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gamepad/platform_data_fetcher_linux.h ('k') | content/browser/udev_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698