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

Side by Side Diff: device/hid/hid_connection_linux.cc

Issue 947663002: Log device/hid messages to chrome://device-log. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Clarified destructor behavior, cleaned up OS X error logging. Created 5 years, 10 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
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 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 "device/hid/hid_connection_linux.h" 5 #include "device/hid/hid_connection_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <linux/hidraw.h> 8 #include <linux/hidraw.h>
9 #include <sys/ioctl.h> 9 #include <sys/ioctl.h>
10 10
11 #include <string> 11 #include <string>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/message_loop/message_pump_libevent.h" 16 #include "base/message_loop/message_pump_libevent.h"
17 #include "base/posix/eintr_wrapper.h" 17 #include "base/posix/eintr_wrapper.h"
18 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
19 #include "base/threading/thread_restrictions.h" 19 #include "base/threading/thread_restrictions.h"
20 #include "components/device_event_log/device_event_log.h"
20 #include "device/hid/hid_service.h" 21 #include "device/hid/hid_service.h"
21 22
22 // These are already defined in newer versions of linux/hidraw.h. 23 // These are already defined in newer versions of linux/hidraw.h.
23 #ifndef HIDIOCSFEATURE 24 #ifndef HIDIOCSFEATURE
24 #define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x06, len) 25 #define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x06, len)
25 #endif 26 #endif
26 #ifndef HIDIOCGFEATURE 27 #ifndef HIDIOCGFEATURE
27 #define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x07, len) 28 #define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x07, len)
28 #endif 29 #endif
29 30
(...skipping 20 matching lines...) Expand all
50 51
51 // Starts the FileDescriptorWatcher that reads input events from the device. 52 // Starts the FileDescriptorWatcher that reads input events from the device.
52 // Must be called on a thread that has a base::MessageLoopForIO. The helper 53 // Must be called on a thread that has a base::MessageLoopForIO. The helper
53 // object is owned by the thread where it was started. 54 // object is owned by the thread where it was started.
54 void Start() { 55 void Start() {
55 base::ThreadRestrictions::AssertIOAllowed(); 56 base::ThreadRestrictions::AssertIOAllowed();
56 thread_checker_.DetachFromThread(); 57 thread_checker_.DetachFromThread();
57 if (!base::MessageLoopForIO::current()->WatchFileDescriptor( 58 if (!base::MessageLoopForIO::current()->WatchFileDescriptor(
58 platform_file_, true, base::MessageLoopForIO::WATCH_READ, 59 platform_file_, true, base::MessageLoopForIO::WATCH_READ,
59 &file_watcher_, this)) { 60 &file_watcher_, this)) {
60 LOG(ERROR) << "Failed to start watching device file."; 61 HID_LOG(ERROR) << "Failed to start watching device file.";
61 } 62 }
62 } 63 }
63 64
64 private: 65 private:
65 // base::MessagePumpLibevent::Watcher implementation. 66 // base::MessagePumpLibevent::Watcher implementation.
66 void OnFileCanReadWithoutBlocking(int fd) override { 67 void OnFileCanReadWithoutBlocking(int fd) override {
67 DCHECK(thread_checker_.CalledOnValidThread()); 68 DCHECK(thread_checker_.CalledOnValidThread());
68 DCHECK_EQ(fd, platform_file_); 69 DCHECK_EQ(fd, platform_file_);
69 70
70 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(report_buffer_size_)); 71 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(report_buffer_size_));
71 char* data = buffer->data(); 72 char* data = buffer->data();
72 size_t length = report_buffer_size_; 73 size_t length = report_buffer_size_;
73 if (!has_report_id_) { 74 if (!has_report_id_) {
74 // Linux will not prefix the buffer with a report ID if report IDs are not 75 // Linux will not prefix the buffer with a report ID if report IDs are not
75 // used by the device. Prefix the buffer with 0. 76 // used by the device. Prefix the buffer with 0.
76 *data++ = 0; 77 *data++ = 0;
77 length--; 78 length--;
78 } 79 }
79 80
80 ssize_t bytes_read = HANDLE_EINTR(read(platform_file_, data, length)); 81 ssize_t bytes_read = HANDLE_EINTR(read(platform_file_, data, length));
81 if (bytes_read < 0) { 82 if (bytes_read < 0) {
82 if (errno != EAGAIN) { 83 if (errno != EAGAIN) {
83 VPLOG(1) << "Read failed"; 84 HID_PLOG(EVENT) << "Read failed";
84 // This assumes that the error is unrecoverable and disables reading 85 // This assumes that the error is unrecoverable and disables reading
85 // from the device until it has been re-opened. 86 // from the device until it has been re-opened.
86 // TODO(reillyg): Investigate starting and stopping the file descriptor 87 // TODO(reillyg): Investigate starting and stopping the file descriptor
87 // watcher in response to pending read requests so that per-request 88 // watcher in response to pending read requests so that per-request
88 // errors can be returned to the client. 89 // errors can be returned to the client.
89 file_watcher_.StopWatchingFileDescriptor(); 90 file_watcher_.StopWatchingFileDescriptor();
90 } 91 }
91 return; 92 return;
92 } 93 }
93 if (!has_report_id_) { 94 if (!has_report_id_) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 device_file_.GetPlatformFile(), HIDIOCSFEATURE(size), buffer, 206 device_file_.GetPlatformFile(), HIDIOCSFEATURE(size), buffer,
206 base::Bind(&HidConnectionLinux::FinishSendFeatureReport, 207 base::Bind(&HidConnectionLinux::FinishSendFeatureReport,
207 weak_factory_.GetWeakPtr(), callback), 208 weak_factory_.GetWeakPtr(), callback),
208 task_runner_)); 209 task_runner_));
209 } 210 }
210 211
211 void HidConnectionLinux::FinishWrite(size_t expected_size, 212 void HidConnectionLinux::FinishWrite(size_t expected_size,
212 const WriteCallback& callback, 213 const WriteCallback& callback,
213 ssize_t result) { 214 ssize_t result) {
214 if (result < 0) { 215 if (result < 0) {
215 VPLOG(1) << "Write failed"; 216 HID_PLOG(EVENT) << "Write failed";
216 callback.Run(false); 217 callback.Run(false);
217 } else { 218 } else {
218 if (static_cast<size_t>(result) != expected_size) { 219 if (static_cast<size_t>(result) != expected_size) {
219 LOG(WARNING) << "Incomplete HID write: " << result 220 HID_LOG(EVENT) << "Incomplete HID write: " << result
220 << " != " << expected_size; 221 << " != " << expected_size;
221 } 222 }
222 callback.Run(true); 223 callback.Run(true);
223 } 224 }
224 } 225 }
225 226
226 void HidConnectionLinux::FinishGetFeatureReport( 227 void HidConnectionLinux::FinishGetFeatureReport(
227 uint8_t report_id, 228 uint8_t report_id,
228 scoped_refptr<net::IOBuffer> buffer, 229 scoped_refptr<net::IOBuffer> buffer,
229 const ReadCallback& callback, 230 const ReadCallback& callback,
230 int result) { 231 int result) {
231 if (result < 0) { 232 if (result < 0) {
232 VPLOG(1) << "Failed to get feature report"; 233 HID_PLOG(EVENT) << "Failed to get feature report";
233 callback.Run(false, NULL, 0); 234 callback.Run(false, NULL, 0);
234 } else if (result == 0) { 235 } else if (result == 0) {
235 VLOG(1) << "Get feature result too short."; 236 HID_LOG(EVENT) << "Get feature result too short.";
236 callback.Run(false, NULL, 0); 237 callback.Run(false, NULL, 0);
237 } else if (report_id == 0) { 238 } else if (report_id == 0) {
238 // Linux adds a 0 to the beginning of the data received from the device. 239 // Linux adds a 0 to the beginning of the data received from the device.
239 scoped_refptr<net::IOBuffer> copied_buffer(new net::IOBuffer(result - 1)); 240 scoped_refptr<net::IOBuffer> copied_buffer(new net::IOBuffer(result - 1));
240 memcpy(copied_buffer->data(), buffer->data() + 1, result - 1); 241 memcpy(copied_buffer->data(), buffer->data() + 1, result - 1);
241 callback.Run(true, copied_buffer, result - 1); 242 callback.Run(true, copied_buffer, result - 1);
242 } else { 243 } else {
243 callback.Run(true, buffer, result); 244 callback.Run(true, buffer, result);
244 } 245 }
245 } 246 }
246 247
247 void HidConnectionLinux::FinishSendFeatureReport(const WriteCallback& callback, 248 void HidConnectionLinux::FinishSendFeatureReport(const WriteCallback& callback,
248 int result) { 249 int result) {
249 if (result < 0) { 250 if (result < 0) {
250 VPLOG(1) << "Failed to send feature report"; 251 HID_PLOG(EVENT) << "Failed to send feature report";
251 callback.Run(false); 252 callback.Run(false);
252 } else { 253 } else {
253 callback.Run(true); 254 callback.Run(true);
254 } 255 }
255 } 256 }
256 257
257 // static 258 // static
258 void HidConnectionLinux::BlockingWrite( 259 void HidConnectionLinux::BlockingWrite(
259 base::PlatformFile platform_file, 260 base::PlatformFile platform_file,
260 scoped_refptr<net::IOBuffer> buffer, 261 scoped_refptr<net::IOBuffer> buffer,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 PendingHidReport report = pending_reports_.front(); 301 PendingHidReport report = pending_reports_.front();
301 302
302 pending_reports_.pop(); 303 pending_reports_.pop();
303 if (CompleteRead(report.buffer, report.size, read.callback)) { 304 if (CompleteRead(report.buffer, report.size, read.callback)) {
304 pending_reads_.pop(); 305 pending_reads_.pop();
305 } 306 }
306 } 307 }
307 } 308 }
308 309
309 } // namespace device 310 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698