diff options
-rw-r--r-- | chrome/browser/extensions/api/usb/usb_apitest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/api/usb/usb_device_resource.cc | 25 | ||||
-rw-r--r-- | chrome/browser/extensions/api/usb/usb_device_resource.h | 6 | ||||
-rw-r--r-- | chrome/browser/usb/usb_device.cc | 36 | ||||
-rw-r--r-- | chrome/browser/usb/usb_device.h | 10 |
5 files changed, 50 insertions, 29 deletions
diff --git a/chrome/browser/extensions/api/usb/usb_apitest.cc b/chrome/browser/extensions/api/usb/usb_apitest.cc index db62cb7..7ce49d8 100644 --- a/chrome/browser/extensions/api/usb/usb_apitest.cc +++ b/chrome/browser/extensions/api/usb/usb_apitest.cc @@ -19,7 +19,7 @@ namespace { ACTION_TEMPLATE(InvokeUsbTransferCallback, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p1)) { - ::std::tr1::get<k>(args).Run(p1); + ::std::tr1::get<k>(args).Run(p1, new net::IOBuffer(1), 1); } // MSVC erroneously thinks that at least one of the arguments for the transfer diff --git a/chrome/browser/extensions/api/usb/usb_device_resource.cc b/chrome/browser/extensions/api/usb/usb_device_resource.cc index 4f5f6e3..ba1939b4 100644 --- a/chrome/browser/extensions/api/usb/usb_device_resource.cc +++ b/chrome/browser/extensions/api/usb/usb_device_resource.cc @@ -187,7 +187,7 @@ void UsbDeviceResource::ControlTransfer(const ControlTransferInfo& transfer) { device_->ControlTransfer(direction, request_type, recipient, transfer.request, transfer.value, transfer.index, buffer, size, 0, base::Bind(&UsbDeviceResource::TransferComplete, - base::Unretained(this), buffer, size)); + base::Unretained(this))); } void UsbDeviceResource::InterruptTransfer(const GenericTransferInfo& transfer) { @@ -203,7 +203,7 @@ void UsbDeviceResource::InterruptTransfer(const GenericTransferInfo& transfer) { device_->InterruptTransfer(direction, transfer.endpoint, buffer, size, 0, base::Bind(&UsbDeviceResource::TransferComplete, - base::Unretained(this), buffer, size)); + base::Unretained(this))); } void UsbDeviceResource::BulkTransfer(const GenericTransferInfo& transfer) { @@ -219,7 +219,7 @@ void UsbDeviceResource::BulkTransfer(const GenericTransferInfo& transfer) { device_->BulkTransfer(direction, transfer.endpoint, buffer, size, 0, base::Bind(&UsbDeviceResource::TransferComplete, - base::Unretained(this), buffer, size)); + base::Unretained(this))); } void UsbDeviceResource::IsochronousTransfer( @@ -239,19 +239,16 @@ void UsbDeviceResource::IsochronousTransfer( device_->IsochronousTransfer(direction, generic_transfer.endpoint, buffer, size, transfer.packets, transfer.packet_length, 0, base::Bind( - &UsbDeviceResource::TransferComplete, base::Unretained(this), buffer, - size)); + &UsbDeviceResource::TransferComplete, base::Unretained(this))); } -void UsbDeviceResource::TransferComplete(net::IOBuffer* buffer, - const size_t length, - UsbTransferStatus status) { - if (buffer) { - base::BinaryValue* const response_buffer = - base::BinaryValue::CreateWithCopiedBuffer(buffer->data(), length); - event_notifier()->OnTransferComplete(status, - ConvertTransferStatusToErrorString(status), response_buffer); - } +void UsbDeviceResource::TransferComplete(UsbTransferStatus status, + scoped_refptr<net::IOBuffer> buffer, + size_t length) { + base::BinaryValue* response_buffer = + base::BinaryValue::CreateWithCopiedBuffer(buffer->data(), length); + event_notifier()->OnTransferComplete(status, + ConvertTransferStatusToErrorString(status), response_buffer); } } // namespace extensions diff --git a/chrome/browser/extensions/api/usb/usb_device_resource.h b/chrome/browser/extensions/api/usb/usb_device_resource.h index a757304..6abb698 100644 --- a/chrome/browser/extensions/api/usb/usb_device_resource.h +++ b/chrome/browser/extensions/api/usb/usb_device_resource.h @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/memory/linked_ptr.h" +#include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" #include "chrome/browser/extensions/api/api_resource.h" #include "chrome/browser/usb/usb_device.h" @@ -50,8 +51,9 @@ class UsbDeviceResource : public ApiResource { private: // Invoked by the underlying device's transfer callbacks. Indicates transfer // completion to the ApiResource's event notifier. - void TransferComplete(net::IOBuffer* buffer, const size_t length, - UsbTransferStatus status); + void TransferComplete(UsbTransferStatus status, + scoped_refptr<net::IOBuffer> buffer, + size_t length); scoped_refptr<UsbDevice> device_; diff --git a/chrome/browser/usb/usb_device.cc b/chrome/browser/usb/usb_device.cc index c06d01f..d288aea 100644 --- a/chrome/browser/usb/usb_device.cc +++ b/chrome/browser/usb/usb_device.cc @@ -115,10 +115,22 @@ void UsbDevice::TransferComplete(PlatformUsbTransferHandle handle) { // TODO(gdk): Handle device disconnect. DCHECK(ContainsKey(transfers_, handle)) << "Missing transfer completed"; Transfer* const transfer = &transfers_[handle]; - if (transfer->buffer.get()) { - transfer->callback.Run(ConvertTransferStatus(handle->status)); + + // If the transfer is a control transfer we do not expose the control transfer + // setup header to the caller, this logic strips off the header from the + // buffer before invoking the callback provided with the transfer with it. + scoped_refptr<net::IOBuffer> buffer = transfer->buffer; + if (transfer->control_transfer) { + scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBuffer( + handle->actual_length - LIBUSB_CONTROL_SETUP_SIZE); + memcpy(resized_buffer->data(), buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, + handle->actual_length - LIBUSB_CONTROL_SETUP_SIZE); + buffer = resized_buffer; } + transfer->callback.Run(ConvertTransferStatus(handle->status), buffer, + handle->actual_length); + transfers_.erase(handle); libusb_free_transfer(handle); } @@ -130,8 +142,9 @@ void UsbDevice::ControlTransfer(const TransferDirection direction, const UsbTransferCallback& callback) { CheckDevice(); + const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length; scoped_refptr<net::IOBuffer> resized_buffer(new net::IOBufferWithSize( - LIBUSB_CONTROL_SETUP_SIZE + length)); + resized_length)); memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(), length); @@ -143,7 +156,7 @@ void UsbDevice::ControlTransfer(const TransferDirection direction, libusb_fill_control_transfer(transfer, handle_, reinterpret_cast<uint8*>( resized_buffer->data()), reinterpret_cast<libusb_transfer_cb_fn>( &HandleTransferCompletion), this, timeout); - SubmitTransfer(transfer, resized_buffer, callback); + SubmitTransfer(transfer, true, resized_buffer, resized_length, callback); } void UsbDevice::BulkTransfer(const TransferDirection direction, @@ -157,7 +170,7 @@ void UsbDevice::BulkTransfer(const TransferDirection direction, reinterpret_cast<uint8*>(buffer->data()), length, reinterpret_cast<libusb_transfer_cb_fn>(&HandleTransferCompletion), this, timeout); - SubmitTransfer(transfer, buffer, callback); + SubmitTransfer(transfer, false, buffer, length, callback); } void UsbDevice::InterruptTransfer(const TransferDirection direction, @@ -171,7 +184,7 @@ void UsbDevice::InterruptTransfer(const TransferDirection direction, reinterpret_cast<uint8*>(buffer->data()), length, reinterpret_cast<libusb_transfer_cb_fn>(&HandleTransferCompletion), this, timeout); - SubmitTransfer(transfer, buffer, callback); + SubmitTransfer(transfer, false, buffer, length, callback); } void UsbDevice::IsochronousTransfer(const TransferDirection direction, @@ -182,7 +195,7 @@ void UsbDevice::IsochronousTransfer(const TransferDirection direction, const uint64 total_length = packets * packet_length; if (total_length > length) { - callback.Run(USB_TRANSFER_LENGTH_SHORT); + callback.Run(USB_TRANSFER_LENGTH_SHORT, NULL, 0); return; } @@ -194,7 +207,7 @@ void UsbDevice::IsochronousTransfer(const TransferDirection direction, timeout); libusb_set_iso_packet_lengths(transfer, packet_length); - SubmitTransfer(transfer, buffer, callback); + SubmitTransfer(transfer, false, buffer, length, callback); } void UsbDevice::CheckDevice() { @@ -202,16 +215,19 @@ void UsbDevice::CheckDevice() { } void UsbDevice::SubmitTransfer(PlatformUsbTransferHandle handle, + bool control_transfer, net::IOBuffer* buffer, + const size_t length, const UsbTransferCallback& callback) { - libusb_submit_transfer(handle); - Transfer transfer; + transfer.control_transfer = control_transfer; transfer.buffer = buffer; + transfer.length = length; transfer.callback = callback; { base::AutoLock lock(lock_); transfers_[handle] = transfer; + libusb_submit_transfer(handle); } } diff --git a/chrome/browser/usb/usb_device.h b/chrome/browser/usb/usb_device.h index 2ed5087..cc58134 100644 --- a/chrome/browser/usb/usb_device.h +++ b/chrome/browser/usb/usb_device.h @@ -37,7 +37,8 @@ enum UsbTransferStatus { USB_TRANSFER_LENGTH_SHORT, }; -typedef base::Callback<void(UsbTransferStatus)> UsbTransferCallback; +typedef base::Callback<void(UsbTransferStatus, scoped_refptr<net::IOBuffer>, + size_t)> UsbTransferCallback; // A UsbDevice wraps the platform's underlying representation of what a USB // device actually is, and provides accessors for performing many of the @@ -110,7 +111,9 @@ class UsbDevice : public base::RefCounted<UsbDevice> { Transfer(); ~Transfer(); + bool control_transfer; scoped_refptr<net::IOBuffer> buffer; + size_t length; UsbTransferCallback callback; }; @@ -120,7 +123,10 @@ class UsbDevice : public base::RefCounted<UsbDevice> { // Submits a transfer and starts tracking it. Retains the buffer and copies // the completion callback until the transfer finishes, whereupon it invokes // the callback then releases the buffer. - void SubmitTransfer(PlatformUsbTransferHandle handle, net::IOBuffer* buffer, + void SubmitTransfer(PlatformUsbTransferHandle handle, + bool control_transfer, + net::IOBuffer* buffer, + const size_t length, const UsbTransferCallback& callback); // The UsbService isn't referenced here to prevent a dependency cycle between |