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