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

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

Powered by Google App Engine
This is Rietveld 408576698