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

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

Issue 364213005: Revert 281282 "Revert 281133 "chrome.hid: enrich model with repo..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 5 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 | « trunk/src/device/hid/hid_connection_linux.h ('k') | trunk/src/device/hid/hid_connection_mac.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) 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 <fcntl.h> 8 #include <fcntl.h>
9 #include <libudev.h> 9 #include <libudev.h>
10 #include <linux/hidraw.h> 10 #include <linux/hidraw.h>
(...skipping 28 matching lines...) Expand all
39 new_buffer->data()[0] = report_id; 39 new_buffer->data()[0] = report_id;
40 memcpy(new_buffer->data() + 1, buffer->data(), buffer->size()); 40 memcpy(new_buffer->data() + 1, buffer->data(), buffer->size());
41 return new_buffer; 41 return new_buffer;
42 } 42 }
43 43
44 } // namespace 44 } // namespace
45 45
46 HidConnectionLinux::HidConnectionLinux(HidDeviceInfo device_info, 46 HidConnectionLinux::HidConnectionLinux(HidDeviceInfo device_info,
47 std::string dev_node) 47 std::string dev_node)
48 : HidConnection(device_info) { 48 : HidConnection(device_info) {
49 DCHECK(thread_checker_.CalledOnValidThread());
50
51 int flags = base::File::FLAG_OPEN | 49 int flags = base::File::FLAG_OPEN |
52 base::File::FLAG_READ | 50 base::File::FLAG_READ |
53 base::File::FLAG_WRITE; 51 base::File::FLAG_WRITE;
54 52
55 base::File device_file(base::FilePath(dev_node), flags); 53 base::File device_file(base::FilePath(dev_node), flags);
56 if (!device_file.IsValid()) { 54 if (!device_file.IsValid()) {
57 base::File::Error file_error = device_file.error_details(); 55 base::File::Error file_error = device_file.error_details();
58 56
59 if (file_error == base::File::FILE_ERROR_ACCESS_DENIED) { 57 if (file_error == base::File::FILE_ERROR_ACCESS_DENIED) {
60 VLOG(1) << "Access denied opening device read-write, trying read-only."; 58 VLOG(1) << "Access denied opening device read-write, trying read-only.";
(...skipping 20 matching lines...) Expand all
81 device_file_.GetPlatformFile(), 79 device_file_.GetPlatformFile(),
82 true, 80 true,
83 base::MessageLoopForIO::WATCH_READ_WRITE, 81 base::MessageLoopForIO::WATCH_READ_WRITE,
84 &device_file_watcher_, 82 &device_file_watcher_,
85 this)) { 83 this)) {
86 LOG(ERROR) << "Failed to start watching device file."; 84 LOG(ERROR) << "Failed to start watching device file.";
87 } 85 }
88 } 86 }
89 87
90 HidConnectionLinux::~HidConnectionLinux() { 88 HidConnectionLinux::~HidConnectionLinux() {
91 DCHECK(thread_checker_.CalledOnValidThread());
92 Disconnect(); 89 Disconnect();
90 Flush();
93 } 91 }
94 92
95 void HidConnectionLinux::OnFileCanReadWithoutBlocking(int fd) { 93 void HidConnectionLinux::PlatformRead(
96 DCHECK(thread_checker_.CalledOnValidThread()); 94 scoped_refptr<net::IOBufferWithSize> buffer,
97 DCHECK_EQ(fd, device_file_.GetPlatformFile()); 95 const IOCallback& callback) {
98
99 uint8 buffer[1024] = {0};
100 int bytes_read =
101 HANDLE_EINTR(read(device_file_.GetPlatformFile(), buffer, 1024));
102 if (bytes_read < 0) {
103 if (errno == EAGAIN) {
104 return;
105 }
106 VPLOG(1) << "Read failed";
107 Disconnect();
108 return;
109 }
110
111 PendingHidReport report;
112 report.buffer = new net::IOBufferWithSize(bytes_read);
113 memcpy(report.buffer->data(), buffer, bytes_read);
114 pending_reports_.push(report);
115 ProcessReadQueue();
116 }
117
118 void HidConnectionLinux::OnFileCanWriteWithoutBlocking(int fd) {}
119
120 void HidConnectionLinux::Disconnect() {
121 DCHECK(thread_checker_.CalledOnValidThread());
122 device_file_watcher_.StopWatchingFileDescriptor();
123 device_file_.Close();
124 while (!pending_reads_.empty()) {
125 PendingHidRead pending_read = pending_reads_.front();
126 pending_reads_.pop();
127 pending_read.callback.Run(false, 0);
128 }
129 }
130
131 void HidConnectionLinux::Read(scoped_refptr<net::IOBufferWithSize> buffer,
132 const IOCallback& callback) {
133 DCHECK(thread_checker_.CalledOnValidThread());
134 PendingHidRead pending_read; 96 PendingHidRead pending_read;
135 pending_read.buffer = buffer; 97 pending_read.buffer = buffer;
136 pending_read.callback = callback; 98 pending_read.callback = callback;
137 pending_reads_.push(pending_read); 99 pending_reads_.push(pending_read);
138 ProcessReadQueue(); 100 ProcessReadQueue();
139 } 101 }
140 102
141 void HidConnectionLinux::Write(uint8_t report_id, 103 void HidConnectionLinux::PlatformWrite(
142 scoped_refptr<net::IOBufferWithSize> buffer, 104 uint8_t report_id,
143 const IOCallback& callback) { 105 scoped_refptr<net::IOBufferWithSize> buffer,
144 DCHECK(thread_checker_.CalledOnValidThread()); 106 const IOCallback& callback) {
145 // If report ID is non-zero, insert it into a new copy of the buffer. 107 // If report ID is non-zero, insert it into a new copy of the buffer.
146 if (report_id != 0) 108 if (report_id != 0)
147 buffer = CopyBufferWithReportId(buffer, report_id); 109 buffer = CopyBufferWithReportId(buffer, report_id);
148 int bytes_written = HANDLE_EINTR( 110 int bytes_written = HANDLE_EINTR(
149 write(device_file_.GetPlatformFile(), buffer->data(), buffer->size())); 111 write(device_file_.GetPlatformFile(), buffer->data(), buffer->size()));
150 if (bytes_written < 0) { 112 if (bytes_written < 0) {
151 VPLOG(1) << "Write failed"; 113 VPLOG(1) << "Write failed";
152 Disconnect(); 114 Disconnect();
153 callback.Run(false, 0); 115 callback.Run(false, 0);
154 } else { 116 } else {
155 callback.Run(true, bytes_written); 117 callback.Run(true, bytes_written);
156 } 118 }
157 } 119 }
158 120
159 void HidConnectionLinux::GetFeatureReport( 121 void HidConnectionLinux::PlatformGetFeatureReport(
160 uint8_t report_id, 122 uint8_t report_id,
161 scoped_refptr<net::IOBufferWithSize> buffer, 123 scoped_refptr<net::IOBufferWithSize> buffer,
162 const IOCallback& callback) { 124 const IOCallback& callback) {
163 DCHECK(thread_checker_.CalledOnValidThread());
164
165 if (buffer->size() == 0) { 125 if (buffer->size() == 0) {
166 callback.Run(false, 0); 126 callback.Run(false, 0);
167 return; 127 return;
168 } 128 }
169 129
170 // The first byte of the destination buffer is the report ID being requested. 130 // The first byte of the destination buffer is the report ID being requested.
171 buffer->data()[0] = report_id; 131 buffer->data()[0] = report_id;
172 int result = ioctl(device_file_.GetPlatformFile(), 132 int result = ioctl(device_file_.GetPlatformFile(),
173 HIDIOCGFEATURE(buffer->size()), 133 HIDIOCGFEATURE(buffer->size()),
174 buffer->data()); 134 buffer->data());
175 if (result < 0) { 135 if (result < 0) {
176 VPLOG(1) << "Failed to get feature report"; 136 VPLOG(1) << "Failed to get feature report";
177 callback.Run(false, 0); 137 callback.Run(false, 0);
178 } else { 138 } else {
179 callback.Run(true, result); 139 callback.Run(true, result);
180 } 140 }
181 } 141 }
182 142
183 void HidConnectionLinux::SendFeatureReport( 143 void HidConnectionLinux::PlatformSendFeatureReport(
184 uint8_t report_id, 144 uint8_t report_id,
185 scoped_refptr<net::IOBufferWithSize> buffer, 145 scoped_refptr<net::IOBufferWithSize> buffer,
186 const IOCallback& callback) { 146 const IOCallback& callback) {
187 DCHECK(thread_checker_.CalledOnValidThread());
188 if (report_id != 0) 147 if (report_id != 0)
189 buffer = CopyBufferWithReportId(buffer, report_id); 148 buffer = CopyBufferWithReportId(buffer, report_id);
190 int result = ioctl(device_file_.GetPlatformFile(), 149 int result = ioctl(device_file_.GetPlatformFile(),
191 HIDIOCSFEATURE(buffer->size()), 150 HIDIOCSFEATURE(buffer->size()),
192 buffer->data()); 151 buffer->data());
193 if (result < 0) { 152 if (result < 0) {
194 VPLOG(1) << "Failed to send feature report"; 153 VPLOG(1) << "Failed to send feature report";
195 callback.Run(false, 0); 154 callback.Run(false, 0);
196 } else { 155 } else {
197 callback.Run(true, result); 156 callback.Run(true, result);
198 } 157 }
199 } 158 }
200 159
160 void HidConnectionLinux::OnFileCanReadWithoutBlocking(int fd) {
161 DCHECK(thread_checker().CalledOnValidThread());
162 DCHECK_EQ(fd, device_file_.GetPlatformFile());
163
164 uint8 raw_buffer[1024] = {0};
165 int bytes_read =
166 HANDLE_EINTR(read(device_file_.GetPlatformFile(), raw_buffer, 1024));
167 if (bytes_read < 0) {
168 if (errno == EAGAIN) {
169 return;
170 }
171 VPLOG(1) << "Read failed";
172 Disconnect();
173 return;
174 }
175
176 scoped_refptr<net::IOBufferWithSize> buffer =
177 new net::IOBufferWithSize(bytes_read);
178 memcpy(buffer->data(), raw_buffer, bytes_read);
179
180 ProcessInputReport(buffer);
181 }
182
183 void HidConnectionLinux::OnFileCanWriteWithoutBlocking(int fd) {
184 }
185
186 void HidConnectionLinux::Disconnect() {
187 DCHECK(thread_checker().CalledOnValidThread());
188 device_file_watcher_.StopWatchingFileDescriptor();
189 device_file_.Close();
190
191 Flush();
192 }
193
194 void HidConnectionLinux::Flush() {
195 while (!pending_reads_.empty()) {
196 pending_reads_.front().callback.Run(false, 0);
197 pending_reads_.pop();
198 }
199 }
200
201 void HidConnectionLinux::ProcessInputReport(
202 scoped_refptr<net::IOBufferWithSize> buffer) {
203 DCHECK(thread_checker().CalledOnValidThread());
204 PendingHidReport report;
205 report.buffer = buffer;
206 pending_reports_.push(report);
207 ProcessReadQueue();
208 }
209
201 void HidConnectionLinux::ProcessReadQueue() { 210 void HidConnectionLinux::ProcessReadQueue() {
211 DCHECK(thread_checker().CalledOnValidThread());
202 while (pending_reads_.size() && pending_reports_.size()) { 212 while (pending_reads_.size() && pending_reports_.size()) {
203 PendingHidRead read = pending_reads_.front(); 213 PendingHidRead read = pending_reads_.front();
204 pending_reads_.pop();
205 PendingHidReport report = pending_reports_.front(); 214 PendingHidReport report = pending_reports_.front();
206 if (report.buffer->size() > read.buffer->size()) { 215
207 read.callback.Run(false, report.buffer->size()); 216 if (read.buffer->size() < report.buffer->size()) {
217 read.callback.Run(false, 0);
218 pending_reads_.pop();
208 } else { 219 } else {
209 memcpy(read.buffer->data(), report.buffer->data(), report.buffer->size()); 220 memcpy(read.buffer->data(), report.buffer->data(), report.buffer->size());
210 pending_reports_.pop(); 221 pending_reports_.pop();
211 read.callback.Run(true, report.buffer->size()); 222
223 if (CompleteRead(report.buffer, read.callback)) {
224 pending_reads_.pop();
225 }
212 } 226 }
213 } 227 }
214 } 228 }
215 229
216 } // namespace device 230 } // namespace device
OLDNEW
« no previous file with comments | « trunk/src/device/hid/hid_connection_linux.h ('k') | trunk/src/device/hid/hid_connection_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698