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

Side by Side Diff: device/usb/usb_service_impl.cc

Issue 1646783002: Update webusb_descriptors.cc to parse the new WebUSB descriptors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@io_buffer
Patch Set: Sometimes MSVC complains about passing size_type to BarrierClosure. Created 4 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
« no previous file with comments | « device/usb/usb_device_impl.h ('k') | device/usb/webusb_descriptors.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 2014 The Chromium Authors. All rights reserved. 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 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/usb/usb_service_impl.h" 5 #include "device/usb/usb_service_impl.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <list> 8 #include <list>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
(...skipping 30 matching lines...) Expand all
41 using net::IOBufferWithSize; 41 using net::IOBufferWithSize;
42 42
43 namespace device { 43 namespace device {
44 44
45 namespace { 45 namespace {
46 46
47 // Standard USB requests and descriptor types: 47 // Standard USB requests and descriptor types:
48 const uint16_t kUsbVersion2_1 = 0x0210; 48 const uint16_t kUsbVersion2_1 = 0x0210;
49 const uint8_t kGetDescriptorRequest = 0x06; 49 const uint8_t kGetDescriptorRequest = 0x06;
50 const uint8_t kStringDescriptorType = 0x03; 50 const uint8_t kStringDescriptorType = 0x03;
51 const uint8_t kBosDescriptorType = 0x0F;
52
53 // WebUSB requests:
54 const uint8_t kGetAllowedOriginsRequest = 0x01;
55 const uint8_t kGetLandingPageRequest = 0x02;
56 51
57 const int kControlTransferTimeout = 60000; // 1 minute 52 const int kControlTransferTimeout = 60000; // 1 minute
58 53
59 #if defined(OS_WIN) 54 #if defined(OS_WIN)
60 55
61 bool IsWinUsbInterface(const std::string& device_path) { 56 bool IsWinUsbInterface(const std::string& device_path) {
62 DeviceInfoQueryWin device_info_query; 57 DeviceInfoQueryWin device_info_query;
63 if (!device_info_query.device_info_list_valid()) { 58 if (!device_info_query.device_info_list_valid()) {
64 USB_PLOG(ERROR) << "Failed to create a device information set"; 59 USB_PLOG(ERROR) << "Failed to create a device information set";
65 return false; 60 return false;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 uint16_t language_id, 138 uint16_t language_id,
144 const base::Callback<void(const base::string16&)>& callback) { 139 const base::Callback<void(const base::string16&)>& callback) {
145 scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(255); 140 scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(255);
146 device_handle->ControlTransfer( 141 device_handle->ControlTransfer(
147 USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, UsbDeviceHandle::DEVICE, 142 USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, UsbDeviceHandle::DEVICE,
148 kGetDescriptorRequest, kStringDescriptorType << 8 | index, language_id, 143 kGetDescriptorRequest, kStringDescriptorType << 8 | index, language_id,
149 buffer, buffer->size(), kControlTransferTimeout, 144 buffer, buffer->size(), kControlTransferTimeout,
150 base::Bind(&OnReadStringDescriptor, callback)); 145 base::Bind(&OnReadStringDescriptor, callback));
151 } 146 }
152 147
153 void OnReadWebUsbLandingPage(scoped_refptr<UsbDevice> device,
154 const base::Closure& callback,
155 UsbTransferStatus status,
156 scoped_refptr<net::IOBuffer> buffer,
157 size_t length) {
158 if (status != USB_TRANSFER_COMPLETED) {
159 USB_LOG(EVENT) << "Failed to read WebUSB landing page.";
160 callback.Run();
161 return;
162 }
163
164 GURL landing_page;
165 if (ParseWebUsbUrlDescriptor(
166 std::vector<uint8_t>(buffer->data(), buffer->data() + length),
167 &landing_page)) {
168 UsbDeviceImpl* device_impl = static_cast<UsbDeviceImpl*>(device.get());
169 device_impl->set_webusb_landing_page(landing_page);
170 }
171 callback.Run();
172 }
173
174 void ReadWebUsbLandingPage(scoped_refptr<UsbDeviceHandle> device_handle,
175 const base::Closure& callback,
176 uint8_t vendor_code) {
177 scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(255);
178 device_handle->ControlTransfer(
179 USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, UsbDeviceHandle::DEVICE,
180 vendor_code, 0, kGetLandingPageRequest, buffer, buffer->size(),
181 kControlTransferTimeout,
182 base::Bind(&OnReadWebUsbLandingPage, device_handle->GetDevice(),
183 callback));
184 }
185
186 void OnReadWebUsbAllowedOrigins(scoped_refptr<UsbDevice> device,
187 const base::Closure& callback,
188 UsbTransferStatus status,
189 scoped_refptr<net::IOBuffer> buffer,
190 size_t length) {
191 if (status != USB_TRANSFER_COMPLETED) {
192 USB_LOG(EVENT) << "Failed to read WebUSB allowed origins.";
193 callback.Run();
194 return;
195 }
196
197 scoped_ptr<WebUsbDescriptorSet> descriptors(new WebUsbDescriptorSet());
198 if (descriptors->Parse(
199 std::vector<uint8_t>(buffer->data(), buffer->data() + length))) {
200 UsbDeviceImpl* device_impl = static_cast<UsbDeviceImpl*>(device.get());
201 device_impl->set_webusb_allowed_origins(std::move(descriptors));
202 }
203 callback.Run();
204 }
205
206 void OnReadWebUsbAllowedOriginsHeader(
207 scoped_refptr<UsbDeviceHandle> device_handle,
208 const base::Closure& callback,
209 uint8_t vendor_code,
210 UsbTransferStatus status,
211 scoped_refptr<net::IOBuffer> buffer,
212 size_t length) {
213 if (status != USB_TRANSFER_COMPLETED || length != 4) {
214 USB_LOG(EVENT) << "Failed to read WebUSB allowed origins header.";
215 callback.Run();
216 return;
217 }
218
219 uint16_t new_length = buffer->data()[2] | (buffer->data()[3] << 8);
220 scoped_refptr<IOBufferWithSize> new_buffer = new IOBufferWithSize(new_length);
221 device_handle->ControlTransfer(
222 USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, UsbDeviceHandle::DEVICE,
223 vendor_code, 0, kGetAllowedOriginsRequest, new_buffer, new_buffer->size(),
224 kControlTransferTimeout,
225 base::Bind(&OnReadWebUsbAllowedOrigins, device_handle->GetDevice(),
226 callback));
227 }
228
229 void ReadWebUsbAllowedOrigins(scoped_refptr<UsbDeviceHandle> device_handle,
230 const base::Closure& callback,
231 uint8_t vendor_code) {
232 scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(4);
233 device_handle->ControlTransfer(
234 USB_DIRECTION_INBOUND, UsbDeviceHandle::VENDOR, UsbDeviceHandle::DEVICE,
235 vendor_code, 0, kGetAllowedOriginsRequest, buffer, buffer->size(),
236 kControlTransferTimeout,
237 base::Bind(&OnReadWebUsbAllowedOriginsHeader, device_handle, callback,
238 vendor_code));
239 }
240
241 void OnReadBosDescriptor(scoped_refptr<UsbDeviceHandle> device_handle,
242 const base::Closure& callback,
243 UsbTransferStatus status,
244 scoped_refptr<net::IOBuffer> buffer,
245 size_t length) {
246 if (status != USB_TRANSFER_COMPLETED) {
247 USB_LOG(EVENT) << "Failed to read BOS descriptor.";
248 callback.Run();
249 return;
250 }
251
252 WebUsbPlatformCapabilityDescriptor descriptor;
253 if (!descriptor.ParseFromBosDescriptor(
254 std::vector<uint8_t>(buffer->data(), buffer->data() + length))) {
255 callback.Run();
256 return;
257 }
258
259 base::Closure barrier = base::BarrierClosure(2, callback);
260 ReadWebUsbLandingPage(device_handle, barrier, descriptor.vendor_code);
261 ReadWebUsbAllowedOrigins(device_handle, barrier, descriptor.vendor_code);
262 }
263
264 void OnReadBosDescriptorHeader(scoped_refptr<UsbDeviceHandle> device_handle,
265 const base::Closure& callback,
266 UsbTransferStatus status,
267 scoped_refptr<net::IOBuffer> buffer,
268 size_t length) {
269 if (status != USB_TRANSFER_COMPLETED || length != 5) {
270 USB_LOG(EVENT) << "Failed to read BOS descriptor header.";
271 callback.Run();
272 return;
273 }
274
275 uint16_t new_length = buffer->data()[2] | (buffer->data()[3] << 8);
276 scoped_refptr<IOBufferWithSize> new_buffer = new IOBufferWithSize(new_length);
277 device_handle->ControlTransfer(
278 USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, UsbDeviceHandle::DEVICE,
279 kGetDescriptorRequest, kBosDescriptorType << 8, 0, new_buffer,
280 new_buffer->size(), kControlTransferTimeout,
281 base::Bind(&OnReadBosDescriptor, device_handle, callback));
282 }
283
284 void ReadBosDescriptor(scoped_refptr<UsbDeviceHandle> device_handle,
285 const base::Closure& callback) {
286 scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(5);
287 device_handle->ControlTransfer(
288 USB_DIRECTION_INBOUND, UsbDeviceHandle::STANDARD, UsbDeviceHandle::DEVICE,
289 kGetDescriptorRequest, kBosDescriptorType << 8, 0, buffer, buffer->size(),
290 kControlTransferTimeout,
291 base::Bind(&OnReadBosDescriptorHeader, device_handle, callback));
292 }
293
294 void CloseHandleAndRunContinuation(scoped_refptr<UsbDeviceHandle> device_handle, 148 void CloseHandleAndRunContinuation(scoped_refptr<UsbDeviceHandle> device_handle,
295 const base::Closure& continuation) { 149 const base::Closure& continuation) {
296 device_handle->Close(); 150 device_handle->Close();
297 continuation.Run(); 151 continuation.Run();
298 } 152 }
299 153
300 void SaveStringAndRunContinuation( 154 void SaveStringAndRunContinuation(
301 const base::Callback<void(const base::string16&)>& save_callback, 155 const base::Callback<void(const base::string16&)>& save_callback,
302 const base::Closure& continuation, 156 const base::Closure& continuation,
303 const base::string16& value) { 157 const base::string16& value) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 196
343 if (serial_number != 0) { 197 if (serial_number != 0) {
344 ReadStringDescriptor( 198 ReadStringDescriptor(
345 device_handle, serial_number, language_id, 199 device_handle, serial_number, language_id,
346 base::Bind(&SaveStringAndRunContinuation, 200 base::Bind(&SaveStringAndRunContinuation,
347 base::Bind(&UsbDeviceImpl::set_serial_number, device), 201 base::Bind(&UsbDeviceImpl::set_serial_number, device),
348 barrier)); 202 barrier));
349 } 203 }
350 } 204 }
351 205
206 void OnReadBosDescriptor(scoped_refptr<UsbDeviceHandle> device_handle,
207 const base::Closure& barrier,
208 scoped_ptr<WebUsbAllowedOrigins> allowed_origins,
209 const GURL& landing_page) {
210 scoped_refptr<UsbDeviceImpl> device =
211 static_cast<UsbDeviceImpl*>(device_handle->GetDevice().get());
212
213 if (allowed_origins)
214 device->set_webusb_allowed_origins(std::move(allowed_origins));
215 if (landing_page.is_valid())
216 device->set_webusb_landing_page(landing_page);
217
218 barrier.Run();
219 }
220
352 void OnDeviceOpenedReadDescriptors( 221 void OnDeviceOpenedReadDescriptors(
353 uint8_t manufacturer, 222 uint8_t manufacturer,
354 uint8_t product, 223 uint8_t product,
355 uint8_t serial_number, 224 uint8_t serial_number,
356 bool read_bos_descriptors, 225 bool read_bos_descriptors,
357 const base::Closure& success_closure, 226 const base::Closure& success_closure,
358 const base::Closure& failure_closure, 227 const base::Closure& failure_closure,
359 scoped_refptr<UsbDeviceHandle> device_handle) { 228 scoped_refptr<UsbDeviceHandle> device_handle) {
360 if (device_handle) { 229 if (device_handle) {
361 int count = 0; 230 int count = 0;
(...skipping 12 matching lines...) Expand all
374 device_handle, success_closure)); 243 device_handle, success_closure));
375 244
376 if (manufacturer != 0 || product != 0 || serial_number != 0) { 245 if (manufacturer != 0 || product != 0 || serial_number != 0) {
377 ReadStringDescriptor( 246 ReadStringDescriptor(
378 device_handle, 0, 0, 247 device_handle, 0, 0,
379 base::Bind(&OnReadLanguageIds, device_handle, manufacturer, product, 248 base::Bind(&OnReadLanguageIds, device_handle, manufacturer, product,
380 serial_number, barrier)); 249 serial_number, barrier));
381 } 250 }
382 251
383 if (read_bos_descriptors) { 252 if (read_bos_descriptors) {
384 ReadBosDescriptor(device_handle, barrier); 253 ReadWebUsbDescriptors(device_handle, base::Bind(&OnReadBosDescriptor,
254 device_handle, barrier));
385 } 255 }
386 } else { 256 } else {
387 failure_closure.Run(); 257 failure_closure.Run();
388 } 258 }
389 } 259 }
390 260
391 #if defined(USE_UDEV) 261 #if defined(USE_UDEV)
392 262
393 void EnumerateUdevDevice(scoped_refptr<UsbDeviceImpl> device, 263 void EnumerateUdevDevice(scoped_refptr<UsbDeviceImpl> device,
394 bool read_bos_descriptors, 264 bool read_bos_descriptors,
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 PlatformDeviceMap::iterator it = platform_devices_.find(platform_device); 665 PlatformDeviceMap::iterator it = platform_devices_.find(platform_device);
796 if (it != platform_devices_.end()) { 666 if (it != platform_devices_.end()) {
797 RemoveDevice(it->second); 667 RemoveDevice(it->second);
798 } else { 668 } else {
799 devices_being_enumerated_.erase(platform_device); 669 devices_being_enumerated_.erase(platform_device);
800 } 670 }
801 libusb_unref_device(platform_device); 671 libusb_unref_device(platform_device);
802 } 672 }
803 673
804 } // namespace device 674 } // namespace device
OLDNEW
« no previous file with comments | « device/usb/usb_device_impl.h ('k') | device/usb/webusb_descriptors.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698