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

Side by Side Diff: chrome/browser/extensions/api/usb/usb_api.cc

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

Powered by Google App Engine
This is Rietveld 408576698