summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/api/usb/usb_apitest.cc2
-rw-r--r--chrome/browser/extensions/api/usb/usb_device_resource.cc25
-rw-r--r--chrome/browser/extensions/api/usb/usb_device_resource.h6
-rw-r--r--chrome/browser/usb/usb_device.cc36
-rw-r--r--chrome/browser/usb/usb_device.h10
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