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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/usb/usb_api.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "chrome/browser/extensions/api/usb/usb_device_resource.h"
13 #include "chrome/browser/extensions/extension_system.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/usb/usb_device_handle.h"
16 #include "chrome/browser/usb/usb_service.h"
17 #include "chrome/common/extensions/api/usb.h"
18 #include "chrome/common/extensions/permissions/usb_device_permission.h"
19 #include "extensions/common/permissions/permissions_data.h"
20
21 namespace usb = extensions::api::usb;
22 namespace BulkTransfer = usb::BulkTransfer;
23 namespace ClaimInterface = usb::ClaimInterface;
24 namespace CloseDevice = usb::CloseDevice;
25 namespace ControlTransfer = usb::ControlTransfer;
26 namespace FindDevices = usb::FindDevices;
27 namespace GetDevices = usb::GetDevices;
28 namespace InterruptTransfer = usb::InterruptTransfer;
29 namespace IsochronousTransfer = usb::IsochronousTransfer;
30 namespace ListInterfaces = usb::ListInterfaces;
31 namespace OpenDevice = usb::OpenDevice;
32 namespace ReleaseInterface = usb::ReleaseInterface;
33 namespace RequestAccess = usb::RequestAccess;
34 namespace ResetDevice = usb::ResetDevice;
35 namespace SetInterfaceAlternateSetting = usb::SetInterfaceAlternateSetting;
36
37 using content::BrowserThread;
38 using std::string;
39 using std::vector;
40 using usb::ControlTransferInfo;
41 using usb::ConnectionHandle;
42 using usb::Device;
43 using usb::Direction;
44 using usb::EndpointDescriptor;
45 using usb::GenericTransferInfo;
46 using usb::InterfaceDescriptor;
47 using usb::IsochronousTransferInfo;
48 using usb::Recipient;
49 using usb::RequestType;
50 using usb::SynchronizationType;
51 using usb::TransferType;
52 using usb::UsageType;
53
54 typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector;
55 typedef scoped_ptr<DeviceVector> ScopedDeviceVector;
56
57 namespace {
58
59 const char kDataKey[] = "data";
60 const char kResultCodeKey[] = "resultCode";
61
62 const char kErrorInitService[] = "Failed to initialize USB service.";
63
64 const char kErrorOpen[] = "Failed to open device.";
65 const char kErrorCancelled[] = "Transfer was cancelled.";
66 const char kErrorDisconnect[] = "Device disconnected.";
67 const char kErrorGeneric[] = "Transfer failed.";
68 #if !defined(OS_CHROMEOS)
69 const char kErrorNotSupported[] = "Not supported on this platform.";
70 #endif
71 const char kErrorOverflow[] = "Inbound transfer overflow.";
72 const char kErrorStalled[] = "Transfer stalled.";
73 const char kErrorTimeout[] = "Transfer timed out.";
74 const char kErrorTransferLength[] = "Transfer length is insufficient.";
75
76 const char kErrorCannotListInterfaces[] = "Error listing interfaces.";
77 const char kErrorCannotClaimInterface[] = "Error claiming interface.";
78 const char kErrorCannotReleaseInterface[] = "Error releasing interface.";
79 const char kErrorCannotSetInterfaceAlternateSetting[] =
80 "Error setting alternate interface setting.";
81 const char kErrorConvertDirection[] = "Invalid transfer direction.";
82 const char kErrorConvertRecipient[] = "Invalid transfer recipient.";
83 const char kErrorConvertRequestType[] = "Invalid request type.";
84 const char kErrorConvertSynchronizationType[] = "Invalid synchronization type";
85 const char kErrorConvertTransferType[] = "Invalid endpoint type.";
86 const char kErrorConvertUsageType[] = "Invalid usage type.";
87 const char kErrorMalformedParameters[] = "Error parsing parameters.";
88 const char kErrorNoDevice[] = "No such device.";
89 const char kErrorPermissionDenied[] =
90 "Permission to access device was denied";
91 const char kErrorInvalidTransferLength[] =
92 "Transfer length must be a positive number less than 104,857,600.";
93 const char kErrorInvalidNumberOfPackets[] =
94 "Number of packets must be a positive number less than 4,194,304.";
95 const char kErrorInvalidPacketLength[] = "Packet length must be a "
96 "positive number less than 65,536.";
97 const char kErrorResetDevice[] =
98 "Error resetting the device. The device has been closed.";
99
100 const size_t kMaxTransferLength = 100 * 1024 * 1024;
101 const int kMaxPackets = 4 * 1024 * 1024;
102 const int kMaxPacketLength = 64 * 1024;
103
104 UsbDevice* g_device_for_test = NULL;
105
ConvertDirectionToApi(const UsbEndpointDirection & input,Direction * output)106 bool ConvertDirectionToApi(const UsbEndpointDirection& input,
107 Direction* output) {
108 switch (input) {
109 case USB_DIRECTION_INBOUND:
110 *output = usb::DIRECTION_IN;
111 return true;
112 case USB_DIRECTION_OUTBOUND:
113 *output = usb::DIRECTION_OUT;
114 return true;
115 default:
116 NOTREACHED();
117 return false;
118 }
119 }
120
ConvertSynchronizationTypeToApi(const UsbSynchronizationType & input,usb::SynchronizationType * output)121 bool ConvertSynchronizationTypeToApi(const UsbSynchronizationType& input,
122 usb::SynchronizationType* output) {
123 switch (input) {
124 case USB_SYNCHRONIZATION_NONE:
125 *output = usb::SYNCHRONIZATION_TYPE_NONE;
126 return true;
127 case USB_SYNCHRONIZATION_ASYNCHRONOUS:
128 *output = usb::SYNCHRONIZATION_TYPE_ASYNCHRONOUS;
129 return true;
130 case USB_SYNCHRONIZATION_ADAPTIVE:
131 *output = usb::SYNCHRONIZATION_TYPE_ADAPTIVE;
132 return true;
133 case USB_SYNCHRONIZATION_SYNCHRONOUS:
134 *output = usb::SYNCHRONIZATION_TYPE_SYNCHRONOUS;
135 return true;
136 default:
137 NOTREACHED();
138 return false;
139 }
140 }
141
ConvertTransferTypeToApi(const UsbTransferType & input,usb::TransferType * output)142 bool ConvertTransferTypeToApi(
143 const UsbTransferType& input,
144 usb::TransferType* output) {
145 switch (input) {
146 case USB_TRANSFER_CONTROL:
147 *output = usb::TRANSFER_TYPE_CONTROL;
148 return true;
149 case USB_TRANSFER_INTERRUPT:
150 *output = usb::TRANSFER_TYPE_INTERRUPT;
151 return true;
152 case USB_TRANSFER_ISOCHRONOUS:
153 *output = usb::TRANSFER_TYPE_ISOCHRONOUS;
154 return true;
155 case USB_TRANSFER_BULK:
156 *output = usb::TRANSFER_TYPE_BULK;
157 return true;
158 default:
159 NOTREACHED();
160 return false;
161 }
162 }
163
ConvertUsageTypeToApi(const UsbUsageType & input,usb::UsageType * output)164 bool ConvertUsageTypeToApi(const UsbUsageType& input, usb::UsageType* output) {
165 switch (input) {
166 case USB_USAGE_DATA:
167 *output = usb::USAGE_TYPE_DATA;
168 return true;
169 case USB_USAGE_FEEDBACK:
170 *output = usb::USAGE_TYPE_FEEDBACK;
171 return true;
172 case USB_USAGE_EXPLICIT_FEEDBACK:
173 *output = usb::USAGE_TYPE_EXPLICITFEEDBACK;
174 return true;
175 default:
176 NOTREACHED();
177 return false;
178 }
179 }
180
ConvertDirection(const Direction & input,UsbEndpointDirection * output)181 bool ConvertDirection(const Direction& input,
182 UsbEndpointDirection* output) {
183 switch (input) {
184 case usb::DIRECTION_IN:
185 *output = USB_DIRECTION_INBOUND;
186 return true;
187 case usb::DIRECTION_OUT:
188 *output = USB_DIRECTION_OUTBOUND;
189 return true;
190 default:
191 NOTREACHED();
192 return false;
193 }
194 }
195
ConvertRequestType(const RequestType & input,UsbDeviceHandle::TransferRequestType * output)196 bool ConvertRequestType(const RequestType& input,
197 UsbDeviceHandle::TransferRequestType* output) {
198 switch (input) {
199 case usb::REQUEST_TYPE_STANDARD:
200 *output = UsbDeviceHandle::STANDARD;
201 return true;
202 case usb::REQUEST_TYPE_CLASS:
203 *output = UsbDeviceHandle::CLASS;
204 return true;
205 case usb::REQUEST_TYPE_VENDOR:
206 *output = UsbDeviceHandle::VENDOR;
207 return true;
208 case usb::REQUEST_TYPE_RESERVED:
209 *output = UsbDeviceHandle::RESERVED;
210 return true;
211 default:
212 NOTREACHED();
213 return false;
214 }
215 }
216
ConvertRecipient(const Recipient & input,UsbDeviceHandle::TransferRecipient * output)217 bool ConvertRecipient(const Recipient& input,
218 UsbDeviceHandle::TransferRecipient* output) {
219 switch (input) {
220 case usb::RECIPIENT_DEVICE:
221 *output = UsbDeviceHandle::DEVICE;
222 return true;
223 case usb::RECIPIENT_INTERFACE:
224 *output = UsbDeviceHandle::INTERFACE;
225 return true;
226 case usb::RECIPIENT_ENDPOINT:
227 *output = UsbDeviceHandle::ENDPOINT;
228 return true;
229 case usb::RECIPIENT_OTHER:
230 *output = UsbDeviceHandle::OTHER;
231 return true;
232 default:
233 NOTREACHED();
234 return false;
235 }
236 }
237
238 template<class T>
GetTransferSize(const T & input,size_t * output)239 bool GetTransferSize(const T& input, size_t* output) {
240 if (input.direction == usb::DIRECTION_IN) {
241 const int* length = input.length.get();
242 if (length && *length >= 0 &&
243 static_cast<size_t>(*length) < kMaxTransferLength) {
244 *output = *length;
245 return true;
246 }
247 } else if (input.direction == usb::DIRECTION_OUT) {
248 if (input.data.get()) {
249 *output = input.data->size();
250 return true;
251 }
252 }
253 return false;
254 }
255
256 template<class T>
CreateBufferForTransfer(const T & input,UsbEndpointDirection direction,size_t size)257 scoped_refptr<net::IOBuffer> CreateBufferForTransfer(
258 const T& input, UsbEndpointDirection direction, size_t size) {
259
260 if (size >= kMaxTransferLength)
261 return NULL;
262
263 // Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This
264 // is due to an impedance mismatch between IOBuffer and URBs. An IOBuffer
265 // cannot represent a zero-length buffer, while an URB can.
266 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max(
267 static_cast<size_t>(1), size));
268
269 if (direction == USB_DIRECTION_INBOUND) {
270 return buffer;
271 } else if (direction == USB_DIRECTION_OUTBOUND) {
272 if (input.data.get() && size <= input.data->size()) {
273 memcpy(buffer->data(), input.data->data(), size);
274 return buffer;
275 }
276 }
277 NOTREACHED();
278 return NULL;
279 }
280
ConvertTransferStatusToErrorString(const UsbTransferStatus status)281 const char* ConvertTransferStatusToErrorString(const UsbTransferStatus status) {
282 switch (status) {
283 case USB_TRANSFER_COMPLETED:
284 return "";
285 case USB_TRANSFER_ERROR:
286 return kErrorGeneric;
287 case USB_TRANSFER_TIMEOUT:
288 return kErrorTimeout;
289 case USB_TRANSFER_CANCELLED:
290 return kErrorCancelled;
291 case USB_TRANSFER_STALLED:
292 return kErrorStalled;
293 case USB_TRANSFER_DISCONNECT:
294 return kErrorDisconnect;
295 case USB_TRANSFER_OVERFLOW:
296 return kErrorOverflow;
297 case USB_TRANSFER_LENGTH_SHORT:
298 return kErrorTransferLength;
299 default:
300 NOTREACHED();
301 return "";
302 }
303 }
304
305 #if defined(OS_CHROMEOS)
RequestUsbDevicesAccessHelper(ScopedDeviceVector devices,std::vector<scoped_refptr<UsbDevice>>::iterator i,int interface_id,const base::Callback<void (ScopedDeviceVector result)> & callback,bool success)306 void RequestUsbDevicesAccessHelper(
307 ScopedDeviceVector devices,
308 std::vector<scoped_refptr<UsbDevice> >::iterator i,
309 int interface_id,
310 const base::Callback<void(ScopedDeviceVector result)>& callback,
311 bool success) {
312 if (success) {
313 ++i;
314 } else {
315 i = devices->erase(i);
316 }
317 if (i == devices->end()) {
318 callback.Run(devices.Pass());
319 return;
320 }
321 (*i)->RequestUsbAcess(interface_id, base::Bind(RequestUsbDevicesAccessHelper,
322 base::Passed(devices.Pass()),
323 i, interface_id, callback));
324 }
325
RequestUsbDevicesAccess(ScopedDeviceVector devices,int interface_id,const base::Callback<void (ScopedDeviceVector result)> & callback)326 void RequestUsbDevicesAccess(
327 ScopedDeviceVector devices,
328 int interface_id,
329 const base::Callback<void(ScopedDeviceVector result)>& callback) {
330 if (devices->empty()) {
331 callback.Run(devices.Pass());
332 return;
333 }
334 std::vector<scoped_refptr<UsbDevice> >::iterator i = devices->begin();
335 (*i)->RequestUsbAcess(
336 interface_id,
337 base::Bind(RequestUsbDevicesAccessHelper, base::Passed(devices.Pass()),
338 i, interface_id, callback));
339 }
340 #endif // OS_CHROMEOS
341
CreateTransferInfo(UsbTransferStatus status,scoped_refptr<net::IOBuffer> data,size_t length)342 base::DictionaryValue* CreateTransferInfo(
343 UsbTransferStatus status,
344 scoped_refptr<net::IOBuffer> data,
345 size_t length) {
346 base::DictionaryValue* result = new base::DictionaryValue();
347 result->SetInteger(kResultCodeKey, status);
348 result->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer(data->data(),
349 length));
350 return result;
351 }
352
PopulateConnectionHandle(int handle,int vendor_id,int product_id)353 base::Value* PopulateConnectionHandle(int handle, int vendor_id,
354 int product_id) {
355 ConnectionHandle result;
356 result.handle = handle;
357 result.vendor_id = vendor_id;
358 result.product_id = product_id;
359 return result.ToValue().release();
360 }
361
PopulateDevice(UsbDevice * device)362 base::Value* PopulateDevice(UsbDevice* device) {
363 Device result;
364 result.device = device->unique_id();
365 result.vendor_id = device->vendor_id();
366 result.product_id = device->product_id();
367 return result.ToValue().release();
368 }
369
PopulateInterfaceDescriptor(int interface_number,int alternate_setting,int interface_class,int interface_subclass,int interface_protocol,std::vector<linked_ptr<EndpointDescriptor>> * endpoints)370 base::Value* PopulateInterfaceDescriptor(
371 int interface_number,
372 int alternate_setting,
373 int interface_class,
374 int interface_subclass,
375 int interface_protocol,
376 std::vector<linked_ptr<EndpointDescriptor> >* endpoints) {
377 InterfaceDescriptor descriptor;
378 descriptor.interface_number = interface_number;
379 descriptor.alternate_setting = alternate_setting;
380 descriptor.interface_class = interface_class;
381 descriptor.interface_subclass = interface_subclass;
382 descriptor.interface_protocol = interface_protocol;
383 descriptor.endpoints = *endpoints;
384 return descriptor.ToValue().release();
385 }
386
387 } // namespace
388
389 namespace extensions {
390
UsbAsyncApiFunction()391 UsbAsyncApiFunction::UsbAsyncApiFunction()
392 : manager_(NULL) {
393 }
394
~UsbAsyncApiFunction()395 UsbAsyncApiFunction::~UsbAsyncApiFunction() {
396 }
397
PrePrepare()398 bool UsbAsyncApiFunction::PrePrepare() {
399 manager_ = ApiResourceManager<UsbDeviceResource>::Get(GetProfile());
400 set_work_thread_id(BrowserThread::FILE);
401 return manager_ != NULL;
402 }
403
Respond()404 bool UsbAsyncApiFunction::Respond() {
405 return error_.empty();
406 }
407
408 scoped_refptr<UsbDevice>
GetDeviceOrOrCompleteWithError(const Device & input_device)409 UsbAsyncApiFunction::GetDeviceOrOrCompleteWithError(
410 const Device& input_device) {
411 if (g_device_for_test)
412 return g_device_for_test;
413
414 const uint16_t vendor_id = input_device.vendor_id;
415 const uint16_t product_id = input_device.product_id;
416 UsbDevicePermission::CheckParam param(
417 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
418 if (!PermissionsData::CheckAPIPermissionWithParam(
419 GetExtension(), APIPermission::kUsbDevice, ¶m)) {
420 LOG(WARNING) << "Insufficient permissions to access device.";
421 CompleteWithError(kErrorPermissionDenied);
422 return NULL;
423 }
424
425 UsbService* service = UsbService::GetInstance();
426 if (!service) {
427 CompleteWithError(kErrorInitService);
428 return NULL;
429 }
430 scoped_refptr<UsbDevice> device;
431
432 device = service->GetDeviceById(input_device.device);
433
434 if (!device) {
435 CompleteWithError(kErrorNoDevice);
436 return NULL;
437 }
438
439 if (device->vendor_id() != input_device.vendor_id ||
440 device->product_id() != input_device.product_id) {
441 // Must act as if there is no such a device.
442 // Otherwise can be used to finger print unauthorized devices.
443 CompleteWithError(kErrorNoDevice);
444 return NULL;
445 }
446
447 return device;
448 }
449
450 scoped_refptr<UsbDeviceHandle>
GetDeviceHandleOrCompleteWithError(const ConnectionHandle & input_device_handle)451 UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError(
452 const ConnectionHandle& input_device_handle) {
453 UsbDeviceResource* resource =
454 manager_->Get(extension_->id(), input_device_handle.handle);
455 if (!resource) {
456 CompleteWithError(kErrorNoDevice);
457 return NULL;
458 }
459
460 if (!resource->device() || !resource->device()->device()) {
461 CompleteWithError(kErrorDisconnect);
462 manager_->Remove(extension_->id(), input_device_handle.handle);
463 return NULL;
464 }
465
466 if (resource->device()->device()->vendor_id() !=
467 input_device_handle.vendor_id ||
468 resource->device()->device()->product_id() !=
469 input_device_handle.product_id) {
470 CompleteWithError(kErrorNoDevice);
471 return NULL;
472 }
473
474 return resource->device();
475 }
476
RemoveUsbDeviceResource(int api_resource_id)477 void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id) {
478 manager_->Remove(extension_->id(), api_resource_id);
479 }
480
CompleteWithError(const std::string & error)481 void UsbAsyncApiFunction::CompleteWithError(const std::string& error) {
482 SetError(error);
483 AsyncWorkCompleted();
484 }
485
UsbAsyncApiTransferFunction()486 UsbAsyncApiTransferFunction::UsbAsyncApiTransferFunction() {}
487
~UsbAsyncApiTransferFunction()488 UsbAsyncApiTransferFunction::~UsbAsyncApiTransferFunction() {}
489
OnCompleted(UsbTransferStatus status,scoped_refptr<net::IOBuffer> data,size_t length)490 void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status,
491 scoped_refptr<net::IOBuffer> data,
492 size_t length) {
493 if (status != USB_TRANSFER_COMPLETED)
494 SetError(ConvertTransferStatusToErrorString(status));
495
496 SetResult(CreateTransferInfo(status, data, length));
497 AsyncWorkCompleted();
498 }
499
ConvertDirectionSafely(const Direction & input,UsbEndpointDirection * output)500 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely(
501 const Direction& input, UsbEndpointDirection* output) {
502 const bool converted = ConvertDirection(input, output);
503 if (!converted)
504 SetError(kErrorConvertDirection);
505 return converted;
506 }
507
ConvertRequestTypeSafely(const RequestType & input,UsbDeviceHandle::TransferRequestType * output)508 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely(
509 const RequestType& input, UsbDeviceHandle::TransferRequestType* output) {
510 const bool converted = ConvertRequestType(input, output);
511 if (!converted)
512 SetError(kErrorConvertRequestType);
513 return converted;
514 }
515
ConvertRecipientSafely(const Recipient & input,UsbDeviceHandle::TransferRecipient * output)516 bool UsbAsyncApiTransferFunction::ConvertRecipientSafely(
517 const Recipient& input, UsbDeviceHandle::TransferRecipient* output) {
518 const bool converted = ConvertRecipient(input, output);
519 if (!converted)
520 SetError(kErrorConvertRecipient);
521 return converted;
522 }
523
UsbFindDevicesFunction()524 UsbFindDevicesFunction::UsbFindDevicesFunction() {}
525
~UsbFindDevicesFunction()526 UsbFindDevicesFunction::~UsbFindDevicesFunction() {}
527
Prepare()528 bool UsbFindDevicesFunction::Prepare() {
529 parameters_ = FindDevices::Params::Create(*args_);
530 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
531 return true;
532 }
533
AsyncWorkStart()534 void UsbFindDevicesFunction::AsyncWorkStart() {
535 scoped_ptr<base::ListValue> result(new base::ListValue());
536
537 if (g_device_for_test) {
538 UsbDeviceResource* const resource = new UsbDeviceResource(
539 extension_->id(),
540 g_device_for_test->Open());
541
542 result->Append(PopulateConnectionHandle(manager_->Add(resource), 0, 0));
543 SetResult(result.release());
544 AsyncWorkCompleted();
545 return;
546 }
547
548 const uint16_t vendor_id = parameters_->options.vendor_id;
549 const uint16_t product_id = parameters_->options.product_id;
550 int interface_id = parameters_->options.interface_id.get() ?
551 *parameters_->options.interface_id.get() :
552 UsbDevicePermissionData::ANY_INTERFACE;
553 UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id);
554 if (!PermissionsData::CheckAPIPermissionWithParam(
555 GetExtension(), APIPermission::kUsbDevice, ¶m)) {
556 LOG(WARNING) << "Insufficient permissions to access device.";
557 CompleteWithError(kErrorPermissionDenied);
558 return;
559 }
560
561 UsbService *service = UsbService::GetInstance();
562 if (!service) {
563 CompleteWithError(kErrorInitService);
564 return;
565 }
566
567 ScopedDeviceVector devices(new DeviceVector());
568 service->GetDevices(devices.get());
569
570 for (DeviceVector::iterator it = devices->begin();
571 it != devices->end();) {
572 if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) {
573 it = devices->erase(it);
574 } else {
575 ++it;
576 }
577 }
578
579 #if defined(OS_CHROMEOS)
580 RequestUsbDevicesAccess(
581 devices.Pass(), interface_id,
582 base::Bind(&UsbFindDevicesFunction::OpenDevices, this));
583 #else
584 OpenDevices(devices.Pass());
585 #endif // OS_CHROMEOS
586 }
587
OpenDevices(ScopedDeviceVector devices)588 void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices) {
589 base::ListValue* result = new base::ListValue();
590
591 for (size_t i = 0; i < devices->size(); ++i) {
592 scoped_refptr<UsbDeviceHandle> device_handle =
593 devices->at(i)->Open();
594 if (device_handle)
595 device_handles_.push_back(device_handle);
596 }
597
598 for (size_t i = 0; i < device_handles_.size(); ++i) {
599 UsbDeviceHandle* const device_handle = device_handles_[i].get();
600 UsbDeviceResource* const resource =
601 new UsbDeviceResource(extension_->id(), device_handle);
602
603 result->Append(PopulateConnectionHandle(manager_->Add(resource),
604 parameters_->options.vendor_id,
605 parameters_->options.product_id));
606 }
607
608 SetResult(result);
609 AsyncWorkCompleted();
610 }
611
UsbGetDevicesFunction()612 UsbGetDevicesFunction::UsbGetDevicesFunction() {
613 }
614
~UsbGetDevicesFunction()615 UsbGetDevicesFunction::~UsbGetDevicesFunction() {
616 }
617
SetDeviceForTest(UsbDevice * device)618 void UsbGetDevicesFunction::SetDeviceForTest(UsbDevice* device) {
619 g_device_for_test = device;
620 }
621
Prepare()622 bool UsbGetDevicesFunction::Prepare() {
623 parameters_ = GetDevices::Params::Create(*args_);
624 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
625 return true;
626 }
627
AsyncWorkStart()628 void UsbGetDevicesFunction::AsyncWorkStart() {
629 scoped_ptr<base::ListValue> result(new base::ListValue());
630
631 if (g_device_for_test) {
632 result->Append(PopulateDevice(g_device_for_test));
633 SetResult(result.release());
634 AsyncWorkCompleted();
635 return;
636 }
637
638 const uint16_t vendor_id = parameters_->options.vendor_id;
639 const uint16_t product_id = parameters_->options.product_id;
640 UsbDevicePermission::CheckParam param(
641 vendor_id, product_id, UsbDevicePermissionData::UNSPECIFIED_INTERFACE);
642 if (!PermissionsData::CheckAPIPermissionWithParam(
643 GetExtension(), APIPermission::kUsbDevice, ¶m)) {
644 LOG(WARNING) << "Insufficient permissions to access device.";
645 CompleteWithError(kErrorPermissionDenied);
646 return;
647 }
648
649 UsbService* service = UsbService::GetInstance();
650 if (!service) {
651 CompleteWithError(kErrorInitService);
652 return;
653 }
654
655 DeviceVector devices;
656 service->GetDevices(&devices);
657
658 for (DeviceVector::iterator it = devices.begin(); it != devices.end();) {
659 if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) {
660 it = devices.erase(it);
661 } else {
662 ++it;
663 }
664 }
665
666 for (size_t i = 0; i < devices.size(); ++i) {
667 result->Append(PopulateDevice(devices[i].get()));
668 }
669
670 SetResult(result.release());
671 AsyncWorkCompleted();
672 }
673
UsbRequestAccessFunction()674 UsbRequestAccessFunction::UsbRequestAccessFunction() {}
675
~UsbRequestAccessFunction()676 UsbRequestAccessFunction::~UsbRequestAccessFunction() {}
677
Prepare()678 bool UsbRequestAccessFunction::Prepare() {
679 parameters_ = RequestAccess::Params::Create(*args_);
680 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
681 return true;
682 }
683
AsyncWorkStart()684 void UsbRequestAccessFunction::AsyncWorkStart() {
685 #if defined(OS_CHROMEOS)
686 scoped_refptr<UsbDevice> device =
687 GetDeviceOrOrCompleteWithError(parameters_->device);
688 if (!device) return;
689
690 device->RequestUsbAcess(parameters_->interface_id,
691 base::Bind(&UsbRequestAccessFunction::OnCompleted,
692 this));
693 #else
694 SetResult(new base::FundamentalValue(false));
695 CompleteWithError(kErrorNotSupported);
696 #endif // OS_CHROMEOS
697 }
698
OnCompleted(bool success)699 void UsbRequestAccessFunction::OnCompleted(bool success) {
700 SetResult(new base::FundamentalValue(success));
701 AsyncWorkCompleted();
702 }
703
UsbOpenDeviceFunction()704 UsbOpenDeviceFunction::UsbOpenDeviceFunction() {}
705
~UsbOpenDeviceFunction()706 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() {}
707
Prepare()708 bool UsbOpenDeviceFunction::Prepare() {
709 parameters_ = OpenDevice::Params::Create(*args_);
710 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
711 return true;
712 }
713
AsyncWorkStart()714 void UsbOpenDeviceFunction::AsyncWorkStart() {
715 scoped_refptr<UsbDevice> device =
716 GetDeviceOrOrCompleteWithError(parameters_->device);
717 if (!device) return;
718
719 handle_ = device->Open();
720 if (!handle_) {
721 SetError(kErrorOpen);
722 AsyncWorkCompleted();
723 return;
724 }
725
726 SetResult(PopulateConnectionHandle(
727 manager_->Add(new UsbDeviceResource(extension_->id(), handle_)),
728 handle_->device()->vendor_id(),
729 handle_->device()->product_id()));
730 AsyncWorkCompleted();
731 }
732
UsbListInterfacesFunction()733 UsbListInterfacesFunction::UsbListInterfacesFunction() {}
734
~UsbListInterfacesFunction()735 UsbListInterfacesFunction::~UsbListInterfacesFunction() {}
736
Prepare()737 bool UsbListInterfacesFunction::Prepare() {
738 parameters_ = ListInterfaces::Params::Create(*args_);
739 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
740 return true;
741 }
742
AsyncWorkStart()743 void UsbListInterfacesFunction::AsyncWorkStart() {
744 scoped_refptr<UsbDeviceHandle> device_handle =
745 GetDeviceHandleOrCompleteWithError(parameters_->handle);
746 if (!device_handle) return;
747
748 scoped_refptr<UsbConfigDescriptor> config =
749 device_handle->device()->ListInterfaces();
750
751 if (!config) {
752 SetError(kErrorCannotListInterfaces);
753 AsyncWorkCompleted();
754 return;
755 }
756
757 result_.reset(new base::ListValue());
758
759 for (size_t i = 0, num_interfaces = config->GetNumInterfaces();
760 i < num_interfaces; ++i) {
761 scoped_refptr<const UsbInterfaceDescriptor>
762 usb_interface(config->GetInterface(i));
763 for (size_t j = 0, num_descriptors = usb_interface->GetNumAltSettings();
764 j < num_descriptors; ++j) {
765 scoped_refptr<const UsbInterfaceAltSettingDescriptor> descriptor
766 = usb_interface->GetAltSetting(j);
767 std::vector<linked_ptr<EndpointDescriptor> > endpoints;
768 for (size_t k = 0, num_endpoints = descriptor->GetNumEndpoints();
769 k < num_endpoints; k++) {
770 scoped_refptr<const UsbEndpointDescriptor> endpoint
771 = descriptor->GetEndpoint(k);
772 linked_ptr<EndpointDescriptor> endpoint_desc(new EndpointDescriptor());
773
774 TransferType type;
775 Direction direction;
776 SynchronizationType synchronization;
777 UsageType usage;
778
779 if (!ConvertTransferTypeSafely(endpoint->GetTransferType(), &type) ||
780 !ConvertDirectionSafely(endpoint->GetDirection(), &direction) ||
781 !ConvertSynchronizationTypeSafely(
782 endpoint->GetSynchronizationType(), &synchronization) ||
783 !ConvertUsageTypeSafely(endpoint->GetUsageType(), &usage)) {
784 SetError(kErrorCannotListInterfaces);
785 AsyncWorkCompleted();
786 return;
787 }
788
789 endpoint_desc->address = endpoint->GetAddress();
790 endpoint_desc->type = type;
791 endpoint_desc->direction = direction;
792 endpoint_desc->maximum_packet_size = endpoint->GetMaximumPacketSize();
793 endpoint_desc->synchronization = synchronization;
794 endpoint_desc->usage = usage;
795
796 int* polling_interval = new int;
797 endpoint_desc->polling_interval.reset(polling_interval);
798 *polling_interval = endpoint->GetPollingInterval();
799
800 endpoints.push_back(endpoint_desc);
801 }
802
803 result_->Append(PopulateInterfaceDescriptor(
804 descriptor->GetInterfaceNumber(),
805 descriptor->GetAlternateSetting(),
806 descriptor->GetInterfaceClass(),
807 descriptor->GetInterfaceSubclass(),
808 descriptor->GetInterfaceProtocol(),
809 &endpoints));
810 }
811 }
812
813 SetResult(result_.release());
814 AsyncWorkCompleted();
815 }
816
ConvertDirectionSafely(const UsbEndpointDirection & input,usb::Direction * output)817 bool UsbListInterfacesFunction::ConvertDirectionSafely(
818 const UsbEndpointDirection& input,
819 usb::Direction* output) {
820 const bool converted = ConvertDirectionToApi(input, output);
821 if (!converted)
822 SetError(kErrorConvertDirection);
823 return converted;
824 }
825
ConvertSynchronizationTypeSafely(const UsbSynchronizationType & input,usb::SynchronizationType * output)826 bool UsbListInterfacesFunction::ConvertSynchronizationTypeSafely(
827 const UsbSynchronizationType& input,
828 usb::SynchronizationType* output) {
829 const bool converted = ConvertSynchronizationTypeToApi(input, output);
830 if (!converted)
831 SetError(kErrorConvertSynchronizationType);
832 return converted;
833 }
834
ConvertTransferTypeSafely(const UsbTransferType & input,usb::TransferType * output)835 bool UsbListInterfacesFunction::ConvertTransferTypeSafely(
836 const UsbTransferType& input,
837 usb::TransferType* output) {
838 const bool converted = ConvertTransferTypeToApi(input, output);
839 if (!converted)
840 SetError(kErrorConvertTransferType);
841 return converted;
842 }
843
ConvertUsageTypeSafely(const UsbUsageType & input,usb::UsageType * output)844 bool UsbListInterfacesFunction::ConvertUsageTypeSafely(
845 const UsbUsageType& input,
846 usb::UsageType* output) {
847 const bool converted = ConvertUsageTypeToApi(input, output);
848 if (!converted)
849 SetError(kErrorConvertUsageType);
850 return converted;
851 }
852
UsbCloseDeviceFunction()853 UsbCloseDeviceFunction::UsbCloseDeviceFunction() {}
854
~UsbCloseDeviceFunction()855 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() {}
856
Prepare()857 bool UsbCloseDeviceFunction::Prepare() {
858 parameters_ = CloseDevice::Params::Create(*args_);
859 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
860 return true;
861 }
862
AsyncWorkStart()863 void UsbCloseDeviceFunction::AsyncWorkStart() {
864 scoped_refptr<UsbDeviceHandle> device_handle =
865 GetDeviceHandleOrCompleteWithError(parameters_->handle);
866 if (!device_handle) return;
867
868 device_handle->Close();
869 RemoveUsbDeviceResource(parameters_->handle.handle);
870 AsyncWorkCompleted();
871 }
872
UsbClaimInterfaceFunction()873 UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() {}
874
~UsbClaimInterfaceFunction()875 UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() {}
876
Prepare()877 bool UsbClaimInterfaceFunction::Prepare() {
878 parameters_ = ClaimInterface::Params::Create(*args_);
879 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
880 return true;
881 }
882
AsyncWorkStart()883 void UsbClaimInterfaceFunction::AsyncWorkStart() {
884 scoped_refptr<UsbDeviceHandle> device_handle =
885 GetDeviceHandleOrCompleteWithError(parameters_->handle);
886 if (!device_handle) return;
887
888 bool success = device_handle->ClaimInterface(parameters_->interface_number);
889
890 if (!success)
891 SetError(kErrorCannotClaimInterface);
892 AsyncWorkCompleted();
893 }
894
UsbReleaseInterfaceFunction()895 UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() {}
896
~UsbReleaseInterfaceFunction()897 UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() {}
898
Prepare()899 bool UsbReleaseInterfaceFunction::Prepare() {
900 parameters_ = ReleaseInterface::Params::Create(*args_);
901 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
902 return true;
903 }
904
AsyncWorkStart()905 void UsbReleaseInterfaceFunction::AsyncWorkStart() {
906 scoped_refptr<UsbDeviceHandle> device_handle =
907 GetDeviceHandleOrCompleteWithError(parameters_->handle);
908 if (!device_handle) return;
909
910 bool success = device_handle->ReleaseInterface(parameters_->interface_number);
911 if (!success)
912 SetError(kErrorCannotReleaseInterface);
913 AsyncWorkCompleted();
914 }
915
916 UsbSetInterfaceAlternateSettingFunction::
UsbSetInterfaceAlternateSettingFunction()917 UsbSetInterfaceAlternateSettingFunction() {}
918
919 UsbSetInterfaceAlternateSettingFunction::
~UsbSetInterfaceAlternateSettingFunction()920 ~UsbSetInterfaceAlternateSettingFunction() {}
921
Prepare()922 bool UsbSetInterfaceAlternateSettingFunction::Prepare() {
923 parameters_ = SetInterfaceAlternateSetting::Params::Create(*args_);
924 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
925 return true;
926 }
927
AsyncWorkStart()928 void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() {
929 scoped_refptr<UsbDeviceHandle> device_handle =
930 GetDeviceHandleOrCompleteWithError(parameters_->handle);
931 if (!device_handle) return;
932
933 bool success = device_handle->SetInterfaceAlternateSetting(
934 parameters_->interface_number,
935 parameters_->alternate_setting);
936 if (!success)
937 SetError(kErrorCannotSetInterfaceAlternateSetting);
938
939 AsyncWorkCompleted();
940 }
941
UsbControlTransferFunction()942 UsbControlTransferFunction::UsbControlTransferFunction() {}
943
~UsbControlTransferFunction()944 UsbControlTransferFunction::~UsbControlTransferFunction() {}
945
Prepare()946 bool UsbControlTransferFunction::Prepare() {
947 parameters_ = ControlTransfer::Params::Create(*args_);
948 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
949 return true;
950 }
951
AsyncWorkStart()952 void UsbControlTransferFunction::AsyncWorkStart() {
953 scoped_refptr<UsbDeviceHandle> device_handle =
954 GetDeviceHandleOrCompleteWithError(parameters_->handle);
955 if (!device_handle) return;
956
957 const ControlTransferInfo& transfer = parameters_->transfer_info;
958
959 UsbEndpointDirection direction;
960 UsbDeviceHandle::TransferRequestType request_type;
961 UsbDeviceHandle::TransferRecipient recipient;
962 size_t size = 0;
963
964 if (!ConvertDirectionSafely(transfer.direction, &direction) ||
965 !ConvertRequestTypeSafely(transfer.request_type, &request_type) ||
966 !ConvertRecipientSafely(transfer.recipient, &recipient)) {
967 AsyncWorkCompleted();
968 return;
969 }
970
971 if (!GetTransferSize(transfer, &size)) {
972 CompleteWithError(kErrorInvalidTransferLength);
973 return;
974 }
975
976 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
977 transfer, direction, size);
978 if (!buffer.get()) {
979 CompleteWithError(kErrorMalformedParameters);
980 return;
981 }
982
983 device_handle->ControlTransfer(
984 direction,
985 request_type,
986 recipient,
987 transfer.request,
988 transfer.value,
989 transfer.index,
990 buffer.get(),
991 size,
992 0,
993 base::Bind(&UsbControlTransferFunction::OnCompleted, this));
994 }
995
UsbBulkTransferFunction()996 UsbBulkTransferFunction::UsbBulkTransferFunction() {}
997
~UsbBulkTransferFunction()998 UsbBulkTransferFunction::~UsbBulkTransferFunction() {}
999
Prepare()1000 bool UsbBulkTransferFunction::Prepare() {
1001 parameters_ = BulkTransfer::Params::Create(*args_);
1002 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
1003 return true;
1004 }
1005
AsyncWorkStart()1006 void UsbBulkTransferFunction::AsyncWorkStart() {
1007 scoped_refptr<UsbDeviceHandle> device_handle =
1008 GetDeviceHandleOrCompleteWithError(parameters_->handle);
1009 if (!device_handle) return;
1010
1011 const GenericTransferInfo& transfer = parameters_->transfer_info;
1012
1013 UsbEndpointDirection direction;
1014 size_t size = 0;
1015
1016 if (!ConvertDirectionSafely(transfer.direction, &direction)) {
1017 AsyncWorkCompleted();
1018 return;
1019 }
1020
1021 if (!GetTransferSize(transfer, &size)) {
1022 CompleteWithError(kErrorInvalidTransferLength);
1023 return;
1024 }
1025
1026 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
1027 transfer, direction, size);
1028 if (!buffer.get()) {
1029 CompleteWithError(kErrorMalformedParameters);
1030 return;
1031 }
1032
1033 device_handle->BulkTransfer(
1034 direction,
1035 transfer.endpoint,
1036 buffer.get(),
1037 size,
1038 0,
1039 base::Bind(&UsbBulkTransferFunction::OnCompleted, this));
1040 }
1041
UsbInterruptTransferFunction()1042 UsbInterruptTransferFunction::UsbInterruptTransferFunction() {}
1043
~UsbInterruptTransferFunction()1044 UsbInterruptTransferFunction::~UsbInterruptTransferFunction() {}
1045
Prepare()1046 bool UsbInterruptTransferFunction::Prepare() {
1047 parameters_ = InterruptTransfer::Params::Create(*args_);
1048 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
1049 return true;
1050 }
1051
AsyncWorkStart()1052 void UsbInterruptTransferFunction::AsyncWorkStart() {
1053 scoped_refptr<UsbDeviceHandle> device_handle =
1054 GetDeviceHandleOrCompleteWithError(parameters_->handle);
1055 if (!device_handle) return;
1056
1057 const GenericTransferInfo& transfer = parameters_->transfer_info;
1058
1059 UsbEndpointDirection direction;
1060 size_t size = 0;
1061
1062 if (!ConvertDirectionSafely(transfer.direction, &direction)) {
1063 AsyncWorkCompleted();
1064 return;
1065 }
1066
1067 if (!GetTransferSize(transfer, &size)) {
1068 CompleteWithError(kErrorInvalidTransferLength);
1069 return;
1070 }
1071
1072 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
1073 transfer, direction, size);
1074 if (!buffer.get()) {
1075 CompleteWithError(kErrorMalformedParameters);
1076 return;
1077 }
1078
1079 device_handle->InterruptTransfer(
1080 direction,
1081 transfer.endpoint,
1082 buffer.get(),
1083 size,
1084 0,
1085 base::Bind(&UsbInterruptTransferFunction::OnCompleted, this));
1086 }
1087
UsbIsochronousTransferFunction()1088 UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() {}
1089
~UsbIsochronousTransferFunction()1090 UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() {}
1091
Prepare()1092 bool UsbIsochronousTransferFunction::Prepare() {
1093 parameters_ = IsochronousTransfer::Params::Create(*args_);
1094 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
1095 return true;
1096 }
1097
AsyncWorkStart()1098 void UsbIsochronousTransferFunction::AsyncWorkStart() {
1099 scoped_refptr<UsbDeviceHandle> device_handle =
1100 GetDeviceHandleOrCompleteWithError(parameters_->handle);
1101 if (!device_handle) return;
1102
1103 const IsochronousTransferInfo& transfer = parameters_->transfer_info;
1104 const GenericTransferInfo& generic_transfer = transfer.transfer_info;
1105
1106 size_t size = 0;
1107 UsbEndpointDirection direction;
1108
1109 if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) {
1110 AsyncWorkCompleted();
1111 return;
1112 }
1113 if (!GetTransferSize(generic_transfer, &size)) {
1114 CompleteWithError(kErrorInvalidTransferLength);
1115 return;
1116 }
1117 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) {
1118 CompleteWithError(kErrorInvalidNumberOfPackets);
1119 return;
1120 }
1121 unsigned int packets = transfer.packets;
1122 if (transfer.packet_length < 0 ||
1123 transfer.packet_length >= kMaxPacketLength) {
1124 CompleteWithError(kErrorInvalidPacketLength);
1125 return;
1126 }
1127 unsigned int packet_length = transfer.packet_length;
1128 const uint64 total_length = packets * packet_length;
1129 if (packets > size || total_length > size) {
1130 CompleteWithError(kErrorTransferLength);
1131 return;
1132 }
1133
1134 scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
1135 generic_transfer, direction, size);
1136 if (!buffer.get()) {
1137 CompleteWithError(kErrorMalformedParameters);
1138 return;
1139 }
1140
1141 device_handle->IsochronousTransfer(
1142 direction,
1143 generic_transfer.endpoint,
1144 buffer.get(),
1145 size,
1146 packets,
1147 packet_length,
1148 0,
1149 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this));
1150 }
1151
UsbResetDeviceFunction()1152 UsbResetDeviceFunction::UsbResetDeviceFunction() {}
1153
~UsbResetDeviceFunction()1154 UsbResetDeviceFunction::~UsbResetDeviceFunction() {}
1155
Prepare()1156 bool UsbResetDeviceFunction::Prepare() {
1157 parameters_ = ResetDevice::Params::Create(*args_);
1158 EXTENSION_FUNCTION_VALIDATE(parameters_.get());
1159 return true;
1160 }
1161
AsyncWorkStart()1162 void UsbResetDeviceFunction::AsyncWorkStart() {
1163 scoped_refptr<UsbDeviceHandle> device_handle =
1164 GetDeviceHandleOrCompleteWithError(parameters_->handle);
1165 if (!device_handle) return;
1166
1167 bool success = device_handle->ResetDevice();
1168 if (!success) {
1169 device_handle->Close();
1170 RemoveUsbDeviceResource(parameters_->handle.handle);
1171 SetResult(new base::FundamentalValue(false));
1172 CompleteWithError(kErrorResetDevice);
1173 return;
1174 }
1175
1176 SetResult(new base::FundamentalValue(true));
1177 AsyncWorkCompleted();
1178 }
1179
1180 } // namespace extensions
1181