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

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

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