OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/browser/api/usb/usb_api.h" | 5 #include "extensions/browser/api/usb/usb_api.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
| 10 #include "base/barrier_closure.h" |
10 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop/message_loop_proxy.h" | |
12 #include "device/core/device_client.h" | 12 #include "device/core/device_client.h" |
13 #include "device/usb/usb_device_handle.h" | 13 #include "device/usb/usb_device_handle.h" |
14 #include "device/usb/usb_service.h" | 14 #include "device/usb/usb_service.h" |
15 #include "extensions/browser/api/device_permissions_manager.h" | 15 #include "extensions/browser/api/device_permissions_manager.h" |
16 #include "extensions/browser/api/device_permissions_prompt.h" | 16 #include "extensions/browser/api/device_permissions_prompt.h" |
17 #include "extensions/browser/api/extensions_api_client.h" | 17 #include "extensions/browser/api/extensions_api_client.h" |
18 #include "extensions/browser/api/usb/usb_device_resource.h" | 18 #include "extensions/browser/api/usb/usb_device_resource.h" |
19 #include "extensions/browser/extension_system.h" | 19 #include "extensions/browser/extension_system.h" |
20 #include "extensions/common/api/usb.h" | 20 #include "extensions/common/api/usb.h" |
21 #include "extensions/common/permissions/permissions_data.h" | 21 #include "extensions/common/permissions/permissions_data.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 using usb::EndpointDescriptor; | 63 using usb::EndpointDescriptor; |
64 using usb::GenericTransferInfo; | 64 using usb::GenericTransferInfo; |
65 using usb::InterfaceDescriptor; | 65 using usb::InterfaceDescriptor; |
66 using usb::IsochronousTransferInfo; | 66 using usb::IsochronousTransferInfo; |
67 using usb::Recipient; | 67 using usb::Recipient; |
68 using usb::RequestType; | 68 using usb::RequestType; |
69 using usb::SynchronizationType; | 69 using usb::SynchronizationType; |
70 using usb::TransferType; | 70 using usb::TransferType; |
71 using usb::UsageType; | 71 using usb::UsageType; |
72 | 72 |
73 typedef std::vector<scoped_refptr<UsbDevice> > DeviceVector; | |
74 typedef scoped_ptr<DeviceVector> ScopedDeviceVector; | |
75 | |
76 namespace { | 73 namespace { |
77 | 74 |
78 const char kDataKey[] = "data"; | 75 const char kDataKey[] = "data"; |
79 const char kResultCodeKey[] = "resultCode"; | 76 const char kResultCodeKey[] = "resultCode"; |
80 | 77 |
81 const char kErrorInitService[] = "Failed to initialize USB service."; | 78 const char kErrorInitService[] = "Failed to initialize USB service."; |
82 | 79 |
83 const char kErrorOpen[] = "Failed to open device."; | 80 const char kErrorOpen[] = "Failed to open device."; |
84 const char kErrorCancelled[] = "Transfer was cancelled."; | 81 const char kErrorCancelled[] = "Transfer was cancelled."; |
85 const char kErrorDisconnect[] = "Device disconnected."; | 82 const char kErrorDisconnect[] = "Device disconnected."; |
86 const char kErrorGeneric[] = "Transfer failed."; | 83 const char kErrorGeneric[] = "Transfer failed."; |
87 const char kErrorNotSupported[] = "Not supported on this platform."; | 84 const char kErrorNotSupported[] = "Not supported on this platform."; |
88 const char kErrorNotConfigured[] = "The device is not in a configured state."; | 85 const char kErrorNotConfigured[] = "The device is not in a configured state."; |
89 const char kErrorOverflow[] = "Inbound transfer overflow."; | 86 const char kErrorOverflow[] = "Inbound transfer overflow."; |
90 const char kErrorStalled[] = "Transfer stalled."; | 87 const char kErrorStalled[] = "Transfer stalled."; |
91 const char kErrorTimeout[] = "Transfer timed out."; | 88 const char kErrorTimeout[] = "Transfer timed out."; |
92 const char kErrorTransferLength[] = "Transfer length is insufficient."; | 89 const char kErrorTransferLength[] = "Transfer length is insufficient."; |
93 const char kErrorCannotSetConfiguration[] = | 90 const char kErrorCannotSetConfiguration[] = |
94 "Error setting device configuration."; | 91 "Error setting device configuration."; |
95 const char kErrorCannotClaimInterface[] = "Error claiming interface."; | 92 const char kErrorCannotClaimInterface[] = "Error claiming interface."; |
96 const char kErrorCannotReleaseInterface[] = "Error releasing interface."; | 93 const char kErrorCannotReleaseInterface[] = "Error releasing interface."; |
97 const char kErrorCannotSetInterfaceAlternateSetting[] = | 94 const char kErrorCannotSetInterfaceAlternateSetting[] = |
98 "Error setting alternate interface setting."; | 95 "Error setting alternate interface setting."; |
99 const char kErrorConvertDirection[] = "Invalid transfer direction."; | 96 const char kErrorConvertDirection[] = "Invalid transfer direction."; |
100 const char kErrorConvertRecipient[] = "Invalid transfer recipient."; | 97 const char kErrorConvertRecipient[] = "Invalid transfer recipient."; |
101 const char kErrorConvertRequestType[] = "Invalid request type."; | 98 const char kErrorConvertRequestType[] = "Invalid request type."; |
102 const char kErrorMalformedParameters[] = "Error parsing parameters."; | 99 const char kErrorMalformedParameters[] = "Error parsing parameters."; |
| 100 const char kErrorNoConnection[] = "No such connection."; |
103 const char kErrorNoDevice[] = "No such device."; | 101 const char kErrorNoDevice[] = "No such device."; |
104 const char kErrorPermissionDenied[] = "Permission to access device was denied"; | 102 const char kErrorPermissionDenied[] = "Permission to access device was denied"; |
105 const char kErrorInvalidTransferLength[] = | 103 const char kErrorInvalidTransferLength[] = |
106 "Transfer length must be a positive number less than 104,857,600."; | 104 "Transfer length must be a positive number less than 104,857,600."; |
107 const char kErrorInvalidNumberOfPackets[] = | 105 const char kErrorInvalidNumberOfPackets[] = |
108 "Number of packets must be a positive number less than 4,194,304."; | 106 "Number of packets must be a positive number less than 4,194,304."; |
109 const char kErrorInvalidPacketLength[] = | 107 const char kErrorInvalidPacketLength[] = |
110 "Packet length must be a positive number less than 65,536."; | 108 "Packet length must be a positive number less than 65,536."; |
111 const char kErrorInvalidTimeout[] = | 109 const char kErrorInvalidTimeout[] = |
112 "Transfer timeout must be greater than or equal to 0."; | 110 "Transfer timeout must be greater than or equal to 0."; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 case device::USB_TRANSFER_OVERFLOW: | 233 case device::USB_TRANSFER_OVERFLOW: |
236 return kErrorOverflow; | 234 return kErrorOverflow; |
237 case device::USB_TRANSFER_LENGTH_SHORT: | 235 case device::USB_TRANSFER_LENGTH_SHORT: |
238 return kErrorTransferLength; | 236 return kErrorTransferLength; |
239 default: | 237 default: |
240 NOTREACHED(); | 238 NOTREACHED(); |
241 return ""; | 239 return ""; |
242 } | 240 } |
243 } | 241 } |
244 | 242 |
245 #if defined(OS_CHROMEOS) | |
246 void RequestUsbDevicesAccessHelper( | |
247 ScopedDeviceVector devices, | |
248 std::vector<scoped_refptr<UsbDevice> >::iterator i, | |
249 int interface_id, | |
250 const base::Callback<void(ScopedDeviceVector result)>& callback, | |
251 bool success) { | |
252 if (success) { | |
253 ++i; | |
254 } else { | |
255 i = devices->erase(i); | |
256 } | |
257 if (i == devices->end()) { | |
258 callback.Run(devices.Pass()); | |
259 return; | |
260 } | |
261 (*i)->RequestUsbAccess(interface_id, | |
262 base::Bind(RequestUsbDevicesAccessHelper, | |
263 base::Passed(devices.Pass()), | |
264 i, | |
265 interface_id, | |
266 callback)); | |
267 } | |
268 | |
269 void RequestUsbDevicesAccess( | |
270 ScopedDeviceVector devices, | |
271 int interface_id, | |
272 const base::Callback<void(ScopedDeviceVector result)>& callback) { | |
273 if (devices->empty()) { | |
274 callback.Run(devices.Pass()); | |
275 return; | |
276 } | |
277 std::vector<scoped_refptr<UsbDevice> >::iterator i = devices->begin(); | |
278 (*i)->RequestUsbAccess(interface_id, | |
279 base::Bind(RequestUsbDevicesAccessHelper, | |
280 base::Passed(devices.Pass()), | |
281 i, | |
282 interface_id, | |
283 callback)); | |
284 } | |
285 #endif // OS_CHROMEOS | |
286 | |
287 base::DictionaryValue* CreateTransferInfo(UsbTransferStatus status, | |
288 scoped_refptr<net::IOBuffer> data, | |
289 size_t length) { | |
290 base::DictionaryValue* result = new base::DictionaryValue(); | |
291 result->SetInteger(kResultCodeKey, status); | |
292 result->Set(kDataKey, | |
293 base::BinaryValue::CreateWithCopiedBuffer(data->data(), length)); | |
294 return result; | |
295 } | |
296 | |
297 base::Value* PopulateConnectionHandle(int handle, | 243 base::Value* PopulateConnectionHandle(int handle, |
298 int vendor_id, | 244 int vendor_id, |
299 int product_id) { | 245 int product_id) { |
300 ConnectionHandle result; | 246 ConnectionHandle result; |
301 result.handle = handle; | 247 result.handle = handle; |
302 result.vendor_id = vendor_id; | 248 result.vendor_id = vendor_id; |
303 result.product_id = product_id; | 249 result.product_id = product_id; |
304 return result.ToValue().release(); | 250 return result.ToValue().release(); |
305 } | 251 } |
306 | 252 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 } | 375 } |
430 if (input.interface_protocol) { | 376 if (input.interface_protocol) { |
431 output->SetInterfaceProtocol(*input.interface_protocol); | 377 output->SetInterfaceProtocol(*input.interface_protocol); |
432 } | 378 } |
433 } | 379 } |
434 | 380 |
435 } // namespace | 381 } // namespace |
436 | 382 |
437 namespace extensions { | 383 namespace extensions { |
438 | 384 |
439 UsbAsyncApiFunction::UsbAsyncApiFunction() : manager_(NULL) { | 385 UsbPermissionCheckingFunction::UsbPermissionCheckingFunction() |
| 386 : device_permissions_manager_(nullptr) { |
440 } | 387 } |
441 | 388 |
442 UsbAsyncApiFunction::~UsbAsyncApiFunction() { | 389 UsbPermissionCheckingFunction::~UsbPermissionCheckingFunction() { |
443 } | 390 } |
444 | 391 |
445 bool UsbAsyncApiFunction::PrePrepare() { | 392 bool UsbPermissionCheckingFunction::HasDevicePermission( |
446 manager_ = ApiResourceManager<UsbDeviceResource>::Get(browser_context()); | 393 scoped_refptr<UsbDevice> device) { |
447 set_work_thread_id(BrowserThread::FILE); | 394 if (!device_permissions_manager_) { |
448 return manager_ != NULL; | 395 device_permissions_manager_ = |
449 } | 396 DevicePermissionsManager::Get(browser_context()); |
| 397 } |
450 | 398 |
451 bool UsbAsyncApiFunction::Respond() { | 399 DevicePermissions* device_permissions = |
452 return error_.empty(); | 400 device_permissions_manager_->GetForExtension(extension_id()); |
453 } | 401 DCHECK(device_permissions); |
454 | 402 |
455 bool UsbAsyncApiFunction::HasDevicePermission(scoped_refptr<UsbDevice> device) { | 403 permission_entry_ = device_permissions->FindEntry(device); |
456 DCHECK(device_permissions_); | |
457 | |
458 // Check the DevicePermissionsManager first so that if an entry is found | |
459 // it can be stored for later. This requires the serial number. | |
460 base::string16 serial_number; | |
461 device->GetSerialNumber(&serial_number); | |
462 | |
463 permission_entry_ = device_permissions_->FindEntry(device, serial_number); | |
464 if (permission_entry_.get()) { | 404 if (permission_entry_.get()) { |
465 return true; | 405 return true; |
466 } | 406 } |
467 | 407 |
468 UsbDevicePermission::CheckParam param( | 408 UsbDevicePermission::CheckParam param( |
469 device->vendor_id(), | 409 device->vendor_id(), |
470 device->product_id(), | 410 device->product_id(), |
471 UsbDevicePermissionData::UNSPECIFIED_INTERFACE); | 411 UsbDevicePermissionData::UNSPECIFIED_INTERFACE); |
472 if (extension()->permissions_data()->CheckAPIPermissionWithParam( | 412 if (extension()->permissions_data()->CheckAPIPermissionWithParam( |
473 APIPermission::kUsbDevice, ¶m)) { | 413 APIPermission::kUsbDevice, ¶m)) { |
474 return true; | 414 return true; |
475 } | 415 } |
476 | 416 |
477 return false; | 417 return false; |
478 } | 418 } |
479 | 419 |
480 scoped_refptr<UsbDeviceHandle> | 420 void UsbPermissionCheckingFunction::RecordDeviceLastUsed() { |
481 UsbAsyncApiFunction::GetDeviceHandleOrCompleteWithError( | 421 if (permission_entry_.get()) { |
482 const ConnectionHandle& input_device_handle) { | 422 device_permissions_manager_->UpdateLastUsed(extension_id(), |
483 UsbDeviceResource* resource = | 423 permission_entry_); |
484 manager_->Get(extension_->id(), input_device_handle.handle); | 424 } |
485 if (!resource) { | 425 } |
486 CompleteWithError(kErrorNoDevice); | 426 |
487 return NULL; | 427 UsbConnectionFunction::UsbConnectionFunction() { |
| 428 } |
| 429 |
| 430 UsbConnectionFunction::~UsbConnectionFunction() { |
| 431 } |
| 432 |
| 433 scoped_refptr<device::UsbDeviceHandle> UsbConnectionFunction::GetDeviceHandle( |
| 434 const extensions::core_api::usb::ConnectionHandle& handle) { |
| 435 ApiResourceManager<UsbDeviceResource>* manager = |
| 436 ApiResourceManager<UsbDeviceResource>::Get(browser_context()); |
| 437 if (!manager) { |
| 438 return nullptr; |
488 } | 439 } |
489 | 440 |
490 if (!resource->device().get() || !resource->device()->GetDevice().get()) { | 441 UsbDeviceResource* resource = manager->Get(extension_id(), handle.handle); |
491 CompleteWithError(kErrorDisconnect); | 442 if (!resource) { |
492 manager_->Remove(extension_->id(), input_device_handle.handle); | 443 return nullptr; |
493 return NULL; | |
494 } | |
495 | |
496 if (resource->device()->GetDevice()->vendor_id() != | |
497 input_device_handle.vendor_id || | |
498 resource->device()->GetDevice()->product_id() != | |
499 input_device_handle.product_id) { | |
500 CompleteWithError(kErrorNoDevice); | |
501 return NULL; | |
502 } | 444 } |
503 | 445 |
504 return resource->device(); | 446 return resource->device(); |
505 } | 447 } |
506 | 448 |
507 void UsbAsyncApiFunction::RemoveUsbDeviceResource(int api_resource_id) { | 449 void UsbConnectionFunction::ReleaseDeviceHandle( |
508 manager_->Remove(extension_->id(), api_resource_id); | 450 const extensions::core_api::usb::ConnectionHandle& handle) { |
| 451 ApiResourceManager<UsbDeviceResource>* manager = |
| 452 ApiResourceManager<UsbDeviceResource>::Get(browser_context()); |
| 453 manager->Remove(extension_id(), handle.handle); |
509 } | 454 } |
510 | 455 |
511 void UsbAsyncApiFunction::CompleteWithError(const std::string& error) { | 456 UsbTransferFunction::UsbTransferFunction() { |
512 SetError(error); | |
513 AsyncWorkCompleted(); | |
514 } | 457 } |
515 | 458 |
516 UsbAsyncApiTransferFunction::UsbAsyncApiTransferFunction() { | 459 UsbTransferFunction::~UsbTransferFunction() { |
517 } | 460 } |
518 | 461 |
519 UsbAsyncApiTransferFunction::~UsbAsyncApiTransferFunction() { | 462 void UsbTransferFunction::OnCompleted(UsbTransferStatus status, |
520 } | 463 scoped_refptr<net::IOBuffer> data, |
| 464 size_t length) { |
| 465 scoped_ptr<base::DictionaryValue> transfer_info(new base::DictionaryValue()); |
| 466 transfer_info->SetInteger(kResultCodeKey, status); |
| 467 transfer_info->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer( |
| 468 data->data(), length)); |
521 | 469 |
522 void UsbAsyncApiTransferFunction::OnCompleted(UsbTransferStatus status, | 470 if (status == device::USB_TRANSFER_COMPLETED) { |
523 scoped_refptr<net::IOBuffer> data, | 471 Respond(OneArgument(transfer_info.release())); |
524 size_t length) { | 472 } else { |
525 if (status != device::USB_TRANSFER_COMPLETED) | 473 scoped_ptr<base::ListValue> error_args(new base::ListValue()); |
526 SetError(ConvertTransferStatusToApi(status)); | 474 error_args->Append(transfer_info.release()); |
527 | 475 // Returning arguments with an error is wrong but we're stuck with it. |
528 SetResult(CreateTransferInfo(status, data, length)); | 476 Respond(ErrorWithArguments(error_args.Pass(), |
529 AsyncWorkCompleted(); | 477 ConvertTransferStatusToApi(status))); |
530 } | 478 } |
531 | |
532 bool UsbAsyncApiTransferFunction::ConvertDirectionSafely( | |
533 const Direction& input, | |
534 UsbEndpointDirection* output) { | |
535 const bool converted = ConvertDirectionFromApi(input, output); | |
536 if (!converted) | |
537 SetError(kErrorConvertDirection); | |
538 return converted; | |
539 } | |
540 | |
541 bool UsbAsyncApiTransferFunction::ConvertRequestTypeSafely( | |
542 const RequestType& input, | |
543 UsbDeviceHandle::TransferRequestType* output) { | |
544 const bool converted = ConvertRequestTypeFromApi(input, output); | |
545 if (!converted) | |
546 SetError(kErrorConvertRequestType); | |
547 return converted; | |
548 } | |
549 | |
550 bool UsbAsyncApiTransferFunction::ConvertRecipientSafely( | |
551 const Recipient& input, | |
552 UsbDeviceHandle::TransferRecipient* output) { | |
553 const bool converted = ConvertRecipientFromApi(input, output); | |
554 if (!converted) | |
555 SetError(kErrorConvertRecipient); | |
556 return converted; | |
557 } | 479 } |
558 | 480 |
559 UsbFindDevicesFunction::UsbFindDevicesFunction() { | 481 UsbFindDevicesFunction::UsbFindDevicesFunction() { |
560 } | 482 } |
561 | 483 |
562 UsbFindDevicesFunction::~UsbFindDevicesFunction() { | 484 UsbFindDevicesFunction::~UsbFindDevicesFunction() { |
563 } | 485 } |
564 | 486 |
565 bool UsbFindDevicesFunction::Prepare() { | 487 ExtensionFunction::ResponseAction UsbFindDevicesFunction::Run() { |
566 parameters_ = FindDevices::Params::Create(*args_); | 488 scoped_ptr<extensions::core_api::usb::FindDevices::Params> parameters = |
567 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 489 FindDevices::Params::Create(*args_); |
568 return true; | 490 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
569 } | |
570 | 491 |
571 void UsbFindDevicesFunction::AsyncWorkStart() { | 492 vendor_id_ = parameters->options.vendor_id; |
572 scoped_ptr<base::ListValue> result(new base::ListValue()); | 493 product_id_ = parameters->options.product_id; |
573 const uint16_t vendor_id = parameters_->options.vendor_id; | 494 interface_id_ = parameters->options.interface_id.get() |
574 const uint16_t product_id = parameters_->options.product_id; | 495 ? *parameters->options.interface_id.get() |
575 int interface_id = parameters_->options.interface_id.get() | 496 : UsbDevicePermissionData::ANY_INTERFACE; |
576 ? *parameters_->options.interface_id.get() | 497 UsbDevicePermission::CheckParam param(vendor_id_, product_id_, interface_id_); |
577 : UsbDevicePermissionData::ANY_INTERFACE; | |
578 UsbDevicePermission::CheckParam param(vendor_id, product_id, interface_id); | |
579 if (!extension()->permissions_data()->CheckAPIPermissionWithParam( | 498 if (!extension()->permissions_data()->CheckAPIPermissionWithParam( |
580 APIPermission::kUsbDevice, ¶m)) { | 499 APIPermission::kUsbDevice, ¶m)) { |
581 LOG(WARNING) << "Insufficient permissions to access device."; | 500 return RespondNow(Error(kErrorPermissionDenied)); |
582 CompleteWithError(kErrorPermissionDenied); | |
583 return; | |
584 } | 501 } |
585 | 502 |
586 UsbService* service = device::DeviceClient::Get()->GetUsbService(); | 503 UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
587 if (!service) { | 504 if (!service) { |
588 CompleteWithError(kErrorInitService); | 505 return RespondNow(Error(kErrorInitService)); |
589 return; | |
590 } | 506 } |
591 | 507 |
592 ScopedDeviceVector devices(new DeviceVector()); | 508 service->GetDevices( |
593 service->GetDevices(devices.get()); | 509 base::Bind(&UsbFindDevicesFunction::OnGetDevicesComplete, this)); |
| 510 return RespondLater(); |
| 511 } |
594 | 512 |
595 for (DeviceVector::iterator it = devices->begin(); it != devices->end();) { | 513 void UsbFindDevicesFunction::OnGetDevicesComplete( |
596 if ((*it)->vendor_id() != vendor_id || (*it)->product_id() != product_id) { | 514 const std::vector<scoped_refptr<UsbDevice>>& devices) { |
597 it = devices->erase(it); | 515 result_.reset(new base::ListValue()); |
| 516 barrier_ = base::BarrierClosure( |
| 517 devices.size(), base::Bind(&UsbFindDevicesFunction::OpenComplete, this)); |
| 518 |
| 519 for (const scoped_refptr<UsbDevice>& device : devices) { |
| 520 if (device->vendor_id() != vendor_id_ || |
| 521 device->product_id() != product_id_) { |
| 522 barrier_.Run(); |
598 } else { | 523 } else { |
599 ++it; | 524 #if defined(OS_CHROMEOS) |
| 525 device->RequestUsbAccess( |
| 526 interface_id_, |
| 527 base::Bind(&UsbFindDevicesFunction::OnRequestAccessComplete, this, |
| 528 device)); |
| 529 #else |
| 530 device->Open(base::Bind(&UsbFindDevicesFunction::OnDeviceOpened, this)); |
| 531 #endif |
600 } | 532 } |
601 } | 533 } |
| 534 } |
602 | 535 |
603 #if defined(OS_CHROMEOS) | 536 #if defined(OS_CHROMEOS) |
604 RequestUsbDevicesAccess( | 537 |
605 devices.Pass(), | 538 void UsbFindDevicesFunction::OnRequestAccessComplete( |
606 interface_id, | 539 scoped_refptr<UsbDevice> device, |
607 base::Bind(&UsbFindDevicesFunction::OpenDevices, this)); | 540 bool success) { |
608 #else | 541 if (success) { |
609 OpenDevices(devices.Pass()); | 542 device->Open(base::Bind(&UsbFindDevicesFunction::OnDeviceOpened, this)); |
610 #endif // OS_CHROMEOS | 543 } else { |
| 544 barrier_.Run(); |
| 545 } |
611 } | 546 } |
612 | 547 |
613 void UsbFindDevicesFunction::OpenDevices(ScopedDeviceVector devices) { | 548 #endif // OS_CHROMEOS |
614 base::ListValue* result = new base::ListValue(); | |
615 | 549 |
616 for (size_t i = 0; i < devices->size(); ++i) { | 550 void UsbFindDevicesFunction::OnDeviceOpened( |
617 scoped_refptr<UsbDeviceHandle> device_handle = devices->at(i)->Open(); | 551 scoped_refptr<UsbDeviceHandle> device_handle) { |
618 if (device_handle.get()) | 552 if (device_handle.get()) { |
619 device_handles_.push_back(device_handle); | 553 ApiResourceManager<UsbDeviceResource>* manager = |
| 554 ApiResourceManager<UsbDeviceResource>::Get(browser_context()); |
| 555 UsbDeviceResource* resource = |
| 556 new UsbDeviceResource(extension_id(), device_handle); |
| 557 scoped_refptr<UsbDevice> device = device_handle->GetDevice(); |
| 558 result_->Append(PopulateConnectionHandle( |
| 559 manager->Add(resource), device->vendor_id(), device->product_id())); |
620 } | 560 } |
| 561 barrier_.Run(); |
| 562 } |
621 | 563 |
622 for (size_t i = 0; i < device_handles_.size(); ++i) { | 564 void UsbFindDevicesFunction::OpenComplete() { |
623 UsbDeviceHandle* const device_handle = device_handles_[i].get(); | 565 Respond(OneArgument(result_.release())); |
624 UsbDeviceResource* const resource = | |
625 new UsbDeviceResource(extension_->id(), device_handle); | |
626 | |
627 result->Append(PopulateConnectionHandle(manager_->Add(resource), | |
628 parameters_->options.vendor_id, | |
629 parameters_->options.product_id)); | |
630 } | |
631 | |
632 SetResult(result); | |
633 AsyncWorkCompleted(); | |
634 } | 566 } |
635 | 567 |
636 UsbGetDevicesFunction::UsbGetDevicesFunction() { | 568 UsbGetDevicesFunction::UsbGetDevicesFunction() { |
637 } | 569 } |
638 | 570 |
639 UsbGetDevicesFunction::~UsbGetDevicesFunction() { | 571 UsbGetDevicesFunction::~UsbGetDevicesFunction() { |
640 } | 572 } |
641 | 573 |
642 bool UsbGetDevicesFunction::Prepare() { | 574 ExtensionFunction::ResponseAction UsbGetDevicesFunction::Run() { |
643 parameters_ = GetDevices::Params::Create(*args_); | 575 scoped_ptr<extensions::core_api::usb::GetDevices::Params> parameters = |
644 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 576 GetDevices::Params::Create(*args_); |
645 device_permissions_ = DevicePermissionsManager::Get(browser_context()) | 577 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
646 ->GetForExtension(extension()->id()); | |
647 return true; | |
648 } | |
649 | 578 |
650 void UsbGetDevicesFunction::AsyncWorkStart() { | 579 if (parameters->options.filters) { |
651 std::vector<UsbDeviceFilter> filters; | 580 filters_.resize(parameters->options.filters->size()); |
652 if (parameters_->options.filters) { | 581 for (size_t i = 0; i < parameters->options.filters->size(); ++i) { |
653 filters.resize(parameters_->options.filters->size()); | 582 ConvertDeviceFilter(*parameters->options.filters->at(i).get(), |
654 for (size_t i = 0; i < parameters_->options.filters->size(); ++i) { | 583 &filters_[i]); |
655 ConvertDeviceFilter(*parameters_->options.filters->at(i).get(), | |
656 &filters[i]); | |
657 } | 584 } |
658 } | 585 } |
659 if (parameters_->options.vendor_id) { | 586 if (parameters->options.vendor_id) { |
660 filters.resize(filters.size() + 1); | 587 filters_.resize(filters_.size() + 1); |
661 filters.back().SetVendorId(*parameters_->options.vendor_id); | 588 filters_.back().SetVendorId(*parameters->options.vendor_id); |
662 if (parameters_->options.product_id) { | 589 if (parameters->options.product_id) { |
663 filters.back().SetProductId(*parameters_->options.product_id); | 590 filters_.back().SetProductId(*parameters->options.product_id); |
664 } | 591 } |
665 } | 592 } |
666 | 593 |
667 UsbService* service = device::DeviceClient::Get()->GetUsbService(); | 594 UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
668 if (!service) { | 595 if (!service) { |
669 CompleteWithError(kErrorInitService); | 596 return RespondNow(Error(kErrorInitService)); |
670 return; | |
671 } | 597 } |
672 | 598 |
673 DeviceVector devices; | 599 service->GetDevices( |
674 service->GetDevices(&devices); | 600 base::Bind(&UsbGetDevicesFunction::OnGetDevicesComplete, this)); |
| 601 return RespondLater(); |
| 602 } |
675 | 603 |
| 604 void UsbGetDevicesFunction::OnGetDevicesComplete( |
| 605 const std::vector<scoped_refptr<UsbDevice>>& devices) { |
676 scoped_ptr<base::ListValue> result(new base::ListValue()); | 606 scoped_ptr<base::ListValue> result(new base::ListValue()); |
677 for (DeviceVector::iterator it = devices.begin(); it != devices.end(); ++it) { | 607 for (const scoped_refptr<UsbDevice>& device : devices) { |
678 scoped_refptr<UsbDevice> device = *it; | 608 if ((filters_.empty() || UsbDeviceFilter::MatchesAny(device, filters_)) && |
679 if ((filters.empty() || UsbDeviceFilter::MatchesAny(device, filters)) && | |
680 HasDevicePermission(device)) { | 609 HasDevicePermission(device)) { |
681 result->Append(PopulateDevice(it->get())); | 610 result->Append(PopulateDevice(device.get())); |
682 } | 611 } |
683 } | 612 } |
684 | 613 |
685 SetResult(result.release()); | 614 Respond(OneArgument(result.release())); |
686 AsyncWorkCompleted(); | |
687 } | 615 } |
688 | 616 |
689 UsbGetUserSelectedDevicesFunction::UsbGetUserSelectedDevicesFunction() { | 617 UsbGetUserSelectedDevicesFunction::UsbGetUserSelectedDevicesFunction() { |
690 } | 618 } |
691 | 619 |
692 UsbGetUserSelectedDevicesFunction::~UsbGetUserSelectedDevicesFunction() { | 620 UsbGetUserSelectedDevicesFunction::~UsbGetUserSelectedDevicesFunction() { |
693 } | 621 } |
694 | 622 |
695 AsyncApiFunction::ResponseAction UsbGetUserSelectedDevicesFunction::Run() { | 623 ExtensionFunction::ResponseAction UsbGetUserSelectedDevicesFunction::Run() { |
696 scoped_ptr<extensions::core_api::usb::GetUserSelectedDevices::Params> | 624 scoped_ptr<extensions::core_api::usb::GetUserSelectedDevices::Params> |
697 parameters = GetUserSelectedDevices::Params::Create(*args_); | 625 parameters = GetUserSelectedDevices::Params::Create(*args_); |
698 EXTENSION_FUNCTION_VALIDATE(parameters.get()); | 626 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
699 | 627 |
700 if (!user_gesture()) { | 628 if (!user_gesture()) { |
701 return RespondNow(OneArgument(new base::ListValue())); | 629 return RespondNow(OneArgument(new base::ListValue())); |
702 } | 630 } |
703 | 631 |
704 bool multiple = false; | 632 bool multiple = false; |
705 if (parameters->options.multiple) { | 633 if (parameters->options.multiple) { |
(...skipping 21 matching lines...) Expand all Loading... |
727 return RespondLater(); | 655 return RespondLater(); |
728 } | 656 } |
729 | 657 |
730 void UsbGetUserSelectedDevicesFunction::OnUsbDevicesChosen( | 658 void UsbGetUserSelectedDevicesFunction::OnUsbDevicesChosen( |
731 const std::vector<scoped_refptr<UsbDevice>>& devices) { | 659 const std::vector<scoped_refptr<UsbDevice>>& devices) { |
732 scoped_ptr<base::ListValue> result(new base::ListValue()); | 660 scoped_ptr<base::ListValue> result(new base::ListValue()); |
733 for (const auto& device : devices) { | 661 for (const auto& device : devices) { |
734 result->Append(PopulateDevice(device.get())); | 662 result->Append(PopulateDevice(device.get())); |
735 } | 663 } |
736 | 664 |
737 SetResult(result.release()); | 665 Respond(OneArgument(result.release())); |
738 SendResponse(true); | |
739 Release(); | 666 Release(); |
740 } | 667 } |
741 | 668 |
742 UsbRequestAccessFunction::UsbRequestAccessFunction() { | 669 UsbRequestAccessFunction::UsbRequestAccessFunction() { |
743 } | 670 } |
744 | 671 |
745 UsbRequestAccessFunction::~UsbRequestAccessFunction() { | 672 UsbRequestAccessFunction::~UsbRequestAccessFunction() { |
746 } | 673 } |
747 | 674 |
748 bool UsbRequestAccessFunction::Prepare() { | 675 ExtensionFunction::ResponseAction UsbRequestAccessFunction::Run() { |
749 parameters_ = RequestAccess::Params::Create(*args_); | 676 scoped_ptr<extensions::core_api::usb::RequestAccess::Params> parameters = |
750 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 677 RequestAccess::Params::Create(*args_); |
751 return true; | 678 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
752 } | 679 return RespondNow(OneArgument(new base::FundamentalValue(true))); |
753 | |
754 void UsbRequestAccessFunction::AsyncWorkStart() { | |
755 SetResult(new base::FundamentalValue(true)); | |
756 AsyncWorkCompleted(); | |
757 } | 680 } |
758 | 681 |
759 UsbOpenDeviceFunction::UsbOpenDeviceFunction() { | 682 UsbOpenDeviceFunction::UsbOpenDeviceFunction() { |
760 } | 683 } |
761 | 684 |
762 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() { | 685 UsbOpenDeviceFunction::~UsbOpenDeviceFunction() { |
763 } | 686 } |
764 | 687 |
765 bool UsbOpenDeviceFunction::Prepare() { | 688 ExtensionFunction::ResponseAction UsbOpenDeviceFunction::Run() { |
766 parameters_ = OpenDevice::Params::Create(*args_); | 689 scoped_ptr<extensions::core_api::usb::OpenDevice::Params> parameters = |
767 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 690 OpenDevice::Params::Create(*args_); |
768 device_permissions_manager_ = | 691 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
769 DevicePermissionsManager::Get(browser_context()); | 692 |
770 device_permissions_ = | 693 UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
771 device_permissions_manager_->GetForExtension(extension()->id()); | 694 if (!service) { |
772 return true; | 695 return RespondNow(Error(kErrorInitService)); |
| 696 } |
| 697 |
| 698 scoped_refptr<UsbDevice> device = |
| 699 service->GetDeviceById(parameters->device.device); |
| 700 if (!device.get()) { |
| 701 return RespondNow(Error(kErrorNoDevice)); |
| 702 } |
| 703 |
| 704 if (!HasDevicePermission(device)) { |
| 705 // This function must act as if there is no such device. Otherwise it can be |
| 706 // used to fingerprint unauthorized devices. |
| 707 return RespondNow(Error(kErrorNoDevice)); |
| 708 } |
| 709 |
| 710 #if defined(OS_CHROMEOS) |
| 711 device->RequestUsbAccess( |
| 712 -1, /* any interface, unused by the permission broker */ |
| 713 base::Bind(&UsbOpenDeviceFunction::OnRequestAccessComplete, this, |
| 714 device)); |
| 715 #else |
| 716 device->Open(base::Bind(&UsbOpenDeviceFunction::OnDeviceOpened, this)); |
| 717 #endif // OS_CHROMEOS |
| 718 |
| 719 return RespondLater(); |
773 } | 720 } |
774 | 721 |
775 void UsbOpenDeviceFunction::AsyncWorkStart() { | 722 void UsbOpenDeviceFunction::OnRequestAccessComplete( |
776 UsbService* service = device::DeviceClient::Get()->GetUsbService(); | 723 scoped_refptr<UsbDevice> device, |
777 if (!service) { | 724 bool success) { |
778 CompleteWithError(kErrorInitService); | 725 if (success) { |
| 726 device->Open(base::Bind(&UsbOpenDeviceFunction::OnDeviceOpened, this)); |
| 727 } else { |
| 728 Respond(Error(kErrorPermissionDenied)); |
| 729 } |
| 730 } |
| 731 |
| 732 void UsbOpenDeviceFunction::OnDeviceOpened( |
| 733 scoped_refptr<UsbDeviceHandle> device_handle) { |
| 734 if (!device_handle.get()) { |
| 735 Respond(Error(kErrorOpen)); |
779 return; | 736 return; |
780 } | 737 } |
781 | 738 |
782 device_ = service->GetDeviceById(parameters_->device.device); | 739 RecordDeviceLastUsed(); |
783 if (!device_.get()) { | |
784 CompleteWithError(kErrorNoDevice); | |
785 return; | |
786 } | |
787 | 740 |
788 if (!HasDevicePermission(device_)) { | 741 ApiResourceManager<UsbDeviceResource>* manager = |
789 // This function must act as if there is no such device. Otherwise it can be | 742 ApiResourceManager<UsbDeviceResource>::Get(browser_context()); |
790 // used to fingerprint unauthorized devices. | 743 scoped_refptr<UsbDevice> device = device_handle->GetDevice(); |
791 CompleteWithError(kErrorNoDevice); | 744 Respond(OneArgument(PopulateConnectionHandle( |
792 return; | 745 manager->Add(new UsbDeviceResource(extension_id(), device_handle)), |
793 } | 746 device->vendor_id(), device->product_id()))); |
794 | |
795 #if defined(OS_CHROMEOS) | |
796 device_->RequestUsbAccess( | |
797 -1, /* any interface, unused by the permission broker */ | |
798 base::Bind(&UsbOpenDeviceFunction::OnRequestAccessComplete, this)); | |
799 #else | |
800 OnRequestAccessComplete(true); | |
801 #endif // OS_CHROMEOS | |
802 } | |
803 | |
804 void UsbOpenDeviceFunction::OnRequestAccessComplete(bool success) { | |
805 if (!success) { | |
806 SetError(kErrorPermissionDenied); | |
807 AsyncWorkCompleted(); | |
808 return; | |
809 } | |
810 | |
811 scoped_refptr<UsbDeviceHandle> handle = device_->Open(); | |
812 if (!handle.get()) { | |
813 SetError(kErrorOpen); | |
814 AsyncWorkCompleted(); | |
815 return; | |
816 } | |
817 | |
818 SetResult(PopulateConnectionHandle( | |
819 manager_->Add(new UsbDeviceResource(extension_->id(), handle)), | |
820 device_->vendor_id(), device_->product_id())); | |
821 AsyncWorkCompleted(); | |
822 } | |
823 | |
824 bool UsbOpenDeviceFunction::Respond() { | |
825 if (permission_entry_.get()) { | |
826 device_permissions_manager_->UpdateLastUsed(extension_->id(), | |
827 permission_entry_); | |
828 } | |
829 return UsbAsyncApiFunction::Respond(); | |
830 } | 747 } |
831 | 748 |
832 UsbSetConfigurationFunction::UsbSetConfigurationFunction() { | 749 UsbSetConfigurationFunction::UsbSetConfigurationFunction() { |
833 } | 750 } |
834 | 751 |
835 UsbSetConfigurationFunction::~UsbSetConfigurationFunction() { | 752 UsbSetConfigurationFunction::~UsbSetConfigurationFunction() { |
836 } | 753 } |
837 | 754 |
838 bool UsbSetConfigurationFunction::Prepare() { | 755 ExtensionFunction::ResponseAction UsbSetConfigurationFunction::Run() { |
839 parameters_ = SetConfiguration::Params::Create(*args_); | 756 scoped_ptr<extensions::core_api::usb::SetConfiguration::Params> parameters = |
840 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 757 SetConfiguration::Params::Create(*args_); |
841 return true; | 758 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
| 759 |
| 760 scoped_refptr<UsbDeviceHandle> device_handle = |
| 761 GetDeviceHandle(parameters->handle); |
| 762 if (!device_handle.get()) { |
| 763 return RespondNow(Error(kErrorNoConnection)); |
| 764 } |
| 765 |
| 766 device_handle->SetConfiguration( |
| 767 parameters->configuration_value, |
| 768 base::Bind(&UsbSetConfigurationFunction::OnComplete, this)); |
| 769 return RespondLater(); |
842 } | 770 } |
843 | 771 |
844 void UsbSetConfigurationFunction::AsyncWorkStart() { | 772 void UsbSetConfigurationFunction::OnComplete(bool success) { |
845 scoped_refptr<UsbDeviceHandle> device_handle = | 773 if (success) { |
846 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 774 Respond(NoArguments()); |
847 if (!device_handle.get()) { | 775 } else { |
848 return; | 776 Respond(Error(kErrorCannotSetConfiguration)); |
849 } | 777 } |
850 | |
851 if (!device_handle->SetConfiguration(parameters_->configuration_value)) { | |
852 SetError(kErrorCannotSetConfiguration); | |
853 } | |
854 AsyncWorkCompleted(); | |
855 } | 778 } |
856 | 779 |
857 UsbGetConfigurationFunction::UsbGetConfigurationFunction() { | 780 UsbGetConfigurationFunction::UsbGetConfigurationFunction() { |
858 } | 781 } |
859 | 782 |
860 UsbGetConfigurationFunction::~UsbGetConfigurationFunction() { | 783 UsbGetConfigurationFunction::~UsbGetConfigurationFunction() { |
861 } | 784 } |
862 | 785 |
863 bool UsbGetConfigurationFunction::Prepare() { | 786 ExtensionFunction::ResponseAction UsbGetConfigurationFunction::Run() { |
864 parameters_ = GetConfiguration::Params::Create(*args_); | 787 scoped_ptr<extensions::core_api::usb::GetConfiguration::Params> parameters = |
865 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 788 GetConfiguration::Params::Create(*args_); |
866 return true; | 789 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
867 } | |
868 | 790 |
869 void UsbGetConfigurationFunction::AsyncWorkStart() { | |
870 scoped_refptr<UsbDeviceHandle> device_handle = | 791 scoped_refptr<UsbDeviceHandle> device_handle = |
871 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 792 GetDeviceHandle(parameters->handle); |
872 if (!device_handle.get()) { | 793 if (!device_handle.get()) { |
873 return; | 794 return RespondNow(Error(kErrorNoConnection)); |
874 } | 795 } |
875 | 796 |
876 const UsbConfigDescriptor* config_descriptor = | 797 const UsbConfigDescriptor* config_descriptor = |
877 device_handle->GetDevice()->GetConfiguration(); | 798 device_handle->GetDevice()->GetConfiguration(); |
878 if (config_descriptor) { | 799 if (config_descriptor) { |
879 ConfigDescriptor config; | 800 ConfigDescriptor config; |
880 ConvertConfigDescriptor(*config_descriptor, &config); | 801 ConvertConfigDescriptor(*config_descriptor, &config); |
881 SetResult(config.ToValue().release()); | 802 return RespondNow(OneArgument(config.ToValue().release())); |
882 } else { | 803 } else { |
883 SetError(kErrorNotConfigured); | 804 return RespondNow(Error(kErrorNotConfigured)); |
884 } | 805 } |
885 | |
886 AsyncWorkCompleted(); | |
887 } | 806 } |
888 | 807 |
889 UsbListInterfacesFunction::UsbListInterfacesFunction() { | 808 UsbListInterfacesFunction::UsbListInterfacesFunction() { |
890 } | 809 } |
891 | 810 |
892 UsbListInterfacesFunction::~UsbListInterfacesFunction() { | 811 UsbListInterfacesFunction::~UsbListInterfacesFunction() { |
893 } | 812 } |
894 | 813 |
895 bool UsbListInterfacesFunction::Prepare() { | 814 ExtensionFunction::ResponseAction UsbListInterfacesFunction::Run() { |
896 parameters_ = ListInterfaces::Params::Create(*args_); | 815 scoped_ptr<extensions::core_api::usb::ListInterfaces::Params> parameters = |
897 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 816 ListInterfaces::Params::Create(*args_); |
898 return true; | 817 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
899 } | |
900 | 818 |
901 void UsbListInterfacesFunction::AsyncWorkStart() { | |
902 scoped_refptr<UsbDeviceHandle> device_handle = | 819 scoped_refptr<UsbDeviceHandle> device_handle = |
903 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 820 GetDeviceHandle(parameters->handle); |
904 if (!device_handle.get()) { | 821 if (!device_handle.get()) { |
905 return; | 822 return RespondNow(Error(kErrorNoConnection)); |
906 } | 823 } |
907 | 824 |
908 const UsbConfigDescriptor* config_descriptor = | 825 const UsbConfigDescriptor* config_descriptor = |
909 device_handle->GetDevice()->GetConfiguration(); | 826 device_handle->GetDevice()->GetConfiguration(); |
910 if (config_descriptor) { | 827 if (config_descriptor) { |
911 ConfigDescriptor config; | 828 ConfigDescriptor config; |
912 ConvertConfigDescriptor(*config_descriptor, &config); | 829 ConvertConfigDescriptor(*config_descriptor, &config); |
913 | 830 |
914 scoped_ptr<base::ListValue> result(new base::ListValue); | 831 scoped_ptr<base::ListValue> result(new base::ListValue); |
915 for (size_t i = 0; i < config.interfaces.size(); ++i) { | 832 for (size_t i = 0; i < config.interfaces.size(); ++i) { |
916 result->Append(config.interfaces[i]->ToValue().release()); | 833 result->Append(config.interfaces[i]->ToValue().release()); |
917 } | 834 } |
918 | 835 |
919 SetResult(result.release()); | 836 return RespondNow(OneArgument(result.release())); |
920 } else { | 837 } else { |
921 SetError(kErrorNotConfigured); | 838 return RespondNow(Error(kErrorNotConfigured)); |
922 } | 839 } |
923 | |
924 AsyncWorkCompleted(); | |
925 } | 840 } |
926 | 841 |
927 UsbCloseDeviceFunction::UsbCloseDeviceFunction() { | 842 UsbCloseDeviceFunction::UsbCloseDeviceFunction() { |
928 } | 843 } |
929 | 844 |
930 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() { | 845 UsbCloseDeviceFunction::~UsbCloseDeviceFunction() { |
931 } | 846 } |
932 | 847 |
933 bool UsbCloseDeviceFunction::Prepare() { | 848 ExtensionFunction::ResponseAction UsbCloseDeviceFunction::Run() { |
934 parameters_ = CloseDevice::Params::Create(*args_); | 849 scoped_ptr<extensions::core_api::usb::CloseDevice::Params> parameters = |
935 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 850 CloseDevice::Params::Create(*args_); |
936 return true; | 851 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
937 } | |
938 | 852 |
939 void UsbCloseDeviceFunction::AsyncWorkStart() { | |
940 scoped_refptr<UsbDeviceHandle> device_handle = | 853 scoped_refptr<UsbDeviceHandle> device_handle = |
941 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 854 GetDeviceHandle(parameters->handle); |
942 if (!device_handle.get()) | 855 if (!device_handle.get()) { |
943 return; | 856 return RespondNow(Error(kErrorNoConnection)); |
| 857 } |
944 | 858 |
945 // The device handle is closed when the resource is destroyed. | 859 // The device handle is closed when the resource is destroyed. |
946 RemoveUsbDeviceResource(parameters_->handle.handle); | 860 ReleaseDeviceHandle(parameters->handle); |
947 AsyncWorkCompleted(); | 861 return RespondNow(NoArguments()); |
948 } | 862 } |
949 | 863 |
950 UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() { | 864 UsbClaimInterfaceFunction::UsbClaimInterfaceFunction() { |
951 } | 865 } |
952 | 866 |
953 UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() { | 867 UsbClaimInterfaceFunction::~UsbClaimInterfaceFunction() { |
954 } | 868 } |
955 | 869 |
956 bool UsbClaimInterfaceFunction::Prepare() { | 870 ExtensionFunction::ResponseAction UsbClaimInterfaceFunction::Run() { |
957 parameters_ = ClaimInterface::Params::Create(*args_); | 871 scoped_ptr<extensions::core_api::usb::ClaimInterface::Params> parameters = |
958 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 872 ClaimInterface::Params::Create(*args_); |
959 return true; | 873 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
| 874 |
| 875 scoped_refptr<UsbDeviceHandle> device_handle = |
| 876 GetDeviceHandle(parameters->handle); |
| 877 if (!device_handle.get()) { |
| 878 return RespondNow(Error(kErrorNoConnection)); |
| 879 } |
| 880 |
| 881 device_handle->ClaimInterface( |
| 882 parameters->interface_number, |
| 883 base::Bind(&UsbClaimInterfaceFunction::OnComplete, this)); |
| 884 return RespondLater(); |
960 } | 885 } |
961 | 886 |
962 void UsbClaimInterfaceFunction::AsyncWorkStart() { | 887 void UsbClaimInterfaceFunction::OnComplete(bool success) { |
963 scoped_refptr<UsbDeviceHandle> device_handle = | 888 if (success) { |
964 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 889 Respond(NoArguments()); |
965 if (!device_handle.get()) | 890 } else { |
966 return; | 891 Respond(Error(kErrorCannotClaimInterface)); |
967 | 892 } |
968 bool success = device_handle->ClaimInterface(parameters_->interface_number); | |
969 | |
970 if (!success) | |
971 SetError(kErrorCannotClaimInterface); | |
972 AsyncWorkCompleted(); | |
973 } | 893 } |
974 | 894 |
975 UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() { | 895 UsbReleaseInterfaceFunction::UsbReleaseInterfaceFunction() { |
976 } | 896 } |
977 | 897 |
978 UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() { | 898 UsbReleaseInterfaceFunction::~UsbReleaseInterfaceFunction() { |
979 } | 899 } |
980 | 900 |
981 bool UsbReleaseInterfaceFunction::Prepare() { | 901 ExtensionFunction::ResponseAction UsbReleaseInterfaceFunction::Run() { |
982 parameters_ = ReleaseInterface::Params::Create(*args_); | 902 scoped_ptr<extensions::core_api::usb::ReleaseInterface::Params> parameters = |
983 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 903 ReleaseInterface::Params::Create(*args_); |
984 return true; | 904 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
985 } | |
986 | 905 |
987 void UsbReleaseInterfaceFunction::AsyncWorkStart() { | |
988 scoped_refptr<UsbDeviceHandle> device_handle = | 906 scoped_refptr<UsbDeviceHandle> device_handle = |
989 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 907 GetDeviceHandle(parameters->handle); |
990 if (!device_handle.get()) | 908 if (!device_handle.get()) { |
991 return; | 909 return RespondNow(Error(kErrorNoConnection)); |
| 910 } |
992 | 911 |
993 bool success = device_handle->ReleaseInterface(parameters_->interface_number); | 912 if (device_handle->ReleaseInterface(parameters->interface_number)) { |
994 if (!success) | 913 return RespondNow(NoArguments()); |
995 SetError(kErrorCannotReleaseInterface); | 914 } else { |
996 AsyncWorkCompleted(); | 915 return RespondNow(Error(kErrorCannotReleaseInterface)); |
| 916 } |
997 } | 917 } |
998 | 918 |
999 UsbSetInterfaceAlternateSettingFunction:: | 919 UsbSetInterfaceAlternateSettingFunction:: |
1000 UsbSetInterfaceAlternateSettingFunction() { | 920 UsbSetInterfaceAlternateSettingFunction() { |
1001 } | 921 } |
1002 | 922 |
1003 UsbSetInterfaceAlternateSettingFunction:: | 923 UsbSetInterfaceAlternateSettingFunction:: |
1004 ~UsbSetInterfaceAlternateSettingFunction() { | 924 ~UsbSetInterfaceAlternateSettingFunction() { |
1005 } | 925 } |
1006 | 926 |
1007 bool UsbSetInterfaceAlternateSettingFunction::Prepare() { | 927 ExtensionFunction::ResponseAction |
1008 parameters_ = SetInterfaceAlternateSetting::Params::Create(*args_); | 928 UsbSetInterfaceAlternateSettingFunction::Run() { |
1009 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 929 scoped_ptr<extensions::core_api::usb::SetInterfaceAlternateSetting::Params> |
1010 return true; | 930 parameters = SetInterfaceAlternateSetting::Params::Create(*args_); |
| 931 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
| 932 |
| 933 scoped_refptr<UsbDeviceHandle> device_handle = |
| 934 GetDeviceHandle(parameters->handle); |
| 935 if (!device_handle.get()) { |
| 936 return RespondNow(Error(kErrorNoConnection)); |
| 937 } |
| 938 |
| 939 device_handle->SetInterfaceAlternateSetting( |
| 940 parameters->interface_number, parameters->alternate_setting, |
| 941 base::Bind(&UsbSetInterfaceAlternateSettingFunction::OnComplete, this)); |
| 942 return RespondLater(); |
1011 } | 943 } |
1012 | 944 |
1013 void UsbSetInterfaceAlternateSettingFunction::AsyncWorkStart() { | 945 void UsbSetInterfaceAlternateSettingFunction::OnComplete(bool success) { |
1014 scoped_refptr<UsbDeviceHandle> device_handle = | 946 if (success) { |
1015 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 947 Respond(NoArguments()); |
1016 if (!device_handle.get()) | 948 } else { |
1017 return; | 949 Respond(Error(kErrorCannotSetInterfaceAlternateSetting)); |
1018 | 950 } |
1019 bool success = device_handle->SetInterfaceAlternateSetting( | |
1020 parameters_->interface_number, parameters_->alternate_setting); | |
1021 if (!success) | |
1022 SetError(kErrorCannotSetInterfaceAlternateSetting); | |
1023 | |
1024 AsyncWorkCompleted(); | |
1025 } | 951 } |
1026 | 952 |
1027 UsbControlTransferFunction::UsbControlTransferFunction() { | 953 UsbControlTransferFunction::UsbControlTransferFunction() { |
1028 } | 954 } |
1029 | 955 |
1030 UsbControlTransferFunction::~UsbControlTransferFunction() { | 956 UsbControlTransferFunction::~UsbControlTransferFunction() { |
1031 } | 957 } |
1032 | 958 |
1033 bool UsbControlTransferFunction::Prepare() { | 959 ExtensionFunction::ResponseAction UsbControlTransferFunction::Run() { |
1034 parameters_ = ControlTransfer::Params::Create(*args_); | 960 scoped_ptr<extensions::core_api::usb::ControlTransfer::Params> parameters = |
1035 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 961 ControlTransfer::Params::Create(*args_); |
1036 return true; | 962 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
1037 } | |
1038 | 963 |
1039 void UsbControlTransferFunction::AsyncWorkStart() { | |
1040 scoped_refptr<UsbDeviceHandle> device_handle = | 964 scoped_refptr<UsbDeviceHandle> device_handle = |
1041 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 965 GetDeviceHandle(parameters->handle); |
1042 if (!device_handle.get()) | 966 if (!device_handle.get()) { |
1043 return; | 967 return RespondNow(Error(kErrorNoConnection)); |
| 968 } |
1044 | 969 |
1045 const ControlTransferInfo& transfer = parameters_->transfer_info; | 970 const ControlTransferInfo& transfer = parameters->transfer_info; |
1046 | |
1047 UsbEndpointDirection direction; | 971 UsbEndpointDirection direction; |
1048 UsbDeviceHandle::TransferRequestType request_type; | 972 UsbDeviceHandle::TransferRequestType request_type; |
1049 UsbDeviceHandle::TransferRecipient recipient; | 973 UsbDeviceHandle::TransferRecipient recipient; |
1050 size_t size = 0; | 974 size_t size = 0; |
1051 | 975 |
1052 if (!ConvertDirectionSafely(transfer.direction, &direction) || | 976 if (!ConvertDirectionFromApi(transfer.direction, &direction)) { |
1053 !ConvertRequestTypeSafely(transfer.request_type, &request_type) || | 977 return RespondNow(Error(kErrorConvertDirection)); |
1054 !ConvertRecipientSafely(transfer.recipient, &recipient)) { | 978 } |
1055 AsyncWorkCompleted(); | 979 |
1056 return; | 980 if (!ConvertRequestTypeFromApi(transfer.request_type, &request_type)) { |
| 981 return RespondNow(Error(kErrorConvertRequestType)); |
| 982 } |
| 983 |
| 984 if (!ConvertRecipientFromApi(transfer.recipient, &recipient)) { |
| 985 return RespondNow(Error(kErrorConvertRecipient)); |
1057 } | 986 } |
1058 | 987 |
1059 if (!GetTransferSize(transfer, &size)) { | 988 if (!GetTransferSize(transfer, &size)) { |
1060 CompleteWithError(kErrorInvalidTransferLength); | 989 return RespondNow(Error(kErrorInvalidTransferLength)); |
1061 return; | |
1062 } | 990 } |
1063 | 991 |
1064 scoped_refptr<net::IOBuffer> buffer = | 992 scoped_refptr<net::IOBuffer> buffer = |
1065 CreateBufferForTransfer(transfer, direction, size); | 993 CreateBufferForTransfer(transfer, direction, size); |
1066 if (!buffer.get()) { | 994 if (!buffer.get()) { |
1067 CompleteWithError(kErrorMalformedParameters); | 995 return RespondNow(Error(kErrorMalformedParameters)); |
1068 return; | |
1069 } | 996 } |
1070 | 997 |
1071 int timeout = transfer.timeout ? *transfer.timeout : 0; | 998 int timeout = transfer.timeout ? *transfer.timeout : 0; |
1072 if (timeout < 0) { | 999 if (timeout < 0) { |
1073 CompleteWithError(kErrorInvalidTimeout); | 1000 return RespondNow(Error(kErrorInvalidTimeout)); |
1074 return; | |
1075 } | 1001 } |
1076 | 1002 |
1077 device_handle->ControlTransfer( | 1003 device_handle->ControlTransfer( |
1078 direction, request_type, recipient, transfer.request, transfer.value, | 1004 direction, request_type, recipient, transfer.request, transfer.value, |
1079 transfer.index, buffer.get(), size, timeout, | 1005 transfer.index, buffer.get(), size, timeout, |
1080 base::Bind(&UsbControlTransferFunction::OnCompleted, this)); | 1006 base::Bind(&UsbControlTransferFunction::OnCompleted, this)); |
| 1007 return RespondLater(); |
1081 } | 1008 } |
1082 | 1009 |
1083 UsbBulkTransferFunction::UsbBulkTransferFunction() { | 1010 UsbBulkTransferFunction::UsbBulkTransferFunction() { |
1084 } | 1011 } |
1085 | 1012 |
1086 UsbBulkTransferFunction::~UsbBulkTransferFunction() { | 1013 UsbBulkTransferFunction::~UsbBulkTransferFunction() { |
1087 } | 1014 } |
1088 | 1015 |
1089 bool UsbBulkTransferFunction::Prepare() { | 1016 ExtensionFunction::ResponseAction UsbBulkTransferFunction::Run() { |
1090 parameters_ = BulkTransfer::Params::Create(*args_); | 1017 scoped_ptr<extensions::core_api::usb::BulkTransfer::Params> parameters = |
1091 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 1018 BulkTransfer::Params::Create(*args_); |
1092 return true; | 1019 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
1093 } | |
1094 | 1020 |
1095 void UsbBulkTransferFunction::AsyncWorkStart() { | |
1096 scoped_refptr<UsbDeviceHandle> device_handle = | 1021 scoped_refptr<UsbDeviceHandle> device_handle = |
1097 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 1022 GetDeviceHandle(parameters->handle); |
1098 if (!device_handle.get()) | 1023 if (!device_handle.get()) { |
1099 return; | 1024 return RespondNow(Error(kErrorNoConnection)); |
| 1025 } |
1100 | 1026 |
1101 const GenericTransferInfo& transfer = parameters_->transfer_info; | 1027 const GenericTransferInfo& transfer = parameters->transfer_info; |
1102 | |
1103 UsbEndpointDirection direction; | 1028 UsbEndpointDirection direction; |
1104 size_t size = 0; | 1029 size_t size = 0; |
1105 | 1030 |
1106 if (!ConvertDirectionSafely(transfer.direction, &direction)) { | 1031 if (!ConvertDirectionFromApi(transfer.direction, &direction)) { |
1107 AsyncWorkCompleted(); | 1032 return RespondNow(Error(kErrorConvertDirection)); |
1108 return; | |
1109 } | 1033 } |
1110 | 1034 |
1111 if (!GetTransferSize(transfer, &size)) { | 1035 if (!GetTransferSize(transfer, &size)) { |
1112 CompleteWithError(kErrorInvalidTransferLength); | 1036 return RespondNow(Error(kErrorInvalidTransferLength)); |
1113 return; | |
1114 } | 1037 } |
1115 | 1038 |
1116 scoped_refptr<net::IOBuffer> buffer = | 1039 scoped_refptr<net::IOBuffer> buffer = |
1117 CreateBufferForTransfer(transfer, direction, size); | 1040 CreateBufferForTransfer(transfer, direction, size); |
1118 if (!buffer.get()) { | 1041 if (!buffer.get()) { |
1119 CompleteWithError(kErrorMalformedParameters); | 1042 return RespondNow(Error(kErrorMalformedParameters)); |
1120 return; | |
1121 } | 1043 } |
1122 | 1044 |
1123 int timeout = transfer.timeout ? *transfer.timeout : 0; | 1045 int timeout = transfer.timeout ? *transfer.timeout : 0; |
1124 if (timeout < 0) { | 1046 if (timeout < 0) { |
1125 CompleteWithError(kErrorInvalidTimeout); | 1047 return RespondNow(Error(kErrorInvalidTimeout)); |
1126 return; | |
1127 } | 1048 } |
1128 | 1049 |
1129 device_handle->BulkTransfer( | 1050 device_handle->BulkTransfer( |
1130 direction, transfer.endpoint, buffer.get(), size, timeout, | 1051 direction, transfer.endpoint, buffer.get(), size, timeout, |
1131 base::Bind(&UsbBulkTransferFunction::OnCompleted, this)); | 1052 base::Bind(&UsbBulkTransferFunction::OnCompleted, this)); |
| 1053 return RespondLater(); |
1132 } | 1054 } |
1133 | 1055 |
1134 UsbInterruptTransferFunction::UsbInterruptTransferFunction() { | 1056 UsbInterruptTransferFunction::UsbInterruptTransferFunction() { |
1135 } | 1057 } |
1136 | 1058 |
1137 UsbInterruptTransferFunction::~UsbInterruptTransferFunction() { | 1059 UsbInterruptTransferFunction::~UsbInterruptTransferFunction() { |
1138 } | 1060 } |
1139 | 1061 |
1140 bool UsbInterruptTransferFunction::Prepare() { | 1062 ExtensionFunction::ResponseAction UsbInterruptTransferFunction::Run() { |
1141 parameters_ = InterruptTransfer::Params::Create(*args_); | 1063 scoped_ptr<extensions::core_api::usb::InterruptTransfer::Params> parameters = |
1142 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 1064 InterruptTransfer::Params::Create(*args_); |
1143 return true; | 1065 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
1144 } | |
1145 | 1066 |
1146 void UsbInterruptTransferFunction::AsyncWorkStart() { | |
1147 scoped_refptr<UsbDeviceHandle> device_handle = | 1067 scoped_refptr<UsbDeviceHandle> device_handle = |
1148 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 1068 GetDeviceHandle(parameters->handle); |
1149 if (!device_handle.get()) | 1069 if (!device_handle.get()) { |
1150 return; | 1070 return RespondNow(Error(kErrorNoConnection)); |
| 1071 } |
1151 | 1072 |
1152 const GenericTransferInfo& transfer = parameters_->transfer_info; | 1073 const GenericTransferInfo& transfer = parameters->transfer_info; |
1153 | |
1154 UsbEndpointDirection direction; | 1074 UsbEndpointDirection direction; |
1155 size_t size = 0; | 1075 size_t size = 0; |
1156 | 1076 |
1157 if (!ConvertDirectionSafely(transfer.direction, &direction)) { | 1077 if (!ConvertDirectionFromApi(transfer.direction, &direction)) { |
1158 AsyncWorkCompleted(); | 1078 return RespondNow(Error(kErrorConvertDirection)); |
1159 return; | |
1160 } | 1079 } |
1161 | 1080 |
1162 if (!GetTransferSize(transfer, &size)) { | 1081 if (!GetTransferSize(transfer, &size)) { |
1163 CompleteWithError(kErrorInvalidTransferLength); | 1082 return RespondNow(Error(kErrorInvalidTransferLength)); |
1164 return; | |
1165 } | 1083 } |
1166 | 1084 |
1167 scoped_refptr<net::IOBuffer> buffer = | 1085 scoped_refptr<net::IOBuffer> buffer = |
1168 CreateBufferForTransfer(transfer, direction, size); | 1086 CreateBufferForTransfer(transfer, direction, size); |
1169 if (!buffer.get()) { | 1087 if (!buffer.get()) { |
1170 CompleteWithError(kErrorMalformedParameters); | 1088 return RespondNow(Error(kErrorMalformedParameters)); |
1171 return; | |
1172 } | 1089 } |
1173 | 1090 |
1174 int timeout = transfer.timeout ? *transfer.timeout : 0; | 1091 int timeout = transfer.timeout ? *transfer.timeout : 0; |
1175 if (timeout < 0) { | 1092 if (timeout < 0) { |
1176 CompleteWithError(kErrorInvalidTimeout); | 1093 return RespondNow(Error(kErrorInvalidTimeout)); |
1177 return; | |
1178 } | 1094 } |
1179 | 1095 |
1180 device_handle->InterruptTransfer( | 1096 device_handle->InterruptTransfer( |
1181 direction, transfer.endpoint, buffer.get(), size, timeout, | 1097 direction, transfer.endpoint, buffer.get(), size, timeout, |
1182 base::Bind(&UsbInterruptTransferFunction::OnCompleted, this)); | 1098 base::Bind(&UsbInterruptTransferFunction::OnCompleted, this)); |
| 1099 return RespondLater(); |
1183 } | 1100 } |
1184 | 1101 |
1185 UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() { | 1102 UsbIsochronousTransferFunction::UsbIsochronousTransferFunction() { |
1186 } | 1103 } |
1187 | 1104 |
1188 UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() { | 1105 UsbIsochronousTransferFunction::~UsbIsochronousTransferFunction() { |
1189 } | 1106 } |
1190 | 1107 |
1191 bool UsbIsochronousTransferFunction::Prepare() { | 1108 ExtensionFunction::ResponseAction UsbIsochronousTransferFunction::Run() { |
1192 parameters_ = IsochronousTransfer::Params::Create(*args_); | 1109 scoped_ptr<extensions::core_api::usb::IsochronousTransfer::Params> |
1193 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 1110 parameters = IsochronousTransfer::Params::Create(*args_); |
1194 return true; | 1111 EXTENSION_FUNCTION_VALIDATE(parameters.get()); |
1195 } | |
1196 | 1112 |
1197 void UsbIsochronousTransferFunction::AsyncWorkStart() { | |
1198 scoped_refptr<UsbDeviceHandle> device_handle = | 1113 scoped_refptr<UsbDeviceHandle> device_handle = |
1199 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 1114 GetDeviceHandle(parameters->handle); |
1200 if (!device_handle.get()) | 1115 if (!device_handle.get()) { |
1201 return; | 1116 return RespondNow(Error(kErrorNoConnection)); |
| 1117 } |
1202 | 1118 |
1203 const IsochronousTransferInfo& transfer = parameters_->transfer_info; | 1119 const IsochronousTransferInfo& transfer = parameters->transfer_info; |
1204 const GenericTransferInfo& generic_transfer = transfer.transfer_info; | 1120 const GenericTransferInfo& generic_transfer = transfer.transfer_info; |
1205 | |
1206 size_t size = 0; | 1121 size_t size = 0; |
1207 UsbEndpointDirection direction; | 1122 UsbEndpointDirection direction; |
1208 | 1123 |
1209 if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) { | 1124 if (!ConvertDirectionFromApi(generic_transfer.direction, &direction)) { |
1210 AsyncWorkCompleted(); | 1125 return RespondNow(Error(kErrorConvertDirection)); |
1211 return; | |
1212 } | 1126 } |
| 1127 |
1213 if (!GetTransferSize(generic_transfer, &size)) { | 1128 if (!GetTransferSize(generic_transfer, &size)) { |
1214 CompleteWithError(kErrorInvalidTransferLength); | 1129 return RespondNow(Error(kErrorInvalidTransferLength)); |
1215 return; | |
1216 } | 1130 } |
| 1131 |
1217 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) { | 1132 if (transfer.packets < 0 || transfer.packets >= kMaxPackets) { |
1218 CompleteWithError(kErrorInvalidNumberOfPackets); | 1133 return RespondNow(Error(kErrorInvalidNumberOfPackets)); |
1219 return; | |
1220 } | 1134 } |
| 1135 |
1221 unsigned int packets = transfer.packets; | 1136 unsigned int packets = transfer.packets; |
1222 if (transfer.packet_length < 0 || | 1137 if (transfer.packet_length < 0 || |
1223 transfer.packet_length >= kMaxPacketLength) { | 1138 transfer.packet_length >= kMaxPacketLength) { |
1224 CompleteWithError(kErrorInvalidPacketLength); | 1139 return RespondNow(Error(kErrorInvalidPacketLength)); |
1225 return; | |
1226 } | 1140 } |
| 1141 |
1227 unsigned int packet_length = transfer.packet_length; | 1142 unsigned int packet_length = transfer.packet_length; |
1228 const uint64 total_length = packets * packet_length; | 1143 const uint64 total_length = packets * packet_length; |
1229 if (packets > size || total_length > size) { | 1144 if (packets > size || total_length > size) { |
1230 CompleteWithError(kErrorTransferLength); | 1145 return RespondNow(Error(kErrorTransferLength)); |
1231 return; | |
1232 } | 1146 } |
1233 | 1147 |
1234 scoped_refptr<net::IOBuffer> buffer = | 1148 scoped_refptr<net::IOBuffer> buffer = |
1235 CreateBufferForTransfer(generic_transfer, direction, size); | 1149 CreateBufferForTransfer(generic_transfer, direction, size); |
1236 if (!buffer.get()) { | 1150 if (!buffer.get()) { |
1237 CompleteWithError(kErrorMalformedParameters); | 1151 return RespondNow(Error(kErrorMalformedParameters)); |
1238 return; | |
1239 } | 1152 } |
1240 | 1153 |
1241 int timeout = generic_transfer.timeout ? *generic_transfer.timeout : 0; | 1154 int timeout = generic_transfer.timeout ? *generic_transfer.timeout : 0; |
1242 if (timeout < 0) { | 1155 if (timeout < 0) { |
1243 CompleteWithError(kErrorInvalidTimeout); | 1156 return RespondNow(Error(kErrorInvalidTimeout)); |
1244 return; | |
1245 } | 1157 } |
1246 | 1158 |
1247 device_handle->IsochronousTransfer( | 1159 device_handle->IsochronousTransfer( |
1248 direction, generic_transfer.endpoint, buffer.get(), size, packets, | 1160 direction, generic_transfer.endpoint, buffer.get(), size, packets, |
1249 packet_length, timeout, | 1161 packet_length, timeout, |
1250 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this)); | 1162 base::Bind(&UsbIsochronousTransferFunction::OnCompleted, this)); |
| 1163 return RespondLater(); |
1251 } | 1164 } |
1252 | 1165 |
1253 UsbResetDeviceFunction::UsbResetDeviceFunction() { | 1166 UsbResetDeviceFunction::UsbResetDeviceFunction() { |
1254 } | 1167 } |
1255 | 1168 |
1256 UsbResetDeviceFunction::~UsbResetDeviceFunction() { | 1169 UsbResetDeviceFunction::~UsbResetDeviceFunction() { |
1257 } | 1170 } |
1258 | 1171 |
1259 bool UsbResetDeviceFunction::Prepare() { | 1172 ExtensionFunction::ResponseAction UsbResetDeviceFunction::Run() { |
1260 parameters_ = ResetDevice::Params::Create(*args_); | 1173 parameters_ = ResetDevice::Params::Create(*args_); |
1261 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); | 1174 EXTENSION_FUNCTION_VALIDATE(parameters_.get()); |
1262 return true; | 1175 |
| 1176 scoped_refptr<UsbDeviceHandle> device_handle = |
| 1177 GetDeviceHandle(parameters_->handle); |
| 1178 if (!device_handle.get()) { |
| 1179 return RespondNow(Error(kErrorNoConnection)); |
| 1180 } |
| 1181 |
| 1182 device_handle->ResetDevice( |
| 1183 base::Bind(&UsbResetDeviceFunction::OnComplete, this)); |
| 1184 return RespondLater(); |
1263 } | 1185 } |
1264 | 1186 |
1265 void UsbResetDeviceFunction::AsyncWorkStart() { | 1187 void UsbResetDeviceFunction::OnComplete(bool success) { |
1266 scoped_refptr<UsbDeviceHandle> device_handle = | 1188 if (success) { |
1267 GetDeviceHandleOrCompleteWithError(parameters_->handle); | 1189 Respond(OneArgument(new base::FundamentalValue(true))); |
1268 if (!device_handle.get()) | 1190 } else { |
1269 return; | 1191 scoped_refptr<UsbDeviceHandle> device_handle = |
| 1192 GetDeviceHandle(parameters_->handle); |
| 1193 if (device_handle.get()) { |
| 1194 device_handle->Close(); |
| 1195 } |
| 1196 ReleaseDeviceHandle(parameters_->handle); |
1270 | 1197 |
1271 bool success = device_handle->ResetDevice(); | 1198 scoped_ptr<base::ListValue> error_args(new base::ListValue()); |
1272 if (!success) { | 1199 error_args->AppendBoolean(false); |
1273 device_handle->Close(); | 1200 // Returning arguments with an error is wrong but we're stuck with it. |
1274 RemoveUsbDeviceResource(parameters_->handle.handle); | 1201 Respond(ErrorWithArguments(error_args.Pass(), kErrorResetDevice)); |
1275 SetResult(new base::FundamentalValue(false)); | |
1276 CompleteWithError(kErrorResetDevice); | |
1277 return; | |
1278 } | 1202 } |
1279 | |
1280 SetResult(new base::FundamentalValue(true)); | |
1281 AsyncWorkCompleted(); | |
1282 } | 1203 } |
1283 | 1204 |
1284 } // namespace extensions | 1205 } // namespace extensions |
OLD | NEW |